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