xref: /btstack/port/nrf5-cinnamon/port/radio_nrf5.c (revision 2fca4dad957cd7b88f4657ed51e89c12615dda72)
1 /*
2  * Copyright (C) 2021 BlueKitchen GmbH
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the copyright holders nor the names of
14  *    contributors may be used to endorse or promote products derived
15  *    from this software without specific prior written permission.
16  * 4. Any redistribution, use, or modification is done solely for
17  *    personal benefit and not for any commercial purpose or for
18  *    monetary gain.
19  *
20  * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN
24  * GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
30  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  *
33  * Please inquire about commercial licensing options at
34  * [email protected]
35  *
36  */
37 
38 #define BTSTACK_FILE__ "radio_nrf5.c"
39 
40 #include "radio.h"
41 #include "btstack_debug.h"
42 #include <inttypes.h>
43 #include "nrf.h"
44 #include "nrf52.h"
45 #include "nrf_gpio.h"
46 #include "nrf_gpiote.h"
47 
48 #define MAXLEN 37
49 
50 static enum {
51     RADIO_OFF,
52     RADIO_DISABLED,
53     RADIO_W2_TX,
54     RADIO_W4_TX_DONE,
55     RADIO_W4_TX_TO_RX,
56     RADIO_W2_RX,
57     RADIO_W4_RX_DONE,
58     RADIO_W4_RX_TIMEOUT,
59     RADIO_W4_DISABLED,
60 } volatile radio_state;
61 
62 static radio_callback_t radio_callback;
63 static int8_t * rssi_buffer;
64 
65 // channel table: freq in hertz and whitening seed
66 static const struct {
67     uint8_t freq_index;
68     uint8_t  whitening;
69 }  channel_table[] = {
70         {  4, 0x01 /* 00000001 */ },
71         {  6, 0x41 /* 01000001 */ },
72         {  8, 0x21 /* 00100001 */ },
73         { 10, 0x61 /* 01100001 */ },
74         { 12, 0x11 /* 00010001 */ },
75         { 14, 0x51 /* 01010001 */ },
76         { 16, 0x31 /* 00110001 */ },
77         { 18, 0x71 /* 01110001 */ },
78         { 20, 0x09 /* 00001001 */ },
79         { 22, 0x49 /* 01001001 */ },
80         { 24, 0x29 /* 00101001 */ },
81         { 28, 0x69 /* 01101001 */ },
82         { 30, 0x19 /* 00011001 */ },
83         { 32, 0x59 /* 01011001 */ },
84         { 34, 0x39 /* 00111001 */ },
85         { 36, 0x79 /* 01111001 */ },
86         { 38, 0x05 /* 00000101 */ },
87         { 40, 0x45 /* 01000101 */ },
88         { 42, 0x25 /* 00100101 */ },
89         { 44, 0x65 /* 01100101 */ },
90         { 46, 0x15 /* 00010101 */ },
91         { 48, 0x55 /* 01010101 */ },
92         { 50, 0x35 /* 00110101 */ },
93         { 52, 0x75 /* 01110101 */ },
94         { 54, 0x0d /* 00001101 */ },
95         { 56, 0x4d /* 01001101 */ },
96         { 58, 0x2d /* 00101101 */ },
97         { 60, 0x6d /* 01101101 */ },
98         { 62, 0x1d /* 00011101 */ },
99         { 64, 0x5d /* 01011101 */ },
100         { 66, 0x3d /* 00111101 */ },
101         { 68, 0x7d /* 01111101 */ },
102         { 70, 0x03 /* 00000011 */ },
103         { 72, 0x43 /* 01000011 */ },
104         { 74, 0x23 /* 00100011 */ },
105         { 76, 0x63 /* 01100011 */ },
106         { 78, 0x13 /* 00010011 */ },
107         {  2, 0x53 /* 01010011 */ },
108         { 26, 0x33 /* 00110011 */ },
109         { 80, 0x73 /* 01110011 */ },
110 };
111 
radio_init(void)112 void radio_init(void){
113 
114     radio_state = RADIO_OFF;
115 
116     /* TIMER0 setup */
117     NRF_TIMER0->TASKS_STOP = 1;
118     NRF_TIMER0->TASKS_SHUTDOWN = 1;
119     NRF_TIMER0->BITMODE = 3;    /* 32-bit timer */
120     NRF_TIMER0->MODE = 0;       /* Timer mode */
121     NRF_TIMER0->PRESCALER = 4;  /* gives us 1 MHz */
122 
123     // PPI setup
124     // Channel 0: RADIO END -> TIMER0 Start
125     NRF_PPI->CH[0].EEP = (uint32_t)&(NRF_RADIO->EVENTS_END);
126     NRF_PPI->CH[0].TEP = (uint32_t)&(NRF_TIMER0->TASKS_START);
127     // Channel 1: RADIO ADDRESS -> TIMER0 Stop
128     NRF_PPI->CH[1].EEP = (uint32_t)&(NRF_RADIO->EVENTS_ADDRESS);
129     NRF_PPI->CH[1].TEP = (uint32_t)&(NRF_TIMER0->TASKS_STOP);
130 
131 #ifdef NRF51
132     // Handle BLE Radio tuning parameters from production if required.
133     // Does not exist on NRF52
134     // See PCN-083.
135     if (NRF_FICR->OVERRIDEEN & FICR_OVERRIDEEN_BLE_1MBIT_Msk){
136         NRF_RADIO->OVERRIDE0 = NRF_FICR->BLE_1MBIT[0];
137         NRF_RADIO->OVERRIDE1 = NRF_FICR->BLE_1MBIT[1];
138         NRF_RADIO->OVERRIDE2 = NRF_FICR->BLE_1MBIT[2];
139         NRF_RADIO->OVERRIDE3 = NRF_FICR->BLE_1MBIT[3];
140         NRF_RADIO->OVERRIDE4 = NRF_FICR->BLE_1MBIT[4] | 0x80000000;
141     }
142 #endif // NRF51
143 
144     // Mode: BLE 1 Mbps
145     NRF_RADIO->MODE  = RADIO_MODE_MODE_Ble_1Mbit << RADIO_MODE_MODE_Pos;
146 
147     // PacketConfig 0:
148     // ---
149     // LENGTH field in bits = 8
150     // S0 field in bytes = 1
151     // S1 field not used
152     // 8 bit preamble
153     NRF_RADIO->PCNF0 =
154             ( 8 << RADIO_PCNF0_LFLEN_Pos ) |
155             ( 1 << RADIO_PCNF0_S0LEN_Pos ) |
156             ( 0 << RADIO_PCNF0_S1LEN_Pos );
157 
158     // PacketConfig 1:
159     // ---
160     // Payload MAXLEN = MAXLEN
161     // No additional bytes
162     // 4 address bytes (1 + 3)
163     // S0, LENGTH, S1, PAYLOAD in little endian
164     // Packet whitening enabled
165     NRF_RADIO->PCNF1 =
166             ( MAXLEN << RADIO_PCNF1_MAXLEN_Pos) |
167             ( 0 << RADIO_PCNF1_STATLEN_Pos ) |
168             ( 3 << RADIO_PCNF1_BALEN_Pos ) |
169             ( RADIO_PCNF1_ENDIAN_Little << RADIO_PCNF1_ENDIAN_Pos ) |
170             ( RADIO_PCNF1_WHITEEN_Enabled << RADIO_PCNF1_WHITEEN_Pos );
171 
172     // Use logical address 0 for sending and receiving
173     NRF_RADIO->TXADDRESS   = 0;
174     NRF_RADIO->RXADDRESSES = 1 << 0;
175 
176     // 24 bit CRC, skip address field
177     NRF_RADIO->CRCCNF    =
178             ( RADIO_CRCCNF_SKIPADDR_Skip << RADIO_CRCCNF_SKIPADDR_Pos ) |
179             ( RADIO_CRCCNF_LEN_Three << RADIO_CRCCNF_LEN_Pos );
180 
181     // The polynomial has the form of x^24 +x^10 +x^9 +x^6 +x^4 +x^3 +x+1
182     NRF_RADIO->CRCPOLY   = 0x100065B;
183 
184     // Inter frame spacing 150 us
185     NRF_RADIO->TIFS      = 150;
186 
187     // Transmit with max power
188     NRF_RADIO->TXPOWER = (RADIO_TXPOWER_TXPOWER_Pos4dBm << RADIO_TXPOWER_TXPOWER_Pos);
189 
190     // Disable all interrupts
191     NRF_RADIO->INTENCLR = 0xffffffff;
192 
193     // enable Radio IRQs
194     NVIC_SetPriority( RADIO_IRQn, 0 );
195     NVIC_ClearPendingIRQ( RADIO_IRQn );
196     NVIC_EnableIRQ( RADIO_IRQn );
197 
198 #ifdef DEBUG_PIN_HF_CLOCK
199     // debug pins
200     nrf_gpio_cfg_output(DEBUG_PIN_HF_CLOCK);
201     nrf_gpio_cfg_output(DEBUG_PIN_ADDRESS);
202     nrf_gpio_cfg_output(DEBUG_PIN_RX);
203     nrf_gpio_cfg_output(DEBUG_PIN_TX);
204     nrf_gpio_cfg_output(DEBUG_PIN_RADIO_IRQ);
205     // toggle DEBUG_PIN_ADDRESS on RADIO ADDRESS event. Use PPI Channel 19 and GPIOT[0]
206     // NOTE: unclear how pin could be cleared after set on address.
207     nrf_gpiote_task_configure(0, DEBUG_PIN_ADDRESS, GPIOTE_CONFIG_POLARITY_Toggle, NRF_GPIOTE_INITIAL_VALUE_LOW);
208     nrf_gpiote_task_enable(0);
209     NRF_PPI->CH[19].EEP = (uint32_t)&(NRF_RADIO->EVENTS_ADDRESS);
210     NRF_PPI->CH[19].TEP = nrf_gpiote_task_addr_get(0);
211     NRF_PPI->CHENSET = PPI_CHEN_CH19_Msk;
212 #endif
213 }
214 
215 // Enable the High Frequency clock on the processor.
radio_hf_clock_enable_reset(radio_result_t result)216 static void radio_hf_clock_enable_reset(radio_result_t result){
217     UNUSED(result);
218 }
radio_hf_clock_enable(bool wait_until_ready)219 void radio_hf_clock_enable(bool wait_until_ready){
220 
221     // Work around for incomplete RX
222     if (radio_state == RADIO_W4_RX_DONE){
223 #ifdef DEBUG_PIN_HF_CLOCK
224         nrf_gpio_pin_clear(DEBUG_PIN_HF_CLOCK);
225         nrf_gpio_pin_set(DEBUG_PIN_HF_CLOCK);
226 #endif
227 #if 0
228         // state = RX, PAYLOAD = 1, END = 0, DISABLED = 0
229         printf("Enable: STATE    %u\n", (int) NRF_RADIO->STATE);
230         printf("Enable: PAYLOAD  %u\n", (int) NRF_RADIO->EVENTS_PAYLOAD);
231         printf("Enable: END      %u\n", (int) NRF_RADIO->EVENTS_END);
232         printf("Enable: DISABLED %u\n", (int) NRF_RADIO->EVENTS_DISABLED);
233         btstack_assert(false);
234 #else
235         printf("\n\nRADIO_W4_RX_DONE hang\n\n\n");
236         radio_stop(&radio_hf_clock_enable_reset);
237         radio_state = RADIO_DISABLED;
238         return;
239 #endif
240     }
241 
242 #ifdef DEBUG_PIN_HF_CLOCK
243     nrf_gpio_pin_set(DEBUG_PIN_HF_CLOCK);
244 #endif
245 
246 
247     // the RADIO module. Without this clock, no communication is possible.
248     NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
249     NRF_CLOCK->TASKS_HFCLKSTART = 1;
250     if (wait_until_ready){
251         while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0);
252     }
253 
254     radio_state = RADIO_DISABLED;
255 }
256 
radio_hf_clock_disable(void)257 void radio_hf_clock_disable(void) {
258 #ifdef DEBUG_PIN_HF_CLOCK
259     nrf_gpio_pin_clear(DEBUG_PIN_HF_CLOCK);
260 #endif
261 
262     NRF_CLOCK->TASKS_HFCLKSTOP = 1;
263     radio_state = RADIO_OFF;
264 }
265 
radio_set_access_address(uint32_t access_address)266 void radio_set_access_address(uint32_t access_address) {
267     NRF_RADIO->BASE0     = ( access_address << 8 ) & 0xFFFFFF00;
268     NRF_RADIO->PREFIX0   = ( access_address >> 24 ) & RADIO_PREFIX0_AP0_Msk;
269 }
270 
radio_set_crc_init(uint32_t crc_init)271 void radio_set_crc_init(uint32_t crc_init){
272     NRF_RADIO->CRCINIT   = crc_init;
273 }
274 
radio_set_channel(uint8_t channel)275 void radio_set_channel(uint8_t channel){
276     // set frequency based on channel
277     NRF_RADIO->FREQUENCY   = channel_table[channel].freq_index;
278 
279     // initializes data whitening with channel index
280     NRF_RADIO->DATAWHITEIV = channel & 0x3F;
281 }
282 
radio_transmit(radio_callback_t callback,radio_transition_t transition,const uint8_t * packet,uint16_t len)283 void radio_transmit(radio_callback_t callback, radio_transition_t transition, const uint8_t * packet, uint16_t len){
284 
285 #ifdef DEBUG_PIN_TX
286     nrf_gpio_pin_set(DEBUG_PIN_TX);
287 #endif
288 
289     uint16_t state = (uint16_t) NRF_RADIO->STATE;
290 
291     switch (radio_state){
292         case RADIO_W2_TX:
293             // already in transition to tx
294             if (state != RADIO_STATE_STATE_TxRu){
295                 log_info("TX Start after RX, transition %u, state 0x%04x", (int) transition, state);
296                 btstack_assert(false);
297             }
298             break;
299         case RADIO_DISABLED:
300             if (state != RADIO_STATE_STATE_Disabled){
301                 log_info("TX Start after Disabled, transition %u, state 0x%04x", (int) transition, state);
302                 btstack_assert(false);
303             }
304             // start tx
305             NRF_RADIO->TASKS_TXEN = 1;
306             break;
307         default:
308             log_info("TX Start unexpected state: our state %u, transition %u, state 0x%04x", radio_state, (int) transition, state);
309             btstack_assert(false);
310             break;
311     }
312 
313     radio_callback = callback;
314 
315     // set data to send (assume it's valid until tx done)
316     NRF_RADIO->PACKETPTR = (uint32_t) packet;
317 
318     switch (transition){
319         case RADIO_TRANSITION_TX_ONLY:
320             radio_state = RADIO_W4_TX_DONE;
321             NRF_RADIO->SHORTS = RADIO_SHORTS_READY_START_Msk | RADIO_SHORTS_END_DISABLE_Msk;
322             break;
323         case RADIO_TRANSITION_TX_TO_RX:
324             radio_state = RADIO_W4_TX_TO_RX;
325             NRF_RADIO->SHORTS = RADIO_SHORTS_READY_START_Msk | RADIO_SHORTS_END_DISABLE_Msk | RADIO_SHORTS_DISABLED_RXEN_Msk;
326             // - Clear Timer0
327             NRF_TIMER0->TASKS_CLEAR = 1;
328             // - Set CC for receive (ca. 300 us)
329             NRF_TIMER0->CC[1] = 300;    // 300 us
330             NRF_TIMER0->EVENTS_COMPARE[1] = 0;
331             // - END -> Start Timer0
332             NRF_PPI->CHENSET = PPI_CHEN_CH0_Msk;
333             // - Timer0 CC[1] -> Radio END
334             NRF_PPI->CHENSET = PPI_CHEN_CH22_Msk;
335             // - Disable address->stop
336             NRF_PPI->CHENCLR = PPI_CHEN_CH1_Msk;
337             break;
338         default:
339             btstack_assert(false);
340             break;
341     }
342 
343     NRF_RADIO->INTENCLR = 0xffffffff;
344     NRF_RADIO->EVENTS_END = 0;
345     NRF_RADIO->EVENTS_DISABLED = 0;
346 
347     NVIC_ClearPendingIRQ(RADIO_IRQn);
348     NVIC_EnableIRQ(RADIO_IRQn);
349 
350     // Interrupt on DISABLED
351     NRF_RADIO->INTENSET = 0x00000010;
352 }
353 
radio_setup_rx(void)354 static void radio_setup_rx(void){
355     NRF_RADIO->EVENTS_ADDRESS = 0;
356     NRF_RADIO->EVENTS_END = 0;
357     NRF_RADIO->EVENTS_DISABLED = 0;
358     // PPI0: END -> Start Timer0
359     NRF_PPI->CHENCLR = PPI_CHEN_CH0_Msk;
360     // PPI1: Radio Address -> Stop Timer
361     NRF_PPI->CHENSET = PPI_CHEN_CH1_Msk;
362     // Update Shortcuts
363     NRF_RADIO->SHORTS = RADIO_SHORTS_READY_START_Msk | RADIO_SHORTS_ADDRESS_RSSISTART_Msk | RADIO_SHORTS_END_DISABLE_Msk | RADIO_SHORTS_DISABLED_TXEN_Msk;
364 }
365 
radio_receive(radio_callback_t callback,uint32_t timeout_us,uint8_t * buffer,uint16_t len,int8_t * rssi)366 void radio_receive(radio_callback_t callback, uint32_t timeout_us, uint8_t * buffer, uint16_t len, int8_t * rssi){
367 
368 #ifdef DEBUG_PIN_RX
369     nrf_gpio_pin_set(DEBUG_PIN_RX);
370 #endif
371 
372     uint16_t state = (uint16_t) NRF_RADIO->STATE;
373 
374     // log_info("RX Start: our state = 0x%0x, radio_state 0x%04x", radio_state, state);
375 
376     radio_callback = callback;
377     rssi_buffer = rssi;
378 
379     NRF_RADIO->PACKETPTR = (uint32_t) buffer;
380     buffer[0] = 0;
381     buffer[1] = 0;
382 
383     switch (radio_state){
384         case RADIO_W2_RX:
385             // radio setup as part of TX->RX transition
386             switch (state){
387                 case RADIO_STATE_STATE_RxRu:
388                 case RADIO_STATE_STATE_RxIdle:
389                 case RADIO_STATE_STATE_Rx:
390                     break;
391                 default:
392                     btstack_assert(false);
393                     break;
394             }
395             break;
396         case RADIO_DISABLED:
397             btstack_assert(state == RADIO_STATE_STATE_Disabled);
398             // - Stop Timer0
399             NRF_TIMER0->TASKS_STOP = 1;
400             // - Clear Timer0
401             NRF_TIMER0->TASKS_CLEAR = 1;
402             // - Set CC for receive
403             NRF_TIMER0->CC[1] = timeout_us;
404             NRF_TIMER0->EVENTS_COMPARE[1] = 0;
405             // - Timer0 CC[1] -> Radio Disable
406             NRF_PPI->CHENSET = PPI_CHEN_CH22_Msk;
407             // - Start Timer0
408             NRF_TIMER0->TASKS_START = 1;
409             // Start Receive
410             radio_setup_rx();
411             NRF_RADIO->TASKS_RXEN = 1;
412             break;
413         default:
414             log_info("RX unexpected radio_state: state 0x%04x / phy state state 0x%04x", radio_state, state);
415             log_info("cc[1] %" PRIu32 "events_compare[1] %u", NRF_TIMER0->CC[1], (int) NRF_TIMER0->EVENTS_COMPARE[1]);
416             btstack_assert(false);
417             break;
418     }
419 
420     // Disable all interrupts
421     NRF_RADIO->INTENCLR = 0xffffffff;
422 
423     NVIC_ClearPendingIRQ(RADIO_IRQn);
424     NVIC_EnableIRQ(RADIO_IRQn);
425 
426     // Interrupt on DISABLED
427     NRF_RADIO->INTENSET = 0x00000010;
428 
429     radio_state = RADIO_W4_RX_DONE;
430 }
431 
radio_stop(radio_callback_t callback)432 void radio_stop(radio_callback_t callback){
433 
434     // log_info("Disable, state 0x%04x", (uint16_t) NRF_RADIO->STATE);
435 
436     radio_callback = callback;
437 
438     NRF_RADIO->SHORTS = 0;
439 
440     uint16_t state = (uint16_t) NRF_RADIO->STATE;
441     switch (state){
442         case RADIO_STATE_STATE_Disabled:
443             (*callback)(RADIO_RESULT_OK);
444             break;
445         default:
446             radio_state = RADIO_W4_DISABLED;
447             NRF_RADIO->TASKS_DISABLE = 1;
448             break;
449     }
450 }
451 
RADIO_IRQHandler(void)452 void RADIO_IRQHandler(void){
453     uint16_t state = (uint16_t) NRF_RADIO->STATE;
454 
455 #ifdef DEBUG_PIN_RADIO_IRQ
456     nrf_gpio_pin_toggle(DEBUG_PIN_RADIO_IRQ);
457 #endif
458 #ifdef DEBUG_PIN_RX
459     nrf_gpio_pin_clear(DEBUG_PIN_RX);
460 #endif
461 #ifdef DEBUG_PIN_TX
462     nrf_gpio_pin_clear(DEBUG_PIN_TX);
463 #endif
464 
465     switch (radio_state){
466         case RADIO_W4_TX_DONE:
467             // TX Done, no transition to rx requested
468             btstack_assert(state == RADIO_STATE_STATE_Disabled);
469             NRF_RADIO->EVENTS_DISABLED = 0;
470             radio_state = RADIO_DISABLED;
471             (*radio_callback)(RADIO_RESULT_OK);
472             break;
473         case RADIO_W4_TX_TO_RX:
474             // TX Done, transition to rx
475             btstack_assert(state == RADIO_STATE_STATE_RxRu);
476             NRF_RADIO->EVENTS_DISABLED = 0;
477             radio_state = RADIO_W2_RX;
478             radio_setup_rx();
479             (*radio_callback)(RADIO_RESULT_OK);
480             break;
481         case RADIO_W4_RX_DONE:
482             // RX Done
483             btstack_assert(state == RADIO_STATE_STATE_TxRu);
484             NRF_RADIO->EVENTS_DISABLED = 0;
485             NRF_TIMER0->TASKS_STOP = 1;
486             // check EVENTS_COMPARE[1]
487             if (NRF_TIMER0->EVENTS_COMPARE[1]){
488                 // compare event -> timeout
489                 radio_state = RADIO_W4_RX_TIMEOUT;
490                 NRF_RADIO->SHORTS = 0;
491                 NRF_RADIO->TASKS_DISABLE = 1;
492 #ifdef DEBUG_PIN_RX
493                 // toggle twice for timeout
494                 nrf_gpio_pin_toggle(DEBUG_PIN_RX);
495                 nrf_gpio_pin_toggle(DEBUG_PIN_RX);
496                 nrf_gpio_pin_toggle(DEBUG_PIN_RX);
497                 nrf_gpio_pin_toggle(DEBUG_PIN_RX);
498 #endif
499             } else {
500                 // no compare event -> packet with address received
501                 radio_state = RADIO_W2_TX;
502                 // RSSI is stored without sign but is negative (range: 0..127)
503                 if (rssi_buffer != NULL){
504                     uint32_t rssi_sample = NRF_RADIO->RSSISAMPLE;
505                     int8_t rssi;
506                     if (rssi_sample < 128){
507                         rssi = -rssi_sample;
508                     } else {
509                         rssi = -128;
510                     }
511                     *rssi_buffer = rssi;
512                 }
513                 // check CRC
514                 radio_result_t result = ((NRF_RADIO->CRCSTATUS & RADIO_CRCSTATUS_CRCSTATUS_Msk) != 0) ? RADIO_RESULT_OK : RADIO_RESULT_CRC_ERROR;
515 #ifdef DEBUG_PIN_RX
516                 // toggle once for crc error
517                 if (result == RADIO_RESULT_CRC_ERROR){
518                     nrf_gpio_pin_toggle(DEBUG_PIN_RX);
519                     nrf_gpio_pin_toggle(DEBUG_PIN_RX);
520                 }
521 #endif
522                 (*radio_callback)(result);
523             }
524             break;
525         case RADIO_W4_RX_TIMEOUT:
526             // after RX Timeout, RX was started and stopped again
527             btstack_assert(state == RADIO_STATE_STATE_Disabled);
528             NRF_RADIO->EVENTS_DISABLED = 0;
529             radio_state = RADIO_DISABLED;
530             (*radio_callback)(RADIO_RESULT_TIMEOUT);
531             break;
532         case RADIO_W4_DISABLED:
533             NRF_RADIO->EVENTS_DISABLED = 0;
534             NRF_RADIO->INTENCLR = 0xffffffff;
535             radio_state = RADIO_DISABLED;
536             (*radio_callback)(RADIO_RESULT_OK);
537             break;
538         default:
539             log_info("IRQ: our state = 0x%0x, radio_state 0x%04x", radio_state, state);
540             btstack_assert(false);
541             break;
542     }
543 #ifdef DEBUG_PIN_RADIO_IRQ
544     nrf_gpio_pin_toggle(DEBUG_PIN_RADIO_IRQ);
545 #endif
546 }
547