Salz' level #1
[hackover2013-badge-firmware.git] / funk / nrf24l01p.c
1 #ifdef R0KET
2 #include <r0ketports.h>
3 #else
4 #include <badge/pinconfig.h>
5
6 #define RB_SPI_NRF_CS HOB_PORT(HOB_RADIO_CS),HOB_PIN(HOB_RADIO_CS)
7 #define RB_NRF_CE HOB_PORT(HOB_RADIO_CE),HOB_PIN(HOB_RADIO_CE)
8 #define RB_NRF_IRQ HOB_PORT(HOB_RADIO_IRQ),HOB_PIN(HOB_RADIO_IRQ)
9
10 #define RB_SPI_NRF_CS_IO HOB_IOCON(HOB_RADIO_CS)
11 #define RB_NRF_CE_IO HOB_IOCON(HOB_RADIO_CE)
12 #define RB_NRF_IRQ_IO HOB_IOCON(HOB_RADIO_IRQ)
13 #endif
14
15 #include "nrf24l01p.h"
16 #include <core/ssp/ssp.h>
17 #include <core/systick/systick.h>
18
19 #define DEFAULT_SPEED R_RF_SETUP_DR_2M
20
21 uint8_t _nrfresets=0;
22
23 /*-----------------------------------------------------------------------*/
24 /* Transmit a byte via SPI */
25 /*-----------------------------------------------------------------------*/
26 static inline void xmit_spi(uint8_t dat) {
27 sspSend(0, (uint8_t*) &dat, 1);
28 }
29
30 static inline void rcv_spi(uint8_t *dat) {
31 sspReceive(0, dat, 1);
32 }
33
34 #define CS_LOW() gpioSetValue(RB_SPI_NRF_CS, 0)
35 #define CS_HIGH() gpioSetValue(RB_SPI_NRF_CS, 1)
36 #define CE_LOW() gpioSetValue(RB_NRF_CE, 0)
37 #define CE_HIGH() gpioSetValue(RB_NRF_CE, 1)
38
39 void nrf_cmd(uint8_t cmd){
40 CS_LOW();
41 xmit_spi(cmd);
42 CS_HIGH();
43 }
44
45 uint8_t nrf_cmd_status(uint8_t cmd){
46 CS_LOW();
47 sspSendReceive(0, &cmd, 1);
48 CS_HIGH();
49 return cmd;
50 }
51
52 void nrf_cmd_rw_long(uint8_t* data, int len){
53 CS_LOW();
54 sspSendReceive(0,data,len);
55 CS_HIGH();
56 }
57
58
59 void nrf_write_reg(const uint8_t reg, const uint8_t val){
60 CS_LOW();
61 xmit_spi(C_W_REGISTER | reg);
62 xmit_spi(val);
63 CS_HIGH();
64 }
65
66 uint8_t nrf_read_reg(const uint8_t reg){
67 uint8_t val;
68 CS_LOW();
69 xmit_spi(C_R_REGISTER | reg);
70 rcv_spi(&val);
71 CS_HIGH();
72 return val;
73 }
74
75 void nrf_read_long(const uint8_t cmd, int len, uint8_t* data){
76 CS_LOW();
77 xmit_spi(cmd);
78 for(int i=0;i<len;i++)
79 data[i] = 0x00;
80 sspSendReceive(0,data,len);
81 CS_HIGH();
82 }
83
84 void nrf_read_pkt(int len, uint8_t* data){
85 CS_LOW();
86 xmit_spi(C_R_RX_PAYLOAD);
87 sspReceive(0,data,len);
88 CS_HIGH();
89 }
90
91 void nrf_read_pkt_crc(int len, uint8_t* data, uint8_t* crc){
92 CS_LOW();
93 xmit_spi(C_R_RX_PAYLOAD);
94 sspReceive(0,data,len);
95 sspReceive(0,crc,2);
96 CS_HIGH();
97 }
98
99 void nrf_write_long(const uint8_t cmd, int len, const uint8_t* data){
100 CS_LOW();
101 xmit_spi(cmd);
102 sspSend(0,data,len);
103 CS_HIGH();
104 }
105
106 #define nrf_write_reg_long(reg, len, data) \
107 nrf_write_long(C_W_REGISTER|(reg), len, data)
108
109 // High-Level:
110 void nrf_rcv_pkt_start(void){
111
112 nrf_write_reg(R_CONFIG,
113 R_CONFIG_PRIM_RX| // Receive mode
114 R_CONFIG_PWR_UP| // Power on
115 R_CONFIG_EN_CRC // CRC on, single byte
116 );
117
118 nrf_cmd(C_FLUSH_RX);
119 nrf_write_reg(R_STATUS,0);
120
121 CE_HIGH();
122 }
123
124 int nrf_rcv_pkt_poll(int maxsize, uint8_t * pkt){
125 uint8_t len;
126 uint8_t status=0;
127
128 for(int i=0;i<maxsize;i++) pkt[i] = 0x00; // Sanity: clear packet buffer
129
130 status =nrf_cmd_status(C_NOP);
131
132 if((status & R_STATUS_RX_P_NO) == R_STATUS_RX_FIFO_EMPTY){
133 if( (status & R_STATUS_RX_DR) == R_STATUS_RX_DR){
134 #ifdef USB_CDC
135 puts("FIFO empty, but RX?\r\n");
136 #endif
137 nrf_write_reg(R_STATUS,R_STATUS_RX_DR);
138 };
139 return 0;
140 };
141
142 nrf_read_long(C_R_RX_PL_WID,1,&len);
143
144 nrf_write_reg(R_STATUS,R_STATUS_RX_DR);
145 if(len>32 || len==0){
146 return -2; // no packet error
147 };
148
149 if(len>maxsize){
150 return -1; // packet too large
151 };
152
153 nrf_read_pkt(len,pkt);
154
155 return len;
156 }
157
158 void nrf_rcv_pkt_end(void){
159 CE_LOW();
160 nrf_cmd(C_FLUSH_RX);
161 nrf_write_reg(R_STATUS,R_STATUS_RX_DR);
162 }
163
164 void nrf_set_rx_mac(int pipe, int rxlen, int maclen, const uint8_t * mac){
165 #ifdef SAFE
166 assert(maclen>=1 || maclen<=5);
167 assert(rxlen>=1 || rxlen<=32);
168 assert(pipe>=0 || pipe<=5);
169 assert(mac!=NULL);
170 if(pipe>1)
171 assert(maclen==1);
172 #endif
173 nrf_write_reg(R_RX_PW_P0+pipe,rxlen);
174
175 nrf_write_reg_long(R_RX_ADDR_P0+pipe,maclen,mac);
176 nrf_write_reg(R_EN_RXADDR,
177 nrf_read_reg(R_EN_RXADDR) | (1<<pipe)
178 );
179 }
180
181 void nrf_set_tx_mac(int maclen, const uint8_t * mac){
182 #ifdef SAFE
183 assert(maclen>=1 || maclen<=5);
184 assert(mac!=NULL);
185 #endif
186 nrf_write_reg_long(R_TX_ADDR,maclen,mac);
187 }
188
189 void nrf_disable_pipe(int pipe){
190 #ifdef SAFE
191 assert(pipe>=0 || pipe<=5);
192 #endif
193 nrf_write_reg(R_EN_RXADDR,
194 nrf_read_reg(R_EN_RXADDR) & ~(1<<pipe)
195 );
196 }
197
198 void nrf_set_channel(int channel){
199 #ifdef SAFE
200 assert(channel &~R_RF_CH_BITS ==0);
201 #endif
202 nrf_write_reg(R_RF_CH, channel);
203 }
204
205 void nrf_config_set(nrfconfig config){
206 nrf_write_reg(R_SETUP_AW,R_SETUP_AW_5);
207
208 nrf_set_channel(config->channel);
209
210 for(int i=0;i<config->nrmacs;i++){
211 nrf_write_reg(R_RX_PW_P0+i,config->maclen[i]);
212 if(i==0){
213 nrf_write_reg_long(R_RX_ADDR_P0,5,config->mac0);
214 }else if(i==1){
215 nrf_write_reg_long(R_RX_ADDR_P1,5,config->mac1);
216 }else if(i>1){
217 nrf_write_reg_long(R_RX_ADDR_P0+i,1,config->mac2345+i-2);
218 };
219 };
220
221 nrf_write_reg_long(R_TX_ADDR,5,config->txmac);
222
223 nrf_write_reg(R_EN_RXADDR,(1<<config->nrmacs)-1);
224 }
225
226 void nrf_config_get(nrfconfig config){
227 // nrf_write_reg(R_SETUP_AW,R_SETUP_AW_5);
228
229 config->channel=nrf_read_reg(R_RF_CH);
230
231 config->nrmacs=nrf_read_reg(R_EN_RXADDR);
232 if(config->nrmacs & R_EN_RXADDR_ERX_P5 )
233 config->nrmacs=6;
234 else if(config->nrmacs & R_EN_RXADDR_ERX_P4 )
235 config->nrmacs=5;
236 else if(config->nrmacs & R_EN_RXADDR_ERX_P3 )
237 config->nrmacs=4;
238 else if(config->nrmacs & R_EN_RXADDR_ERX_P2 )
239 config->nrmacs=3;
240 else if(config->nrmacs & R_EN_RXADDR_ERX_P1 )
241 config->nrmacs=2;
242 else
243 config->nrmacs=1;
244
245 // config->nrmacs=6;
246
247 for(int i=0;i<config->nrmacs;i++){
248 config->maclen[i]=nrf_read_reg(R_RX_PW_P0+i);
249 if(i==0){
250 nrf_read_long(R_RX_ADDR_P0,5,config->mac0);
251 }else if(i==1){
252 nrf_read_long(R_RX_ADDR_P1,5,config->mac1);
253 }else if(i>1){
254 nrf_read_long(R_RX_ADDR_P0+i,1,config->mac2345+i-2);
255 };
256 };
257
258 nrf_read_long(R_TX_ADDR,5,config->txmac);
259
260 }
261
262 void nrf_set_strength(unsigned char strength){
263 if(strength>3)
264 strength=3;
265 nrf_write_reg(R_RF_SETUP,DEFAULT_SPEED|(strength<<1));
266 }
267
268 void nrf_init() {
269 // Enable SPI correctly
270 sspInit(0, sspClockPolarity_Low, sspClockPhase_RisingEdge);
271
272 // Enable CS & CE pins
273 gpioSetDir(RB_SPI_NRF_CS, gpioDirection_Output);
274 gpioSetPullup(&RB_SPI_NRF_CS_IO, gpioPullupMode_Inactive);
275 gpioSetDir(RB_NRF_CE, gpioDirection_Output);
276 gpioSetPullup(&RB_NRF_CE_IO, gpioPullupMode_PullUp);
277 CE_LOW();
278
279 // Setup for nrf24l01+
280 // power up takes 1.5ms - 3.5ms (depending on crystal)
281 CS_LOW();
282 nrf_write_reg(R_CONFIG,
283 R_CONFIG_PRIM_RX| // Receive mode
284 R_CONFIG_PWR_UP| // Power on
285 R_CONFIG_EN_CRC // CRC on, single byte
286 );
287
288 nrf_write_reg(R_EN_AA, 0); // Disable Enhanced ShockBurst;
289
290 // Set speed / strength
291 nrf_write_reg(R_RF_SETUP,DEFAULT_SPEED|R_RF_SETUP_RF_PWR_3);
292
293 // Clear MAX_RT, just in case.
294 nrf_write_reg(R_STATUS,R_STATUS_MAX_RT);
295 }
296
297 void nrf_off() {
298 nrf_write_reg(R_CONFIG,
299 R_CONFIG_MASK_RX_DR|
300 R_CONFIG_MASK_TX_DS|
301 R_CONFIG_MASK_MAX_RT
302 ); // Most important: no R_CONFIG_PWR_UP
303 }
304
305 void nrf_startCW() {
306 // Enable SPI correctly
307 sspInit(0, sspClockPolarity_Low, sspClockPhase_RisingEdge);
308
309 // Enable CS & CE pins
310 gpioSetDir(RB_SPI_NRF_CS, gpioDirection_Output);
311 gpioSetPullup(&RB_SPI_NRF_CS_IO, gpioPullupMode_Inactive);
312 gpioSetDir(RB_NRF_CE, gpioDirection_Output);
313 gpioSetPullup(&RB_NRF_CE_IO, gpioPullupMode_PullUp);
314 CE_LOW();
315
316 // Setup for nrf24l01+
317 // power up takes 1.5ms - 3.5ms (depending on crystal)
318 CS_LOW();
319
320 nrf_write_reg(R_CONFIG, R_CONFIG_PWR_UP);
321 systickDelay(2);
322 nrf_write_reg(R_RF_SETUP, R_RF_SETUP_CONT_WAVE |
323 R_RF_SETUP_PLL_LOCK |
324 R_RF_SETUP_RF_PWR_3);
325 nrf_write_reg(R_RF_CH, 81);
326 CE_HIGH();
327 }
328
329 void nrf_check_reset(void){
330 if(nrf_cmd_status(C_NOP) & R_STATUS_MAX_RT){
331 _nrfresets++;
332 nrf_init();
333 };
334 }
This page took 0.063718 seconds and 5 git commands to generate.