nrf_to_nrf - NRF52 Radio Driver v1.2.2
TMRh20 2023 - OSI Layer 2 radio driver using RF24 API
Loading...
Searching...
No Matches
nrf_to_nrf.cpp
Go to the documentation of this file.
1
2
3#include "nrf_to_nrf.h"
4
5#if defined(NRF52832_XXAA) || defined(NRF52832_XXAB) || defined(NRF52811_XXAA) || defined(NRF52810_XXAA) || defined(NRF52805_XXAA)
6 // TX power range (Product Specification): -20 .. +4dbm, configurable in 4 dB steps
7 #define TXPOWER_PA_MIN 0xF4 // -12dBm
8 #define TXPOWER_PA_LOW 0xFC // -4dBm
9 #define TXPOWER_PA_HIGH 0x00 // 0dBm
10 #define TXPOWER_PA_MAX 0x04 // 4dBm
11#else // nRF52840, nRF52833, nRF52820
12 // TX power range (Product Specification): -20 .. +8dbm, configurable in 4 dB steps
13 #define TXPOWER_PA_MIN 0xF4 // -12dBm
14 #define TXPOWER_PA_LOW 0x02 // 2dBm
15 #define TXPOWER_PA_HIGH 0x06 // 6dBm
16 #define TXPOWER_PA_MAX 0x08 // 8dBm
17#endif
18
19// Note that 250Kbit mode is deprecated and might not work reliably on all devices.
20// See: https://devzone.nordicsemi.com/f/nordic-q-a/78469/250-kbit-s-nordic-proprietary-radio-mode-on-nrf52840
21#ifndef RADIO_MODE_MODE_Nrf_250Kbit
22 #define RADIO_MODE_MODE_Nrf_250Kbit (2UL)
23#endif
24
25/**********************************************************************************************************/
26
27// Function to do bytewise bit-swap on an unsigned 32-bit value
28static uint32_t bytewise_bit_swap(uint8_t const* p_inp)
29{
30 uint32_t inp = (p_inp[3] << 24) | (p_inp[2] << 16) | (p_inp[1] << 8) | (p_inp[0]);
31 inp = (inp & 0xF0F0F0F0) >> 4 | (inp & 0x0F0F0F0F) << 4;
32 inp = (inp & 0xCCCCCCCC) >> 2 | (inp & 0x33333333) << 2;
33 inp = (inp & 0xAAAAAAAA) >> 1 | (inp & 0x55555555) << 1;
34 return inp;
35}
36
37/**********************************************************************************************************/
38
39// Convert a base address from nRF24L format to nRF5 format
40static uint32_t addr_conv(uint8_t const* p_addr)
41{
42 return __REV(
43 bytewise_bit_swap(p_addr)); // lint -esym(628, __rev) -esym(526, __rev) */
44}
45
46/**********************************************************************************************************/
47
48uint32_t nrf_to_nrf::addrConv32(uint32_t addr)
49{
50
51 uint8_t buffer[4];
52 buffer[0] = addr & 0xFF;
53 buffer[1] = (addr >> 8) & 0xFF;
54 buffer[2] = (addr >> 16) & 0xFF;
55 buffer[3] = (addr >> 24) & 0xFF;
56
57 return addr_conv(buffer);
58}
59
60/**********************************************************************************************************/
61
63{
64 DPL = false;
65 staticPayloadSize = 32;
66 // Enable auto ack on all pipes by default
67 setAutoAck(1);
68 retries = 5;
69 retryDuration = 5;
70 ackPayloadsEnabled = false;
71 ackPipe = 0;
72 inRxMode = false;
73 ARC = 0;
74 addressWidth = 5;
75 ackTimeout = ACK_TIMEOUT_1MBPS;
76 payloadAvailable = false;
77
78#if defined CCM_ENCRYPTION_ENABLED
79 NRF_CCM->INPTR = (uint32_t)inBuffer;
80 NRF_CCM->OUTPTR = (uint32_t)outBuffer;
81 NRF_CCM->CNFPTR = (uint32_t)&ccmData;
82 NRF_CCM->SCRATCHPTR = (uint32_t)scratchPTR;
83 ccmData.counter = 12345;
84
85 NRF_CCM->MODE = 1 << 24 | 1 << 16;
86 NRF_CCM->MAXPACKETSIZE = MAX_PACKET_SIZE;
87 NRF_CCM->SHORTS = 1;
88 NRF_CCM->ENABLE = 2;
89 enableEncryption = false;
90 NRF_RNG->CONFIG = 1;
91 NRF_RNG->TASKS_START = 1;
92#endif
93};
94
95/**********************************************************************************************************/
96
98{
99
100 NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
101 NRF_CLOCK->TASKS_HFCLKSTART = 1;
102
103 /* Wait for the external oscillator to start up */
104 while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0) {
105 // Do nothing.
106 }
107
108 NRF_CLOCK->EVENTS_LFCLKSTARTED = 0;
109 NRF_CLOCK->TASKS_LFCLKSTART = 1;
110
111 /* Wait for the low frequency clock to start up */
112 while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0) {
113 // Do nothing.
114 }
115
116 NRF_RADIO->POWER = 1;
117 // NRF_POWER->DCDCEN=1;
118
119 NRF_RADIO->PCNF0 = (1 << RADIO_PCNF0_S0LEN_Pos) | (0 << RADIO_PCNF0_LFLEN_Pos) | (1 << RADIO_PCNF0_S1LEN_Pos);
120
121 NRF_RADIO->PCNF1 = (RADIO_PCNF1_WHITEEN_Disabled << RADIO_PCNF1_WHITEEN_Pos) | (RADIO_PCNF1_ENDIAN_Big << RADIO_PCNF1_ENDIAN_Pos) | (4 << RADIO_PCNF1_BALEN_Pos) | (staticPayloadSize << RADIO_PCNF1_STATLEN_Pos) | (staticPayloadSize << RADIO_PCNF1_MAXLEN_Pos);
122
123 NRF_RADIO->BASE0 = 0xE7E7E7E7; /* Base address 0 */
124 NRF_RADIO->BASE1 = 0x43434343;
125 NRF_RADIO->PREFIX0 = 0x23C343E7; /* Prefixes bytes for logical addresses 0 */
126 NRF_RADIO->PREFIX1 = 0x13E363A3;
127 NRF_RADIO->RXADDRESSES = 0x01;
128 NRF_RADIO->TXADDRESS = 0x00;
129 /* Receive address select */
130 txBase = NRF_RADIO->BASE0;
131 txPrefix = NRF_RADIO->PREFIX0;
132 rxBase = NRF_RADIO->BASE0;
133 rxPrefix = NRF_RADIO->PREFIX0;
134 // Configure CRC for 16-bit
135 NRF_RADIO->CRCCNF = RADIO_CRCCNF_LEN_Two; /* CRC configuration: 16bit */
136 NRF_RADIO->CRCINIT = 0xFFFFUL; // Initial value
137 NRF_RADIO->CRCPOLY = 0x11021UL; // CRC poly: x^16+x^12^x^5+1
138
139 NRF_RADIO->PACKETPTR = (uint32_t)radioData;
140 NRF_RADIO->MODE = (RADIO_MODE_MODE_Nrf_1Mbit << RADIO_MODE_MODE_Pos);
141 NRF_RADIO->MODECNF0 = 0x200;
142 NRF_RADIO->MODECNF0 |= 1;
143 NRF_RADIO->TXPOWER = (TXPOWER_PA_MAX << RADIO_TXPOWER_TXPOWER_Pos);
144 NRF_RADIO->SHORTS = 1 << 19;
145 NRF_RADIO->FREQUENCY = 0x4C;
146
147 DPL = false;
148 return 1;
149}
150
151/**********************************************************************************************************/
152
153#ifdef NRF_HAS_ENERGY_DETECT
154 #define ED_RSSISCALE 4 // From electrical specifications
155uint8_t nrf_to_nrf::sample_ed(void)
156{
157 int val;
158 NRF_RADIO->TASKS_EDSTART = 1; // Start
159 while (NRF_RADIO->EVENTS_EDEND != 1) {
160 // CPU can sleep here or do something else
161 // Use of interrupts are encouraged
162 }
163 val = NRF_RADIO->EDSAMPLE; // Read level
164 return (uint8_t)(val > 63
165 ? 255
166 : val * ED_RSSISCALE); // Convert to IEEE 802.15.4 scale
167}
168#endif
169
170/**********************************************************************************************************/
171
173{
174 uint8_t pipe_num = 0;
175 return available(&pipe_num);
176}
177
178/**********************************************************************************************************/
179
180bool nrf_to_nrf::available(uint8_t* pipe_num)
181{
182
183 if (payloadAvailable) {
184 *pipe_num = (uint8_t)NRF_RADIO->RXMATCH;
185 return true;
186 }
187
188 if (!inRxMode) {
189 if (ackPayloadAvailable) {
190 *pipe_num = ackAvailablePipeNo;
191 return true;
192 }
193 }
194 if (NRF_RADIO->EVENTS_CRCOK) {
195 uint32_t counter = 0;
196#if defined CCM_ENCRYPTION_ENABLED
197 uint8_t tmpIV[CCM_IV_SIZE];
198#endif
199 NRF_RADIO->EVENTS_CRCOK = 0;
200 if (DPL) {
201 if (radioData[0] > ACTUAL_MAX_PAYLOAD_SIZE - 4 && NRF_RADIO->CRCCNF == RADIO_CRCCNF_LEN_Two) {
202 if (inRxMode) {
203 NRF_RADIO->TASKS_START = 1;
204 }
205 return 0;
206 }
207 else if (radioData[0] > ACTUAL_MAX_PAYLOAD_SIZE - 3 && NRF_RADIO->CRCCNF == RADIO_CRCCNF_LEN_One) {
208 if (inRxMode) {
209 NRF_RADIO->TASKS_START = 1;
210 }
211 return 0;
212 }
213 else if (radioData[0] > ACTUAL_MAX_PAYLOAD_SIZE - 2 && NRF_RADIO->CRCCNF == 0) {
214 if (inRxMode) {
215 NRF_RADIO->TASKS_START = 1;
216 }
217 return 0;
218 }
219 }
220
221 *pipe_num = (uint8_t)NRF_RADIO->RXMATCH;
222 if (!DPL && acksEnabled(*pipe_num) == false) {
223#if defined CCM_ENCRYPTION_ENABLED
224 if (enableEncryption) {
225 memcpy(&rxBuffer[1], &radioData[CCM_IV_SIZE + CCM_COUNTER_SIZE], staticPayloadSize);
226 memcpy(ccmData.iv, &radioData[0], CCM_IV_SIZE);
227 memcpy(&counter, &radioData[CCM_IV_SIZE], CCM_COUNTER_SIZE);
228 }
229 else {
230#endif
231 memcpy(&rxBuffer[1], &radioData[0], staticPayloadSize);
232#if defined CCM_ENCRYPTION_ENABLED
233 }
234#endif
235 }
236 else {
237#if defined CCM_ENCRYPTION_ENABLED
238 if (enableEncryption) {
239 if (DPL) {
240 memcpy(&rxBuffer[1], &radioData[2 + CCM_IV_SIZE + CCM_COUNTER_SIZE], max(0, radioData[0] - CCM_IV_SIZE - CCM_COUNTER_SIZE));
241 }
242 else {
243 memcpy(&rxBuffer[1], &radioData[2 + CCM_IV_SIZE + CCM_COUNTER_SIZE], max(0, staticPayloadSize - CCM_IV_SIZE - CCM_COUNTER_SIZE));
244 }
245 memcpy(tmpIV, &radioData[2], CCM_IV_SIZE);
246 memcpy(&counter, &radioData[2 + CCM_IV_SIZE], CCM_COUNTER_SIZE);
247 }
248 else {
249#endif
250 if (DPL) {
251 memcpy(&rxBuffer[1], &radioData[2], radioData[0]);
252 }
253 else {
254 memcpy(&rxBuffer[1], &radioData[2], staticPayloadSize);
255 }
256#if defined CCM_ENCRYPTION_ENABLED
257 }
258#endif
259 }
260 rxBuffer[0] = radioData[0];
261 rxFifoAvailable = true;
262 uint8_t packetCtr = 0;
263 if (DPL) {
264 packetCtr = radioData[1];
265 }
266 else {
267 packetCtr = radioData[0];
268 }
269
270 ackPID = packetCtr;
271 uint16_t packetData = NRF_RADIO->RXCRC;
272 // If ack is enabled on this receiving pipe
273 if (acksEnabled(NRF_RADIO->RXMATCH)) {
274 stopListening(false, false);
275 uint32_t txAddress = NRF_RADIO->TXADDRESS;
276 NRF_RADIO->TXADDRESS = NRF_RADIO->RXMATCH;
277 delayMicroseconds(75);
278 if (ackPayloadsEnabled) {
279 if (*pipe_num == ackPipe) {
280 write(&ackBuffer[1], ackBuffer[0], 1, 0);
281 }
282 else {
283 write(0, 0, 1, 0);
284 }
285 }
286 else {
287 uint8_t payloadSize = 0;
288 if (!DPL) {
289 payloadSize = getPayloadSize();
291 }
292 write(0, 0, 1, 0); // Send an ACK
293 if (!DPL) {
294 setPayloadSize(payloadSize);
295 }
296 }
297 NRF_RADIO->TXADDRESS = txAddress;
298 startListening(false);
299
300 // If the packet has the same ID number and data, it is most likely a
301 // duplicate
302 if (NRF_RADIO->CRCCNF != 0) { // If CRC enabled, check this data
303 if (packetCtr == lastPacketCounter && packetData == lastData) {
304 if (inRxMode) {
305 NRF_RADIO->TASKS_START = 1;
306 }
307 return 0;
308 }
309 }
310 }
311
312#if defined CCM_ENCRYPTION_ENABLED
313 if (enableEncryption) {
314 ccmData.counter = counter;
315 memcpy(&ccmData.iv[0], &tmpIV[0], CCM_IV_SIZE);
316 if (DPL) {
317 if (!decrypt(&rxBuffer[1], rxBuffer[0] - CCM_IV_SIZE - CCM_COUNTER_SIZE)) {
318 Serial.println("DECRYPT FAIL");
319 if (inRxMode) {
320 NRF_RADIO->TASKS_START = 1;
321 }
322 return 0;
323 }
324 }
325 else {
326 if (!decrypt(&rxBuffer[1], staticPayloadSize - CCM_IV_SIZE - CCM_COUNTER_SIZE)) {
327 Serial.println("DECRYPT FAIL");
328 if (inRxMode) {
329 NRF_RADIO->TASKS_START = 1;
330 }
331 return 0;
332 }
333 }
334
335 memset(&rxBuffer[1], 0, sizeof(rxBuffer) - 1);
336
337 if (DPL) {
338 rxBuffer[0] -= (CCM_MIC_SIZE + CCM_IV_SIZE + CCM_COUNTER_SIZE);
339 memcpy(&rxBuffer[1], &outBuffer[CCM_START_SIZE], rxBuffer[0]);
340 }
341 else {
342 memcpy(&rxBuffer[1], &outBuffer[CCM_START_SIZE], staticPayloadSize - (CCM_MIC_SIZE - CCM_IV_SIZE - CCM_COUNTER_SIZE));
343 }
344 }
345#endif
346 lastPacketCounter = packetCtr;
347 lastData = packetData;
348 payloadAvailable = true;
349 if (inRxMode) {
350 NRF_RADIO->TASKS_START = 1;
351 }
352 return 1;
353 }
354 if (NRF_RADIO->EVENTS_CRCERROR) {
355 NRF_RADIO->EVENTS_CRCERROR = 0;
356 NRF_RADIO->TASKS_START = 1;
357 }
358 return 0;
359}
360
361/**********************************************************************************************************/
362
363void nrf_to_nrf::read(void* buf, uint8_t len)
364{
365 memcpy(buf, &rxBuffer[1], len);
366 ackPayloadAvailable = false;
367 payloadAvailable = false;
368}
369
370/**********************************************************************************************************/
371
372bool nrf_to_nrf::write(void* buf, uint8_t len, bool multicast, bool doEncryption)
373{
374
375 uint8_t PID = ackPID;
376 if (DPL) {
377 PID = ((ackPID += 1) % 7) << 1;
378 }
379 else {
380 PID = ackPID++;
381 }
382 uint8_t payloadSize = 0;
383
384#if defined CCM_ENCRYPTION_ENABLED
385 uint8_t tmpIV[CCM_IV_SIZE];
386 uint32_t tmpCounter = 0;
387 uint8_t tmpBuffer[MAX_PACKET_SIZE + CCM_MIC_SIZE + CCM_START_SIZE];
388
389 if (enableEncryption && doEncryption) {
390 if (len) {
391
392 for (int i = 0; i < CCM_IV_SIZE; i++) {
393 while (!NRF_RNG->EVENTS_VALRDY) {
394 }
395 NRF_RNG->EVENTS_VALRDY = 0;
396 tmpIV[i] = NRF_RNG->VALUE;
397 ccmData.iv[i] = tmpIV[i];
398 }
399 tmpCounter = packetCounter;
400 ccmData.counter = tmpCounter;
401
402 if (!encrypt(buf, len)) {
403 return 0;
404 }
405
406 memcpy(tmpBuffer, &outBuffer[CCM_START_SIZE], len + CCM_MIC_SIZE);
408 packetCounter++;
409 if (packetCounter > 200000) {
410 packetCounter = 0;
411 }
412 }
413 }
414#endif
415
416 for (int i = 0; i < (retries + 1); i++) {
417 ARC = i;
418 if (DPL) {
419 radioData[0] = len;
420 radioData[1] = PID;
421 }
422 else {
423 radioData[1] = 0;
424 radioData[0] = PID;
425 }
426
427 uint8_t dataStart = 0;
428
429#if defined CCM_ENCRYPTION_ENABLED
430
431 if (enableEncryption && doEncryption) {
432 dataStart = (!DPL && acksEnabled(0) == false) ? CCM_IV_SIZE + CCM_COUNTER_SIZE : CCM_IV_SIZE + CCM_COUNTER_SIZE + 2;
433 }
434 else {
435#endif
436 dataStart = (!DPL && acksEnabled(0) == false) ? 0 : 2;
437#if defined CCM_ENCRYPTION_ENABLED
438 }
439#endif
440
441#if defined CCM_ENCRYPTION_ENABLED
442 if (enableEncryption && doEncryption) {
443 memcpy(&radioData[dataStart - CCM_COUNTER_SIZE], &tmpCounter, CCM_COUNTER_SIZE);
444 memcpy(&radioData[dataStart - CCM_IV_SIZE - CCM_COUNTER_SIZE], &tmpIV[0], CCM_IV_SIZE);
445 memcpy(&radioData[dataStart], &tmpBuffer[0], len - (CCM_IV_SIZE + CCM_COUNTER_SIZE));
446 }
447 else {
448#endif
449 memcpy(&radioData[dataStart], buf, len);
450#if defined CCM_ENCRYPTION_ENABLED
451 }
452#endif
453
454 if (NRF_RADIO->STATE < 9) {
455 NRF_RADIO->EVENTS_TXREADY = 0;
456 NRF_RADIO->TASKS_TXEN = 1;
457 while (NRF_RADIO->EVENTS_TXREADY == 0) {
458 }
459 NRF_RADIO->EVENTS_TXREADY = 0;
460 }
461
462 NRF_RADIO->EVENTS_END = 0;
463 NRF_RADIO->TASKS_START = 1;
464 while (NRF_RADIO->EVENTS_END == 0) {
465 }
466 NRF_RADIO->EVENTS_END = 0;
467 if (!multicast && acksPerPipe[NRF_RADIO->TXADDRESS] == true) {
468 uint32_t rxAddress = NRF_RADIO->RXADDRESSES;
469 NRF_RADIO->RXADDRESSES = 1 << NRF_RADIO->TXADDRESS;
470 if (!DPL) {
471 payloadSize = getPayloadSize();
473 }
474 startListening(false);
475
476 uint32_t realAckTimeout = ackTimeout;
477 if (!DPL) {
478 if (NRF_RADIO->MODE == (RADIO_MODE_MODE_Nrf_1Mbit << RADIO_MODE_MODE_Pos)) {
479 realAckTimeout -= ACK_TIMEOUT_1MBPS_OFFSET;
480 }
481 else if (NRF_RADIO->MODE == (RADIO_MODE_MODE_Nrf_250Kbit << RADIO_MODE_MODE_Pos)) {
482 realAckTimeout -= ACK_TIMEOUT_250KBPS_OFFSET;
483 }
484 else {
485 realAckTimeout -= ACK_TIMEOUT_2MBPS_OFFSET;
486 }
487 }
488 else {
489 if (ackPayloadsEnabled && staticPayloadSize <= DEFAULT_MAX_PAYLOAD_SIZE) {
490 realAckTimeout += 200;
491 }
492 else {
493 realAckTimeout += ACK_PAYLOAD_TIMEOUT_OFFSET;
494 }
495 }
496 uint32_t ack_timeout = micros();
497 while (!NRF_RADIO->EVENTS_CRCOK && !NRF_RADIO->EVENTS_CRCERROR) {
498 if (micros() - ack_timeout > realAckTimeout) {
499 break;
500 }
501 }
502 if (NRF_RADIO->EVENTS_CRCOK) {
503 if (ackPayloadsEnabled && radioData[0] > 0) {
504#if defined CCM_ENCRYPTION_ENABLED
505 if (enableEncryption && doEncryption) {
506 memcpy(&rxBuffer[1], &radioData[2 + CCM_COUNTER_SIZE + CCM_IV_SIZE], max(0, radioData[0] - CCM_COUNTER_SIZE - CCM_IV_SIZE));
507 }
508 else {
509 memcpy(&rxBuffer[1], &radioData[2], radioData[0]);
510 }
511#else
512 memcpy(&rxBuffer[1], &radioData[2], radioData[0]);
513#endif
514
515#if defined CCM_ENCRYPTION_ENABLED
516 if (enableEncryption && radioData[0] > 0) {
517 memcpy(ccmData.iv, &radioData[2], CCM_IV_SIZE);
518 memcpy(&ccmData.counter, &radioData[2 + CCM_IV_SIZE], CCM_COUNTER_SIZE);
519
520 if (!decrypt(&rxBuffer[1], radioData[0])) {
521 Serial.println("DECRYPT FAIL");
522 return 0;
523 }
526 }
527 memcpy(&rxBuffer[1], &outBuffer[CCM_START_SIZE], radioData[0]);
528 }
529#endif
530 rxBuffer[0] = radioData[0];
531 ackPayloadAvailable = true;
532 ackAvailablePipeNo = NRF_RADIO->RXMATCH;
533 }
534 NRF_RADIO->EVENTS_CRCOK = 0;
535 stopListening(false, false);
536 if (!DPL) {
537 setPayloadSize(payloadSize);
538 }
539 NRF_RADIO->RXADDRESSES = rxAddress;
540 lastTxResult = true;
541 return 1;
542 }
543 else if (NRF_RADIO->EVENTS_CRCERROR) {
544 NRF_RADIO->EVENTS_CRCERROR = 0;
545 }
546 uint32_t duration = 258 * retryDuration;
547 delayMicroseconds(duration);
548 stopListening(false, false);
549 if (!DPL) {
550 setPayloadSize(payloadSize);
551 }
552 NRF_RADIO->RXADDRESSES = rxAddress;
553 }
554 else {
555 lastTxResult = true;
556 return 1;
557 }
558 }
559 lastTxResult = false;
560 return 0;
561}
562
563/**********************************************************************************************************/
564
565bool nrf_to_nrf::startWrite(void* buf, uint8_t len, bool multicast, bool doEncryption)
566{
567
568 uint8_t PID = ackPID;
569 if (DPL) {
570 PID = ((ackPID += 1) % 7) << 1;
571 }
572 else {
573 PID = ackPID++;
574 }
575
576#if defined CCM_ENCRYPTION_ENABLED
577 uint8_t tmpIV[CCM_IV_SIZE];
578 uint32_t tmpCounter = 0;
579 uint8_t tmpBuffer[MAX_PACKET_SIZE + CCM_MIC_SIZE + CCM_START_SIZE];
580
581 if (enableEncryption && doEncryption) {
582 if (len) {
583
584 for (int i = 0; i < CCM_IV_SIZE; i++) {
585 while (!NRF_RNG->EVENTS_VALRDY) {
586 }
587 NRF_RNG->EVENTS_VALRDY = 0;
588 tmpIV[i] = NRF_RNG->VALUE;
589 ccmData.iv[i] = tmpIV[i];
590 }
591 tmpCounter = packetCounter;
592 ccmData.counter = tmpCounter;
593
594 if (!encrypt(buf, len)) {
595 return 0;
596 }
597
598 memcpy(tmpBuffer, &outBuffer[CCM_START_SIZE], len + CCM_MIC_SIZE);
600 packetCounter++;
601 if (packetCounter > 200000) {
602 packetCounter = 0;
603 }
604 }
605 }
606#endif
607
608 // for (int i = 0; i < retries; i++) {
609 ARC = 0;
610 if (DPL) {
611 radioData[0] = len;
612 radioData[1] = PID;
613 }
614 else {
615 radioData[1] = 0;
616 radioData[0] = PID;
617 }
618
619 uint8_t dataStart = 0;
620
621#if defined CCM_ENCRYPTION_ENABLED
622
623 if (enableEncryption && doEncryption) {
624 dataStart = (!DPL && acksEnabled(0) == false) ? CCM_IV_SIZE + CCM_COUNTER_SIZE : CCM_IV_SIZE + CCM_COUNTER_SIZE + 2;
625 }
626 else {
627#endif
628 dataStart = (!DPL && acksEnabled(0) == false) ? 0 : 2;
629#if defined CCM_ENCRYPTION_ENABLED
630 }
631#endif
632
633#if defined CCM_ENCRYPTION_ENABLED
634 if (enableEncryption && doEncryption) {
635 memcpy(&radioData[dataStart - CCM_COUNTER_SIZE], &tmpCounter, CCM_COUNTER_SIZE);
636 memcpy(&radioData[dataStart - CCM_IV_SIZE - CCM_COUNTER_SIZE], &tmpIV[0], CCM_IV_SIZE);
637 memcpy(&radioData[dataStart], &tmpBuffer[0], len - (CCM_IV_SIZE + CCM_COUNTER_SIZE));
638 }
639 else {
640#endif
641 memcpy(&radioData[dataStart], buf, len);
642#if defined CCM_ENCRYPTION_ENABLED
643 }
644#endif
645
646 if (NRF_RADIO->STATE < 9) {
647 NRF_RADIO->EVENTS_TXREADY = 0;
648 NRF_RADIO->TASKS_TXEN = 1;
649 while (NRF_RADIO->EVENTS_TXREADY == 0) {
650 }
651 NRF_RADIO->EVENTS_TXREADY = 0;
652 }
653
654 NRF_RADIO->EVENTS_END = 0;
655 NRF_RADIO->TASKS_START = 1;
656 lastTxResult = true;
657
658 return true;
659}
660
661/**********************************************************************************************************/
662
663bool nrf_to_nrf::writeAckPayload(uint8_t pipe, void* buf, uint8_t len)
664{
665
666#if defined CCM_ENCRYPTION_ENABLED
667 if (enableEncryption) {
668 if (len) {
669
670 for (int i = 0; i < CCM_IV_SIZE; i++) {
671 while (!NRF_RNG->EVENTS_VALRDY) {
672 }
673 NRF_RNG->EVENTS_VALRDY = 0;
674 ccmData.iv[i] = NRF_RNG->VALUE;
675 ackBuffer[i + 1] = ccmData.iv[i];
676 }
677
678 ccmData.counter = packetCounter;
679 memcpy(&ackBuffer[1 + CCM_IV_SIZE], &ccmData.counter, CCM_COUNTER_SIZE);
680
681 if (!encrypt(buf, len)) {
682 return 0;
683 }
684
687 packetCounter++;
688 if (packetCounter > 200000) {
689 packetCounter = 0;
690 }
691 }
692 }
693 else {
694#endif
695 memcpy(&ackBuffer[1], buf, len);
696#if defined CCM_ENCRYPTION_ENABLED
697 }
698#endif
699 ackBuffer[0] = len;
700 ackPipe = pipe;
701 return true;
702}
703
704/**********************************************************************************************************/
705
706void nrf_to_nrf::enableAckPayload() { ackPayloadsEnabled = true; }
707
708/**********************************************************************************************************/
709
710void nrf_to_nrf::disableAckPayload() { ackPayloadsEnabled = false; }
711
712/**********************************************************************************************************/
713
714void nrf_to_nrf::startListening(bool resetAddresses)
715{
716
717 NRF_RADIO->EVENTS_DISABLED = 0;
718 NRF_RADIO->TASKS_DISABLE = 1;
719 while (NRF_RADIO->EVENTS_DISABLED == 0) {
720 }
721 NRF_RADIO->EVENTS_DISABLED = 0;
722 if (resetAddresses == true) {
723 // Serial.println("rst ad");
724 NRF_RADIO->BASE0 = rxBase;
725 NRF_RADIO->PREFIX0 = rxPrefix;
726 // Serial.println(addrConv32(NRF_RADIO->BASE0),HEX);
727 // Serial.println(addrConv32(NRF_RADIO->PREFIX0),HEX);
728 }
729 NRF_RADIO->EVENTS_RXREADY = 0;
730 NRF_RADIO->EVENTS_CRCOK = 0;
731 NRF_RADIO->TASKS_RXEN = 1;
732 inRxMode = true;
733}
734
735/**********************************************************************************************************/
736
737void nrf_to_nrf::stopListening(bool setWritingPipe, bool resetAddresses)
738{
739
740 NRF_RADIO->EVENTS_DISABLED = 0;
741 NRF_RADIO->TASKS_DISABLE = 1;
742 while (NRF_RADIO->EVENTS_DISABLED == 0) {
743 }
744 NRF_RADIO->EVENTS_DISABLED = 0;
745 if (resetAddresses) {
746 NRF_RADIO->BASE0 = txBase;
747 NRF_RADIO->PREFIX0 = txPrefix;
748 }
749 if (setWritingPipe) {
750 NRF_RADIO->TXADDRESS = 0x00;
751 }
752 // NRF_RADIO->EVENTS_TXREADY = 0;
753 // NRF_RADIO->TASKS_TXEN = 1;
754 // while (NRF_RADIO->EVENTS_TXREADY == 0);
755 // NRF_RADIO->EVENTS_TXREADY = 0;
756 inRxMode = false;
757}
758
759/**********************************************************************************************************/
760
762{
763 uint8_t size = min(staticPayloadSize, rxBuffer[0]);
764 return size;
765}
766
767/**********************************************************************************************************/
768
770{
771
772 uint32_t freq = NRF_RADIO->FREQUENCY;
773 NRF_RADIO->FREQUENCY = 0x4C;
774 if (NRF_RADIO->FREQUENCY == 0x4C) {
775 NRF_RADIO->FREQUENCY = freq;
776 return 1;
777 }
778 return 0;
779}
780
781/**********************************************************************************************************/
782
783void nrf_to_nrf::setChannel(uint8_t channel) { NRF_RADIO->FREQUENCY = channel; }
784
785/**********************************************************************************************************/
786
787uint8_t nrf_to_nrf::getChannel() { return (uint8_t)NRF_RADIO->FREQUENCY; }
788
789/**********************************************************************************************************/
790
791void nrf_to_nrf::setAutoAck(bool enable)
792{
793
794 for (int i = 0; i < 8; i++) {
795 acksPerPipe[i] = enable;
796 }
797 if (!DPL) {
798 disableDynamicPayloads(); // Called to re-configure the PCNF0 register
799 }
800}
801
802/**********************************************************************************************************/
803
804void nrf_to_nrf::setAutoAck(uint8_t pipe, bool enable)
805{
806
807 acksPerPipe[pipe] = enable;
808 if (!DPL) {
809 disableDynamicPayloads(); // Called to re-configure the PCNF0 register
810 }
811}
812
813/**********************************************************************************************************/
814
815void nrf_to_nrf::enableDynamicPayloads(uint8_t payloadSize)
816{
817
818 if (!DPL) {
819 DPL = true;
820 staticPayloadSize = payloadSize;
821
822 if (payloadSize <= 32) {
823 NRF_RADIO->PCNF0 = (0 << RADIO_PCNF0_S0LEN_Pos) | (6 << RADIO_PCNF0_LFLEN_Pos) | (3 << RADIO_PCNF0_S1LEN_Pos);
824 }
825 else {
826 // Using 8 bits for length
827 NRF_RADIO->PCNF0 = (0 << RADIO_PCNF0_S0LEN_Pos) | (8 << RADIO_PCNF0_LFLEN_Pos) | (3 << RADIO_PCNF0_S1LEN_Pos);
828 }
829 NRF_RADIO->PCNF1 = (RADIO_PCNF1_WHITEEN_Disabled << RADIO_PCNF1_WHITEEN_Pos) | (RADIO_PCNF1_ENDIAN_Big << RADIO_PCNF1_ENDIAN_Pos) | ((addressWidth - 1) << RADIO_PCNF1_BALEN_Pos) | (0 << RADIO_PCNF1_STATLEN_Pos) | (payloadSize << RADIO_PCNF1_MAXLEN_Pos);
830 }
831}
832
833/**********************************************************************************************************/
834
836{
837 DPL = false;
838
839 uint8_t lenConfig = 0;
840 if (acksEnabled(0)) {
841 lenConfig = 1;
842 }
843 NRF_RADIO->PCNF0 = (lenConfig << RADIO_PCNF0_S0LEN_Pos) | (0 << RADIO_PCNF0_LFLEN_Pos) | (lenConfig << RADIO_PCNF0_S1LEN_Pos);
844
845 NRF_RADIO->PCNF1 = (RADIO_PCNF1_WHITEEN_Disabled << RADIO_PCNF1_WHITEEN_Pos) | (RADIO_PCNF1_ENDIAN_Big << RADIO_PCNF1_ENDIAN_Pos) | ((addressWidth - 1) << RADIO_PCNF1_BALEN_Pos) | (staticPayloadSize << RADIO_PCNF1_STATLEN_Pos) | (staticPayloadSize << RADIO_PCNF1_MAXLEN_Pos);
846}
847
848/**********************************************************************************************************/
849
851{
852 staticPayloadSize = size;
853 DPL = false;
854
855 uint8_t lenConfig = 0;
856 if (acksEnabled(0)) {
857 lenConfig = 1;
858 }
859 NRF_RADIO->PCNF0 = (lenConfig << RADIO_PCNF0_S0LEN_Pos) | (0 << RADIO_PCNF0_LFLEN_Pos) | (lenConfig << RADIO_PCNF0_S1LEN_Pos);
860
861 NRF_RADIO->PCNF1 = (RADIO_PCNF1_WHITEEN_Disabled << RADIO_PCNF1_WHITEEN_Pos) | (RADIO_PCNF1_ENDIAN_Big << RADIO_PCNF1_ENDIAN_Pos) | ((addressWidth - 1) << RADIO_PCNF1_BALEN_Pos) | (staticPayloadSize << RADIO_PCNF1_STATLEN_Pos) | (staticPayloadSize << RADIO_PCNF1_MAXLEN_Pos);
862}
863
864/**********************************************************************************************************/
865
867{
868 return staticPayloadSize;
869}
870
871/**********************************************************************************************************/
872
873void nrf_to_nrf::setRetries(uint8_t retryVar, uint8_t attempts)
874{
875
876 retries = attempts;
877 retryDuration = retryVar;
878}
879
880/**********************************************************************************************************/
881
882void nrf_to_nrf::openReadingPipe(uint8_t child, uint64_t address)
883{
884
885 // child += 1;
886 uint32_t base = address >> 8;
887 uint32_t prefix = address & 0xFF;
888
889 base = addrConv32(base);
890
891 prefix = addrConv32(address);
892 prefix = prefix >> 24;
893
894 if (!child) {
895 NRF_RADIO->PREFIX0 = rxPrefix;
896 NRF_RADIO->BASE0 = base;
897 NRF_RADIO->PREFIX0 &= ~(0xFF);
898 NRF_RADIO->PREFIX0 |= prefix;
899 rxBase = NRF_RADIO->BASE0;
900 rxPrefix = NRF_RADIO->PREFIX0;
901 }
902 else if (child < 4) { // prefixes AP1-3 are in prefix0
903 NRF_RADIO->PREFIX0 = rxPrefix;
904 NRF_RADIO->BASE1 = base;
905 NRF_RADIO->PREFIX0 &= ~(0xFF << (8 * child));
906 NRF_RADIO->PREFIX0 |= prefix << (8 * child);
907 rxPrefix = NRF_RADIO->PREFIX0;
908 }
909 else {
910 NRF_RADIO->BASE1 = base;
911 NRF_RADIO->PREFIX1 &= ~(0xFF << (8 * (child - 4)));
912 NRF_RADIO->PREFIX1 |= prefix << (8 * (child - 4));
913 }
914 NRF_RADIO->RXADDRESSES |= 1 << child;
915
916 // Serial.println(addrConv32(NRF_RADIO->BASE1),HEX);
917 // Serial.println(addrConv32(NRF_RADIO->PREFIX0),HEX);
918 // Serial.println(NRF_RADIO->RXADDRESSES);
919}
920
921/**********************************************************************************************************/
922
923void nrf_to_nrf::openWritingPipe(uint64_t address)
924{
925 uint32_t base = address >> 8;
926 uint32_t prefix = address & 0xFF;
927 base = addrConv32(base);
928
929 prefix = addrConv32(address);
930 prefix = prefix >> 24;
931
932 NRF_RADIO->BASE0 = base;
933 NRF_RADIO->PREFIX0 &= 0xFFFFFF00;
934 NRF_RADIO->PREFIX0 |= prefix;
935 NRF_RADIO->TXADDRESS = 0x00;
936 txBase = NRF_RADIO->BASE0;
937 txPrefix = NRF_RADIO->PREFIX0;
938 // Serial.println(addrConv32(NRF_RADIO->BASE0),HEX);
939 // Serial.println(addrConv32(NRF_RADIO->PREFIX0),HEX);
940}
941
942/**********************************************************************************************************/
943
944void nrf_to_nrf::openReadingPipe(uint8_t child, const uint8_t* address)
945{
946
947 // child +=1;
948
949 uint32_t base = addr_conv(&address[1]);
950 uint32_t prefix = 0;
951 uint8_t prefixArray[5];
952 prefixArray[0] = address[0];
953 prefix = addr_conv(prefixArray);
954 prefix = prefix >> 24;
955
956 // Using pipes 1-7 for reading pipes, leaving pipe0 for a tx pipe
957 if (!child) {
958 NRF_RADIO->PREFIX0 = rxPrefix;
959 NRF_RADIO->BASE0 = base;
960 NRF_RADIO->PREFIX0 &= ~(0xFF);
961 NRF_RADIO->PREFIX0 |= prefix;
962 rxBase = NRF_RADIO->BASE0;
963 rxPrefix = NRF_RADIO->PREFIX0;
964 }
965 else if (child < 4) { // prefixes AP1-3 are in prefix0
966 NRF_RADIO->PREFIX0 = rxPrefix;
967 NRF_RADIO->BASE1 = base;
968 NRF_RADIO->PREFIX0 &= ~(0xFF << (8 * child));
969 NRF_RADIO->PREFIX0 |= prefix << (8 * child);
970 rxPrefix = NRF_RADIO->PREFIX0;
971 }
972 else {
973 NRF_RADIO->BASE1 = base;
974 NRF_RADIO->PREFIX1 &= ~(0xFF << (8 * (child - 4)));
975 NRF_RADIO->PREFIX1 |= prefix << (8 * (child - 4));
976 }
977 NRF_RADIO->RXADDRESSES |= 1 << child;
978
979 // Serial.println(addrConv32(NRF_RADIO->BASE0),HEX);
980 // Serial.println(addrConv32(NRF_RADIO->PREFIX0),HEX);
981 // Serial.println(NRF_RADIO->RXADDRESSES);
982}
983
984/**********************************************************************************************************/
985
986void nrf_to_nrf::openWritingPipe(const uint8_t* address)
987{
988
989 uint32_t base = 0;
990 uint32_t prefix = 0;
991
992 base = addr_conv(&address[1]);
993 prefix = addr_conv(&address[0]);
994 prefix = prefix >> 24;
995
996 NRF_RADIO->BASE0 = base;
997 NRF_RADIO->PREFIX0 &= 0xFFFFFF00;
998 NRF_RADIO->PREFIX0 |= prefix;
999 NRF_RADIO->TXADDRESS = 0x00;
1000 txBase = NRF_RADIO->BASE0;
1001 txPrefix = NRF_RADIO->PREFIX0;
1002}
1003
1004/**********************************************************************************************************/
1005
1007{
1008
1009 if (NRF_RADIO->STATE == 11) {
1010 while (NRF_RADIO->EVENTS_END == 0) {
1011 }
1012 NRF_RADIO->EVENTS_END = 0;
1013 }
1014
1015 NRF_RADIO->EVENTS_DISABLED = 0;
1016 NRF_RADIO->TASKS_DISABLE = 1;
1017 while (NRF_RADIO->EVENTS_DISABLED == 0) {
1018 }
1019 NRF_RADIO->EVENTS_DISABLED = 0;
1020
1021 return lastTxResult;
1022}
1023
1024/**********************************************************************************************************/
1025
1026bool nrf_to_nrf::txStandBy(uint32_t timeout, bool startTx)
1027{
1028
1029 if (NRF_RADIO->STATE == 11) {
1030 while (NRF_RADIO->EVENTS_END == 0) {
1031 }
1032 NRF_RADIO->EVENTS_END = 0;
1033 }
1034
1035 NRF_RADIO->EVENTS_DISABLED = 0;
1036 NRF_RADIO->TASKS_DISABLE = 1;
1037 while (NRF_RADIO->EVENTS_DISABLED == 0) {
1038 }
1039 NRF_RADIO->EVENTS_DISABLED = 0;
1040
1041 return lastTxResult;
1042}
1043
1044/**********************************************************************************************************/
1045
1046bool nrf_to_nrf::writeFast(void* buf, uint8_t len, bool multicast)
1047{
1048 lastTxResult = write((void*)buf, len, multicast);
1049 return lastTxResult;
1050}
1051
1052/**********************************************************************************************************/
1053
1054bool nrf_to_nrf::acksEnabled(uint8_t pipe)
1055{
1056
1057 if (acksPerPipe[pipe]) {
1058 return 1;
1059 }
1060 return 0;
1061}
1062
1063/**********************************************************************************************************/
1064
1066
1067/**********************************************************************************************************/
1068
1069bool nrf_to_nrf::setDataRate(uint8_t speed)
1070{
1071
1072 if (speed == NRF_1MBPS) {
1073 NRF_RADIO->MODE = (RADIO_MODE_MODE_Nrf_1Mbit << RADIO_MODE_MODE_Pos);
1074 ackTimeout = ACK_TIMEOUT_1MBPS;
1075 }
1076 else if (speed == NRF_250KBPS) {
1077 NRF_RADIO->MODE = (RADIO_MODE_MODE_Nrf_250Kbit << RADIO_MODE_MODE_Pos);
1078 ackTimeout = ACK_TIMEOUT_250KBPS;
1079 }
1080 else { // NRF_2MBPS
1081 NRF_RADIO->MODE = (RADIO_MODE_MODE_Nrf_2Mbit << RADIO_MODE_MODE_Pos);
1082 ackTimeout = ACK_TIMEOUT_2MBPS;
1083 }
1084
1085 return 1;
1086}
1087
1088/**********************************************************************************************************/
1089
1090void nrf_to_nrf::setPALevel(uint8_t level, bool lnaEnable)
1091{
1092
1093 uint8_t paLevel = 0x00;
1094
1095 if (level == NRF_PA_MIN) {
1096 paLevel = TXPOWER_PA_MIN;
1097 }
1098 else if (level == NRF_PA_LOW) {
1099 paLevel = TXPOWER_PA_LOW;
1100 }
1101 else if (level == NRF_PA_HIGH) {
1102 paLevel = TXPOWER_PA_HIGH;
1103 }
1104 else if (level == NRF_PA_MAX) {
1105 paLevel = TXPOWER_PA_MAX;
1106 }
1107 NRF_RADIO->TXPOWER = paLevel;
1108}
1109
1110/**********************************************************************************************************/
1111
1113{
1114
1115 uint8_t paLevel = NRF_RADIO->TXPOWER;
1116
1117 if (paLevel == TXPOWER_PA_MIN) {
1118 return NRF_PA_MIN;
1119 }
1120 else if (paLevel == TXPOWER_PA_LOW) {
1121 return NRF_PA_LOW;
1122 }
1123 else if (paLevel == TXPOWER_PA_HIGH) {
1124 return NRF_PA_HIGH;
1125 }
1126 else if (paLevel == TXPOWER_PA_MAX) {
1127 return NRF_PA_MAX;
1128 }
1129 else {
1130 return NRF_PA_ERROR;
1131 }
1132}
1133
1134/**********************************************************************************************************/
1135
1137{
1138 return ARC;
1139}
1140
1141/**********************************************************************************************************/
1142
1144{
1145
1146 if (length == NRF_CRC_16) {
1147 NRF_RADIO->CRCCNF = RADIO_CRCCNF_LEN_Two; /* CRC configuration: 16bit */
1148 NRF_RADIO->CRCINIT = 0xFFFFUL; // Initial value
1149 NRF_RADIO->CRCPOLY = 0x11021UL; // CRC poly: x^16+x^12^x^5+1
1150 }
1151 else if (length == NRF_CRC_8) {
1152 NRF_RADIO->CRCCNF = RADIO_CRCCNF_LEN_One; /* CRC configuration: 8bit */
1153 NRF_RADIO->CRCINIT = 0xFFUL;
1154 NRF_RADIO->CRCPOLY = 0x107UL;
1155 }
1156 else {
1157 NRF_RADIO->CRCCNF = 0; /* CRC configuration: Disabled */
1158 NRF_RADIO->CRCINIT = 0x00L;
1159 NRF_RADIO->CRCPOLY = 0x00UL;
1160 }
1161}
1162
1163/**********************************************************************************************************/
1164
1166{
1167 if (NRF_RADIO->CRCCNF == 0) {
1168 return NRF_CRC_DISABLED;
1169 }
1170 else if (NRF_RADIO->CRCCNF == RADIO_CRCCNF_LEN_One) {
1171 return NRF_CRC_8;
1172 }
1173 else {
1174 return NRF_CRC_16;
1175 }
1176}
1177
1178/**********************************************************************************************************/
1179
1180bool nrf_to_nrf::testCarrier(uint8_t RSSI)
1181{
1182
1183 NRF_RADIO->EVENTS_RSSIEND = 0;
1184 NRF_RADIO->TASKS_RSSISTART = 1;
1185 while (!NRF_RADIO->EVENTS_RSSIEND) {
1186 }
1187 if (NRF_RADIO->RSSISAMPLE < RSSI) {
1188 return 1;
1189 }
1190 return 0;
1191}
1192
1193/**********************************************************************************************************/
1194
1195bool nrf_to_nrf::testRPD(uint8_t RSSI)
1196{
1197 return testCarrier(RSSI);
1198}
1199
1200/**********************************************************************************************************/
1201
1203{
1204 NRF_RADIO->EVENTS_RSSIEND = 0;
1205 NRF_RADIO->TASKS_RSSISTART = 1;
1206 while (!NRF_RADIO->EVENTS_RSSIEND) {
1207 }
1208 return (uint8_t)NRF_RADIO->RSSISAMPLE;
1209}
1210
1211/**********************************************************************************************************/
1212
1214{
1215 NRF_RADIO->POWER = 1;
1216}
1217
1218/**********************************************************************************************************/
1219
1221{
1222 NRF_RADIO->POWER = 0;
1223}
1224
1225/**********************************************************************************************************/
1226void nrf_to_nrf::setAddressWidth(uint8_t a_width)
1227{
1228
1229 addressWidth = a_width;
1230
1231 uint8_t pSize = 0;
1232 if (!DPL) {
1233 pSize = staticPayloadSize;
1234 }
1235
1236 NRF_RADIO->PCNF1 = (RADIO_PCNF1_WHITEEN_Disabled << RADIO_PCNF1_WHITEEN_Pos) | (RADIO_PCNF1_ENDIAN_Big << RADIO_PCNF1_ENDIAN_Pos) | ((a_width - 1) << RADIO_PCNF1_BALEN_Pos) | (pSize << RADIO_PCNF1_STATLEN_Pos) | (staticPayloadSize << RADIO_PCNF1_MAXLEN_Pos);
1237}
1238
1239/**********************************************************************************************************/
1240
1242{
1243
1244 Serial.println("================ Radio Configuration ================");
1245 Serial.print("STATUS\t\t= ");
1246 Serial.println(NRF_RADIO->STATE);
1247
1248 // Serial.println(addrConv32(NRF_RADIO->PREFIX0);
1249 Serial.print("RX_ADDR_P0-1\t= 0x");
1250 uint32_t base = addrConv32(NRF_RADIO->BASE0);
1251 for (int i = addressWidth - 2; i > -1; i--) {
1252 Serial.print((base >> (i * 8)) & 0xFF, HEX);
1253 }
1254 uint32_t prefixes = addrConv32(NRF_RADIO->PREFIX0);
1255 uint8_t prefix = (prefixes >> 24) & 0xFF;
1256 Serial.print(prefix, HEX);
1257 Serial.print(" 0x");
1258 base = addrConv32(NRF_RADIO->BASE1);
1259 for (int i = addressWidth - 2; i > -1; i--) {
1260 Serial.print((base >> (i * 8)) & 0xFF, HEX);
1261 }
1262 prefix = (prefixes >> 16) & 0xFF;
1263 Serial.println(prefix, HEX);
1264
1265 Serial.print("RX_ADDR_P2-7\t= 0x");
1266 prefix = (prefixes >> 8) & 0xFF;
1267 Serial.print(prefix, HEX);
1268 Serial.print(" 0x");
1269 prefix = (prefixes)&0xFF;
1270 Serial.print(prefix, HEX);
1271 Serial.print(" 0x");
1272 prefixes = addrConv32(NRF_RADIO->PREFIX1);
1273 prefix = (prefixes >> 24) & 0xFF;
1274 Serial.print(prefix, HEX);
1275 Serial.print(" 0x");
1276 prefix = (prefixes >> 16) & 0xFF;
1277 Serial.print(prefix, HEX);
1278 Serial.print(" 0x");
1279 prefix = (prefixes >> 8) & 0xFF;
1280 Serial.print(prefix, HEX);
1281 Serial.print(" 0x");
1282 prefix = (prefixes)&0xFF;
1283 Serial.println(prefix, HEX);
1284
1285 uint8_t enAA = 0;
1286 for (int i = 0; i < 6; i++) {
1287 enAA |= acksPerPipe[i] << i;
1288 }
1289 Serial.print("EN_AA\t\t= 0x");
1290 Serial.println(enAA, HEX);
1291 Serial.print("EN_RXADDR\t= 0x");
1292 Serial.println(NRF_RADIO->RXADDRESSES, HEX);
1293 Serial.print("RF_CH\t\t= 0x");
1294 Serial.println(NRF_RADIO->FREQUENCY, HEX);
1295 Serial.println("DYNPD/FEATURE\t= 0x");
1296 Serial.print("Data Rate\t= ");
1297 Serial.println(NRF_RADIO->MODE ? "2 MBPS" : "1MBPS");
1298 Serial.println("Model\t\t= NRF52");
1299 Serial.print("CRC Length\t= ");
1300 uint8_t crcLen = getCRCLength();
1301 if (crcLen == NRF_CRC_16) {
1302 Serial.println("16 bits");
1303 }
1304 else if (crcLen == NRF_CRC_8) {
1305 Serial.println("8 bits");
1306 }
1307 else {
1308 Serial.println("Disabled");
1309 }
1310 Serial.print("PA Power\t= ");
1311 uint8_t paLevel = getPALevel();
1312 if (paLevel == NRF_PA_MAX) {
1313 Serial.println("PA_MAX");
1314 }
1315 else if (paLevel == NRF_PA_HIGH) {
1316 Serial.println("PA_HIGH");
1317 }
1318 else if (paLevel == NRF_PA_LOW) {
1319 Serial.println("PA_LOW");
1320 }
1321 else if (paLevel == NRF_PA_MIN) {
1322 Serial.println("PA_MIN");
1323 }
1324 else {
1325 Serial.println("?");
1326 }
1327 Serial.print("ARC\t\t= ");
1328 Serial.println(ARC);
1329}
1330
1331/**********************************************************************************************************/
1332
1333#if defined CCM_ENCRYPTION_ENABLED
1334
1335uint8_t nrf_to_nrf::encrypt(void* bufferIn, uint8_t size)
1336{
1337
1338 if (!size) {
1339 return 0;
1340 }
1341 if (size > MAX_PACKET_SIZE) {
1342 return 0;
1343 }
1344
1345 inBuffer[0] = 0;
1346 inBuffer[1] = size;
1347 inBuffer[2] = 0;
1348
1349 memcpy(&inBuffer[CCM_START_SIZE], bufferIn, size);
1350 memset(outBuffer, 0, sizeof(outBuffer));
1351
1352 NRF_CCM->OUTPTR = (uint32_t)outBuffer;
1353 NRF_CCM->EVENTS_ENDKSGEN = 0;
1354 NRF_CCM->EVENTS_ENDCRYPT = 0;
1355 NRF_CCM->TASKS_KSGEN = 1;
1356 while (!NRF_CCM->EVENTS_ENDCRYPT) {
1357 };
1358
1359 if (NRF_CCM->EVENTS_ERROR) {
1360 return 0;
1361 }
1362 return outBuffer[1];
1363}
1364
1365/**********************************************************************************************************/
1366
1367uint8_t nrf_to_nrf::decrypt(void* bufferIn, uint8_t size)
1368{
1369
1370 if (!size) {
1371 return 0;
1372 }
1373 if (size > MAX_PACKET_SIZE) {
1374 return 0;
1375 }
1376
1377 memcpy(&inBuffer[3], bufferIn, size);
1378
1379 inBuffer[0] = 0;
1380 inBuffer[1] = size;
1381 inBuffer[2] = 0;
1382
1383 memset(outBuffer, 0, sizeof(outBuffer));
1384
1385 NRF_CCM->EVENTS_ENDKSGEN = 0;
1386 NRF_CCM->EVENTS_ENDCRYPT = 0;
1387 NRF_CCM->TASKS_KSGEN = 1;
1388
1389 while (!NRF_CCM->EVENTS_ENDCRYPT) {
1390 };
1391
1392 if (NRF_CCM->EVENTS_ERROR) {
1393 return 0;
1394 }
1395 return outBuffer[1];
1396}
1397
1398/**********************************************************************************************************/
1399
1401{
1402
1403 memcpy(ccmData.key, key, CCM_KEY_SIZE);
1404}
1405
1406/**********************************************************************************************************/
1407
1408void nrf_to_nrf::setCounter(uint64_t counter)
1409{
1410
1411 ccmData.counter = counter;
1412 packetCounter = counter;
1413}
1414/**********************************************************************************************************/
1415
1417{
1418
1419 for (int i = 0; i < CCM_IV_SIZE; i++) {
1420 ccmData.iv[i] = IV[i];
1421 }
1422}
1423
1424#endif // defined CCM_ENCRYPTION_ENABLED
void startListening(bool resetAddresses=true)
void openReadingPipe(uint8_t child, const uint8_t *address)
bool available()
void setPALevel(uint8_t level, bool lnaEnable=true)
bool testCarrier(uint8_t RSSI=65)
bool txStandBy()
uint8_t decrypt(void *bufferIn, uint8_t size)
uint8_t radioData[ACTUAL_MAX_PAYLOAD_SIZE+2]
Definition nrf_to_nrf.h:204
void setChannel(uint8_t channel)
uint32_t addrConv32(uint32_t addr)
void disableDynamicPayloads()
bool write(void *buf, uint8_t len, bool multicast=false, bool doEncryption=true)
bool testRPD(uint8_t RSSI=65)
void setCounter(uint64_t counter)
bool isChipConnected()
void setAddressWidth(uint8_t a_width)
uint8_t getDynamicPayloadSize()
bool setDataRate(uint8_t speed)
bool isValid()
void setKey(uint8_t key[CCM_KEY_SIZE])
bool begin()
bool writeAckPayload(uint8_t pipe, void *buf, uint8_t len)
bool enableEncryption
Definition nrf_to_nrf.h:470
void enableDynamicPayloads(uint8_t payloadSize=DEFAULT_MAX_PAYLOAD_SIZE)
void disableAckPayload()
void powerDown()
uint8_t getARC()
uint8_t encrypt(void *bufferIn, uint8_t size)
void printDetails()
uint8_t getChannel()
bool startWrite(void *buf, uint8_t len, bool multicast, bool doEncryption=true)
uint8_t getRSSI()
uint8_t outBuffer[MAX_PACKET_SIZE+CCM_MIC_SIZE+CCM_START_SIZE]
Definition nrf_to_nrf.h:437
void setRetries(uint8_t retryVar, uint8_t attempts)
void enableAckPayload()
void openWritingPipe(const uint8_t *address)
void setCRCLength(nrf_crclength_e length)
bool writeFast(void *buf, uint8_t len, bool multicast=0)
uint8_t getPALevel()
void setAutoAck(bool enable)
void read(void *buf, uint8_t len)
void stopListening(bool setWritingPipe=true, bool resetAddresses=true)
void setIV(uint8_t IV[CCM_IV_SIZE])
void setPayloadSize(uint8_t size)
nrf_crclength_e getCRCLength()
uint8_t getPayloadSize()
#define RADIO_MODE_MODE_Nrf_250Kbit
#define TXPOWER_PA_MIN
#define TXPOWER_PA_MAX
#define TXPOWER_PA_HIGH
#define TXPOWER_PA_LOW
static uint32_t bytewise_bit_swap(uint8_t const *p_inp)
static uint32_t addr_conv(uint8_t const *p_addr)
#define ACK_TIMEOUT_1MBPS_OFFSET
Definition nrf_to_nrf.h:25
#define DEFAULT_MAX_PAYLOAD_SIZE
Definition nrf_to_nrf.h:20
#define ACK_PAYLOAD_TIMEOUT_OFFSET
Definition nrf_to_nrf.h:28
@ NRF_PA_MAX
Definition nrf_to_nrf.h:62
@ NRF_PA_HIGH
Definition nrf_to_nrf.h:58
@ NRF_PA_LOW
Definition nrf_to_nrf.h:54
@ NRF_PA_MIN
Definition nrf_to_nrf.h:50
@ NRF_PA_ERROR
Definition nrf_to_nrf.h:66
#define CCM_COUNTER_SIZE
Definition nrf_to_nrf.h:39
#define ACK_TIMEOUT_250KBPS_OFFSET
Definition nrf_to_nrf.h:27
nrf_crclength_e
Definition nrf_to_nrf.h:100
@ NRF_CRC_8
Definition nrf_to_nrf.h:104
@ NRF_CRC_DISABLED
Definition nrf_to_nrf.h:102
@ NRF_CRC_16
Definition nrf_to_nrf.h:106
#define ACK_TIMEOUT_250KBPS
Definition nrf_to_nrf.h:24
@ NRF_1MBPS
Definition nrf_to_nrf.h:81
@ NRF_250KBPS
Definition nrf_to_nrf.h:85
#define ACK_TIMEOUT_2MBPS
Definition nrf_to_nrf.h:23
#define CCM_START_SIZE
Definition nrf_to_nrf.h:41
#define ACTUAL_MAX_PAYLOAD_SIZE
Definition nrf_to_nrf.h:21
#define MAX_PACKET_SIZE
Definition nrf_to_nrf.h:35
#define CCM_MIC_SIZE
Definition nrf_to_nrf.h:40
#define CCM_KEY_SIZE
Definition nrf_to_nrf.h:36
#define ACK_TIMEOUT_2MBPS_OFFSET
Definition nrf_to_nrf.h:26
#define ACK_TIMEOUT_1MBPS
Definition nrf_to_nrf.h:22
#define CCM_IV_SIZE
Definition nrf_to_nrf.h:37