-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathradio.c
173 lines (137 loc) · 4.62 KB
/
radio.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
#include <stdio.h>
#include <string.h>
#include "rf.h"
#include "interrupt.h"
#include "main.h"
#include "crc8.h"
#if EN_AES
#include "tiny-AES128/include/aes.h"
#endif
///////////////////////////////////////////
// Inline function definitions
///////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// static __INLINE uint8_t enc_dec_accel_galois_multiply(uint8_t a, uint8_t b) __reentrant
//
// Description:
// Performs a GF(2^8) mutliplication in hardware and returns the result
//
// Parameters:
// uint8_t a - multiplier in the operation
// uint8_t b - multiplicand in the operation
//
// Return value:
// Result of the GF(2^8) multiplication
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//See enc_dec_accel_galois_multiply.c for function details (function body is the same)
unsigned char enc_dec_accel_galois_multiply(unsigned char a, unsigned char b)
{
//Load the hardware registers for the operators
CCPDATIA = a;
CCPDATIB = b;
//Return the result of the hardware GF(2^8) multiplication
return CCPDATO;
}
void rfinit() {
uint8_t setup;
rf_spi_configure_enable();
setup = RF_CONFIG_EN_CRC; // power up here, CRC 1 bytes
rf_power_up_param(false, setup);
setup = RF_SETUP_RETR_ARD_750 | RF_SETUP_RETR_ARC_3; // 750us, 3 retry
rf_write_register(RF_SETUP_RETR, &setup, 1);
setup = RF_SETUP_AW_5BYTES; // 5 bytes address
rf_write_register(RF_SETUP_AW, &setup, 1);
setup = RF_EN_RXADDR_ERX_P0 | RF_EN_RXADDR_ERX_P1; // enable pipe0 & pipe1
rf_write_register(RF_EN_RXADDR, &setup, 1);
rf_write_register(RF_RX_ADDR_P0, config.sndaddr, 5);
rf_write_register(RF_TX_ADDR, config.sndaddr, 5);
config.rcvaddr[4] = config.deviceid;
rf_write_register(RF_RX_ADDR_P1, config.rcvaddr, 5);
setup = MSGLEN; /* Number of bytes in RX payload */
rf_write_register(RF_RX_PW_P0, &setup, 1);
rf_write_register(RF_RX_PW_P1, &setup, 1);
setup = RF_EN_AA_ENAA_P0 | RF_EN_AA_ENAA_P1; // set autoask
rf_write_register(RF_EN_AA, &setup, 1);
rf_set_rf_channel(config.channel);
rf_set_output_power(RF_RF_SETUP_RF_PWR_0_DBM);
setup &= ~(RF_RF_SETUP_RF_DR_LOW | RF_RF_SETUP_RF_DR_HIGH); // default datarate 1Mhz
rf_write_register(RF_RF_SETUP, &setup, 1);
interrupt_control_rfirq_enable();
}
void rfdown(void) {
rf_irq_clear_all();
rf_power_down();
}
void rfsend(const MESSAGE_T *msg) {
uint16_t timeout;
uint8_t retry = config.maxsend;
uint8_t buf[MSGLEN], out[MSGLEN];
if (!(rf_read_register_1_byte(RF_CONFIG) & RF_CONFIG_PWR_UP))
rfinit();
memcpy(&buf, msg, MSGLEN);
#if EN_CRC
buf[MSGLEN-1] = CRC8((uint8_t *) msg, MSGLEN-1);
#endif
#if EN_AES
AES128_ECB_encrypt((uint8_t*) buf, config.aeskey, out);
#else
memcpy(&out, &buf, MSGLEN);
#endif
start:
if (rf_tx_fifo_is_full())
rf_flush_tx();
rf_irq_clear_all(); //clear all interrupts in the 24L01
rf_set_as_tx(); //resume normal operation as a TX
rf_write_tx_payload(out, MSGLEN, true); //transmit received char over RF
//wait until the packet has been sent or the maximum number of retries has been reached
timeout = 90; // 90*26us = 2.3ms > 750uS * 3
while(! rf_irq_pin_active()) {
if (timeout-- == 0) { // checking timeout if nothing
if (retry-- > 0) goto start;
break;
}
delay_us(10); // 10us
}
if (rf_irq_pin_active() && rf_irq_max_rt_active()) { // checking max_rt bit
if (retry-- > 0) goto start;
}
rf_irq_clear_all();
}
// blocking read NRF24LE1, timeout in 10us intervals
uint8_t rfread(MESSAGE_T *msg, uint16_t timeout) {
uint8_t status, state = 0;
uint8_t buf[MSGLEN], in[MSGLEN];
if (!(rf_read_register_1_byte(RF_CONFIG) & RF_CONFIG_PWR_UP))
rfinit();
rf_set_as_rx(true); //change the device to an RX to get the character back from the other 24L01
rf_irq_clear_all(); //clear interrupts again
while (timeout-- > 0) {
//wait a while to see if we get the data back (change the loop maximum and the lower if
// argument (should be loop maximum - 1) to lengthen or shorten this time frame
if(rf_irq_pin_active() && rf_irq_rx_dr_active()) {
status = rf_read_rx_payload(buf, MSGLEN); //get the payload into data
if (rf_is_rxed_payload_on_pipe_1_in_status_val(status)) {
state = 1;
break;
}
}
delay_us(10); // 10us
}
rf_irq_clear_all();
if (!state)
return state;
#if EN_AES
AES128_ECB_decrypt(buf, config.aeskey, in);
#else
memcpy(&in, &buf, MSGLEN);
#endif
#if EN_CRC
if (in[MSGLEN-1] != CRC8(in, MSGLEN-1)) {
return 0;
}
#endif
memcpy(msg, &in, MSGLEN);
return state;
}