wl_module.c


1
/*
2
  Copyright (c) 2011 by Ernst Buchmann 
3
  
4
  Code based on the work of Stefan Engelke and Brennan Ball
5
  
6
    Permission is hereby granted, free of charge, to any person 
7
    obtaining a copy of this software and associated documentation 
8
    files (the "Software"), to deal in the Software without 
9
    restriction, including without limitation the rights to use, copy, 
10
    modify, merge, publish, distribute, sublicense, and/or sell copies 
11
    of the Software, and to permit persons to whom the Software is 
12
    furnished to do so, subject to the following conditions:
13
14
    The above copyright notice and this permission notice shall be 
15
    included in all copies or substantial portions of the Software.
16
17
    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
18
    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
19
    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
20
    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 
21
    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 
22
    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
23
    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
24
    DEALINGS IN THE SOFTWARE.
25
26
    
27
*/
28
29
#include "wl_module.h"
30
#include "nRF24L01.h"
31
#include "spi.h"
32
#include <avr/io.h>
33
#include <avr/interrupt.h>
34
#include <util/delay.h>
35
36
// Defines for setting the wl_module registers for transmitting or receiving mode
37
#define TX_POWERUP wl_module_config_register(CONFIG, wl_module_CONFIG | ( (1<<PWR_UP) | (0<<PRIM_RX) ) )
38
#define RX_POWERUP wl_module_config_register(CONFIG, wl_module_CONFIG | ( (1<<PWR_UP) | (1<<PRIM_RX) ) )
39
40
41
// Flag which denotes transmitting mode
42
volatile uint8_t PTX;
43
44
void wl_module_init() 
45
// Initializes pins and interrupt to communicate with the wl_module
46
// Should be called in the early initializing phase at startup.
47
{
48
    // Define CSN and CE as Output and set them to default
49
    DDRB |= ((1<<CSN)|(1<<CE));
50
    wl_module_CE_lo;
51
    wl_module_CSN_hi;
52
53
54
    // Initialize spi module
55
    spi_init();
56
}
57
58
59
void wl_module_config() 
60
// Sets the important registers in the wl-module and powers the module
61
// in receiving mode
62
{
63
    // Set RF channel
64
    wl_module_config_register(RF_CH,wl_module_CH);
65
  // Set data speed & Output Power configured in wl_module.h
66
  wl_module_config_register(RF_SETUP,wl_module_RF_SETUP);
67
  // Set length of incoming payload 
68
    wl_module_config_register(RX_PW_P0, wl_module_PAYLOAD);
69
  
70
    // Start receiver 
71
    PTX = 0;        // Start in receiving mode
72
    RX_POWERUP;     // Power up in receiving mode
73
    wl_module_CE_hi;     // Listening for pakets
74
}
75
76
extern void wl_module_rx_config() 
77
// Sets the important registers in the wl-module and powers the module
78
// in receiving mode
79
{
80
  uint8_t data[5];
81
    // Set RF channel
82
    wl_module_config_register(RF_CH,wl_module_CH);
83
  // Set data speed & Output Power configured in wl_module.h
84
  wl_module_config_register(RF_SETUP,wl_module_RF_SETUP);
85
  //Enable all RX Data-Pipes
86
  wl_module_config_register(EN_RXADDR, EN_RXADDR_ERX_ALL);
87
  //Set RX_Address Pipe 0
88
  data[0]= data[1]= data[2]= data[3]= data[4]= RX_ADDR_P0_B0_DEFAULT_VAL;
89
  wl_module_set_rx_addr(data, 5, 0);
90
  //Set RX_Address Pipe 1
91
  data[0]= data[1]= data[2]= data[3]= data[4]= RX_ADDR_P1_B0_DEFAULT_VAL;
92
  wl_module_set_rx_addr(data, 5, 1);
93
  //Set RX_Address Pipe 2-5
94
  data[0]=RX_ADDR_P2_DEFAULT_VAL;
95
  wl_module_set_rx_addr(data, 1, 2);
96
  data[0]=RX_ADDR_P3_DEFAULT_VAL;
97
  wl_module_set_rx_addr(data, 1, 3);
98
  data[0]=RX_ADDR_P4_DEFAULT_VAL;
99
  wl_module_set_rx_addr(data, 1, 4);
100
  data[0]=RX_ADDR_P5_DEFAULT_VAL;
101
  wl_module_set_rx_addr(data, 1, 5);
102
    // Set length of incoming payload 
103
    wl_module_config_register(RX_PW_P0, wl_module_PAYLOAD);
104
  wl_module_config_register(RX_PW_P1, wl_module_PAYLOAD);
105
  wl_module_config_register(RX_PW_P2, wl_module_PAYLOAD);
106
  wl_module_config_register(RX_PW_P3, wl_module_PAYLOAD);
107
  wl_module_config_register(RX_PW_P4, wl_module_PAYLOAD);
108
  wl_module_config_register(RX_PW_P5, wl_module_PAYLOAD);
109
  
110
  
111
    // Start receiver 
112
    PTX = 0;        // Start in receiving mode
113
    RX_POWERUP;     // Power up in receiving mode
114
    wl_module_CE_hi;     // Listening for pakets
115
}
116
117
// Sets the wl-module as one of the six sender. Define for every sender a unique Number (wl_module_TX_NR_x) 
118
// when you call this Function.
119
//  Each TX will get a TX-Address corresponding to the RX-Device.
120
// RX_Address_Pipe_0 must be the same as the TX-Address
121
extern void wl_module_tx_config(uint8_t tx_nr) 
122
{
123
  uint8_t tx_addr[5];
124
  
125
    // Set RF channel
126
    wl_module_config_register(RF_CH,wl_module_CH);
127
  // Set data speed & Output Power configured in wl_module.h
128
  wl_module_config_register(RF_SETUP,wl_module_RF_SETUP);
129
  //Config the CONFIG Register (Mask IRQ, CRC, etc)
130
  wl_module_config_register(CONFIG, wl_module_CONFIG);
131
    // Set length of incoming payload 
132
    wl_module_config_register(RX_PW_P0, wl_module_PAYLOAD);
133
  
134
  wl_module_config_register(SETUP_RETR,(SETUP_RETR_ARD_750 | SETUP_RETR_ARC_15));
135
  
136
  //set the TX address for the pipe with the same number as the iteration
137
      switch(tx_nr)      
138
      {
139
        case 0: //setup TX address as default RX address for pipe 0 (E7:E7:E7:E7:E7)
140
          tx_addr[0] = tx_addr[1] = tx_addr[2] = tx_addr[3] = tx_addr[4] = RX_ADDR_P0_B0_DEFAULT_VAL;
141
          wl_module_set_TADDR(tx_addr);
142
          wl_module_set_RADDR(tx_addr);
143
          break;
144
        case 1: //setup TX address as default RX address for pipe 1 (C2:C2:C2:C2:C2)
145
          tx_addr[0] = tx_addr[1] = tx_addr[2] = tx_addr[3] = tx_addr[4] = RX_ADDR_P1_B0_DEFAULT_VAL;
146
          wl_module_set_TADDR(tx_addr);
147
          wl_module_set_RADDR(tx_addr);
148
          break;
149
        case 2: //setup TX address as default RX address for pipe 2 (C2:C2:C2:C2:C3)
150
          tx_addr[1] = tx_addr[2] = tx_addr[3] = tx_addr[4] = RX_ADDR_P1_B0_DEFAULT_VAL;
151
          tx_addr[0] = RX_ADDR_P2_DEFAULT_VAL;
152
          wl_module_set_TADDR(tx_addr);
153
          wl_module_set_RADDR(tx_addr);
154
          break;
155
        case 3: //setup TX address as default RX address for pipe 3 (C2:C2:C2:C2:C4)
156
          tx_addr[1] = tx_addr[2] = tx_addr[3] = tx_addr[4] = RX_ADDR_P1_B0_DEFAULT_VAL;
157
          tx_addr[0] = RX_ADDR_P3_DEFAULT_VAL;
158
          wl_module_set_TADDR(tx_addr);
159
          wl_module_set_RADDR(tx_addr);
160
          break;
161
        case 4: //setup TX address as default RX address for pipe 4 (C2:C2:C2:C2:C5)
162
          tx_addr[1] = tx_addr[2] = tx_addr[3] = tx_addr[4] = RX_ADDR_P1_B0_DEFAULT_VAL;
163
          tx_addr[0] = RX_ADDR_P4_DEFAULT_VAL;
164
          wl_module_set_TADDR(tx_addr);
165
          wl_module_set_RADDR(tx_addr);
166
          break;
167
        case 5: //setup TX address as default RX address for pipe 5 (C2:C2:C2:C2:C6)
168
          tx_addr[1] = tx_addr[2] = tx_addr[3] = tx_addr[4] = RX_ADDR_P1_B0_DEFAULT_VAL;
169
          tx_addr[0] = RX_ADDR_P5_DEFAULT_VAL;
170
          wl_module_set_TADDR(tx_addr);
171
          wl_module_set_RADDR(tx_addr);
172
          break;
173
      }
174
  
175
  PTX =0;
176
  TX_POWERUP;
177
  /*
178
    // Start receiver 
179
    PTX = 0;        // Start in receiving mode
180
    RX_POWERUP;     // Power up in receiving mode
181
    wl_module_CE_hi;     // Listening for pakets
182
  */
183
}
184
185
//sets the TX address in the TX_ADDR register
186
//unsigned char * address is the actual address to be used.  It should be sized
187
//  according to the tx_addr length specified to the nrf24l01.
188
//unsigned int len is the length of the address.  Its value should be specified
189
//  according to the tx_addr length specified to the nrf24l01.
190
extern void wl_module_set_tx_addr(uint8_t * address, uint8_t len)
191
{    
192
  wl_module_write_register(TX_ADDR, address, len);
193
}
194
195
//sets up the 24L01 as a transmitter
196
//this function takes the existing contents of the CONFIG register and simply
197
//  clears the PRIM_RX bit in the CONFIG register.
198
//note: if the read value of the CONFIG register already has the PRIM_RX bit cleared, this 
199
//  function exits in order to not make an unecessary register write.
200
extern void wl_module_set_as_tx()
201
{
202
  unsigned char config;
203
  
204
  wl_module_read_register(CONFIG, &config, 1);
205
  
206
  if((config & CONFIG_PRIM_RX) == 0)
207
    return;
208
  
209
  config &= (~CONFIG_PRIM_RX);
210
  
211
  wl_module_write_register(CONFIG, &config, 1);
212
213
  wl_module_CE_lo;
214
}
215
216
//powers down the 24L01
217
//this function takes the existing contents of the CONFIG register and simply
218
//  clears the PWR_UP bit in the CONFIG register.
219
//note: if the read value of the CONFIG register already has the PWR_UP bit cleared, this 
220
//  function exits in order to not make an unecessary register write.
221
extern void wl_module_power_down()
222
{
223
  unsigned char config;
224
  
225
  wl_module_read_register(CONFIG, &config, 1);
226
  
227
  if((config & CONFIG_PWR_UP) == 0)
228
    return;
229
  
230
  config &= (~CONFIG_PWR_UP);
231
  
232
  wl_module_write_register(CONFIG, &config, 1);
233
234
  wl_module_CE_lo;
235
}
236
237
//sets the RX address in the RX_ADDR register that is offset by rxpipenum
238
//unsigned char * address is the actual address to be used.  It should be sized
239
//  according to the rx_addr length that is being filled.
240
//unsigned int len is the length of the address.  Its value should be specified
241
//  according to the rx_addr length specified to the nrf24l01.
242
//unsigned char rxpipenum is the pipe number (zero to five) whose address is being
243
//  specified.  If an invalid address (greater than five) is supplied, the function
244
//  does nothing.
245
extern void wl_module_set_rx_addr(uint8_t * address, uint8_t len, uint8_t rxpipenum)
246
{  
247
  if(rxpipenum > 5)
248
    return;
249
    
250
  wl_module_write_register(RX_ADDR_P0 + rxpipenum, address, len);
251
}
252
253
extern void wl_module_get_rx_addr(uint8_t *data, uint8_t rxpipenum, uint8_t len)
254
{
255
  
256
  if((rxpipenum > 5))
257
    return;
258
    
259
  wl_module_read_register(RX_ADDR_P0 + rxpipenum, data, len);
260
  
261
  
262
}
263
264
//sets the RX payload width on the pipe offset by rxpipenum
265
//unsigned char payloadwidth is the length of the payload for the pipe referenced in
266
//  rxpipenum.  It must be less than or equal to 32.  If an invalid payload width is
267
//  specified, the function does nothing.
268
//unsigned char rxpipenum is the pipe number (zero to five) whose address is being
269
//  specified.  If an invalid address (greater than five) is supplied, the function
270
//  does nothing.
271
extern void wl_module_set_rx_pw(unsigned char payloadwidth, unsigned char rxpipenum)
272
{
273
  if((rxpipenum > 5) || (payloadwidth > 32))
274
    return;
275
    
276
  wl_module_write_register(RX_PW_P0 + rxpipenum, &payloadwidth, 1);
277
}
278
279
//gets the RX payload width on the pipe offset by rxpipenum
280
//unsigned char rxpipenum is the pipe number (zero to five) whose address is being
281
//  specified.  If an invalid address (greater than five) is supplied, the function
282
//  does nothing.
283
extern uint8_t wl_module_get_rx_pw(uint8_t rxpipenum)
284
{
285
  unsigned char data;
286
  
287
  if((rxpipenum > 5))
288
    return 0;
289
    
290
  wl_module_read_register(RX_PW_P0 + rxpipenum, &data, 1);
291
  
292
  return data;
293
}
294
295
//returns the current pipe in the 24L01's STATUS register
296
extern uint8_t wl_module_get_rx_pipe()
297
{
298
  return wl_module_get_rx_pipe_from_status(wl_module_get_status());
299
}
300
301
extern uint8_t wl_module_get_rx_pipe_from_status(uint8_t status)
302
{
303
  return ((status & 0xE) >> 1);
304
}
305
306
void wl_module_set_RADDR(uint8_t * adr) 
307
// Sets the receiving address
308
{
309
    wl_module_CE_lo;
310
    wl_module_write_register(RX_ADDR_P0,adr,5);
311
    wl_module_CE_hi;
312
}
313
314
void wl_module_set_TADDR(uint8_t * adr)
315
// Sets the transmitting address
316
{
317
    wl_module_write_register(TX_ADDR, adr,5);
318
}
319
320
321
322
extern uint8_t wl_module_data_ready() 
323
// Checks if data is available for reading
324
{
325
    if (PTX) return 0;
326
    uint8_t status;
327
    // Read wl_module status 
328
    wl_module_CSN_lo;                                // Pull down chip select
329
    status = spi_fast_shift(NOP);               // Read status register
330
    wl_module_CSN_hi;                                // Pull up chip select
331
    return status & (1<<RX_DR);
332
}
333
334
//returns true if TX_EMPTY bit in FIFO_STATUS register is set, false otherwise
335
extern uint8_t wl_module_fifo_tx_empty()
336
{
337
  uint8_t data;
338
  
339
  wl_module_read_register(FIFO_STATUS, &data, 1);
340
  
341
  
342
  return (data & FIFO_STATUS_TX_EMPTY);
343
}
344
345
//returns true if RX_EMPTY bit in FIFO_STATUS register is set, false otherwise
346
extern uint8_t wl_module_fifo_rx_empty()
347
{
348
  uint8_t data;
349
  
350
  wl_module_read_register(FIFO_STATUS, &data, 1);
351
  
352
  return (data & FIFO_STATUS_RX_EMPTY);
353
}
354
355
//returns the current RF channel in RF_CH register
356
extern uint8_t wl_module_get_rf_ch()
357
{
358
  uint8_t data;
359
  
360
  wl_module_read_register(RF_CH, &data, 1);
361
  
362
  return data;
363
}
364
365
//returns the current RF_SETUP Register
366
extern uint8_t wl_module_get_rf_setup()
367
{
368
  uint8_t data;
369
  
370
  wl_module_read_register(RF_SETUP, &data, 1);
371
  
372
  return data;
373
}
374
375
//returns the current PLOS_CNT value in OBSERVE_TX register
376
extern uint8_t wl_module_get_plos_cnt()
377
{
378
  uint8_t data;
379
  
380
  wl_module_read_register(OBSERVE_TX, &data, 1);
381
  
382
  return ((data & OBSERVE_TX_PLOS_CNT) >> 4);
383
}
384
385
//returns the current ARC_CNT value in OBSERVE_TX register
386
extern uint8_t wl_module_get_arc_cnt()
387
{
388
  uint8_t data;
389
  
390
  wl_module_read_register(OBSERVE_TX, &data, 1);
391
  
392
  return (data & OBSERVE_TX_ARC_CNT);
393
}
394
395
//return the value of the status register
396
extern uint8_t wl_module_get_status()
397
{
398
  return wl_module_get_one_byte(NOP);
399
}
400
401
extern uint8_t wl_module_get_rx_pipe_reading_status()
402
{
403
  uint8_t pipe;
404
  pipe = wl_module_get_one_byte(NOP);
405
  return ((pipe & 0x0E) >> 1);
406
}
407
408
extern uint8_t wl_module_get_one_byte(uint8_t command)
409
{
410
uint8_t status;
411
412
wl_module_CSN_lo;
413
status = spi_fast_shift(command);
414
wl_module_CSN_hi;
415
416
return status;
417
418
}
419
420
extern uint8_t wl_module_get_data(uint8_t * data) 
421
// Reads wl_module_PAYLOAD bytes into data array
422
{
423
  uint8_t status;
424
    wl_module_CSN_lo;                               // Pull down chip select
425
    status = spi_fast_shift( R_RX_PAYLOAD );            // Send cmd to read rx payload
426
    spi_transfer_sync(data,data,wl_module_PAYLOAD); // Read payload
427
    wl_module_CSN_hi;                               // Pull up chip select
428
    wl_module_config_register(STATUS,(1<<RX_DR));   // Reset status register
429
  return status;
430
}
431
432
void wl_module_config_register(uint8_t reg, uint8_t value)
433
// Clocks only one byte into the given wl-module register
434
{
435
    wl_module_CSN_lo;
436
    spi_fast_shift(W_REGISTER | (REGISTER_MASK & reg));
437
    spi_fast_shift(value);
438
    wl_module_CSN_hi;
439
}
440
441
void wl_module_read_register(uint8_t reg, uint8_t * value, uint8_t len)
442
// Reads an array of bytes from the given start position in the wl-module registers.
443
{
444
    wl_module_CSN_lo;
445
    spi_fast_shift(R_REGISTER | (REGISTER_MASK & reg));
446
    spi_transfer_sync(value,value,len);
447
    wl_module_CSN_hi;
448
}
449
450
void wl_module_write_register(uint8_t reg, uint8_t * value, uint8_t len) 
451
// Writes an array of bytes into inte the wl-module registers.
452
{
453
    wl_module_CSN_lo;
454
    spi_fast_shift(W_REGISTER | (REGISTER_MASK & reg));
455
    spi_transmit_sync(value,len);
456
    wl_module_CSN_hi;
457
}
458
459
460
void wl_module_send(uint8_t * value, uint8_t len) 
461
// Sends a data package to the default address. Be sure to send the correct
462
// amount of bytes as configured as payload on the receiver.
463
{
464
    while (PTX) {}                  // Wait until last paket is send
465
466
    wl_module_CE_lo;
467
468
    PTX = 1;                        // Set to transmitter mode
469
    TX_POWERUP;                     // Power up
470
    
471
    wl_module_CSN_lo;                    // Pull down chip select
472
    spi_fast_shift( FLUSH_TX );     // Write cmd to flush tx fifo
473
    wl_module_CSN_hi;                    // Pull up chip select
474
    
475
    wl_module_CSN_lo;                    // Pull down chip select
476
    spi_fast_shift( W_TX_PAYLOAD ); // Write cmd to write payload
477
    spi_transmit_sync(value,len);   // Write payload
478
    wl_module_CSN_hi;                    // Pull up chip select
479
    
480
    wl_module_CE_hi;                     // Start transmission
481
  _delay_us(20);            // Grünes Modul funktioniert nicht mit 10µs delay
482
  wl_module_CE_lo;
483
}