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 "mcu/cmsis_nvic.h"
27 #include "nimble/ble.h"
28 #include "nimble/nimble_opt.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
34 #if MYNEWT
35 #include "mcu/nrf51_clock.h"
36 #endif
37
38 /* XXX: 4) Make sure RF is higher priority interrupt than schedule */
39
40 /*
41 * XXX: Maximum possible transmit time is 1 msec for a 60ppm crystal
42 * and 16ms for a 30ppm crystal! We need to limit PDU size based on
43 * crystal accuracy. Look at this in the spec.
44 */
45
46 /* XXX: private header file? */
47 extern uint8_t g_nrf_num_irks;
48 extern uint32_t g_nrf_irk_list[];
49
50 /* To disable all radio interrupts */
51 #define NRF_RADIO_IRQ_MASK_ALL (0x34FF)
52
53 /*
54 * We configure the nrf with a 1 byte S0 field, 8 bit length field, and
55 * zero bit S1 field. The preamble is 8 bits long.
56 */
57 #define NRF_LFLEN_BITS (8)
58 #define NRF_S0_LEN (1)
59
60 /* Maximum length of frames */
61 #define NRF_MAXLEN (255)
62 #define NRF_BALEN (3) /* For base address of 3 bytes */
63
64 /* Maximum tx power */
65 #define NRF_TX_PWR_MAX_DBM (4)
66 #define NRF_TX_PWR_MIN_DBM (-40)
67
68 /* Max. encrypted payload length */
69 #define NRF_MAX_ENCRYPTED_PYLD_LEN (27)
70 #define NRF_ENC_HDR_SIZE (3)
71 #define NRF_ENC_BUF_SIZE \
72 (NRF_MAX_ENCRYPTED_PYLD_LEN + NRF_ENC_HDR_SIZE + BLE_LL_DATA_MIC_LEN)
73
74 /* BLE PHY data structure */
75 struct ble_phy_obj
76 {
77 uint8_t phy_stats_initialized;
78 int8_t phy_txpwr_dbm;
79 uint8_t phy_chan;
80 uint8_t phy_state;
81 uint8_t phy_transition;
82 uint8_t phy_rx_started;
83 uint8_t phy_encrypted;
84 uint8_t phy_privacy;
85 uint8_t phy_tx_pyld_len;
86 uint8_t *rxdptr;
87 uint32_t phy_aar_scratch;
88 uint32_t phy_access_address;
89 struct ble_mbuf_hdr rxhdr;
90 void *txend_arg;
91 ble_phy_tx_end_func txend_cb;
92 uint32_t phy_start_cputime;
93 };
94 struct ble_phy_obj g_ble_phy_data;
95
96 /* XXX: if 27 byte packets desired we can make this smaller */
97 /* Global transmit/receive buffer */
98 static uint32_t g_ble_phy_tx_buf[(BLE_PHY_MAX_PDU_LEN + 3) / 4];
99 static uint32_t g_ble_phy_rx_buf[(BLE_PHY_MAX_PDU_LEN + 3) / 4];
100
101 #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) == 1)
102 /* Make sure word-aligned for faster copies */
103 static uint32_t g_ble_phy_enc_buf[(NRF_ENC_BUF_SIZE + 3) / 4];
104 #endif
105
106 /* RF center frequency for each channel index (offset from 2400 MHz) */
107 static const uint8_t g_ble_phy_chan_freq[BLE_PHY_NUM_CHANS] = {
108 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, /* 0-9 */
109 24, 28, 30, 32, 34, 36, 38, 40, 42, 44, /* 10-19 */
110 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, /* 20-29 */
111 66, 68, 70, 72, 74, 76, 78, 2, 26, 80, /* 30-39 */
112 };
113
114 /* Statistics */
115 STATS_SECT_START(ble_phy_stats)
116 STATS_SECT_ENTRY(phy_isrs)
117 STATS_SECT_ENTRY(tx_good)
118 STATS_SECT_ENTRY(tx_fail)
119 STATS_SECT_ENTRY(tx_late)
120 STATS_SECT_ENTRY(tx_bytes)
121 STATS_SECT_ENTRY(rx_starts)
122 STATS_SECT_ENTRY(rx_aborts)
123 STATS_SECT_ENTRY(rx_valid)
124 STATS_SECT_ENTRY(rx_crc_err)
125 STATS_SECT_ENTRY(rx_late)
126 STATS_SECT_ENTRY(radio_state_errs)
127 STATS_SECT_ENTRY(rx_hw_err)
128 STATS_SECT_ENTRY(tx_hw_err)
129 STATS_SECT_END
130 STATS_SECT_DECL(ble_phy_stats) ble_phy_stats;
131
132 STATS_NAME_START(ble_phy_stats)
133 STATS_NAME(ble_phy_stats, phy_isrs)
134 STATS_NAME(ble_phy_stats, tx_good)
135 STATS_NAME(ble_phy_stats, tx_fail)
136 STATS_NAME(ble_phy_stats, tx_late)
137 STATS_NAME(ble_phy_stats, tx_bytes)
138 STATS_NAME(ble_phy_stats, rx_starts)
139 STATS_NAME(ble_phy_stats, rx_aborts)
140 STATS_NAME(ble_phy_stats, rx_valid)
141 STATS_NAME(ble_phy_stats, rx_crc_err)
142 STATS_NAME(ble_phy_stats, rx_late)
143 STATS_NAME(ble_phy_stats, radio_state_errs)
144 STATS_NAME(ble_phy_stats, rx_hw_err)
145 STATS_NAME(ble_phy_stats, tx_hw_err)
146 STATS_NAME_END(ble_phy_stats)
147
148 /*
149 * NOTE:
150 * Tested the following to see what would happen:
151 * -> NVIC has radio irq enabled (interrupt # 1, mask 0x2).
152 * -> Set up nrf to receive. Clear ADDRESS event register.
153 * -> Enable ADDRESS interrupt on nrf5 by writing to INTENSET.
154 * -> Enable RX.
155 * -> Disable interrupts globally using OS_ENTER_CRITICAL().
156 * -> Wait until a packet is received and the ADDRESS event occurs.
157 * -> Call ble_phy_disable().
158 *
159 * At this point I wanted to see the state of the cortex NVIC. The IRQ
160 * pending bit was TRUE for the radio interrupt (as expected) as we never
161 * serviced the radio interrupt (interrupts were disabled).
162 *
163 * What was unexpected was this: without clearing the pending IRQ in the NVIC,
164 * when radio interrupts were re-enabled (address event bit in INTENSET set to
165 * 1) and the radio ADDRESS event register read 1 (it was never cleared after
166 * the first address event), the radio did not enter the ISR! I would have
167 * expected that if the following were true, an interrupt would occur:
168 * -> NVIC ISER bit set to TRUE
169 * -> NVIC ISPR bit reads TRUE, meaning interrupt is pending.
170 * -> Radio peripheral interrupts are enabled for some event (or events).
171 * -> Corresponding event register(s) in radio peripheral read 1.
172 *
173 * Not sure what the end result of all this is. We will clear the pending
174 * bit in the NVIC just to be sure when we disable the PHY.
175 */
176
177 #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) == 1)
178 /* Per nordic, the number of bytes needed for scratch is 16 + MAX_PKT_SIZE. */
179 #define NRF_ENC_SCRATCH_WORDS (((NRF_MAX_ENCRYPTED_PYLD_LEN + 16) + 3) / 4)
180
181 uint32_t g_nrf_encrypt_scratchpad[NRF_ENC_SCRATCH_WORDS];
182
183 struct nrf_ccm_data
184 {
185 uint8_t key[16];
186 uint64_t pkt_counter;
187 uint8_t dir_bit;
188 uint8_t iv[8];
189 } __attribute__((packed));
190
191 struct nrf_ccm_data g_nrf_ccm_data;
192 #endif
193
194 /**
195 * Copies the data from the phy receive buffer into a mbuf chain.
196 *
197 * @param dptr Pointer to receive buffer
198 * @param rxpdu Pointer to already allocated mbuf chain
199 *
200 * NOTE: the packet header already has the total mbuf length in it. The
201 * lengths of the individual mbufs are not set prior to calling.
202 *
203 */
204 void
ble_phy_rxpdu_copy(uint8_t * dptr,struct os_mbuf * rxpdu)205 ble_phy_rxpdu_copy(uint8_t *dptr, struct os_mbuf *rxpdu)
206 {
207 uint16_t rem_bytes;
208 uint16_t mb_bytes;
209 uint16_t copylen;
210 uint32_t *dst;
211 uint32_t *src;
212 struct os_mbuf *m;
213 struct ble_mbuf_hdr *ble_hdr;
214 struct os_mbuf_pkthdr *pkthdr;
215
216 /* Better be aligned */
217 assert(((uint32_t)dptr & 3) == 0);
218
219 pkthdr = OS_MBUF_PKTHDR(rxpdu);
220 rem_bytes = pkthdr->omp_len;
221
222 /* Fill in the mbuf pkthdr first. */
223 dst = (uint32_t *)(rxpdu->om_data);
224 src = (uint32_t *)dptr;
225
226 mb_bytes = (rxpdu->om_omp->omp_databuf_len - rxpdu->om_pkthdr_len - 4);
227 copylen = min(mb_bytes, rem_bytes);
228 copylen &= 0xFFFC;
229 rem_bytes -= copylen;
230 mb_bytes -= copylen;
231 rxpdu->om_len = copylen;
232 while (copylen > 0) {
233 *dst = *src;
234 ++dst;
235 ++src;
236 copylen -= 4;
237 }
238
239 /* Copy remaining bytes */
240 m = rxpdu;
241 while (rem_bytes > 0) {
242 /* If there are enough bytes in the mbuf, copy them and leave */
243 if (rem_bytes <= mb_bytes) {
244 memcpy(m->om_data + m->om_len, src, rem_bytes);
245 m->om_len += rem_bytes;
246 break;
247 }
248
249 m = SLIST_NEXT(m, om_next);
250 assert(m != NULL);
251
252 mb_bytes = m->om_omp->omp_databuf_len;
253 copylen = min(mb_bytes, rem_bytes);
254 copylen &= 0xFFFC;
255 rem_bytes -= copylen;
256 mb_bytes -= copylen;
257 m->om_len = copylen;
258 dst = (uint32_t *)m->om_data;
259 while (copylen > 0) {
260 *dst = *src;
261 ++dst;
262 ++src;
263 copylen -= 4;
264 }
265 }
266
267 /* Copy ble header */
268 ble_hdr = BLE_MBUF_HDR_PTR(rxpdu);
269 memcpy(ble_hdr, &g_ble_phy_data.rxhdr, sizeof(struct ble_mbuf_hdr));
270 }
271
272 /**
273 * Called when we want to wait if the radio is in either the rx or tx
274 * disable states. We want to wait until that state is over before doing
275 * anything to the radio
276 */
277 static void
nrf_wait_disabled(void)278 nrf_wait_disabled(void)
279 {
280 uint32_t state;
281
282 /*
283 * RX and TX states have the same values except for 3rd bit (0=RX, 1=TX) so
284 * we use RX symbols only.
285 */
286 state = NRF_RADIO->STATE & 0x07;
287
288 if (state != RADIO_STATE_STATE_Disabled) {
289 /* If PHY is in idle state for whatever reason, disable it now */
290 if (state == RADIO_STATE_STATE_RxIdle) {
291 NRF_RADIO->TASKS_DISABLE = 1;
292 STATS_INC(ble_phy_stats, radio_state_errs);
293 }
294
295 if (state == RADIO_STATE_STATE_RxDisable) {
296 /* This will end within a short time (6 usecs). Just poll */
297 while (NRF_RADIO->STATE == state) {
298 /* If this fails, something is really wrong. Should last
299 * no more than 6 usecs */
300 }
301 }
302 }
303 }
304
305 /**
306 *
307 *
308 */
309 int
ble_phy_set_start_time(uint32_t cputime,uint8_t rem_usecs)310 ble_phy_set_start_time(uint32_t cputime, uint8_t rem_usecs)
311 {
312 uint32_t next_cc;
313 uint32_t cur_cc;
314 uint32_t cntr;
315 uint32_t delta;
316
317 /*
318 * XXX: The TXEN time is 140 usecs but there may be additional delays
319 * Need to look at this.
320 */
321
322 /*
323 * With the 32.768 kHz crystal, we may need to adjust the RTC compare
324 * value by 1 tick due to the time it takes for TXEN. The code uses a 5 RTC
325 * tick offset, which is 152.5 usecs. The TXEN time is 140 usecs. This
326 * means that with a remainder of 0, TIMER0 should be set to 12 or 13 (as
327 * TIMER0 counts at 1MHz). A remainder of 19 or more we will need to add
328 * 1 tick. We dont need to add 1 tick per se, but it does give us slightly
329 * more time and thus less of a chance to miss a tick. Another note: we
330 * cant set TIMER0 CC to 0 as the compare wont occur; it must be 1 or more.
331 * This is why we subtract 18 (as opposed to 19) as rem_uses will be >= 1.
332 */
333 if (rem_usecs <= 18) {
334 cputime -= 5;
335 rem_usecs += 12;
336 } else {
337 cputime -= 4;
338 rem_usecs -= 18;
339 }
340
341 /*
342 * Can we set the RTC compare to start TIMER0? We can do it if:
343 * a) Current compare value is not N+1 or N+2 ticks from current
344 * counter.
345 * b) The value we want to set is not at least N+2 from current
346 * counter.
347 *
348 * NOTE: since the counter can tick 1 while we do these calculations we
349 * need to account for it.
350 */
351 next_cc = cputime & 0xffffff;
352 cur_cc = NRF_RTC0->CC[0];
353 cntr = NRF_RTC0->COUNTER;
354
355 delta = (cur_cc - cntr) & 0xffffff;
356 if ((delta <= 3) && (delta != 0)) {
357 return -1;
358 }
359 delta = (next_cc - cntr) & 0xffffff;
360 if ((delta & 0x800000) || (delta < 3)) {
361 return -1;
362 }
363
364 /* Clear and set TIMER0 to fire off at proper time */
365 NRF_TIMER0->TASKS_CLEAR = 1;
366 NRF_TIMER0->CC[0] = rem_usecs;
367 NRF_TIMER0->EVENTS_COMPARE[0] = 0;
368
369 /* Set RTC compare to start TIMER0 */
370 NRF_RTC0->EVENTS_COMPARE[0] = 0;
371 NRF_RTC0->CC[0] = next_cc;
372 NRF_RTC0->EVTENSET = RTC_EVTENSET_COMPARE0_Msk;
373
374 /* Enable PPI */
375 NRF_PPI->CHENSET = PPI_CHEN_CH31_Msk;
376
377 /* Store the cputime at which we set the RTC */
378 g_ble_phy_data.phy_start_cputime = cputime;
379
380 return 0;
381 }
382
383 /**
384 * Function is used to set PPI so that we can time out waiting for a reception
385 * to occur. This happens for two reasons: we have sent a packet and we are
386 * waiting for a respons (txrx should be set to ENABLE_TXRX) or we are
387 * starting a connection event and we are a slave and we are waiting for the
388 * master to send us a packet (txrx should be set to ENABLE_RX).
389 *
390 * NOTE: when waiting for a txrx turn-around, wfr_usecs is not used as there
391 * is no additional time to wait; we know when we should receive the address of
392 * the received frame.
393 *
394 * @param txrx Flag denoting if this wfr is a txrx turn-around or not.
395 * @param tx_phy_mode phy mode for last TX (not used on nRF51)
396 * @param wfr_usecs Amount of usecs to wait.
397 */
398 void
ble_phy_wfr_enable(int txrx,uint8_t tx_phy_mode,uint32_t wfr_usecs)399 ble_phy_wfr_enable(int txrx, uint8_t tx_phy_mode, uint32_t wfr_usecs)
400 {
401 uint32_t end_time;
402
403 if (txrx == BLE_PHY_WFR_ENABLE_TXRX) {
404 /*
405 * Timeout occurs an IFS time plus time it takes to receive address
406 * from the transmit end. We add additional time to make sure the
407 * address event comes before the compare. Note that transmit end
408 * is captured in CC[2]. I just made up the 16 usecs I add here.
409 */
410 end_time = NRF_TIMER0->CC[2] + BLE_LL_IFS +
411 ble_phy_mode_pdu_start_off(BLE_PHY_MODE_1M) + 16;
412 } else {
413 /* CC[0] is set to when RXEN occurs. */
414 end_time = NRF_TIMER0->CC[0] + XCVR_RX_START_DELAY_USECS + wfr_usecs +
415 ble_phy_mode_pdu_start_off(BLE_PHY_MODE_1M) + BLE_LL_JITTER_USECS;
416 }
417
418 /* wfr_secs is the time from rxen until timeout */
419 NRF_TIMER0->CC[3] = end_time;
420 NRF_TIMER0->EVENTS_COMPARE[3] = 0;
421
422 /* Enable wait for response PPI */
423 NRF_PPI->CHENSET = (PPI_CHEN_CH4_Msk | PPI_CHEN_CH5_Msk);
424
425 /* Enable the disabled interrupt so we time out on events compare */
426 NRF_RADIO->INTENSET = RADIO_INTENSET_DISABLED_Msk;
427 }
428
429 /**
430 * Setup transceiver for receive.
431 */
432 static void
ble_phy_rx_xcvr_setup(void)433 ble_phy_rx_xcvr_setup(void)
434 {
435 uint8_t *dptr;
436
437 dptr = (uint8_t *)&g_ble_phy_rx_buf[0];
438
439 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION)
440 if (g_ble_phy_data.phy_encrypted) {
441 dptr += 3;
442 NRF_RADIO->PACKETPTR = (uint32_t)&g_ble_phy_enc_buf[0];
443 NRF_CCM->INPTR = (uint32_t)&g_ble_phy_enc_buf[0];
444 NRF_CCM->OUTPTR = (uint32_t)dptr;
445 NRF_CCM->SCRATCHPTR = (uint32_t)&g_nrf_encrypt_scratchpad[0];
446 NRF_CCM->MODE = CCM_MODE_MODE_Decryption;
447 NRF_CCM->CNFPTR = (uint32_t)&g_nrf_ccm_data;
448 NRF_CCM->SHORTS = 0;
449 NRF_CCM->EVENTS_ERROR = 0;
450 NRF_CCM->EVENTS_ENDCRYPT = 0;
451 NRF_PPI->CHENSET = PPI_CHEN_CH24_Msk | PPI_CHEN_CH25_Msk;
452 } else {
453 NRF_RADIO->PACKETPTR = (uint32_t)dptr;
454 }
455 #else
456 NRF_RADIO->PACKETPTR = (uint32_t)dptr;
457 #endif
458
459 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY)
460 if (g_ble_phy_data.phy_privacy) {
461 dptr += 3;
462 NRF_RADIO->PACKETPTR = (uint32_t)dptr;
463 NRF_RADIO->PCNF0 = (6 << RADIO_PCNF0_LFLEN_Pos) |
464 (2 << RADIO_PCNF0_S1LEN_Pos) |
465 (NRF_S0_LEN << RADIO_PCNF0_S0LEN_Pos);
466 NRF_AAR->ENABLE = AAR_ENABLE_ENABLE_Enabled;
467 NRF_AAR->IRKPTR = (uint32_t)&g_nrf_irk_list[0];
468 NRF_AAR->SCRATCHPTR = (uint32_t)&g_ble_phy_data.phy_aar_scratch;
469 NRF_AAR->EVENTS_END = 0;
470 NRF_AAR->EVENTS_RESOLVED = 0;
471 NRF_AAR->EVENTS_NOTRESOLVED = 0;
472 } else {
473 if (g_ble_phy_data.phy_encrypted == 0) {
474 NRF_RADIO->PCNF0 = (NRF_LFLEN_BITS << RADIO_PCNF0_LFLEN_Pos) |
475 (NRF_S0_LEN << RADIO_PCNF0_S0LEN_Pos);
476 /* XXX: do I only need to do this once? Figure out what I can do
477 once. */
478 NRF_AAR->ENABLE = AAR_ENABLE_ENABLE_Disabled;
479 }
480 }
481 #endif
482
483 /* Turn off trigger TXEN on output compare match and AAR on bcmatch */
484 NRF_PPI->CHENCLR = PPI_CHEN_CH20_Msk | PPI_CHEN_CH23_Msk;
485
486 /* Reset the rx started flag. Used for the wait for response */
487 g_ble_phy_data.phy_rx_started = 0;
488 g_ble_phy_data.phy_state = BLE_PHY_STATE_RX;
489 g_ble_phy_data.rxdptr = dptr;
490
491 /* I want to know when 1st byte received (after address) */
492 NRF_RADIO->BCC = 8; /* in bits */
493 NRF_RADIO->EVENTS_ADDRESS = 0;
494 NRF_RADIO->EVENTS_DEVMATCH = 0;
495 NRF_RADIO->EVENTS_BCMATCH = 0;
496 NRF_RADIO->EVENTS_RSSIEND = 0;
497 NRF_RADIO->SHORTS = RADIO_SHORTS_END_DISABLE_Msk |
498 RADIO_SHORTS_READY_START_Msk |
499 RADIO_SHORTS_DISABLED_TXEN_Msk |
500 RADIO_SHORTS_ADDRESS_BCSTART_Msk |
501 RADIO_SHORTS_ADDRESS_RSSISTART_Msk |
502 RADIO_SHORTS_DISABLED_RSSISTOP_Msk;
503
504 NRF_RADIO->INTENSET = RADIO_INTENSET_ADDRESS_Msk;
505 }
506
507 /**
508 * Called from interrupt context when the transmit ends
509 *
510 */
511 static void
ble_phy_tx_end_isr(void)512 ble_phy_tx_end_isr(void)
513 {
514 uint8_t was_encrypted;
515 uint8_t transition;
516 uint8_t txlen;
517 uint32_t wfr_time;
518
519 /* If this transmission was encrypted we need to remember it */
520 was_encrypted = g_ble_phy_data.phy_encrypted;
521 (void)was_encrypted;
522
523 /* Better be in TX state! */
524 assert(g_ble_phy_data.phy_state == BLE_PHY_STATE_TX);
525
526 /* Clear events and clear interrupt on disabled event */
527 NRF_RADIO->EVENTS_DISABLED = 0;
528 NRF_RADIO->INTENCLR = RADIO_INTENCLR_DISABLED_Msk;
529 NRF_RADIO->EVENTS_END = 0;
530 wfr_time = NRF_RADIO->SHORTS;
531 (void)wfr_time;
532
533 #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) == 1)
534 /*
535 * XXX: not sure what to do. We had a HW error during transmission.
536 * For now I just count a stat but continue on like all is good.
537 */
538 if (was_encrypted) {
539 if (NRF_CCM->EVENTS_ERROR) {
540 STATS_INC(ble_phy_stats, tx_hw_err);
541 NRF_CCM->EVENTS_ERROR = 0;
542 }
543 }
544 #endif
545
546 /* Call transmit end callback */
547 if (g_ble_phy_data.txend_cb) {
548 g_ble_phy_data.txend_cb(g_ble_phy_data.txend_arg);
549 }
550
551 transition = g_ble_phy_data.phy_transition;
552 if (transition == BLE_PHY_TRANSITION_TX_RX) {
553 /* Packet pointer needs to be reset. */
554 ble_phy_rx_xcvr_setup();
555
556 /*
557 * Enable the wait for response timer. Note that cc #1 on
558 * timer 0 contains the transmit start time
559 */
560 txlen = g_ble_phy_data.phy_tx_pyld_len;
561 if (txlen && was_encrypted) {
562 txlen += BLE_LL_DATA_MIC_LEN;
563 }
564 ble_phy_wfr_enable(BLE_PHY_WFR_ENABLE_TXRX, 0, 0);
565 } else {
566 /*
567 * XXX: not sure we need to stop the timer here all the time. Or that
568 * it should be stopped here.
569 */
570 NRF_TIMER0->TASKS_STOP = 1;
571 NRF_TIMER0->TASKS_SHUTDOWN = 1;
572 NRF_PPI->CHENCLR = PPI_CHEN_CH4_Msk | PPI_CHEN_CH5_Msk |
573 PPI_CHEN_CH20_Msk | PPI_CHEN_CH31_Msk;
574 assert(transition == BLE_PHY_TRANSITION_NONE);
575 }
576 }
577
578 static void
ble_phy_rx_end_isr(void)579 ble_phy_rx_end_isr(void)
580 {
581 int rc;
582 uint8_t *dptr;
583 uint8_t crcok;
584 struct ble_mbuf_hdr *ble_hdr;
585
586 /* Clear events and clear interrupt */
587 NRF_RADIO->EVENTS_END = 0;
588 NRF_RADIO->INTENCLR = RADIO_INTENCLR_END_Msk;
589
590 /* Disable automatic RXEN */
591 NRF_PPI->CHENCLR = PPI_CHEN_CH21_Msk;
592
593 /* Set RSSI and CRC status flag in header */
594 ble_hdr = &g_ble_phy_data.rxhdr;
595 assert(NRF_RADIO->EVENTS_RSSIEND != 0);
596 ble_hdr->rxinfo.rssi = -1 * NRF_RADIO->RSSISAMPLE;
597
598 dptr = g_ble_phy_data.rxdptr;
599
600 /* Count PHY crc errors and valid packets */
601 crcok = (uint8_t)NRF_RADIO->CRCSTATUS;
602 if (!crcok) {
603 STATS_INC(ble_phy_stats, rx_crc_err);
604 } else {
605 STATS_INC(ble_phy_stats, rx_valid);
606 ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_CRC_OK;
607 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION)
608 if (g_ble_phy_data.phy_encrypted) {
609 /* Only set MIC failure flag if frame is not zero length */
610 if ((dptr[1] != 0) && (NRF_CCM->MICSTATUS == 0)) {
611 ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_MIC_FAILURE;
612 }
613
614 /*
615 * XXX: not sure how to deal with this. This should not
616 * be a MIC failure but we should not hand it up. I guess
617 * this is just some form of rx error and that is how we
618 * handle it? For now, just set CRC error flags
619 */
620 if (NRF_CCM->EVENTS_ERROR) {
621 STATS_INC(ble_phy_stats, rx_hw_err);
622 ble_hdr->rxinfo.flags &= ~BLE_MBUF_HDR_F_CRC_OK;
623 }
624
625 /*
626 * XXX: This is a total hack work-around for now but I dont
627 * know what else to do. If ENDCRYPT is not set and we are
628 * encrypted we need to not trust this frame and drop it.
629 */
630 if (NRF_CCM->EVENTS_ENDCRYPT == 0) {
631 STATS_INC(ble_phy_stats, rx_hw_err);
632 ble_hdr->rxinfo.flags &= ~BLE_MBUF_HDR_F_CRC_OK;
633 }
634 }
635 #endif
636 }
637
638 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) || MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY)
639 if (g_ble_phy_data.phy_encrypted || g_ble_phy_data.phy_privacy) {
640 /*
641 * XXX: This is a horrible ugly hack to deal with the RAM S1 byte.
642 * This should get fixed as we should not be handing up the header
643 * and length as part of the pdu.
644 */
645 dptr[2] = dptr[1];
646 dptr[1] = dptr[0];
647 ++dptr;
648 }
649 #endif
650 rc = ble_ll_rx_end(dptr, ble_hdr);
651 if (rc < 0) {
652 ble_phy_disable();
653 }
654 }
655
656 static void
ble_phy_rx_start_isr(void)657 ble_phy_rx_start_isr(void)
658 {
659 int rc;
660 uint32_t state;
661 uint32_t usecs;
662 uint32_t ticks;
663 struct ble_mbuf_hdr *ble_hdr;
664 #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) == 1)
665 uint8_t *dptr;
666
667 dptr = (uint8_t *)&g_ble_phy_rx_buf[0];
668 #endif
669
670 /* Clear events and clear interrupt */
671 NRF_RADIO->EVENTS_ADDRESS = 0;
672
673 /* Clear wfr timer channels and DISABLED interrupt */
674 NRF_RADIO->INTENCLR = RADIO_INTENCLR_DISABLED_Msk | RADIO_INTENCLR_ADDRESS_Msk;
675 NRF_PPI->CHENCLR = PPI_CHEN_CH4_Msk | PPI_CHEN_CH5_Msk;
676
677 /* Initialize flags, channel and state in ble header at rx start */
678 ble_hdr = &g_ble_phy_data.rxhdr;
679 ble_hdr->rxinfo.flags = ble_ll_state_get();
680 ble_hdr->rxinfo.channel = g_ble_phy_data.phy_chan;
681 ble_hdr->rxinfo.handle = 0;
682 ble_hdr->rxinfo.phy = BLE_PHY_1M;
683 ble_hdr->rxinfo.phy_mode = BLE_PHY_MODE_1M;
684 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
685 ble_hdr->rxinfo.user_data = NULL;
686 #endif
687
688 /*
689 * Calculate receive start time.
690 *
691 * XXX: possibly use other routine with remainder!
692 */
693 usecs = NRF_TIMER0->CC[1] - ble_phy_mode_pdu_start_off(BLE_PHY_MODE_1M);
694 ticks = os_cputime_usecs_to_ticks(usecs);
695 ble_hdr->rem_usecs = usecs - os_cputime_ticks_to_usecs(ticks);
696 if (ble_hdr->rem_usecs == 31) {
697 ble_hdr->rem_usecs = 0;
698 ++ticks;
699 }
700 ble_hdr->beg_cputime = g_ble_phy_data.phy_start_cputime + ticks;
701
702 /* Wait to get 1st byte of frame */
703 while (1) {
704 state = NRF_RADIO->STATE;
705 if (NRF_RADIO->EVENTS_BCMATCH != 0) {
706 break;
707 }
708
709 /*
710 * If state is disabled, we should have the BCMATCH. If not,
711 * something is wrong!
712 */
713 if (state == RADIO_STATE_STATE_Disabled) {
714 NRF_RADIO->INTENCLR = NRF_RADIO_IRQ_MASK_ALL;
715 NRF_RADIO->SHORTS = 0;
716 return;
717 }
718 }
719
720 /* Call Link Layer receive start function */
721 rc = ble_ll_rx_start(g_ble_phy_data.rxdptr, g_ble_phy_data.phy_chan,
722 &g_ble_phy_data.rxhdr);
723 if (rc >= 0) {
724 /* Set rx started flag and enable rx end ISR */
725 g_ble_phy_data.phy_rx_started = 1;
726 NRF_RADIO->INTENSET = RADIO_INTENSET_END_Msk;
727
728 #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) == 1)
729 /* Must start aar if we need to */
730 if (g_ble_phy_data.phy_privacy) {
731 NRF_RADIO->EVENTS_BCMATCH = 0;
732 NRF_PPI->CHENSET = PPI_CHEN_CH23_Msk;
733 /*
734 * Setup AAR to resolve AdvA and trigger it after complete address
735 * is received, i.e. after PDU header and AdvA is received.
736 *
737 * AdvA starts at 4th octet in receive buffer, after S0, len and S1
738 * fields.
739 *
740 * In case of extended advertising AdvA is located after extended
741 * header (+2 octets).
742 */
743 if (BLE_MBUF_HDR_EXT_ADV(&g_ble_phy_data.rxhdr)) {
744 NRF_AAR->ADDRPTR = (uint32_t)(dptr + 5);
745 NRF_RADIO->BCC = (BLE_DEV_ADDR_LEN + BLE_LL_PDU_HDR_LEN + 2) * 8;
746
747 } else {
748 NRF_AAR->ADDRPTR = (uint32_t)(dptr + 3);
749 NRF_RADIO->BCC = (BLE_DEV_ADDR_LEN + BLE_LL_PDU_HDR_LEN) * 8;
750 }
751 }
752 #endif
753 } else {
754 /* Disable PHY */
755 ble_phy_disable();
756 STATS_INC(ble_phy_stats, rx_aborts);
757 }
758
759 /* Count rx starts */
760 STATS_INC(ble_phy_stats, rx_starts);
761 }
762
763 static void
ble_phy_isr(void)764 ble_phy_isr(void)
765 {
766 uint32_t irq_en;
767
768 os_trace_isr_enter();
769
770 /* Read irq register to determine which interrupts are enabled */
771 irq_en = NRF_RADIO->INTENCLR;
772
773 /*
774 * NOTE: order of checking is important! Possible, if things get delayed,
775 * we have both an ADDRESS and DISABLED interrupt in rx state. If we get
776 * an address, we disable the DISABLED interrupt.
777 */
778
779 /* We get this if we have started to receive a frame */
780 if ((irq_en & RADIO_INTENCLR_ADDRESS_Msk) && NRF_RADIO->EVENTS_ADDRESS) {
781 irq_en &= ~RADIO_INTENCLR_DISABLED_Msk;
782 ble_phy_rx_start_isr();
783 }
784
785 /* Check for disabled event. This only happens for transmits now */
786 if ((irq_en & RADIO_INTENCLR_DISABLED_Msk) && NRF_RADIO->EVENTS_DISABLED) {
787 if (g_ble_phy_data.phy_state == BLE_PHY_STATE_RX) {
788 NRF_RADIO->EVENTS_DISABLED = 0;
789 ble_ll_wfr_timer_exp(NULL);
790 } else {
791 ble_phy_tx_end_isr();
792 }
793 }
794
795 /* Receive packet end (we dont enable this for transmit) */
796 if ((irq_en & RADIO_INTENCLR_END_Msk) && NRF_RADIO->EVENTS_END) {
797 ble_phy_rx_end_isr();
798 }
799
800 /* Ensures IRQ is cleared */
801 irq_en = NRF_RADIO->SHORTS;
802
803 /* Count # of interrupts */
804 STATS_INC(ble_phy_stats, phy_isrs);
805
806 os_trace_isr_exit();
807 }
808
809 /**
810 * ble phy init
811 *
812 * Initialize the PHY.
813 *
814 * @return int 0: success; PHY error code otherwise
815 */
816 int
ble_phy_init(void)817 ble_phy_init(void)
818 {
819 int rc;
820
821 #if !defined(BLE_XCVR_RFCLK)
822 /* BLE wants the HFXO on all the time in this case */
823 ble_phy_rfclk_enable();
824
825 /*
826 * XXX: I do not think we need to wait for settling time here since
827 * we will probably not use the radio for longer than the settling time
828 * and it will only degrade performance. Might want to wait here though.
829 */
830 #endif
831
832 /* Set phy channel to an invalid channel so first set channel works */
833 g_ble_phy_data.phy_chan = BLE_PHY_NUM_CHANS;
834
835 /* Toggle peripheral power to reset (just in case) */
836 NRF_RADIO->POWER = 0;
837 NRF_RADIO->POWER = 1;
838
839 /* Disable all interrupts */
840 NRF_RADIO->INTENCLR = NRF_RADIO_IRQ_MASK_ALL;
841
842 /* Set configuration registers */
843 NRF_RADIO->MODE = RADIO_MODE_MODE_Ble_1Mbit;
844 NRF_RADIO->PCNF0 = (NRF_LFLEN_BITS << RADIO_PCNF0_LFLEN_Pos) |
845 (NRF_S0_LEN << RADIO_PCNF0_S0LEN_Pos);
846 /* XXX: should maxlen be 251 for encryption? */
847 NRF_RADIO->PCNF1 = NRF_MAXLEN |
848 (RADIO_PCNF1_ENDIAN_Little << RADIO_PCNF1_ENDIAN_Pos) |
849 (NRF_BALEN << RADIO_PCNF1_BALEN_Pos) |
850 RADIO_PCNF1_WHITEEN_Msk;
851
852 /* Set base0 with the advertising access address */
853 NRF_RADIO->BASE0 = (BLE_ACCESS_ADDR_ADV << 8) & 0xFFFFFF00;
854 NRF_RADIO->PREFIX0 = (BLE_ACCESS_ADDR_ADV >> 24) & 0xFF;
855
856 /* Configure the CRC registers */
857 NRF_RADIO->CRCCNF = RADIO_CRCCNF_SKIPADDR_Msk | RADIO_CRCCNF_LEN_Three;
858
859 /* Configure BLE poly */
860 NRF_RADIO->CRCPOLY = 0x0100065B;
861
862 /* Configure IFS */
863 NRF_RADIO->TIFS = BLE_LL_IFS;
864
865 /* Captures tx/rx start in timer0 cc 1 and tx/rx end in timer0 cc 2 */
866 NRF_PPI->CHENSET = PPI_CHEN_CH26_Msk | PPI_CHEN_CH27_Msk;
867
868 #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) == 1)
869 NRF_CCM->INTENCLR = 0xffffffff;
870 NRF_CCM->SHORTS = CCM_SHORTS_ENDKSGEN_CRYPT_Msk;
871 NRF_CCM->EVENTS_ERROR = 0;
872 memset(g_nrf_encrypt_scratchpad, 0, sizeof(g_nrf_encrypt_scratchpad));
873 #endif
874
875 #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) == 1)
876 g_ble_phy_data.phy_aar_scratch = 0;
877 NRF_AAR->IRKPTR = (uint32_t)&g_nrf_irk_list[0];
878 NRF_AAR->INTENCLR = 0xffffffff;
879 NRF_AAR->EVENTS_END = 0;
880 NRF_AAR->EVENTS_RESOLVED = 0;
881 NRF_AAR->EVENTS_NOTRESOLVED = 0;
882 NRF_AAR->NIRK = 0;
883 #endif
884
885 /* TIMER0 setup for PHY when using RTC */
886 NRF_TIMER0->TASKS_STOP = 1;
887 NRF_TIMER0->TASKS_SHUTDOWN = 1;
888 NRF_TIMER0->BITMODE = 3; /* 32-bit timer */
889 NRF_TIMER0->MODE = 0; /* Timer mode */
890 NRF_TIMER0->PRESCALER = 4; /* gives us 1 MHz */
891
892 /*
893 * PPI setup.
894 * Channel 4: Captures TIMER0 in CC[3] when EVENTS_ADDRESS occurs. Used
895 * to cancel the wait for response timer.
896 * Channel 5: TIMER0 CC[3] to TASKS_DISABLE on radio. This is the wait
897 * for response timer.
898 */
899 NRF_PPI->CH[4].EEP = (uint32_t)&(NRF_RADIO->EVENTS_ADDRESS);
900 NRF_PPI->CH[4].TEP = (uint32_t)&(NRF_TIMER0->TASKS_CAPTURE[3]);
901 NRF_PPI->CH[5].EEP = (uint32_t)&(NRF_TIMER0->EVENTS_COMPARE[3]);
902 NRF_PPI->CH[5].TEP = (uint32_t)&(NRF_RADIO->TASKS_DISABLE);
903
904 /* Set isr in vector table and enable interrupt */
905 NVIC_SetPriority(RADIO_IRQn, 0);
906 NVIC_SetVector(RADIO_IRQn, (uint32_t)ble_phy_isr);
907 NVIC_EnableIRQ(RADIO_IRQn);
908
909 /* Register phy statistics */
910 if (!g_ble_phy_data.phy_stats_initialized) {
911 rc = stats_init_and_reg(STATS_HDR(ble_phy_stats),
912 STATS_SIZE_INIT_PARMS(ble_phy_stats,
913 STATS_SIZE_32),
914 STATS_NAME_INIT_PARMS(ble_phy_stats),
915 "ble_phy");
916 assert(rc == 0);
917
918 g_ble_phy_data.phy_stats_initialized = 1;
919 }
920
921 return 0;
922 }
923
924 /**
925 * Puts the phy into receive mode.
926 *
927 * @return int 0: success; BLE Phy error code otherwise
928 */
929 int
ble_phy_rx(void)930 ble_phy_rx(void)
931 {
932 /* Check radio state */
933 nrf_wait_disabled();
934 if (NRF_RADIO->STATE != RADIO_STATE_STATE_Disabled) {
935 ble_phy_disable();
936 STATS_INC(ble_phy_stats, radio_state_errs);
937 return BLE_PHY_ERR_RADIO_STATE;
938 }
939
940 /* Make sure all interrupts are disabled */
941 NRF_RADIO->INTENCLR = NRF_RADIO_IRQ_MASK_ALL;
942
943 /* Clear events prior to enabling receive */
944 NRF_RADIO->EVENTS_END = 0;
945 NRF_RADIO->EVENTS_DISABLED = 0;
946
947 /* Setup for rx */
948 ble_phy_rx_xcvr_setup();
949
950 /* Start the receive task in the radio if not automatically going to rx */
951 if ((NRF_PPI->CHEN & PPI_CHEN_CH21_Msk) == 0) {
952 NRF_RADIO->TASKS_RXEN = 1;
953 }
954
955 return 0;
956 }
957
958 #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) == 1)
959 /**
960 * Called to enable encryption at the PHY. Note that this state will persist
961 * in the PHY; in other words, if you call this function you have to call
962 * disable so that future PHY transmits/receives will not be encrypted.
963 *
964 * @param pkt_counter
965 * @param iv
966 * @param key
967 * @param is_master
968 */
969 void
ble_phy_encrypt_enable(uint64_t pkt_counter,uint8_t * iv,uint8_t * key,uint8_t is_master)970 ble_phy_encrypt_enable(uint64_t pkt_counter, uint8_t *iv, uint8_t *key,
971 uint8_t is_master)
972 {
973 memcpy(g_nrf_ccm_data.key, key, 16);
974 g_nrf_ccm_data.pkt_counter = pkt_counter;
975 memcpy(g_nrf_ccm_data.iv, iv, 8);
976 g_nrf_ccm_data.dir_bit = is_master;
977 g_ble_phy_data.phy_encrypted = 1;
978
979 /* Encryption uses LFLEN=5, S1LEN = 3. */
980 NRF_RADIO->PCNF0 = (5 << RADIO_PCNF0_LFLEN_Pos) |
981 (3 << RADIO_PCNF0_S1LEN_Pos) |
982 (NRF_S0_LEN << RADIO_PCNF0_S0LEN_Pos);
983
984 /* Enable the module (AAR cannot be on while CCM on) */
985 NRF_AAR->ENABLE = AAR_ENABLE_ENABLE_Disabled;
986 NRF_CCM->ENABLE = CCM_ENABLE_ENABLE_Enabled;
987 }
988
989 void
ble_phy_encrypt_set_pkt_cntr(uint64_t pkt_counter,int dir)990 ble_phy_encrypt_set_pkt_cntr(uint64_t pkt_counter, int dir)
991 {
992 g_nrf_ccm_data.pkt_counter = pkt_counter;
993 g_nrf_ccm_data.dir_bit = dir;
994 }
995
996 void
ble_phy_encrypt_disable(void)997 ble_phy_encrypt_disable(void)
998 {
999 NRF_PPI->CHENCLR = (PPI_CHEN_CH24_Msk | PPI_CHEN_CH25_Msk);
1000 NRF_CCM->TASKS_STOP = 1;
1001 NRF_CCM->EVENTS_ERROR = 0;
1002 NRF_CCM->ENABLE = CCM_ENABLE_ENABLE_Disabled;
1003
1004 /* Switch back to normal length */
1005 NRF_RADIO->PCNF0 = (NRF_LFLEN_BITS << RADIO_PCNF0_LFLEN_Pos) |
1006 (NRF_S0_LEN << RADIO_PCNF0_S0LEN_Pos);
1007
1008 g_ble_phy_data.phy_encrypted = 0;
1009 }
1010 #endif
1011
1012 void
ble_phy_set_txend_cb(ble_phy_tx_end_func txend_cb,void * arg)1013 ble_phy_set_txend_cb(ble_phy_tx_end_func txend_cb, void *arg)
1014 {
1015 /* Set transmit end callback and arg */
1016 g_ble_phy_data.txend_cb = txend_cb;
1017 g_ble_phy_data.txend_arg = arg;
1018 }
1019
1020 /**
1021 * Called to set the start time of a transmission.
1022 *
1023 * This function is called to set the start time when we are not going from
1024 * rx to tx automatically.
1025 *
1026 * NOTE: care must be taken when calling this function. The channel should
1027 * already be set.
1028 *
1029 * @param cputime This is the tick at which the 1st bit of the preamble
1030 * should be transmitted
1031 * @param rem_usecs This is used only when the underlying timing uses a 32.768
1032 * kHz crystal. It is the # of usecs from the cputime tick
1033 * at which the first bit of the preamble should be
1034 * transmitted.
1035 * @return int
1036 */
1037 int
ble_phy_tx_set_start_time(uint32_t cputime,uint8_t rem_usecs)1038 ble_phy_tx_set_start_time(uint32_t cputime, uint8_t rem_usecs)
1039 {
1040 int rc;
1041
1042 ble_phy_trace_u32x2(BLE_PHY_TRACE_ID_START_TX, cputime, rem_usecs);
1043
1044 /* XXX: This should not be necessary, but paranoia is good! */
1045 /* Clear timer0 compare to RXEN since we are transmitting */
1046 NRF_PPI->CHENCLR = PPI_CHEN_CH21_Msk;
1047
1048 /*
1049 * XXX: The TXEN time is 140 usecs but there may be additional delays
1050 * Need to look at this.
1051 */
1052 if (ble_phy_set_start_time(cputime, rem_usecs) != 0) {
1053 STATS_INC(ble_phy_stats, tx_late);
1054 ble_phy_disable();
1055 rc = BLE_PHY_ERR_TX_LATE;
1056 } else {
1057 /* Enable PPI to automatically start TXEN */
1058 NRF_PPI->CHENSET = PPI_CHEN_CH20_Msk;
1059 rc = 0;
1060 }
1061 return rc;
1062 }
1063 /**
1064 * Called to set the start time of a reception
1065 *
1066 * This function acts a bit differently than transmit. If we are late getting
1067 * here we will still attempt to receive.
1068 *
1069 * NOTE: care must be taken when calling this function. The channel should
1070 * already be set.
1071 *
1072 * @param cputime
1073 *
1074 * @return int
1075 */
1076 int
ble_phy_rx_set_start_time(uint32_t cputime,uint8_t rem_usecs)1077 ble_phy_rx_set_start_time(uint32_t cputime, uint8_t rem_usecs)
1078 {
1079 int rc;
1080
1081 ble_phy_trace_u32x2(BLE_PHY_TRACE_ID_START_RX, cputime, rem_usecs);
1082
1083 /* XXX: This should not be necessary, but paranoia is good! */
1084 /* Clear timer0 compare to TXEN since we are transmitting */
1085 NRF_PPI->CHENCLR = PPI_CHEN_CH20_Msk;
1086
1087 /*
1088 * XXX: The RXEN time is 138 usecs but there may be additional delays
1089 * Need to look at this.
1090 */
1091 if (ble_phy_set_start_time(cputime, rem_usecs) != 0) {
1092 STATS_INC(ble_phy_stats, rx_late);
1093 NRF_PPI->CHENCLR = PPI_CHEN_CH21_Msk;
1094 NRF_RADIO->TASKS_RXEN = 1;
1095 rc = BLE_PHY_ERR_RX_LATE;
1096 } else {
1097 /* Enable PPI to automatically start RXEN */
1098 NRF_PPI->CHENSET = PPI_CHEN_CH21_Msk;
1099
1100 /* Start rx */
1101 rc = ble_phy_rx();
1102 }
1103 return rc;
1104 }
1105
1106 int
ble_phy_tx(ble_phy_tx_pducb_t pducb,void * pducb_arg,uint8_t end_trans)1107 ble_phy_tx(ble_phy_tx_pducb_t pducb, void *pducb_arg, uint8_t end_trans)
1108 {
1109 int rc;
1110 uint8_t *dptr;
1111 uint8_t payload_len;
1112 uint8_t payload_off;
1113 uint8_t hdr_byte;
1114 uint32_t state;
1115 uint32_t shortcuts;
1116
1117 /*
1118 * This check is to make sure that the radio is not in a state where
1119 * it is moving to disabled state. If so, let it get there.
1120 */
1121 nrf_wait_disabled();
1122
1123 /*
1124 * XXX: Although we may not have to do this here, I clear all the PPI
1125 * that should not be used when transmitting. Some of them are only enabled
1126 * if encryption and/or privacy is on, but I dont care. Better to be
1127 * paranoid, and if you are going to clear one, might as well clear them
1128 * all.
1129 */
1130 NRF_PPI->CHENCLR = PPI_CHEN_CH4_Msk | PPI_CHEN_CH5_Msk | PPI_CHEN_CH23_Msk |
1131 PPI_CHEN_CH25_Msk;
1132
1133 #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) == 1)
1134 if (g_ble_phy_data.phy_encrypted) {
1135 /* RAM representation has S0, LENGTH and S1 fields. (3 bytes) */
1136 dptr = (uint8_t *)&g_ble_phy_enc_buf[0];
1137 payload_off = 3;
1138
1139 NRF_CCM->SHORTS = 1;
1140 NRF_CCM->INPTR = (uint32_t)&g_ble_phy_enc_buf[0];
1141 NRF_CCM->OUTPTR = (uint32_t)&g_ble_phy_tx_buf[0];
1142 NRF_CCM->SCRATCHPTR = (uint32_t)&g_nrf_encrypt_scratchpad[0];
1143 NRF_CCM->EVENTS_ERROR = 0;
1144 NRF_CCM->MODE = CCM_MODE_MODE_Encryption;
1145 NRF_CCM->CNFPTR = (uint32_t)&g_nrf_ccm_data;
1146 NRF_PPI->CHENSET = PPI_CHEN_CH24_Msk;
1147 } else {
1148 #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) == 1)
1149 /* Reconfigure PCNF0 */
1150 NRF_RADIO->PCNF0 = (NRF_LFLEN_BITS << RADIO_PCNF0_LFLEN_Pos) |
1151 (NRF_S0_LEN << RADIO_PCNF0_S0LEN_Pos);
1152 NRF_AAR->IRKPTR = (uint32_t)&g_nrf_irk_list[0];
1153 #endif
1154 /* RAM representation has S0 and LENGTH fields (2 bytes) */
1155 dptr = (uint8_t *)&g_ble_phy_tx_buf[0];
1156 payload_off = 2;
1157 }
1158 #else
1159
1160 #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) == 1)
1161 /* Reconfigure PCNF0 */
1162 NRF_RADIO->PCNF0 = (NRF_LFLEN_BITS << RADIO_PCNF0_LFLEN_Pos) |
1163 (NRF_S0_LEN << RADIO_PCNF0_S0LEN_Pos);
1164 #endif
1165
1166 /* RAM representation has S0 and LENGTH fields (2 bytes) */
1167 dptr = (uint8_t *)&g_ble_phy_tx_buf[0];
1168 payload_off = 2;
1169 #endif
1170
1171 NRF_RADIO->PACKETPTR = (uint32_t)&g_ble_phy_tx_buf[0];
1172
1173 /* Clear the ready, end and disabled events */
1174 NRF_RADIO->EVENTS_READY = 0;
1175 NRF_RADIO->EVENTS_END = 0;
1176 NRF_RADIO->EVENTS_DISABLED = 0;
1177
1178 /* Enable shortcuts for transmit start/end. */
1179 shortcuts = RADIO_SHORTS_END_DISABLE_Msk | RADIO_SHORTS_READY_START_Msk;
1180 if (end_trans == BLE_PHY_TRANSITION_TX_RX) {
1181 shortcuts |= RADIO_SHORTS_DISABLED_RXEN_Msk;
1182 }
1183 NRF_RADIO->SHORTS = shortcuts;
1184 NRF_RADIO->INTENSET = RADIO_INTENSET_DISABLED_Msk;
1185
1186 /* Set PDU payload */
1187 payload_len = pducb(&dptr[payload_off], pducb_arg, &hdr_byte);
1188
1189 /* Set PDU header */
1190 dptr[0] = hdr_byte;
1191 dptr[1] = payload_len;
1192 if (payload_off > 2) {
1193 dptr[2] = 0;
1194 }
1195
1196 /* Set the PHY transition */
1197 g_ble_phy_data.phy_transition = end_trans;
1198
1199 /* Set transmitted payload length */
1200 g_ble_phy_data.phy_tx_pyld_len = payload_len;
1201
1202 /* If we already started transmitting, abort it! */
1203 state = NRF_RADIO->STATE;
1204 if (state != RADIO_STATE_STATE_Tx) {
1205
1206 /* Set phy state to transmitting and count packet statistics */
1207 g_ble_phy_data.phy_state = BLE_PHY_STATE_TX;
1208 STATS_INC(ble_phy_stats, tx_good);
1209 STATS_INCN(ble_phy_stats, tx_bytes, payload_len + BLE_LL_PDU_HDR_LEN);
1210 rc = BLE_ERR_SUCCESS;
1211 } else {
1212 ble_phy_disable();
1213 STATS_INC(ble_phy_stats, tx_late);
1214 rc = BLE_PHY_ERR_RADIO_STATE;
1215 }
1216
1217 return rc;
1218 }
1219
1220 /**
1221 * ble phy txpwr set
1222 *
1223 * Set the transmit output power (in dBm).
1224 *
1225 * NOTE: If the output power specified is within the BLE limits but outside
1226 * the chip limits, we "rail" the power level so we dont exceed the min/max
1227 * chip values.
1228 *
1229 * @param dbm Power output in dBm.
1230 *
1231 * @return int 0: success; anything else is an error
1232 */
1233 int
ble_phy_txpwr_set(int dbm)1234 ble_phy_txpwr_set(int dbm)
1235 {
1236 /* Check valid range */
1237 assert(dbm <= BLE_PHY_MAX_PWR_DBM);
1238
1239 /* "Rail" power level if outside supported range */
1240 if (dbm > NRF_TX_PWR_MAX_DBM) {
1241 dbm = NRF_TX_PWR_MAX_DBM;
1242 } else {
1243 if (dbm < NRF_TX_PWR_MIN_DBM) {
1244 dbm = NRF_TX_PWR_MIN_DBM;
1245 }
1246 }
1247
1248 NRF_RADIO->TXPOWER = dbm;
1249 g_ble_phy_data.phy_txpwr_dbm = dbm;
1250
1251 return 0;
1252 }
1253
1254 /**
1255 * ble phy txpwr round
1256 *
1257 * Get the rounded transmit output power (in dBm).
1258 *
1259 * @param dbm Power output in dBm.
1260 *
1261 * @return int Rounded power in dBm
1262 */
ble_phy_txpower_round(int dbm)1263 int ble_phy_txpower_round(int dbm)
1264 {
1265 /* "Rail" power level if outside supported range */
1266 if (dbm > NRF_TX_PWR_MAX_DBM) {
1267 dbm = NRF_TX_PWR_MAX_DBM;
1268 } else {
1269 if (dbm < NRF_TX_PWR_MIN_DBM) {
1270 dbm = NRF_TX_PWR_MIN_DBM;
1271 }
1272 }
1273
1274 return dbm;
1275 }
1276
1277 /**
1278 * ble phy txpwr get
1279 *
1280 * Get the transmit power.
1281 *
1282 * @return int The current PHY transmit power, in dBm
1283 */
1284 int
ble_phy_txpwr_get(void)1285 ble_phy_txpwr_get(void)
1286 {
1287 return g_ble_phy_data.phy_txpwr_dbm;
1288 }
1289
1290 /**
1291 * ble phy setchan
1292 *
1293 * Sets the logical frequency of the transceiver. The input parameter is the
1294 * BLE channel index (0 to 39, inclusive). The NRF frequency register works like
1295 * this: logical frequency = 2400 + FREQ (MHz).
1296 *
1297 * Thus, to get a logical frequency of 2402 MHz, you would program the
1298 * FREQUENCY register to 2.
1299 *
1300 * @param chan This is the Data Channel Index or Advertising Channel index
1301 *
1302 * @return int 0: success; PHY error code otherwise
1303 */
1304 int
ble_phy_setchan(uint8_t chan,uint32_t access_addr,uint32_t crcinit)1305 ble_phy_setchan(uint8_t chan, uint32_t access_addr, uint32_t crcinit)
1306 {
1307 uint32_t prefix;
1308
1309 assert(chan < BLE_PHY_NUM_CHANS);
1310
1311 /* Check for valid channel range */
1312 if (chan >= BLE_PHY_NUM_CHANS) {
1313 return BLE_PHY_ERR_INV_PARAM;
1314 }
1315
1316 /* Get correct frequency */
1317 if (chan < BLE_PHY_NUM_DATA_CHANS) {
1318 /* Set current access address */
1319 g_ble_phy_data.phy_access_address = access_addr;
1320
1321 /* Configure logical address 1 and crcinit */
1322 prefix = NRF_RADIO->PREFIX0;
1323 prefix &= 0xffff00ff;
1324 prefix |= ((access_addr >> 24) & 0xFF) << 8;
1325 NRF_RADIO->BASE1 = (access_addr << 8) & 0xFFFFFF00;
1326 NRF_RADIO->PREFIX0 = prefix;
1327 NRF_RADIO->TXADDRESS = 1;
1328 NRF_RADIO->RXADDRESSES = (1 << 1);
1329 NRF_RADIO->CRCINIT = crcinit;
1330 } else {
1331 /* Logical adddress 0 preconfigured */
1332 NRF_RADIO->TXADDRESS = 0;
1333 NRF_RADIO->RXADDRESSES = (1 << 0);
1334 NRF_RADIO->CRCINIT = BLE_LL_CRCINIT_ADV;
1335
1336 /* Set current access address */
1337 g_ble_phy_data.phy_access_address = BLE_ACCESS_ADDR_ADV;
1338 }
1339
1340 /* Set the frequency and the data whitening initial value */
1341 g_ble_phy_data.phy_chan = chan;
1342 NRF_RADIO->FREQUENCY = g_ble_phy_chan_freq[chan];
1343 NRF_RADIO->DATAWHITEIV = chan;
1344
1345 return 0;
1346 }
1347
1348 /**
1349 * Stop the timer used to count microseconds when using RTC for cputime
1350 */
1351 void
ble_phy_stop_usec_timer(void)1352 ble_phy_stop_usec_timer(void)
1353 {
1354 NRF_TIMER0->TASKS_STOP = 1;
1355 NRF_TIMER0->TASKS_SHUTDOWN = 1;
1356 NRF_RTC0->EVTENCLR = RTC_EVTENSET_COMPARE0_Msk;
1357 }
1358
1359 /**
1360 * ble phy disable irq and ppi
1361 *
1362 * This routine is to be called when reception was stopped due to either a
1363 * wait for response timeout or a packet being received and the phy is to be
1364 * restarted in receive mode. Generally, the disable routine is called to stop
1365 * the phy.
1366 */
1367 void
ble_phy_disable_irq_and_ppi(void)1368 ble_phy_disable_irq_and_ppi(void)
1369 {
1370 NRF_RADIO->INTENCLR = NRF_RADIO_IRQ_MASK_ALL;
1371 NRF_RADIO->SHORTS = 0;
1372 NRF_RADIO->TASKS_DISABLE = 1;
1373 NRF_PPI->CHENCLR = PPI_CHEN_CH4_Msk | PPI_CHEN_CH5_Msk | PPI_CHEN_CH20_Msk |
1374 PPI_CHEN_CH21_Msk | PPI_CHEN_CH23_Msk | PPI_CHEN_CH24_Msk |
1375 PPI_CHEN_CH25_Msk | PPI_CHEN_CH31_Msk;
1376 NVIC_ClearPendingIRQ(RADIO_IRQn);
1377 g_ble_phy_data.phy_state = BLE_PHY_STATE_IDLE;
1378 }
1379
1380 void
ble_phy_restart_rx(void)1381 ble_phy_restart_rx(void)
1382 {
1383 ble_phy_disable_irq_and_ppi();
1384 ble_phy_rx();
1385 }
1386
1387 /**
1388 * ble phy disable
1389 *
1390 * Disables the PHY. This should be called when an event is over. It stops
1391 * the usec timer (if used), disables interrupts, disables the RADIO, disables
1392 * PPI and sets state to idle.
1393 */
1394 void
ble_phy_disable(void)1395 ble_phy_disable(void)
1396 {
1397 ble_phy_trace_void(BLE_PHY_TRACE_ID_DISABLE);
1398
1399 ble_phy_stop_usec_timer();
1400 ble_phy_disable_irq_and_ppi();
1401 }
1402
1403 /* Gets the current access address */
ble_phy_access_addr_get(void)1404 uint32_t ble_phy_access_addr_get(void)
1405 {
1406 return g_ble_phy_data.phy_access_address;
1407 }
1408
1409 /**
1410 * Return the phy state
1411 *
1412 * @return int The current PHY state.
1413 */
1414 int
ble_phy_state_get(void)1415 ble_phy_state_get(void)
1416 {
1417 return g_ble_phy_data.phy_state;
1418 }
1419
1420 /**
1421 * Called to see if a reception has started
1422 *
1423 * @return int
1424 */
1425 int
ble_phy_rx_started(void)1426 ble_phy_rx_started(void)
1427 {
1428 return g_ble_phy_data.phy_rx_started;
1429 }
1430
1431 /**
1432 * Return the transceiver state
1433 *
1434 * @return int transceiver state.
1435 */
1436 uint8_t
ble_phy_xcvr_state_get(void)1437 ble_phy_xcvr_state_get(void)
1438 {
1439 uint32_t state;
1440 state = NRF_RADIO->STATE;
1441 return (uint8_t)state;
1442 }
1443
1444 /**
1445 * Called to return the maximum data pdu payload length supported by the
1446 * phy. For this chip, if encryption is enabled, the maximum payload is 27
1447 * bytes.
1448 *
1449 * @return uint8_t Maximum data channel PDU payload size supported
1450 */
1451 uint8_t
ble_phy_max_data_pdu_pyld(void)1452 ble_phy_max_data_pdu_pyld(void)
1453 {
1454 #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) == 1)
1455 return NRF_MAX_ENCRYPTED_PYLD_LEN;
1456 #else
1457 return BLE_LL_DATA_PDU_MAX_PYLD;
1458 #endif
1459 }
1460
1461 #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) == 1)
1462 void
ble_phy_resolv_list_enable(void)1463 ble_phy_resolv_list_enable(void)
1464 {
1465 NRF_AAR->NIRK = (uint32_t)g_nrf_num_irks;
1466 g_ble_phy_data.phy_privacy = 1;
1467 }
1468
1469 void
ble_phy_resolv_list_disable(void)1470 ble_phy_resolv_list_disable(void)
1471 {
1472 g_ble_phy_data.phy_privacy = 0;
1473 }
1474 #endif
1475
1476 void
ble_phy_rfclk_enable(void)1477 ble_phy_rfclk_enable(void)
1478 {
1479 #if MYNEWT
1480 nrf51_clock_hfxo_request();
1481 #else
1482 NRF_CLOCK->TASKS_HFCLKSTART = 1;
1483 #endif
1484 }
1485
1486 void
ble_phy_rfclk_disable(void)1487 ble_phy_rfclk_disable(void)
1488 {
1489 #if MYNEWT
1490 nrf51_clock_hfxo_release();
1491 #else
1492 NRF_CLOCK->TASKS_HFCLKSTOP = 1;
1493 #endif
1494 }
1495