xref: /nrf52832-nimble/packages/NimBLE-latest/nimble/drivers/nrf52/src/ble_phy.c (revision 042d53a763ad75cb1465103098bb88c245d95138)
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements.  See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership.  The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License.  You may obtain a copy of the License at
9  *
10  *  http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  * KIND, either express or implied.  See the License for the
16  * specific language governing permissions and limitations
17  * under the License.
18  */
19 
20 #include <stdint.h>
21 #include <string.h>
22 #include <assert.h>
23 #include "syscfg/syscfg.h"
24 #include "os/os.h"
25 #include "ble/xcvr.h"
26 #include "nimble/ble.h"
27 #include "nimble/nimble_opt.h"
28 #include "nimble/nimble_npl.h"
29 #include "controller/ble_phy.h"
30 #include "controller/ble_phy_trace.h"
31 #include "controller/ble_ll.h"
32 #include "nrfx.h"
33 #if MYNEWT
34 #include "mcu/nrf52_clock.h"
35 #include "mcu/cmsis_nvic.h"
36 #include "hal/hal_gpio.h"
37 #else
38 #include "core_cm4.h"
39 #endif
40 
41 /*
42  * NOTE: This code uses a couple of PPI channels so care should be taken when
43  *       using PPI somewhere else.
44  *
45  * Pre-programmed channels: CH20, CH21, CH23, CH25, CH31
46  * Regular channels: CH4, CH5 and optionally CH17, CH18, CH19
47  *  - CH4 = cancel wfr timer on address match
48  *  - CH5 = disable radio on wfr timer expiry
49  *  - CH17 = (optional) gpio debug for radio ramp-up
50  *  - CH18 = (optional) gpio debug for wfr timer RX enabled
51  *  - CH19 = (optional) gpio debug for wfr timer radio disabled
52  *
53  */
54 
55 /* XXX: 4) Make sure RF is higher priority interrupt than schedule */
56 
57 /*
58  * XXX: Maximum possible transmit time is 1 msec for a 60ppm crystal
59  * and 16ms for a 30ppm crystal! We need to limit PDU size based on
60  * crystal accuracy. Look at this in the spec.
61  */
62 
63 /* XXX: private header file? */
64 extern uint8_t g_nrf_num_irks;
65 extern uint32_t g_nrf_irk_list[];
66 
67 /* To disable all radio interrupts */
68 #define NRF_RADIO_IRQ_MASK_ALL  (0x34FF)
69 
70 /*
71  * We configure the nrf with a 1 byte S0 field, 8 bit length field, and
72  * zero bit S1 field. The preamble is 8 bits long.
73  */
74 #define NRF_LFLEN_BITS          (8)
75 #define NRF_S0LEN               (1)
76 #define NRF_S1LEN_BITS          (0)
77 #define NRF_CILEN_BITS          (2)
78 #define NRF_TERMLEN_BITS        (3)
79 
80 /* Maximum length of frames */
81 #define NRF_MAXLEN              (255)
82 #define NRF_BALEN               (3)     /* For base address of 3 bytes */
83 
84 /* Maximum tx power */
85 #define NRF_TX_PWR_MAX_DBM      (4)
86 #define NRF_TX_PWR_MIN_DBM      (-40)
87 
88 /* NRF_RADIO->PCNF0 configuration values */
89 #define NRF_PCNF0               (NRF_LFLEN_BITS << RADIO_PCNF0_LFLEN_Pos) | \
90                                 (RADIO_PCNF0_S1INCL_Msk) | \
91                                 (NRF_S0LEN << RADIO_PCNF0_S0LEN_Pos) | \
92                                 (NRF_S1LEN_BITS << RADIO_PCNF0_S1LEN_Pos)
93 #define NRF_PCNF0_1M            (NRF_PCNF0) | \
94                                 (RADIO_PCNF0_PLEN_8bit << RADIO_PCNF0_PLEN_Pos)
95 #define NRF_PCNF0_2M            (NRF_PCNF0) | \
96                                 (RADIO_PCNF0_PLEN_16bit << RADIO_PCNF0_PLEN_Pos)
97 #define NRF_PCNF0_CODED         (NRF_PCNF0) | \
98                                 (RADIO_PCNF0_PLEN_LongRange << RADIO_PCNF0_PLEN_Pos) | \
99                                 (NRF_CILEN_BITS << RADIO_PCNF0_CILEN_Pos) | \
100                                 (NRF_TERMLEN_BITS << RADIO_PCNF0_TERMLEN_Pos)
101 
102 /* BLE PHY data structure */
103 struct ble_phy_obj
104 {
105     uint8_t phy_stats_initialized;
106     int8_t  phy_txpwr_dbm;
107     uint8_t phy_chan;
108     uint8_t phy_state;
109     uint8_t phy_transition;
110     uint8_t phy_transition_late;
111     uint8_t phy_rx_started;
112     uint8_t phy_encrypted;
113     uint8_t phy_privacy;
114     uint8_t phy_tx_pyld_len;
115     uint8_t phy_txtorx_phy_mode;
116     uint8_t phy_cur_phy_mode;
117     uint8_t phy_bcc_offset;
118     uint32_t phy_aar_scratch;
119     uint32_t phy_access_address;
120     struct ble_mbuf_hdr rxhdr;
121     void *txend_arg;
122     ble_phy_tx_end_func txend_cb;
123     uint32_t phy_start_cputime;
124 };
125 struct ble_phy_obj g_ble_phy_data;
126 
127 /* XXX: if 27 byte packets desired we can make this smaller */
128 /* Global transmit/receive buffer */
129 static uint32_t g_ble_phy_tx_buf[(BLE_PHY_MAX_PDU_LEN + 3) / 4];
130 static uint32_t g_ble_phy_rx_buf[(BLE_PHY_MAX_PDU_LEN + 3) / 4];
131 
132 #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) == 1)
133 /* Make sure word-aligned for faster copies */
134 static uint32_t g_ble_phy_enc_buf[(BLE_PHY_MAX_PDU_LEN + 3) / 4];
135 #endif
136 
137 /* RF center frequency for each channel index (offset from 2400 MHz) */
138 static const uint8_t g_ble_phy_chan_freq[BLE_PHY_NUM_CHANS] = {
139      4,  6,  8, 10, 12, 14, 16, 18, 20, 22, /* 0-9 */
140     24, 28, 30, 32, 34, 36, 38, 40, 42, 44, /* 10-19 */
141     46, 48, 50, 52, 54, 56, 58, 60, 62, 64, /* 20-29 */
142     66, 68, 70, 72, 74, 76, 78,  2, 26, 80, /* 30-39 */
143 };
144 
145 #if (BLE_LL_BT5_PHY_SUPPORTED == 1)
146 /* packet start offsets (in usecs) */
147 static const uint16_t g_ble_phy_mode_pkt_start_off[BLE_PHY_NUM_MODE] = { 376, 40, 24, 376 };
148 #endif
149 
150 /* Various radio timings */
151 /* Radio ramp-up times in usecs (fast mode) */
152 #define BLE_PHY_T_TXENFAST      (XCVR_TX_RADIO_RAMPUP_USECS)
153 #define BLE_PHY_T_RXENFAST      (XCVR_RX_RADIO_RAMPUP_USECS)
154 /* delay between EVENTS_READY and start of tx */
155 static const uint8_t g_ble_phy_t_txdelay[BLE_PHY_NUM_MODE] = { 5, 4, 3, 5 };
156 /* delay between EVENTS_END and end of txd packet */
157 static const uint8_t g_ble_phy_t_txenddelay[BLE_PHY_NUM_MODE] = { 9, 4, 3, 3 };
158 /* delay between rxd access address (w/ TERM1 for coded) and EVENTS_ADDRESS */
159 static const uint8_t g_ble_phy_t_rxaddrdelay[BLE_PHY_NUM_MODE] = { 17, 6, 2, 17 };
160 /* delay between end of rxd packet and EVENTS_END */
161 static const uint8_t g_ble_phy_t_rxenddelay[BLE_PHY_NUM_MODE] = { 27, 6, 2, 22 };
162 
163 /* Statistics */
164 STATS_SECT_START(ble_phy_stats)
165     STATS_SECT_ENTRY(phy_isrs)
166     STATS_SECT_ENTRY(tx_good)
167     STATS_SECT_ENTRY(tx_fail)
168     STATS_SECT_ENTRY(tx_late)
169     STATS_SECT_ENTRY(tx_bytes)
170     STATS_SECT_ENTRY(rx_starts)
171     STATS_SECT_ENTRY(rx_aborts)
172     STATS_SECT_ENTRY(rx_valid)
173     STATS_SECT_ENTRY(rx_crc_err)
174     STATS_SECT_ENTRY(rx_late)
175     STATS_SECT_ENTRY(radio_state_errs)
176     STATS_SECT_ENTRY(rx_hw_err)
177     STATS_SECT_ENTRY(tx_hw_err)
178 STATS_SECT_END
179 STATS_SECT_DECL(ble_phy_stats) ble_phy_stats;
180 
181 STATS_NAME_START(ble_phy_stats)
182     STATS_NAME(ble_phy_stats, phy_isrs)
183     STATS_NAME(ble_phy_stats, tx_good)
184     STATS_NAME(ble_phy_stats, tx_fail)
185     STATS_NAME(ble_phy_stats, tx_late)
186     STATS_NAME(ble_phy_stats, tx_bytes)
187     STATS_NAME(ble_phy_stats, rx_starts)
188     STATS_NAME(ble_phy_stats, rx_aborts)
189     STATS_NAME(ble_phy_stats, rx_valid)
190     STATS_NAME(ble_phy_stats, rx_crc_err)
191     STATS_NAME(ble_phy_stats, rx_late)
192     STATS_NAME(ble_phy_stats, radio_state_errs)
193     STATS_NAME(ble_phy_stats, rx_hw_err)
194     STATS_NAME(ble_phy_stats, tx_hw_err)
195 STATS_NAME_END(ble_phy_stats)
196 
197 /*
198  * NOTE:
199  * Tested the following to see what would happen:
200  *  -> NVIC has radio irq enabled (interrupt # 1, mask 0x2).
201  *  -> Set up nrf to receive. Clear ADDRESS event register.
202  *  -> Enable ADDRESS interrupt on nrf5 by writing to INTENSET.
203  *  -> Enable RX.
204  *  -> Disable interrupts globally using OS_ENTER_CRITICAL().
205  *  -> Wait until a packet is received and the ADDRESS event occurs.
206  *  -> Call ble_phy_disable().
207  *
208  *  At this point I wanted to see the state of the cortex NVIC. The IRQ
209  *  pending bit was TRUE for the radio interrupt (as expected) as we never
210  *  serviced the radio interrupt (interrupts were disabled).
211  *
212  *  What was unexpected was this: without clearing the pending IRQ in the NVIC,
213  *  when radio interrupts were re-enabled (address event bit in INTENSET set to
214  *  1) and the radio ADDRESS event register read 1 (it was never cleared after
215  *  the first address event), the radio did not enter the ISR! I would have
216  *  expected that if the following were true, an interrupt would occur:
217  *      -> NVIC ISER bit set to TRUE
218  *      -> NVIC ISPR bit reads TRUE, meaning interrupt is pending.
219  *      -> Radio peripheral interrupts are enabled for some event (or events).
220  *      -> Corresponding event register(s) in radio peripheral read 1.
221  *
222  *  Not sure what the end result of all this is. We will clear the pending
223  *  bit in the NVIC just to be sure when we disable the PHY.
224  */
225 
226 #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) == 1)
227 
228 /*
229  * Per nordic, the number of bytes needed for scratch is 16 + MAX_PKT_SIZE.
230  * However, when I used a smaller size it still overwrote the scratchpad. Until
231  * I figure this out I am just going to allocate 67 words so we have enough
232  * space for 267 bytes of scratch. I used 268 bytes since not sure if this
233  * needs to be aligned and burning a byte is no big deal.
234  */
235 //#define NRF_ENC_SCRATCH_WORDS (((MYNEWT_VAL(BLE_LL_MAX_PKT_SIZE) + 16) + 3) / 4)
236 #define NRF_ENC_SCRATCH_WORDS   (67)
237 
238 uint32_t g_nrf_encrypt_scratchpad[NRF_ENC_SCRATCH_WORDS];
239 
240 struct nrf_ccm_data
241 {
242     uint8_t key[16];
243     uint64_t pkt_counter;
244     uint8_t dir_bit;
245     uint8_t iv[8];
246 } __attribute__((packed));
247 
248 struct nrf_ccm_data g_nrf_ccm_data;
249 #endif
250 
251 #ifdef NRF52
252 static void
ble_phy_apply_errata_102_106_107(void)253 ble_phy_apply_errata_102_106_107(void)
254 {
255     /* [102] RADIO: PAYLOAD/END events delayed or not triggered after ADDRESS
256      * [106] RADIO: Higher CRC error rates for some access addresses
257      * [107] RADIO: Immediate address match for access addresses containing MSBs 0x00
258      */
259     *(volatile uint32_t *)0x40001774 = ((*(volatile uint32_t *)0x40001774) &
260                          0xfffffffe) | 0x01000000;
261 }
262 #endif
263 
264 #if (BLE_LL_BT5_PHY_SUPPORTED == 1)
265 
266 /* Packet start offset (in usecs). This is the preamble plus access address.
267  * For LE Coded PHY this also includes CI and TERM1. */
268 uint32_t
ble_phy_mode_pdu_start_off(int phy_mode)269 ble_phy_mode_pdu_start_off(int phy_mode)
270 {
271     return g_ble_phy_mode_pkt_start_off[phy_mode];
272 }
273 
274 #if NRF52840_XXAA
275 static inline bool
ble_phy_mode_is_coded(uint8_t phy_mode)276 ble_phy_mode_is_coded(uint8_t phy_mode)
277 {
278     return (phy_mode == BLE_PHY_MODE_CODED_125KBPS) ||
279            (phy_mode == BLE_PHY_MODE_CODED_500KBPS);
280 }
281 
282 static void
ble_phy_apply_nrf52840_errata(uint8_t new_phy_mode)283 ble_phy_apply_nrf52840_errata(uint8_t new_phy_mode)
284 {
285     bool new_coded = ble_phy_mode_is_coded(new_phy_mode);
286     bool cur_coded = ble_phy_mode_is_coded(g_ble_phy_data.phy_cur_phy_mode);
287 
288     /*
289      * Workarounds should be applied only when switching to/from LE Coded PHY
290      * so no need to apply them every time.
291      *
292      * nRF52840 Engineering A Errata v1.2
293      * [164] RADIO: Low sensitivity in long range mode
294      *
295      * nRF52840 Rev 1 Errata
296      * [191] RADIO: High packet error rate in BLE Long Range mode
297      */
298     if (new_coded == cur_coded) {
299         return;
300     }
301 
302     if (new_coded) {
303 #if MYNEWT_VAL(BLE_PHY_NRF52840_ERRATA_164)
304         /* [164] */
305         *(volatile uint32_t *)0x4000173C |= 0x80000000;
306         *(volatile uint32_t *)0x4000173C =
307                         ((*(volatile uint32_t *)0x4000173C & 0xFFFFFF00) | 0x5C);
308 #endif
309 #if MYNEWT_VAL(BLE_PHY_NRF52840_ERRATA_191)
310         /* [191] */
311         *(volatile uint32_t *) 0x40001740 =
312                         ((*((volatile uint32_t *) 0x40001740)) & 0x7FFF00FF) |
313                         0x80000000 | (((uint32_t)(196)) << 8);
314 #endif
315     } else {
316 #if MYNEWT_VAL(BLE_PHY_NRF52840_ERRATA_164)
317         /* [164] */
318         *(volatile uint32_t *)0x4000173C &= ~0x80000000;
319 #endif
320 #if MYNEWT_VAL(BLE_PHY_NRF52840_ERRATA_191)
321         /* [191] */
322         *(volatile uint32_t *) 0x40001740 =
323                         ((*((volatile uint32_t *) 0x40001740)) & 0x7FFFFFFF);
324 #endif
325     }
326 }
327 #endif
328 
329 void
ble_phy_mode_set(uint8_t new_phy_mode,uint8_t txtorx_phy_mode)330 ble_phy_mode_set(uint8_t new_phy_mode, uint8_t txtorx_phy_mode)
331 {
332     if (new_phy_mode == g_ble_phy_data.phy_cur_phy_mode) {
333         g_ble_phy_data.phy_txtorx_phy_mode = txtorx_phy_mode;
334         return;
335     }
336 
337 #if NRF52840_XXAA
338     ble_phy_apply_nrf52840_errata(new_phy_mode);
339 #endif
340 
341     switch (new_phy_mode) {
342     case BLE_PHY_MODE_1M:
343         NRF_RADIO->MODE = RADIO_MODE_MODE_Ble_1Mbit;
344         NRF_RADIO->PCNF0 = NRF_PCNF0_1M;
345         break;
346 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_2M_PHY)
347     case BLE_PHY_MODE_2M:
348         NRF_RADIO->MODE = RADIO_MODE_MODE_Ble_2Mbit;
349         NRF_RADIO->PCNF0 = NRF_PCNF0_2M;
350         break;
351 #endif
352 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY)
353     case BLE_PHY_MODE_CODED_125KBPS:
354         NRF_RADIO->MODE = RADIO_MODE_MODE_Ble_LR125Kbit;
355         NRF_RADIO->PCNF0 = NRF_PCNF0_CODED;
356         break;
357     case BLE_PHY_MODE_CODED_500KBPS:
358         NRF_RADIO->MODE = RADIO_MODE_MODE_Ble_LR500Kbit;
359         NRF_RADIO->PCNF0 = NRF_PCNF0_CODED;
360         break;
361 #endif
362     default:
363         assert(0);
364     }
365 
366     g_ble_phy_data.phy_cur_phy_mode = new_phy_mode;
367     g_ble_phy_data.phy_txtorx_phy_mode = txtorx_phy_mode;
368 }
369 #endif
370 
371 int
ble_phy_get_cur_phy(void)372 ble_phy_get_cur_phy(void)
373 {
374 #if (BLE_LL_BT5_PHY_SUPPORTED == 1)
375     switch (g_ble_phy_data.phy_cur_phy_mode) {
376         case BLE_PHY_MODE_1M:
377             return BLE_PHY_1M;
378         case BLE_PHY_MODE_2M:
379             return BLE_PHY_2M;
380         case BLE_PHY_MODE_CODED_125KBPS:
381         case BLE_PHY_MODE_CODED_500KBPS:
382             return BLE_PHY_CODED;
383         default:
384             assert(0);
385             return -1;
386     }
387 #else
388     return BLE_PHY_1M;
389 #endif
390 }
391 
392 /**
393  * Copies the data from the phy receive buffer into a mbuf chain.
394  *
395  * @param dptr Pointer to receive buffer
396  * @param rxpdu Pointer to already allocated mbuf chain
397  *
398  * NOTE: the packet header already has the total mbuf length in it. The
399  * lengths of the individual mbufs are not set prior to calling.
400  *
401  */
402 void
ble_phy_rxpdu_copy(uint8_t * dptr,struct os_mbuf * rxpdu)403 ble_phy_rxpdu_copy(uint8_t *dptr, struct os_mbuf *rxpdu)
404 {
405     uint16_t rem_bytes;
406     uint16_t mb_bytes;
407     uint16_t copylen;
408     uint32_t *dst;
409     uint32_t *src;
410     struct os_mbuf *m;
411     struct ble_mbuf_hdr *ble_hdr;
412     struct os_mbuf_pkthdr *pkthdr;
413 
414     /* Better be aligned */
415     assert(((uint32_t)dptr & 3) == 0);
416 
417     pkthdr = OS_MBUF_PKTHDR(rxpdu);
418     rem_bytes = pkthdr->omp_len;
419 
420     /* Fill in the mbuf pkthdr first. */
421     dst = (uint32_t *)(rxpdu->om_data);
422     src = (uint32_t *)dptr;
423 
424     mb_bytes = (rxpdu->om_omp->omp_databuf_len - rxpdu->om_pkthdr_len - 4);
425     copylen = min(mb_bytes, rem_bytes);
426     copylen &= 0xFFFC;
427     rem_bytes -= copylen;
428     mb_bytes -= copylen;
429     rxpdu->om_len = copylen;
430     while (copylen > 0) {
431         *dst = *src;
432         ++dst;
433         ++src;
434         copylen -= 4;
435     }
436 
437     /* Copy remaining bytes */
438     m = rxpdu;
439     while (rem_bytes > 0) {
440         /* If there are enough bytes in the mbuf, copy them and leave */
441         if (rem_bytes <= mb_bytes) {
442             memcpy(m->om_data + m->om_len, src, rem_bytes);
443             m->om_len += rem_bytes;
444             break;
445         }
446 
447         m = SLIST_NEXT(m, om_next);
448         assert(m != NULL);
449 
450         mb_bytes = m->om_omp->omp_databuf_len;
451         copylen = min(mb_bytes, rem_bytes);
452         copylen &= 0xFFFC;
453         rem_bytes -= copylen;
454         mb_bytes -= copylen;
455         m->om_len = copylen;
456         dst = (uint32_t *)m->om_data;
457         while (copylen > 0) {
458             *dst = *src;
459             ++dst;
460             ++src;
461             copylen -= 4;
462         }
463     }
464 
465     /* Copy ble header */
466     ble_hdr = BLE_MBUF_HDR_PTR(rxpdu);
467     memcpy(ble_hdr, &g_ble_phy_data.rxhdr, sizeof(struct ble_mbuf_hdr));
468 }
469 
470 /**
471  * Called when we want to wait if the radio is in either the rx or tx
472  * disable states. We want to wait until that state is over before doing
473  * anything to the radio
474  */
475 static void
nrf_wait_disabled(void)476 nrf_wait_disabled(void)
477 {
478     uint32_t state;
479 
480     state = NRF_RADIO->STATE;
481     if (state != RADIO_STATE_STATE_Disabled) {
482         if ((state == RADIO_STATE_STATE_RxDisable) ||
483             (state == RADIO_STATE_STATE_TxDisable)) {
484             /* This will end within a short time (6 usecs). Just poll */
485             while (NRF_RADIO->STATE == state) {
486                 /* If this fails, something is really wrong. Should last
487                  * no more than 6 usecs */
488             }
489         }
490     }
491 }
492 
493 /**
494  *
495  *
496  */
497 static int
ble_phy_set_start_time(uint32_t cputime,uint8_t rem_usecs,bool tx)498 ble_phy_set_start_time(uint32_t cputime, uint8_t rem_usecs, bool tx)
499 {
500     uint32_t next_cc;
501     uint32_t cur_cc;
502     uint32_t cntr;
503     uint32_t delta;
504 
505     /*
506      * We need to adjust start time to include radio ramp-up and TX pipeline
507      * delay (the latter only if applicable, so only for TX).
508      *
509      * Radio ramp-up time is 40 usecs and TX delay is 3 or 5 usecs depending on
510      * phy, thus we'll offset RTC by 2 full ticks (61 usecs) and then compensate
511      * using TIMER0 with 1 usec precision.
512      */
513 
514     cputime -= 2;
515     rem_usecs += 61;
516     if (tx) {
517         rem_usecs -= BLE_PHY_T_TXENFAST;
518         rem_usecs -= g_ble_phy_t_txdelay[g_ble_phy_data.phy_cur_phy_mode];
519     } else {
520         rem_usecs -= BLE_PHY_T_RXENFAST;
521     }
522 
523     /*
524      * rem_usecs will be no more than 2 ticks, but if it is more than single
525      * tick then we should better count one more low-power tick rather than
526      * 30 high-power usecs. Also make sure we don't set TIMER0 CC to 0 as the
527      * compare won't occur.
528      */
529 
530     if (rem_usecs > 30) {
531         cputime++;
532         rem_usecs -= 30;
533     }
534 
535     /*
536      * Can we set the RTC compare to start TIMER0? We can do it if:
537      *      a) Current compare value is not N+1 or N+2 ticks from current
538      *      counter.
539      *      b) The value we want to set is not at least N+2 from current
540      *      counter.
541      *
542      * NOTE: since the counter can tick 1 while we do these calculations we
543      * need to account for it.
544      */
545     next_cc = cputime & 0xffffff;
546     cur_cc = NRF_RTC0->CC[0];
547     cntr = NRF_RTC0->COUNTER;
548 
549     delta = (cur_cc - cntr) & 0xffffff;
550     if ((delta <= 3) && (delta != 0)) {
551         return -1;
552     }
553     delta = (next_cc - cntr) & 0xffffff;
554     if ((delta & 0x800000) || (delta < 3)) {
555         return -1;
556     }
557 
558     /* Clear and set TIMER0 to fire off at proper time */
559     NRF_TIMER0->TASKS_CLEAR = 1;
560     NRF_TIMER0->CC[0] = rem_usecs;
561     NRF_TIMER0->EVENTS_COMPARE[0] = 0;
562 
563     /* Set RTC compare to start TIMER0 */
564     NRF_RTC0->EVENTS_COMPARE[0] = 0;
565     NRF_RTC0->CC[0] = next_cc;
566     NRF_RTC0->EVTENSET = RTC_EVTENSET_COMPARE0_Msk;
567 
568     /* Enable PPI */
569     NRF_PPI->CHENSET = PPI_CHEN_CH31_Msk;
570 
571     /* Store the cputime at which we set the RTC */
572     g_ble_phy_data.phy_start_cputime = cputime;
573 
574     return 0;
575 }
576 
577 static int
ble_phy_set_start_now(void)578 ble_phy_set_start_now(void)
579 {
580     uint32_t cntr;
581 
582     /* Read current RTC0 state */
583     cntr = NRF_RTC0->COUNTER;
584 
585     /*
586      * Set TIMER0 to fire immediately. We can't set CC to 0 as compare will not
587      * occur in such case.
588      */
589     NRF_TIMER0->TASKS_CLEAR = 1;
590     NRF_TIMER0->CC[0] = 1;
591     NRF_TIMER0->EVENTS_COMPARE[0] = 0;
592 
593     /*
594      * Set RTC compare to start TIMER0. We need to set it to at least N+2 ticks
595      * from current value to guarantee triggering compare event, but let's set
596      * it to N+3 to account for possible extra tick on RTC0 during these
597      * operations.
598      */
599     NRF_RTC0->EVENTS_COMPARE[0] = 0;
600     NRF_RTC0->CC[0] = cntr + 3;
601     NRF_RTC0->EVTENSET = RTC_EVTENSET_COMPARE0_Msk;
602 
603     /* Enable PPI */
604     NRF_PPI->CHENSET = PPI_CHEN_CH31_Msk;
605 
606     /*
607      * Store the cputime at which we set the RTC
608      *
609      * XXX Compare event may be triggered on previous CC value (if it was set to
610      * less than N+2) so in rare cases actual start time may be 2 ticks earlier
611      * than what we expect. Since this is only used on RX, it may cause AUX scan
612      * to be scheduled 1 or 2 ticks too late so we'll miss it - it's acceptable
613      * for now.
614      */
615     g_ble_phy_data.phy_start_cputime = cntr + 3;
616 
617     return 0;
618 }
619 
620 /**
621  * Function is used to set PPI so that we can time out waiting for a reception
622  * to occur. This happens for two reasons: we have sent a packet and we are
623  * waiting for a respons (txrx should be set to ENABLE_TXRX) or we are
624  * starting a connection event and we are a slave and we are waiting for the
625  * master to send us a packet (txrx should be set to ENABLE_RX).
626  *
627  * NOTE: when waiting for a txrx turn-around, wfr_usecs is not used as there
628  * is no additional time to wait; we know when we should receive the address of
629  * the received frame.
630  *
631  * @param txrx Flag denoting if this wfr is a txrx turn-around or not.
632  * @param tx_phy_mode phy mode for last TX (only valid for TX->RX)
633  * @param wfr_usecs Amount of usecs to wait.
634  */
635 void
ble_phy_wfr_enable(int txrx,uint8_t tx_phy_mode,uint32_t wfr_usecs)636 ble_phy_wfr_enable(int txrx, uint8_t tx_phy_mode, uint32_t wfr_usecs)
637 {
638     uint32_t end_time;
639     uint8_t phy;
640 
641     phy = g_ble_phy_data.phy_cur_phy_mode;
642 
643     if (txrx == BLE_PHY_WFR_ENABLE_TXRX) {
644         /* RX shall start exactly T_IFS after TX end captured in CC[2] */
645         end_time = NRF_TIMER0->CC[2] + BLE_LL_IFS;
646         /* Adjust for delay between EVENT_END and actual TX end time */
647         end_time += g_ble_phy_t_txenddelay[tx_phy_mode];
648         /* Wait a bit longer due to allowed active clock accuracy */
649         end_time += 2;
650         /*
651          * It's possible that we'll capture PDU start time at the end of timer
652          * cycle and since wfr expires at the beginning of calculated timer
653          * cycle it can be almost 1 usec too early. Let's compensate for this
654          * by waiting 1 usec more.
655          */
656         end_time += 1;
657 #if MYNEWT_VAL(BLE_PHY_CODED_RX_IFS_EXTRA_MARGIN) > 0
658         if ((phy == BLE_PHY_MODE_CODED_125KBPS) ||
659                                     (phy == BLE_PHY_MODE_CODED_500KBPS)) {
660             /*
661              * Some controllers exceed T_IFS when transmitting on coded phy
662              * so let's wait a bit longer to be able to talk to them if this
663              * workaround is enabled.
664              */
665             end_time += MYNEWT_VAL(BLE_PHY_CODED_RX_IFS_EXTRA_MARGIN);
666         }
667 #endif
668     } else {
669         /*
670          * RX shall start no later than wfr_usecs after RX enabled.
671          * CC[0] is the time of RXEN so adjust for radio ram-up.
672          * Do not add jitter since this is already covered by LL.
673          */
674         end_time = NRF_TIMER0->CC[0] + BLE_PHY_T_RXENFAST + wfr_usecs;
675     }
676 
677     /*
678      * Note: on LE Coded EVENT_ADDRESS is fired after TERM1 is received, so
679      *       we are actually calculating relative to start of packet payload
680      *       which is fine.
681      */
682 
683     /* Adjust for receiving access address since this triggers EVENT_ADDRESS */
684     end_time += ble_phy_mode_pdu_start_off(phy);
685     /* Adjust for delay between actual access address RX and EVENT_ADDRESS */
686     end_time += g_ble_phy_t_rxaddrdelay[phy];
687 
688     /* wfr_secs is the time from rxen until timeout */
689     NRF_TIMER0->CC[3] = end_time;
690     NRF_TIMER0->EVENTS_COMPARE[3] = 0;
691 
692     /* Enable wait for response PPI */
693     NRF_PPI->CHENSET = (PPI_CHEN_CH4_Msk | PPI_CHEN_CH5_Msk);
694 
695     /* Enable the disabled interrupt so we time out on events compare */
696     NRF_RADIO->INTENSET = RADIO_INTENSET_DISABLED_Msk;
697 
698     /*
699      * It may happen that if CPU is halted for a brief moment (e.g. during flash
700      * erase or write), TIMER0 already counted past CC[3] and thus wfr will not
701      * fire as expected. In case this happened, let's just disable PPIs for wfr
702      * and trigger wfr manually (i.e. disable radio).
703      *
704      * Note that the same applies to RX start time set in CC[0] but since it
705      * should fire earlier than wfr, fixing wfr is enough.
706      *
707      * CC[1] is only used as a reference on RX start, we do not need it here so
708      * it can be used to read TIMER0 counter.
709      */
710     NRF_TIMER0->TASKS_CAPTURE[1] = 1;
711     if (NRF_TIMER0->CC[1] > NRF_TIMER0->CC[3]) {
712         NRF_PPI->CHENCLR = PPI_CHEN_CH4_Msk | PPI_CHEN_CH5_Msk;
713         NRF_RADIO->TASKS_DISABLE = 1;
714     }
715 }
716 
717 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION)
718 static uint32_t
ble_phy_get_ccm_datarate(void)719 ble_phy_get_ccm_datarate(void)
720 {
721 #if BLE_LL_BT5_PHY_SUPPORTED
722     switch (g_ble_phy_data.phy_cur_phy_mode) {
723     case BLE_PHY_MODE_1M:
724         return CCM_MODE_DATARATE_1Mbit << CCM_MODE_DATARATE_Pos;
725     case BLE_PHY_MODE_2M:
726         return CCM_MODE_DATARATE_2Mbit << CCM_MODE_DATARATE_Pos;
727 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY)
728     case BLE_PHY_MODE_CODED_125KBPS:
729         return CCM_MODE_DATARATE_125Kbps << CCM_MODE_DATARATE_Pos;
730     case BLE_PHY_MODE_CODED_500KBPS:
731         return CCM_MODE_DATARATE_500Kbps << CCM_MODE_DATARATE_Pos;
732 #endif
733     }
734 
735     assert(0);
736     return 0;
737 #else
738     return CCM_MODE_DATARATE_1Mbit << CCM_MODE_DATARATE_Pos;
739 #endif
740 }
741 #endif
742 
743 /**
744  * Setup transceiver for receive.
745  */
746 static void
ble_phy_rx_xcvr_setup(void)747 ble_phy_rx_xcvr_setup(void)
748 {
749     uint8_t *dptr;
750 
751     dptr = (uint8_t *)&g_ble_phy_rx_buf[0];
752     dptr += 3;
753 
754 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION)
755     if (g_ble_phy_data.phy_encrypted) {
756         NRF_RADIO->PACKETPTR = (uint32_t)&g_ble_phy_enc_buf[0];
757         NRF_CCM->INPTR = (uint32_t)&g_ble_phy_enc_buf[0];
758         NRF_CCM->OUTPTR = (uint32_t)dptr;
759         NRF_CCM->SCRATCHPTR = (uint32_t)&g_nrf_encrypt_scratchpad[0];
760         NRF_CCM->MODE = CCM_MODE_LENGTH_Msk | CCM_MODE_MODE_Decryption |
761                                                     ble_phy_get_ccm_datarate();
762         NRF_CCM->CNFPTR = (uint32_t)&g_nrf_ccm_data;
763         NRF_CCM->SHORTS = 0;
764         NRF_CCM->EVENTS_ERROR = 0;
765         NRF_CCM->EVENTS_ENDCRYPT = 0;
766         NRF_CCM->TASKS_KSGEN = 1;
767         NRF_PPI->CHENSET = PPI_CHEN_CH25_Msk;
768     } else {
769         NRF_RADIO->PACKETPTR = (uint32_t)dptr;
770     }
771 #else
772     NRF_RADIO->PACKETPTR = (uint32_t)dptr;
773 #endif
774 
775 #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) == 1)
776     if (g_ble_phy_data.phy_privacy) {
777         NRF_AAR->ENABLE = AAR_ENABLE_ENABLE_Enabled;
778         NRF_AAR->IRKPTR = (uint32_t)&g_nrf_irk_list[0];
779         NRF_AAR->SCRATCHPTR = (uint32_t)&g_ble_phy_data.phy_aar_scratch;
780         NRF_AAR->EVENTS_END = 0;
781         NRF_AAR->EVENTS_RESOLVED = 0;
782         NRF_AAR->EVENTS_NOTRESOLVED = 0;
783     } else {
784         if (g_ble_phy_data.phy_encrypted == 0) {
785             NRF_AAR->ENABLE = AAR_ENABLE_ENABLE_Disabled;
786         }
787     }
788 #endif
789 
790     /* Turn off trigger TXEN on output compare match and AAR on bcmatch */
791     NRF_PPI->CHENCLR = PPI_CHEN_CH20_Msk | PPI_CHEN_CH23_Msk;
792 
793     /* Reset the rx started flag. Used for the wait for response */
794     g_ble_phy_data.phy_rx_started = 0;
795     g_ble_phy_data.phy_state = BLE_PHY_STATE_RX;
796 
797 #if BLE_LL_BT5_PHY_SUPPORTED
798     /*
799      * On Coded PHY there are CI and TERM1 fields before PDU starts so we need
800      * to take this into account when setting up BCC.
801      */
802     if (g_ble_phy_data.phy_cur_phy_mode == BLE_PHY_MODE_CODED_125KBPS ||
803             g_ble_phy_data.phy_cur_phy_mode == BLE_PHY_MODE_CODED_500KBPS) {
804         g_ble_phy_data.phy_bcc_offset = 5;
805     } else {
806         g_ble_phy_data.phy_bcc_offset = 0;
807     }
808 #else
809     g_ble_phy_data.phy_bcc_offset = 0;
810 #endif
811 
812     /* I want to know when 1st byte received (after address) */
813     NRF_RADIO->BCC = 8 + g_ble_phy_data.phy_bcc_offset; /* in bits */
814     NRF_RADIO->EVENTS_ADDRESS = 0;
815     NRF_RADIO->EVENTS_DEVMATCH = 0;
816     NRF_RADIO->EVENTS_BCMATCH = 0;
817     NRF_RADIO->EVENTS_RSSIEND = 0;
818     NRF_RADIO->EVENTS_CRCOK = 0;
819     NRF_RADIO->SHORTS = RADIO_SHORTS_END_DISABLE_Msk |
820                         RADIO_SHORTS_READY_START_Msk |
821                         RADIO_SHORTS_ADDRESS_BCSTART_Msk |
822                         RADIO_SHORTS_ADDRESS_RSSISTART_Msk |
823                         RADIO_SHORTS_DISABLED_RSSISTOP_Msk;
824 
825     NRF_RADIO->INTENSET = RADIO_INTENSET_ADDRESS_Msk;
826 }
827 
828 /**
829  * Called from interrupt context when the transmit ends
830  *
831  */
832 static void
ble_phy_tx_end_isr(void)833 ble_phy_tx_end_isr(void)
834 {
835 #if (BLE_LL_BT5_PHY_SUPPORTED == 1)
836     int phy;
837 #endif
838     uint8_t tx_phy_mode;
839     uint8_t was_encrypted;
840     uint8_t transition;
841     uint32_t rx_time;
842     uint32_t wfr_time;
843 
844     /* Store PHY on which we've just transmitted smth */
845     tx_phy_mode = g_ble_phy_data.phy_cur_phy_mode;
846 
847     /* If this transmission was encrypted we need to remember it */
848     was_encrypted = g_ble_phy_data.phy_encrypted;
849     (void)was_encrypted;
850 
851     /* Better be in TX state! */
852     assert(g_ble_phy_data.phy_state == BLE_PHY_STATE_TX);
853 
854     /* Clear events and clear interrupt on disabled event */
855     NRF_RADIO->EVENTS_DISABLED = 0;
856     NRF_RADIO->INTENCLR = RADIO_INTENCLR_DISABLED_Msk;
857     NRF_RADIO->EVENTS_END = 0;
858     wfr_time = NRF_RADIO->SHORTS;
859     (void)wfr_time;
860 
861 #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) == 1)
862     /*
863      * XXX: not sure what to do. We had a HW error during transmission.
864      * For now I just count a stat but continue on like all is good.
865      */
866     if (was_encrypted) {
867         if (NRF_CCM->EVENTS_ERROR) {
868             STATS_INC(ble_phy_stats, tx_hw_err);
869             NRF_CCM->EVENTS_ERROR = 0;
870         }
871     }
872 #endif
873 
874     /* Call transmit end callback */
875     if (g_ble_phy_data.txend_cb) {
876         g_ble_phy_data.txend_cb(g_ble_phy_data.txend_arg);
877     }
878 
879     transition = g_ble_phy_data.phy_transition;
880     if (transition == BLE_PHY_TRANSITION_TX_RX) {
881 
882 #if (BLE_LL_BT5_PHY_SUPPORTED == 1)
883         /* See if a new phy has been specified for tx to rx transition */
884         phy = g_ble_phy_data.phy_txtorx_phy_mode;
885         if (phy != g_ble_phy_data.phy_cur_phy_mode) {
886             ble_phy_mode_set(phy, phy);
887         }
888 #endif
889 
890         /* Packet pointer needs to be reset. */
891         ble_phy_rx_xcvr_setup();
892 
893         ble_phy_wfr_enable(BLE_PHY_WFR_ENABLE_TXRX, tx_phy_mode, 0);
894 
895         /* Schedule RX exactly T_IFS after TX end captured in CC[2] */
896         rx_time = NRF_TIMER0->CC[2] + BLE_LL_IFS;
897         /* Adjust for delay between EVENT_END and actual TX end time */
898         rx_time += g_ble_phy_t_txenddelay[tx_phy_mode];
899         /* Adjust for radio ramp-up */
900         rx_time -= BLE_PHY_T_RXENFAST;
901         /* Start listening a bit earlier due to allowed active clock accuracy */
902         rx_time -= 2;
903 
904         NRF_TIMER0->CC[0] = rx_time;
905         NRF_TIMER0->EVENTS_COMPARE[0] = 0;
906         NRF_PPI->CHENSET = PPI_CHEN_CH21_Msk;
907     } else {
908         /*
909          * XXX: not sure we need to stop the timer here all the time. Or that
910          * it should be stopped here.
911          */
912         NRF_TIMER0->TASKS_STOP = 1;
913         NRF_TIMER0->TASKS_SHUTDOWN = 1;
914         NRF_PPI->CHENCLR = PPI_CHEN_CH4_Msk | PPI_CHEN_CH5_Msk |
915                            PPI_CHEN_CH20_Msk | PPI_CHEN_CH31_Msk;
916         assert(transition == BLE_PHY_TRANSITION_NONE);
917     }
918 }
919 
920 static inline uint8_t
ble_phy_get_cur_rx_phy_mode(void)921 ble_phy_get_cur_rx_phy_mode(void)
922 {
923     uint8_t phy;
924 
925     phy = g_ble_phy_data.phy_cur_phy_mode;
926 
927 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY)
928     /*
929      * For Coded PHY mode can be set to either codings since actual coding is
930      * set in packet header. However, here we need actual coding of received
931      * packet as this determines pipeline delays so need to figure this out
932      * using CI field.
933      */
934     if ((phy == BLE_PHY_MODE_CODED_125KBPS) ||
935                                     (phy == BLE_PHY_MODE_CODED_500KBPS)) {
936         phy = NRF_RADIO->PDUSTAT & RADIO_PDUSTAT_CISTAT_Msk ?
937                                    BLE_PHY_MODE_CODED_500KBPS :
938                                    BLE_PHY_MODE_CODED_125KBPS;
939     }
940 #endif
941 
942     return phy;
943 }
944 
945 static void
ble_phy_rx_end_isr(void)946 ble_phy_rx_end_isr(void)
947 {
948     int rc;
949     uint8_t *dptr;
950     uint8_t crcok;
951     uint32_t tx_time;
952     struct ble_mbuf_hdr *ble_hdr;
953 
954     /* Clear events and clear interrupt */
955     NRF_RADIO->EVENTS_END = 0;
956     NRF_RADIO->INTENCLR = RADIO_INTENCLR_END_Msk;
957 
958     /* Disable automatic RXEN */
959     NRF_PPI->CHENCLR = PPI_CHEN_CH21_Msk;
960 
961     /* Set RSSI and CRC status flag in header */
962     ble_hdr = &g_ble_phy_data.rxhdr;
963     assert(NRF_RADIO->EVENTS_RSSIEND != 0);
964     ble_hdr->rxinfo.rssi = -1 * NRF_RADIO->RSSISAMPLE;
965 
966     dptr = (uint8_t *)&g_ble_phy_rx_buf[0];
967     dptr += 3;
968 
969     /* Count PHY crc errors and valid packets */
970     crcok = NRF_RADIO->EVENTS_CRCOK;
971     if (!crcok) {
972         STATS_INC(ble_phy_stats, rx_crc_err);
973     } else {
974         STATS_INC(ble_phy_stats, rx_valid);
975         ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_CRC_OK;
976 #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) == 1)
977         if (g_ble_phy_data.phy_encrypted) {
978             /* Only set MIC failure flag if frame is not zero length */
979             if ((dptr[1] != 0) && (NRF_CCM->MICSTATUS == 0)) {
980                 ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_MIC_FAILURE;
981             }
982 
983             /*
984              * XXX: not sure how to deal with this. This should not
985              * be a MIC failure but we should not hand it up. I guess
986              * this is just some form of rx error and that is how we
987              * handle it? For now, just set CRC error flags
988              */
989             if (NRF_CCM->EVENTS_ERROR) {
990                 STATS_INC(ble_phy_stats, rx_hw_err);
991                 ble_hdr->rxinfo.flags &= ~BLE_MBUF_HDR_F_CRC_OK;
992             }
993 
994             /*
995              * XXX: This is a total hack work-around for now but I dont
996              * know what else to do. If ENDCRYPT is not set and we are
997              * encrypted we need to not trust this frame and drop it.
998              */
999             if (NRF_CCM->EVENTS_ENDCRYPT == 0) {
1000                 STATS_INC(ble_phy_stats, rx_hw_err);
1001                 ble_hdr->rxinfo.flags &= ~BLE_MBUF_HDR_F_CRC_OK;
1002             }
1003         }
1004 #endif
1005     }
1006 
1007     /*
1008      * Let's schedule TX now and we will just cancel it after processing RXed
1009      * packet if we don't need TX.
1010      *
1011      * We need this to initiate connection in case AUX_CONNECT_REQ was sent on
1012      * LE Coded S8. In this case the time we process RXed packet is roughly the
1013      * same as the limit when we need to have TX scheduled (i.e. TIMER0 and PPI
1014      * armed) so we may simply miss the slot and set the timer in the past.
1015      *
1016      * When TX is scheduled in advance, we may event process packet a bit longer
1017      * during radio ramp-up - this gives us extra 40 usecs which is more than
1018      * enough.
1019      */
1020 
1021     /* Schedule TX exactly T_IFS after RX end captured in CC[2] */
1022     tx_time = NRF_TIMER0->CC[2] + BLE_LL_IFS;
1023     /* Adjust for delay between actual RX end time and EVENT_END */
1024     tx_time -= g_ble_phy_t_rxenddelay[ble_hdr->rxinfo.phy_mode];
1025     /* Adjust for radio ramp-up */
1026     tx_time -= BLE_PHY_T_TXENFAST;
1027     /* Adjust for delay between EVENT_READY and actual TX start time */
1028     /* XXX: we may have asymmetric phy so next phy may be different... */
1029     tx_time -= g_ble_phy_t_txdelay[g_ble_phy_data.phy_cur_phy_mode];
1030 
1031     NRF_TIMER0->CC[0] = tx_time;
1032     NRF_TIMER0->EVENTS_COMPARE[0] = 0;
1033     NRF_PPI->CHENSET = PPI_CHEN_CH20_Msk;
1034 
1035     /*
1036      * XXX: Hack warning!
1037      *
1038      * It may happen (during flash erase) that CPU is stopped for a moment and
1039      * TIMER0 already counted past CC[0]. In such case we will be stuck waiting
1040      * for TX to start since EVENTS_COMPARE[0] will not happen any time soon.
1041      * For now let's set a flag denoting that we are late in RX-TX transition so
1042      * ble_phy_tx() will fail - this allows everything to cleanup nicely without
1043      * the need for extra handling in many places.
1044      *
1045      * Note: CC[3] is used only for wfr which we do not need here.
1046      */
1047     NRF_TIMER0->TASKS_CAPTURE[3] = 1;
1048     if (NRF_TIMER0->CC[3] > NRF_TIMER0->CC[0]) {
1049         NRF_PPI->CHENCLR = PPI_CHEN_CH20_Msk;
1050         g_ble_phy_data.phy_transition_late = 1;
1051     }
1052 
1053     /*
1054      * XXX: This is a horrible ugly hack to deal with the RAM S1 byte
1055      * that is not sent over the air but is present here. Simply move the
1056      * data pointer to deal with it. Fix this later.
1057      */
1058     dptr[2] = dptr[1];
1059     dptr[1] = dptr[0];
1060     rc = ble_ll_rx_end(dptr + 1, ble_hdr);
1061     if (rc < 0) {
1062         ble_phy_disable();
1063     }
1064 }
1065 
1066 static bool
ble_phy_rx_start_isr(void)1067 ble_phy_rx_start_isr(void)
1068 {
1069     int rc;
1070     uint32_t state;
1071     uint32_t usecs;
1072     uint32_t pdu_usecs;
1073     uint32_t ticks;
1074     struct ble_mbuf_hdr *ble_hdr;
1075     uint8_t *dptr;
1076 
1077     dptr = (uint8_t *)&g_ble_phy_rx_buf[0];
1078 
1079     /* Clear events and clear interrupt */
1080     NRF_RADIO->EVENTS_ADDRESS = 0;
1081 
1082     /* Clear wfr timer channels and DISABLED interrupt */
1083     NRF_RADIO->INTENCLR = RADIO_INTENCLR_DISABLED_Msk | RADIO_INTENCLR_ADDRESS_Msk;
1084     NRF_PPI->CHENCLR = PPI_CHEN_CH4_Msk | PPI_CHEN_CH5_Msk;
1085 
1086     /* Initialize the ble mbuf header */
1087     ble_hdr = &g_ble_phy_data.rxhdr;
1088     ble_hdr->rxinfo.flags = ble_ll_state_get();
1089     ble_hdr->rxinfo.channel = g_ble_phy_data.phy_chan;
1090     ble_hdr->rxinfo.handle = 0;
1091     ble_hdr->rxinfo.phy = ble_phy_get_cur_phy();
1092     ble_hdr->rxinfo.phy_mode = ble_phy_get_cur_rx_phy_mode();
1093 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
1094     ble_hdr->rxinfo.user_data = NULL;
1095 #endif
1096 
1097     /*
1098      * Calculate accurate packets start time (with remainder)
1099      *
1100      * We may start receiving packet somewhere during preamble in which case
1101      * it is possible that actual transmission started before TIMER0 was
1102      * running - need to take this into account.
1103      */
1104     ble_hdr->beg_cputime = g_ble_phy_data.phy_start_cputime;
1105 
1106     usecs = NRF_TIMER0->CC[1];
1107     pdu_usecs = ble_phy_mode_pdu_start_off(ble_hdr->rxinfo.phy_mode) +
1108                 g_ble_phy_t_rxaddrdelay[ble_hdr->rxinfo.phy_mode];
1109     if (usecs < pdu_usecs) {
1110         g_ble_phy_data.phy_start_cputime--;
1111         usecs += 30;
1112     }
1113     usecs -= pdu_usecs;
1114 
1115     ticks = os_cputime_usecs_to_ticks(usecs);
1116     usecs -= os_cputime_ticks_to_usecs(ticks);
1117     if (usecs == 31) {
1118         usecs = 0;
1119         ++ticks;
1120     }
1121 
1122     ble_hdr->beg_cputime += ticks;
1123     ble_hdr->rem_usecs = usecs;
1124 
1125     /* XXX: I wonder if we always have the 1st byte. If we need to wait for
1126      * rx chain delay, it could be 18 usecs from address interrupt. The
1127        nrf52 may be able to get here early. */
1128     /* Wait to get 1st byte of frame */
1129     while (1) {
1130         state = NRF_RADIO->STATE;
1131         if (NRF_RADIO->EVENTS_BCMATCH != 0) {
1132             break;
1133         }
1134 
1135         /*
1136          * If state is disabled, we should have the BCMATCH. If not,
1137          * something is wrong!
1138          */
1139         if (state == RADIO_STATE_STATE_Disabled) {
1140             NRF_RADIO->INTENCLR = NRF_RADIO_IRQ_MASK_ALL;
1141             NRF_RADIO->SHORTS = 0;
1142             return false;
1143         }
1144     }
1145 
1146     /* Call Link Layer receive start function */
1147     rc = ble_ll_rx_start(dptr + 3,
1148                          g_ble_phy_data.phy_chan,
1149                          &g_ble_phy_data.rxhdr);
1150     if (rc >= 0) {
1151         /* Set rx started flag and enable rx end ISR */
1152         g_ble_phy_data.phy_rx_started = 1;
1153         NRF_RADIO->INTENSET = RADIO_INTENSET_END_Msk;
1154 
1155 #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) == 1)
1156         /* Must start aar if we need to  */
1157         if (g_ble_phy_data.phy_privacy) {
1158             NRF_RADIO->EVENTS_BCMATCH = 0;
1159             NRF_PPI->CHENSET = PPI_CHEN_CH23_Msk;
1160 
1161             /*
1162              * Setup AAR to resolve AdvA and trigger it after complete address
1163              * is received, i.e. after PDU header and AdvA is received.
1164              *
1165              * AdvA starts at 4th octet in receive buffer, after S0, len and S1
1166              * fields.
1167              *
1168              * In case of extended advertising AdvA is located after extended
1169              * header (+2 octets).
1170              */
1171             if (BLE_MBUF_HDR_EXT_ADV(&g_ble_phy_data.rxhdr)) {
1172                 NRF_AAR->ADDRPTR = (uint32_t)(dptr + 5);
1173                 NRF_RADIO->BCC = (BLE_DEV_ADDR_LEN + BLE_LL_PDU_HDR_LEN + 2) * 8 +
1174                                  g_ble_phy_data.phy_bcc_offset;
1175             } else {
1176                 NRF_AAR->ADDRPTR = (uint32_t)(dptr + 3);
1177                 NRF_RADIO->BCC = (BLE_DEV_ADDR_LEN + BLE_LL_PDU_HDR_LEN) * 8 +
1178                                  g_ble_phy_data.phy_bcc_offset;
1179             }
1180         }
1181 #endif
1182     } else {
1183         /* Disable PHY */
1184         ble_phy_disable();
1185         STATS_INC(ble_phy_stats, rx_aborts);
1186     }
1187 
1188     /* Count rx starts */
1189     STATS_INC(ble_phy_stats, rx_starts);
1190 
1191     return true;
1192 }
1193 
1194 static void
ble_phy_isr(void)1195 ble_phy_isr(void)
1196 {
1197     uint32_t irq_en;
1198 
1199     os_trace_isr_enter();
1200 
1201     /* Read irq register to determine which interrupts are enabled */
1202     irq_en = NRF_RADIO->INTENCLR;
1203 
1204     /*
1205      * NOTE: order of checking is important! Possible, if things get delayed,
1206      * we have both an ADDRESS and DISABLED interrupt in rx state. If we get
1207      * an address, we disable the DISABLED interrupt.
1208      */
1209 
1210     /* We get this if we have started to receive a frame */
1211     if ((irq_en & RADIO_INTENCLR_ADDRESS_Msk) && NRF_RADIO->EVENTS_ADDRESS) {
1212         /*
1213          * wfr timer is calculated to expire at the exact time we should start
1214          * receiving a packet (with 1 usec precision) so it is possible  it will
1215          * fire at the same time as EVENT_ADDRESS. If this happens, radio will
1216          * be disabled while we are waiting for EVENT_BCCMATCH after 1st byte
1217          * of payload is received and ble_phy_rx_start_isr() will fail. In this
1218          * case we should not clear DISABLED irq mask so it will be handled as
1219          * regular radio disabled event below. In other case radio was disabled
1220          * on purpose and there's nothing more to handle so we can clear mask.
1221          */
1222         if (ble_phy_rx_start_isr()) {
1223             irq_en &= ~RADIO_INTENCLR_DISABLED_Msk;
1224         }
1225     }
1226 
1227     /* Check for disabled event. This only happens for transmits now */
1228     if ((irq_en & RADIO_INTENCLR_DISABLED_Msk) && NRF_RADIO->EVENTS_DISABLED) {
1229         if (g_ble_phy_data.phy_state == BLE_PHY_STATE_RX) {
1230             NRF_RADIO->EVENTS_DISABLED = 0;
1231             ble_ll_wfr_timer_exp(NULL);
1232         } else if (g_ble_phy_data.phy_state == BLE_PHY_STATE_IDLE) {
1233             assert(0);
1234         } else {
1235             ble_phy_tx_end_isr();
1236         }
1237     }
1238 
1239     /* Receive packet end (we dont enable this for transmit) */
1240     if ((irq_en & RADIO_INTENCLR_END_Msk) && NRF_RADIO->EVENTS_END) {
1241         ble_phy_rx_end_isr();
1242     }
1243 
1244     g_ble_phy_data.phy_transition_late = 0;
1245 
1246     /* Ensures IRQ is cleared */
1247     irq_en = NRF_RADIO->SHORTS;
1248 
1249     /* Count # of interrupts */
1250     STATS_INC(ble_phy_stats, phy_isrs);
1251 
1252     os_trace_isr_exit();
1253 }
1254 
1255 #if MYNEWT_VAL(BLE_PHY_DBG_TIME_TXRXEN_READY_PIN) >= 0 || \
1256         MYNEWT_VAL(BLE_PHY_DBG_TIME_ADDRESS_END_PIN) >= 0 || \
1257         MYNEWT_VAL(BLE_PHY_DBG_TIME_WFR_PIN) >= 0
1258 static inline void
ble_phy_dbg_time_setup_gpiote(int index,int pin)1259 ble_phy_dbg_time_setup_gpiote(int index, int pin)
1260 {
1261     NRF_GPIO_Type *port;
1262 
1263 #if NRF52840_XXAA
1264     port = pin > 31 ? NRF_P1 : NRF_P0;
1265     pin &= 0x1f;
1266 #else
1267     port = NRF_P0;
1268 #endif
1269 
1270     /* Configure GPIO directly to avoid dependency to hal_gpio (for porting) */
1271     port->DIRSET = (1 << pin);
1272     port->OUTCLR = (1 << pin);
1273 
1274     NRF_GPIOTE->CONFIG[index] =
1275                         (GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos) |
1276                         ((pin & 0x1F) << GPIOTE_CONFIG_PSEL_Pos) |
1277 #if NRF52840_XXAA
1278                         ((port == NRF_P1) << GPIOTE_CONFIG_PORT_Pos);
1279 #else
1280                         0;
1281 #endif
1282 }
1283 #endif
1284 
1285 static void
ble_phy_dbg_time_setup(void)1286 ble_phy_dbg_time_setup(void)
1287 {
1288     int gpiote_idx __attribute__((unused)) = 8;
1289 
1290     /*
1291      * We setup GPIOTE starting from last configuration index to minimize risk
1292      * of conflict with GPIO setup via hal. It's not great solution, but since
1293      * this is just debugging code we can live with this.
1294      */
1295 
1296 #if MYNEWT_VAL(BLE_PHY_DBG_TIME_TXRXEN_READY_PIN) >= 0
1297     ble_phy_dbg_time_setup_gpiote(--gpiote_idx,
1298                               MYNEWT_VAL(BLE_PHY_DBG_TIME_TXRXEN_READY_PIN));
1299 
1300     NRF_PPI->CH[17].EEP = (uint32_t)&(NRF_RADIO->EVENTS_READY);
1301     NRF_PPI->CH[17].TEP = (uint32_t)&(NRF_GPIOTE->TASKS_CLR[gpiote_idx]);
1302     NRF_PPI->CHENSET = PPI_CHEN_CH17_Msk;
1303 
1304     /* CH[20] and PPI CH[21] are on to trigger TASKS_TXEN or TASKS_RXEN */
1305     NRF_PPI->FORK[20].TEP = (uint32_t)&(NRF_GPIOTE->TASKS_SET[gpiote_idx]);
1306     NRF_PPI->FORK[21].TEP = (uint32_t)&(NRF_GPIOTE->TASKS_SET[gpiote_idx]);
1307 #endif
1308 
1309 #if MYNEWT_VAL(BLE_PHY_DBG_TIME_ADDRESS_END_PIN) >= 0
1310     ble_phy_dbg_time_setup_gpiote(--gpiote_idx,
1311                               MYNEWT_VAL(BLE_PHY_DBG_TIME_ADDRESS_END_PIN));
1312 
1313     /* CH[26] and CH[27] are always on for EVENT_ADDRESS and EVENT_END */
1314     NRF_PPI->FORK[26].TEP = (uint32_t)&(NRF_GPIOTE->TASKS_SET[gpiote_idx]);
1315     NRF_PPI->FORK[27].TEP = (uint32_t)&(NRF_GPIOTE->TASKS_CLR[gpiote_idx]);
1316 #endif
1317 
1318 #if MYNEWT_VAL(BLE_PHY_DBG_TIME_WFR_PIN) >= 0
1319     ble_phy_dbg_time_setup_gpiote(--gpiote_idx,
1320                               MYNEWT_VAL(BLE_PHY_DBG_TIME_WFR_PIN));
1321 
1322 #if NRF52840_XXAA
1323     NRF_PPI->CH[18].EEP = (uint32_t)&(NRF_RADIO->EVENTS_RXREADY);
1324 #else
1325     NRF_PPI->CH[18].EEP = (uint32_t)&(NRF_RADIO->EVENTS_READY);
1326 #endif
1327     NRF_PPI->CH[18].TEP = (uint32_t)&(NRF_GPIOTE->TASKS_SET[gpiote_idx]);
1328     NRF_PPI->CH[19].EEP = (uint32_t)&(NRF_RADIO->EVENTS_DISABLED);
1329     NRF_PPI->CH[19].TEP = (uint32_t)&(NRF_GPIOTE->TASKS_CLR[gpiote_idx]);
1330     NRF_PPI->CHENSET = PPI_CHEN_CH18_Msk | PPI_CHEN_CH19_Msk;
1331 
1332     /* CH[4] and CH[5] are always on for wfr */
1333     NRF_PPI->FORK[4].TEP = (uint32_t)&(NRF_GPIOTE->TASKS_CLR[gpiote_idx]);
1334     NRF_PPI->FORK[5].TEP = (uint32_t)&(NRF_GPIOTE->TASKS_CLR[gpiote_idx]);
1335 #endif
1336 }
1337 
1338 /**
1339  * ble phy init
1340  *
1341  * Initialize the PHY.
1342  *
1343  * @return int 0: success; PHY error code otherwise
1344  */
1345 int
ble_phy_init(void)1346 ble_phy_init(void)
1347 {
1348     int rc;
1349 
1350     /* Default phy to use is 1M */
1351     g_ble_phy_data.phy_cur_phy_mode = BLE_PHY_MODE_1M;
1352     g_ble_phy_data.phy_txtorx_phy_mode = BLE_PHY_MODE_1M;
1353 
1354 #if !defined(BLE_XCVR_RFCLK)
1355     /* BLE wants the HFXO on all the time in this case */
1356     ble_phy_rfclk_enable();
1357 
1358     /*
1359      * XXX: I do not think we need to wait for settling time here since
1360      * we will probably not use the radio for longer than the settling time
1361      * and it will only degrade performance. Might want to wait here though.
1362      */
1363 #endif
1364 
1365     /* Set phy channel to an invalid channel so first set channel works */
1366     g_ble_phy_data.phy_chan = BLE_PHY_NUM_CHANS;
1367 
1368     /* Toggle peripheral power to reset (just in case) */
1369     NRF_RADIO->POWER = 0;
1370     NRF_RADIO->POWER = 1;
1371 
1372     /* Disable all interrupts */
1373     NRF_RADIO->INTENCLR = NRF_RADIO_IRQ_MASK_ALL;
1374 
1375     /* Set configuration registers */
1376     NRF_RADIO->MODE = RADIO_MODE_MODE_Ble_1Mbit;
1377     NRF_RADIO->PCNF0 = NRF_PCNF0;
1378 
1379     /* XXX: should maxlen be 251 for encryption? */
1380     NRF_RADIO->PCNF1 = NRF_MAXLEN |
1381                        (RADIO_PCNF1_ENDIAN_Little <<  RADIO_PCNF1_ENDIAN_Pos) |
1382                        (NRF_BALEN << RADIO_PCNF1_BALEN_Pos) |
1383                        RADIO_PCNF1_WHITEEN_Msk;
1384 
1385     /* Enable radio fast ramp-up */
1386     NRF_RADIO->MODECNF0 |= (RADIO_MODECNF0_RU_Fast << RADIO_MODECNF0_RU_Pos) &
1387                             RADIO_MODECNF0_RU_Msk;
1388 
1389     /* Set logical address 1 for TX and RX */
1390     NRF_RADIO->TXADDRESS  = 0;
1391     NRF_RADIO->RXADDRESSES  = (1 << 0);
1392 
1393     /* Configure the CRC registers */
1394     NRF_RADIO->CRCCNF = (RADIO_CRCCNF_SKIPADDR_Skip << RADIO_CRCCNF_SKIPADDR_Pos) | RADIO_CRCCNF_LEN_Three;
1395 
1396     /* Configure BLE poly */
1397     NRF_RADIO->CRCPOLY = 0x0000065B;
1398 
1399     /* Configure IFS */
1400     NRF_RADIO->TIFS = BLE_LL_IFS;
1401 
1402     /* Captures tx/rx start in timer0 cc 1 and tx/rx end in timer0 cc 2 */
1403     NRF_PPI->CHENSET = PPI_CHEN_CH26_Msk | PPI_CHEN_CH27_Msk;
1404 
1405 #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) == 1)
1406     NRF_CCM->INTENCLR = 0xffffffff;
1407     NRF_CCM->SHORTS = CCM_SHORTS_ENDKSGEN_CRYPT_Msk;
1408     NRF_CCM->EVENTS_ERROR = 0;
1409     memset(g_nrf_encrypt_scratchpad, 0, sizeof(g_nrf_encrypt_scratchpad));
1410 #endif
1411 
1412 #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) == 1)
1413     g_ble_phy_data.phy_aar_scratch = 0;
1414     NRF_AAR->IRKPTR = (uint32_t)&g_nrf_irk_list[0];
1415     NRF_AAR->INTENCLR = 0xffffffff;
1416     NRF_AAR->EVENTS_END = 0;
1417     NRF_AAR->EVENTS_RESOLVED = 0;
1418     NRF_AAR->EVENTS_NOTRESOLVED = 0;
1419     NRF_AAR->NIRK = 0;
1420 #endif
1421 
1422     /* TIMER0 setup for PHY when using RTC */
1423     NRF_TIMER0->TASKS_STOP = 1;
1424     NRF_TIMER0->TASKS_SHUTDOWN = 1;
1425     NRF_TIMER0->BITMODE = 3;    /* 32-bit timer */
1426     NRF_TIMER0->MODE = 0;       /* Timer mode */
1427     NRF_TIMER0->PRESCALER = 4;  /* gives us 1 MHz */
1428 
1429     /*
1430      * PPI setup.
1431      * Channel 4: Captures TIMER0 in CC[3] when EVENTS_ADDRESS occurs. Used
1432      *            to cancel the wait for response timer.
1433      * Channel 5: TIMER0 CC[3] to TASKS_DISABLE on radio. This is the wait
1434      *            for response timer.
1435      */
1436     NRF_PPI->CH[4].EEP = (uint32_t)&(NRF_RADIO->EVENTS_ADDRESS);
1437     NRF_PPI->CH[4].TEP = (uint32_t)&(NRF_TIMER0->TASKS_CAPTURE[3]);
1438     NRF_PPI->CH[5].EEP = (uint32_t)&(NRF_TIMER0->EVENTS_COMPARE[3]);
1439     NRF_PPI->CH[5].TEP = (uint32_t)&(NRF_RADIO->TASKS_DISABLE);
1440 
1441     /* Set isr in vector table and enable interrupt */
1442     NVIC_SetPriority(RADIO_IRQn, 0);
1443 #if MYNEWT
1444     NVIC_SetVector(RADIO_IRQn, (uint32_t)ble_phy_isr);
1445 #else
1446     ble_npl_hw_set_isr(RADIO_IRQn, ble_phy_isr);
1447 #endif
1448     NVIC_EnableIRQ(RADIO_IRQn);
1449 
1450     /* Register phy statistics */
1451     if (!g_ble_phy_data.phy_stats_initialized) {
1452         rc = stats_init_and_reg(STATS_HDR(ble_phy_stats),
1453                                 STATS_SIZE_INIT_PARMS(ble_phy_stats,
1454                                                       STATS_SIZE_32),
1455                                 STATS_NAME_INIT_PARMS(ble_phy_stats),
1456                                 "ble_phy");
1457         assert(rc == 0);
1458 
1459         g_ble_phy_data.phy_stats_initialized  = 1;
1460     }
1461 
1462     ble_phy_dbg_time_setup();
1463 
1464     return 0;
1465 }
1466 
1467 /**
1468  * Puts the phy into receive mode.
1469  *
1470  * @return int 0: success; BLE Phy error code otherwise
1471  */
1472 int
ble_phy_rx(void)1473 ble_phy_rx(void)
1474 {
1475     /*
1476      * Check radio state.
1477      *
1478      * In case radio is now disabling we'll wait for it to finish, but if for
1479      * any reason it's just in idle state we proceed with RX as usual since
1480      * nRF52 radio can ramp-up from idle state as well.
1481      *
1482      * Note that TX and RX states values are the same except for 3rd bit so we
1483      * can make a shortcut here when checking for idle state.
1484      */
1485     nrf_wait_disabled();
1486     if ((NRF_RADIO->STATE != RADIO_STATE_STATE_Disabled) &&
1487             ((NRF_RADIO->STATE & 0x07) != RADIO_STATE_STATE_RxIdle)) {
1488         ble_phy_disable();
1489         STATS_INC(ble_phy_stats, radio_state_errs);
1490         return BLE_PHY_ERR_RADIO_STATE;
1491     }
1492 
1493     /* Make sure all interrupts are disabled */
1494     NRF_RADIO->INTENCLR = NRF_RADIO_IRQ_MASK_ALL;
1495 
1496     /* Clear events prior to enabling receive */
1497     NRF_RADIO->EVENTS_END = 0;
1498     NRF_RADIO->EVENTS_DISABLED = 0;
1499 
1500     /* Setup for rx */
1501     ble_phy_rx_xcvr_setup();
1502 
1503     /* PPI to start radio automatically shall be set here */
1504     assert(NRF_PPI->CHEN & PPI_CHEN_CH21_Msk);
1505 
1506     return 0;
1507 }
1508 
1509 #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) == 1)
1510 /**
1511  * Called to enable encryption at the PHY. Note that this state will persist
1512  * in the PHY; in other words, if you call this function you have to call
1513  * disable so that future PHY transmits/receives will not be encrypted.
1514  *
1515  * @param pkt_counter
1516  * @param iv
1517  * @param key
1518  * @param is_master
1519  */
1520 void
ble_phy_encrypt_enable(uint64_t pkt_counter,uint8_t * iv,uint8_t * key,uint8_t is_master)1521 ble_phy_encrypt_enable(uint64_t pkt_counter, uint8_t *iv, uint8_t *key,
1522                        uint8_t is_master)
1523 {
1524     memcpy(g_nrf_ccm_data.key, key, 16);
1525     g_nrf_ccm_data.pkt_counter = pkt_counter;
1526     memcpy(g_nrf_ccm_data.iv, iv, 8);
1527     g_nrf_ccm_data.dir_bit = is_master;
1528     g_ble_phy_data.phy_encrypted = 1;
1529     /* Enable the module (AAR cannot be on while CCM on) */
1530     NRF_AAR->ENABLE = AAR_ENABLE_ENABLE_Disabled;
1531     NRF_CCM->ENABLE = CCM_ENABLE_ENABLE_Enabled;
1532 }
1533 
1534 void
ble_phy_encrypt_set_pkt_cntr(uint64_t pkt_counter,int dir)1535 ble_phy_encrypt_set_pkt_cntr(uint64_t pkt_counter, int dir)
1536 {
1537     g_nrf_ccm_data.pkt_counter = pkt_counter;
1538     g_nrf_ccm_data.dir_bit = dir;
1539 }
1540 
1541 void
ble_phy_encrypt_disable(void)1542 ble_phy_encrypt_disable(void)
1543 {
1544     NRF_PPI->CHENCLR = PPI_CHEN_CH25_Msk;
1545     NRF_CCM->TASKS_STOP = 1;
1546     NRF_CCM->EVENTS_ERROR = 0;
1547     NRF_CCM->ENABLE = CCM_ENABLE_ENABLE_Disabled;
1548 
1549     g_ble_phy_data.phy_encrypted = 0;
1550 }
1551 #endif
1552 
1553 void
ble_phy_set_txend_cb(ble_phy_tx_end_func txend_cb,void * arg)1554 ble_phy_set_txend_cb(ble_phy_tx_end_func txend_cb, void *arg)
1555 {
1556     /* Set transmit end callback and arg */
1557     g_ble_phy_data.txend_cb = txend_cb;
1558     g_ble_phy_data.txend_arg = arg;
1559 }
1560 
1561 /**
1562  * Called to set the start time of a transmission.
1563  *
1564  * This function is called to set the start time when we are not going from
1565  * rx to tx automatically.
1566  *
1567  * NOTE: care must be taken when calling this function. The channel should
1568  * already be set.
1569  *
1570  * @param cputime   This is the tick at which the 1st bit of the preamble
1571  *                  should be transmitted
1572  * @param rem_usecs This is used only when the underlying timing uses a 32.768
1573  *                  kHz crystal. It is the # of usecs from the cputime tick
1574  *                  at which the first bit of the preamble should be
1575  *                  transmitted.
1576  * @return int
1577  */
1578 int
ble_phy_tx_set_start_time(uint32_t cputime,uint8_t rem_usecs)1579 ble_phy_tx_set_start_time(uint32_t cputime, uint8_t rem_usecs)
1580 {
1581     int rc;
1582 
1583     ble_phy_trace_u32x2(BLE_PHY_TRACE_ID_START_TX, cputime, rem_usecs);
1584 
1585     /* XXX: This should not be necessary, but paranoia is good! */
1586     /* Clear timer0 compare to RXEN since we are transmitting */
1587     NRF_PPI->CHENCLR = PPI_CHEN_CH21_Msk;
1588 
1589     if (ble_phy_set_start_time(cputime, rem_usecs, true) != 0) {
1590         STATS_INC(ble_phy_stats, tx_late);
1591         ble_phy_disable();
1592         rc = BLE_PHY_ERR_TX_LATE;
1593     } else {
1594         /* Enable PPI to automatically start TXEN */
1595         NRF_PPI->CHENSET = PPI_CHEN_CH20_Msk;
1596         rc = 0;
1597     }
1598     return rc;
1599 }
1600 
1601 /**
1602  * Called to set the start time of a reception
1603  *
1604  * This function acts a bit differently than transmit. If we are late getting
1605  * here we will still attempt to receive.
1606  *
1607  * NOTE: care must be taken when calling this function. The channel should
1608  * already be set.
1609  *
1610  * @param cputime
1611  *
1612  * @return int
1613  */
1614 int
ble_phy_rx_set_start_time(uint32_t cputime,uint8_t rem_usecs)1615 ble_phy_rx_set_start_time(uint32_t cputime, uint8_t rem_usecs)
1616 {
1617     bool late = false;
1618     int rc = 0;
1619 
1620     ble_phy_trace_u32x2(BLE_PHY_TRACE_ID_START_RX, cputime, rem_usecs);
1621 
1622     /* XXX: This should not be necessary, but paranoia is good! */
1623     /* Clear timer0 compare to TXEN since we are transmitting */
1624     NRF_PPI->CHENCLR = PPI_CHEN_CH20_Msk;
1625 
1626     if (ble_phy_set_start_time(cputime, rem_usecs, false) != 0) {
1627         STATS_INC(ble_phy_stats, rx_late);
1628 
1629         /* We're late so let's just try to start RX as soon as possible */
1630         ble_phy_set_start_now();
1631 
1632         late = true;
1633     }
1634 
1635     /* Enable PPI to automatically start RXEN */
1636     NRF_PPI->CHENSET = PPI_CHEN_CH21_Msk;
1637 
1638     /* Start rx */
1639     rc = ble_phy_rx();
1640 
1641     /*
1642      * If we enabled receiver but were late, let's return proper error code so
1643      * caller can handle this.
1644      */
1645     if (!rc && late) {
1646         rc = BLE_PHY_ERR_RX_LATE;
1647     }
1648 
1649     return rc;
1650 }
1651 
1652 int
ble_phy_tx(ble_phy_tx_pducb_t pducb,void * pducb_arg,uint8_t end_trans)1653 ble_phy_tx(ble_phy_tx_pducb_t pducb, void *pducb_arg, uint8_t end_trans)
1654 {
1655     int rc;
1656     uint8_t *dptr;
1657     uint8_t *pktptr;
1658     uint8_t payload_len;
1659     uint8_t hdr_byte;
1660     uint32_t state;
1661     uint32_t shortcuts;
1662 
1663     if (g_ble_phy_data.phy_transition_late) {
1664         ble_phy_disable();
1665         STATS_INC(ble_phy_stats, tx_late);
1666         return BLE_PHY_ERR_TX_LATE;
1667     }
1668 
1669     /*
1670      * This check is to make sure that the radio is not in a state where
1671      * it is moving to disabled state. If so, let it get there.
1672      */
1673     nrf_wait_disabled();
1674 
1675     /*
1676      * XXX: Although we may not have to do this here, I clear all the PPI
1677      * that should not be used when transmitting. Some of them are only enabled
1678      * if encryption and/or privacy is on, but I dont care. Better to be
1679      * paranoid, and if you are going to clear one, might as well clear them
1680      * all.
1681      */
1682     NRF_PPI->CHENCLR = PPI_CHEN_CH4_Msk | PPI_CHEN_CH5_Msk | PPI_CHEN_CH23_Msk |
1683                        PPI_CHEN_CH25_Msk;
1684 
1685 #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) == 1)
1686     if (g_ble_phy_data.phy_encrypted) {
1687         dptr = (uint8_t *)&g_ble_phy_enc_buf[0];
1688         pktptr = (uint8_t *)&g_ble_phy_tx_buf[0];
1689         NRF_CCM->SHORTS = CCM_SHORTS_ENDKSGEN_CRYPT_Msk;
1690         NRF_CCM->INPTR = (uint32_t)dptr;
1691         NRF_CCM->OUTPTR = (uint32_t)pktptr;
1692         NRF_CCM->SCRATCHPTR = (uint32_t)&g_nrf_encrypt_scratchpad[0];
1693         NRF_CCM->EVENTS_ERROR = 0;
1694         NRF_CCM->MODE = CCM_MODE_LENGTH_Msk | ble_phy_get_ccm_datarate();
1695         NRF_CCM->CNFPTR = (uint32_t)&g_nrf_ccm_data;
1696     } else {
1697 #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) == 1)
1698         NRF_AAR->IRKPTR = (uint32_t)&g_nrf_irk_list[0];
1699 #endif
1700         dptr = (uint8_t *)&g_ble_phy_tx_buf[0];
1701         pktptr = dptr;
1702     }
1703 #else
1704     dptr = (uint8_t *)&g_ble_phy_tx_buf[0];
1705     pktptr = dptr;
1706 #endif
1707 
1708     /* Set PDU payload */
1709     payload_len = pducb(&dptr[3], pducb_arg, &hdr_byte);
1710 
1711     /* RAM representation has S0, LENGTH and S1 fields. (3 bytes) */
1712     dptr[0] = hdr_byte;
1713     dptr[1] = payload_len;
1714     dptr[2] = 0;
1715 
1716 #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) == 1)
1717     /* Start key-stream generation and encryption (via short) */
1718     if (g_ble_phy_data.phy_encrypted) {
1719         NRF_CCM->TASKS_KSGEN = 1;
1720     }
1721 #endif
1722 
1723     NRF_RADIO->PACKETPTR = (uint32_t)pktptr;
1724 
1725     /* Clear the ready, end and disabled events */
1726     NRF_RADIO->EVENTS_READY = 0;
1727     NRF_RADIO->EVENTS_END = 0;
1728     NRF_RADIO->EVENTS_DISABLED = 0;
1729 
1730     /* Enable shortcuts for transmit start/end. */
1731     shortcuts = RADIO_SHORTS_END_DISABLE_Msk | RADIO_SHORTS_READY_START_Msk;
1732     NRF_RADIO->SHORTS = shortcuts;
1733     NRF_RADIO->INTENSET = RADIO_INTENSET_DISABLED_Msk;
1734 
1735     /* Set the PHY transition */
1736     g_ble_phy_data.phy_transition = end_trans;
1737 
1738     /* Set transmitted payload length */
1739     g_ble_phy_data.phy_tx_pyld_len = payload_len;
1740 
1741     /* If we already started transmitting, abort it! */
1742     state = NRF_RADIO->STATE;
1743     if (state != RADIO_STATE_STATE_Tx) {
1744         /* Set phy state to transmitting and count packet statistics */
1745         g_ble_phy_data.phy_state = BLE_PHY_STATE_TX;
1746         STATS_INC(ble_phy_stats, tx_good);
1747         STATS_INCN(ble_phy_stats, tx_bytes, payload_len + BLE_LL_PDU_HDR_LEN);
1748         rc = BLE_ERR_SUCCESS;
1749     } else {
1750         ble_phy_disable();
1751         STATS_INC(ble_phy_stats, tx_late);
1752         rc = BLE_PHY_ERR_RADIO_STATE;
1753     }
1754 
1755     return rc;
1756 }
1757 
1758 /**
1759  * ble phy txpwr set
1760  *
1761  * Set the transmit output power (in dBm).
1762  *
1763  * NOTE: If the output power specified is within the BLE limits but outside
1764  * the chip limits, we "rail" the power level so we dont exceed the min/max
1765  * chip values.
1766  *
1767  * @param dbm Power output in dBm.
1768  *
1769  * @return int 0: success; anything else is an error
1770  */
1771 int
ble_phy_txpwr_set(int dbm)1772 ble_phy_txpwr_set(int dbm)
1773 {
1774     /* Check valid range */
1775     assert(dbm <= BLE_PHY_MAX_PWR_DBM);
1776 
1777     /* "Rail" power level if outside supported range */
1778     if (dbm > NRF_TX_PWR_MAX_DBM) {
1779         dbm = NRF_TX_PWR_MAX_DBM;
1780     } else {
1781         if (dbm < NRF_TX_PWR_MIN_DBM) {
1782             dbm = NRF_TX_PWR_MIN_DBM;
1783         }
1784     }
1785 
1786     NRF_RADIO->TXPOWER = dbm;
1787     g_ble_phy_data.phy_txpwr_dbm = dbm;
1788 
1789     return 0;
1790 }
1791 
1792 /**
1793  * ble phy txpwr round
1794  *
1795  * Get the rounded transmit output power (in dBm).
1796  *
1797  * @param dbm Power output in dBm.
1798  *
1799  * @return int Rounded power in dBm
1800  */
ble_phy_txpower_round(int dbm)1801 int ble_phy_txpower_round(int dbm)
1802 {
1803     /* "Rail" power level if outside supported range */
1804     if (dbm > NRF_TX_PWR_MAX_DBM) {
1805         dbm = NRF_TX_PWR_MAX_DBM;
1806     } else {
1807         if (dbm < NRF_TX_PWR_MIN_DBM) {
1808             dbm = NRF_TX_PWR_MIN_DBM;
1809         }
1810     }
1811 
1812     return dbm;
1813 }
1814 
1815 /**
1816  * ble phy set access addr
1817  *
1818  * Set access address.
1819  *
1820  * @param access_addr Access address
1821  *
1822  * @return int 0: success; PHY error code otherwise
1823  */
1824 int
ble_phy_set_access_addr(uint32_t access_addr)1825 ble_phy_set_access_addr(uint32_t access_addr)
1826 {
1827     NRF_RADIO->BASE0 = (access_addr << 8);
1828     NRF_RADIO->PREFIX0 = (NRF_RADIO->PREFIX0 & 0xFFFFFF00) | (access_addr >> 24);
1829 
1830     g_ble_phy_data.phy_access_address = access_addr;
1831 
1832 #ifdef NRF52
1833     ble_phy_apply_errata_102_106_107();
1834 #endif
1835 
1836     return 0;
1837 }
1838 
1839 /**
1840  * ble phy txpwr get
1841  *
1842  * Get the transmit power.
1843  *
1844  * @return int  The current PHY transmit power, in dBm
1845  */
1846 int
ble_phy_txpwr_get(void)1847 ble_phy_txpwr_get(void)
1848 {
1849     return g_ble_phy_data.phy_txpwr_dbm;
1850 }
1851 
1852 /**
1853  * ble phy setchan
1854  *
1855  * Sets the logical frequency of the transceiver. The input parameter is the
1856  * BLE channel index (0 to 39, inclusive). The NRF frequency register works like
1857  * this: logical frequency = 2400 + FREQ (MHz).
1858  *
1859  * Thus, to get a logical frequency of 2402 MHz, you would program the
1860  * FREQUENCY register to 2.
1861  *
1862  * @param chan This is the Data Channel Index or Advertising Channel index
1863  *
1864  * @return int 0: success; PHY error code otherwise
1865  */
1866 int
ble_phy_setchan(uint8_t chan,uint32_t access_addr,uint32_t crcinit)1867 ble_phy_setchan(uint8_t chan, uint32_t access_addr, uint32_t crcinit)
1868 {
1869     assert(chan < BLE_PHY_NUM_CHANS);
1870 
1871     /* Check for valid channel range */
1872     if (chan >= BLE_PHY_NUM_CHANS) {
1873         return BLE_PHY_ERR_INV_PARAM;
1874     }
1875 
1876     /* Set current access address */
1877     ble_phy_set_access_addr(access_addr);
1878 
1879     /* Configure crcinit */
1880     NRF_RADIO->CRCINIT = crcinit;
1881 
1882     /* Set the frequency and the data whitening initial value */
1883     g_ble_phy_data.phy_chan = chan;
1884     NRF_RADIO->FREQUENCY = g_ble_phy_chan_freq[chan];
1885     NRF_RADIO->DATAWHITEIV = chan;
1886 
1887     return 0;
1888 }
1889 
1890 /**
1891  * Stop the timer used to count microseconds when using RTC for cputime
1892  */
1893 void
ble_phy_stop_usec_timer(void)1894 ble_phy_stop_usec_timer(void)
1895 {
1896     NRF_TIMER0->TASKS_STOP = 1;
1897     NRF_TIMER0->TASKS_SHUTDOWN = 1;
1898     NRF_RTC0->EVTENCLR = RTC_EVTENSET_COMPARE0_Msk;
1899 }
1900 
1901 /**
1902  * ble phy disable irq and ppi
1903  *
1904  * This routine is to be called when reception was stopped due to either a
1905  * wait for response timeout or a packet being received and the phy is to be
1906  * restarted in receive mode. Generally, the disable routine is called to stop
1907  * the phy.
1908  */
1909 void
ble_phy_disable_irq_and_ppi(void)1910 ble_phy_disable_irq_and_ppi(void)
1911 {
1912     NRF_RADIO->INTENCLR = NRF_RADIO_IRQ_MASK_ALL;
1913     NRF_RADIO->SHORTS = 0;
1914     NRF_RADIO->TASKS_DISABLE = 1;
1915     NRF_PPI->CHENCLR = PPI_CHEN_CH4_Msk | PPI_CHEN_CH5_Msk | PPI_CHEN_CH20_Msk |
1916           PPI_CHEN_CH21_Msk | PPI_CHEN_CH23_Msk |
1917           PPI_CHEN_CH25_Msk | PPI_CHEN_CH31_Msk;
1918     NVIC_ClearPendingIRQ(RADIO_IRQn);
1919     g_ble_phy_data.phy_state = BLE_PHY_STATE_IDLE;
1920 }
1921 
1922 void
ble_phy_restart_rx(void)1923 ble_phy_restart_rx(void)
1924 {
1925     ble_phy_disable_irq_and_ppi();
1926 
1927     ble_phy_set_start_now();
1928     /* Enable PPI to automatically start RXEN */
1929     NRF_PPI->CHENSET = PPI_CHEN_CH21_Msk;
1930 
1931     ble_phy_rx();
1932 }
1933 
1934 /**
1935  * ble phy disable
1936  *
1937  * Disables the PHY. This should be called when an event is over. It stops
1938  * the usec timer (if used), disables interrupts, disables the RADIO, disables
1939  * PPI and sets state to idle.
1940  */
1941 void
ble_phy_disable(void)1942 ble_phy_disable(void)
1943 {
1944     ble_phy_trace_void(BLE_PHY_TRACE_ID_DISABLE);
1945 
1946     ble_phy_stop_usec_timer();
1947     ble_phy_disable_irq_and_ppi();
1948 }
1949 
1950 /* Gets the current access address */
ble_phy_access_addr_get(void)1951 uint32_t ble_phy_access_addr_get(void)
1952 {
1953     return g_ble_phy_data.phy_access_address;
1954 }
1955 
1956 /**
1957  * Return the phy state
1958  *
1959  * @return int The current PHY state.
1960  */
1961 int
ble_phy_state_get(void)1962 ble_phy_state_get(void)
1963 {
1964     return g_ble_phy_data.phy_state;
1965 }
1966 
1967 /**
1968  * Called to see if a reception has started
1969  *
1970  * @return int
1971  */
1972 int
ble_phy_rx_started(void)1973 ble_phy_rx_started(void)
1974 {
1975     return g_ble_phy_data.phy_rx_started;
1976 }
1977 
1978 /**
1979  * Return the transceiver state
1980  *
1981  * @return int transceiver state.
1982  */
1983 uint8_t
ble_phy_xcvr_state_get(void)1984 ble_phy_xcvr_state_get(void)
1985 {
1986     uint32_t state;
1987     state = NRF_RADIO->STATE;
1988     return (uint8_t)state;
1989 }
1990 
1991 /**
1992  * Called to return the maximum data pdu payload length supported by the
1993  * phy. For this chip, if encryption is enabled, the maximum payload is 27
1994  * bytes.
1995  *
1996  * @return uint8_t Maximum data channel PDU payload size supported
1997  */
1998 uint8_t
ble_phy_max_data_pdu_pyld(void)1999 ble_phy_max_data_pdu_pyld(void)
2000 {
2001     return BLE_LL_DATA_PDU_MAX_PYLD;
2002 }
2003 
2004 #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) == 1)
2005 void
ble_phy_resolv_list_enable(void)2006 ble_phy_resolv_list_enable(void)
2007 {
2008     NRF_AAR->NIRK = (uint32_t)g_nrf_num_irks;
2009     g_ble_phy_data.phy_privacy = 1;
2010 }
2011 
2012 void
ble_phy_resolv_list_disable(void)2013 ble_phy_resolv_list_disable(void)
2014 {
2015     g_ble_phy_data.phy_privacy = 0;
2016 }
2017 #endif
2018 
2019 #if MYNEWT_VAL(BLE_LL_DIRECT_TEST_MODE) == 1
ble_phy_enable_dtm(void)2020 void ble_phy_enable_dtm(void)
2021 {
2022     /* When DTM is enabled we need to disable whitening as per
2023      * Bluetooth v5.0 Vol 6. Part F. 4.1.1
2024      */
2025     NRF_RADIO->PCNF1 &= ~RADIO_PCNF1_WHITEEN_Msk;
2026 }
2027 
ble_phy_disable_dtm(void)2028 void ble_phy_disable_dtm(void)
2029 {
2030     /* Enable whitening */
2031     NRF_RADIO->PCNF1 |= RADIO_PCNF1_WHITEEN_Msk;
2032 }
2033 #endif
2034 
2035 void
ble_phy_rfclk_enable(void)2036 ble_phy_rfclk_enable(void)
2037 {
2038 #if MYNEWT
2039     nrf52_clock_hfxo_request();
2040 #else
2041     NRF_CLOCK->TASKS_HFCLKSTART = 1;
2042 #endif
2043 }
2044 
2045 void
ble_phy_rfclk_disable(void)2046 ble_phy_rfclk_disable(void)
2047 {
2048 #if MYNEWT
2049     nrf52_clock_hfxo_release();
2050 #else
2051     NRF_CLOCK->TASKS_HFCLKSTOP = 1;
2052 #endif
2053 }
2054