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