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
  wl_module_config_register(RF_SETUP,0b00000110);  // 0 dBm, 1Mbps
68
  // Set length of incoming payload 
69
    wl_module_config_register(RX_PW_P0, wl_module_PAYLOAD);
70
  
71
    // Start receiver 
72
    PTX = 0;        // Start in receiving mode
73
    RX_POWERUP;     // Power up in receiving mode
74
    wl_module_CE_hi;     // Listening for pakets
75
}
76
77
extern void wl_module_rx_config() 
78
// Sets the important registers in the wl-module and powers the module
79
// in receiving mode
80
{
81
  uint8_t data[5];
82
    // Set RF channel
83
    wl_module_config_register(RF_CH,wl_module_CH);
84
  // Set data speed & Output Power configured in wl_module.h
85
  //wl_module_config_register(RF_SETUP,wl_module_RF_SETUP);
86
  wl_module_config_register(RF_SETUP,0b00000110);  // 0 dBm, 1Mbps
87
  //Enable all RX Data-Pipes
88
  wl_module_config_register(EN_RXADDR, EN_RXADDR_ERX_ALL);
89
  //Set RX_Address Pipe 0
90
  data[0]= data[1]= data[2]= data[3]= data[4]= RX_ADDR_P0_B0_DEFAULT_VAL;
91
  wl_module_set_rx_addr(data, 5, 0);
92
  //Set RX_Address Pipe 1
93
  data[0]= data[1]= data[2]= data[3]= data[4]= RX_ADDR_P1_B0_DEFAULT_VAL;
94
  wl_module_set_rx_addr(data, 5, 1);
95
  //Set RX_Address Pipe 2-5
96
  data[0]=RX_ADDR_P2_DEFAULT_VAL;
97
  wl_module_set_rx_addr(data, 1, 2);
98
  data[0]=RX_ADDR_P3_DEFAULT_VAL;
99
  wl_module_set_rx_addr(data, 1, 3);
100
  data[0]=RX_ADDR_P4_DEFAULT_VAL;
101
  wl_module_set_rx_addr(data, 1, 4);
102
  data[0]=RX_ADDR_P5_DEFAULT_VAL;
103
  wl_module_set_rx_addr(data, 1, 5);
104
    // Set length of incoming payload 
105
    wl_module_config_register(RX_PW_P0, wl_module_PAYLOAD);
106
  wl_module_config_register(RX_PW_P1, wl_module_PAYLOAD);
107
  wl_module_config_register(RX_PW_P2, wl_module_PAYLOAD);
108
  wl_module_config_register(RX_PW_P3, wl_module_PAYLOAD);
109
  wl_module_config_register(RX_PW_P4, wl_module_PAYLOAD);
110
  wl_module_config_register(RX_PW_P5, wl_module_PAYLOAD);
111
  
112
  
113
    // Start receiver 
114
    PTX = 0;        // Start in receiving mode
115
    RX_POWERUP;     // Power up in receiving mode
116
    wl_module_CE_hi;     // Listening for pakets
117
}
118
119
// Sets the wl-module as one of the six sender. Define for every sender a unique Number (wl_module_TX_NR_x) 
120
// when you call this Function.
121
//  Each TX will get a TX-Address corresponding to the RX-Device.
122
// RX_Address_Pipe_0 must be the same as the TX-Address
123
extern void wl_module_tx_config(uint8_t tx_nr) 
124
{
125
  uint8_t tx_addr[5];
126
  
127
    // Set RF channel
128
    wl_module_config_register(RF_CH,wl_module_CH);
129
  // Set data speed & Output Power configured in wl_module.h
130
  //wl_module_config_register(RF_SETUP,wl_module_RF_SETUP);
131
  wl_module_config_register(RF_SETUP,0b00000110);  // 0 dBm, 1Mbps
132
  //Config the CONFIG Register (Mask IRQ, CRC, etc)
133
  wl_module_config_register(CONFIG, wl_module_CONFIG);
134
    // Set length of incoming payload 
135
    wl_module_config_register(RX_PW_P0, wl_module_PAYLOAD);
136
  
137
  wl_module_config_register(SETUP_RETR,(SETUP_RETR_ARD_750 | SETUP_RETR_ARC_15));
138
  
139
  
140
  
141
  //set the TX address for the pipe with the same number as the iteration
142
      switch(tx_nr)      
143
      {
144
        case 0: //setup TX address as default RX address for pipe 0 (E7:E7:E7:E7:E7)
145
          tx_addr[0] = tx_addr[1] = tx_addr[2] = tx_addr[3] = tx_addr[4] = RX_ADDR_P0_B0_DEFAULT_VAL;
146
          wl_module_set_TADDR(tx_addr);
147
          wl_module_set_RADDR(tx_addr);
148
          break;
149
        case 1: //setup TX address as default RX address for pipe 1 (C2:C2:C2:C2:C2)
150
          tx_addr[0] = tx_addr[1] = tx_addr[2] = tx_addr[3] = tx_addr[4] = RX_ADDR_P1_B0_DEFAULT_VAL;
151
          wl_module_set_TADDR(tx_addr);
152
          wl_module_set_RADDR(tx_addr);
153
          break;
154
        case 2: //setup TX address as default RX address for pipe 2 (C2:C2:C2:C2:C3)
155
          tx_addr[1] = tx_addr[2] = tx_addr[3] = tx_addr[4] = RX_ADDR_P1_B0_DEFAULT_VAL;
156
          tx_addr[0] = RX_ADDR_P2_DEFAULT_VAL;
157
          wl_module_set_TADDR(tx_addr);
158
          wl_module_set_RADDR(tx_addr);
159
          break;
160
        case 3: //setup TX address as default RX address for pipe 3 (C2:C2:C2:C2:C4)
161
          tx_addr[1] = tx_addr[2] = tx_addr[3] = tx_addr[4] = RX_ADDR_P1_B0_DEFAULT_VAL;
162
          tx_addr[0] = RX_ADDR_P3_DEFAULT_VAL;
163
          wl_module_set_TADDR(tx_addr);
164
          wl_module_set_RADDR(tx_addr);
165
          break;
166
        case 4: //setup TX address as default RX address for pipe 4 (C2:C2:C2:C2:C5)
167
          tx_addr[1] = tx_addr[2] = tx_addr[3] = tx_addr[4] = RX_ADDR_P1_B0_DEFAULT_VAL;
168
          tx_addr[0] = RX_ADDR_P4_DEFAULT_VAL;
169
          wl_module_set_TADDR(tx_addr);
170
          wl_module_set_RADDR(tx_addr);
171
          break;
172
        case 5: //setup TX address as default RX address for pipe 5 (C2:C2:C2:C2:C6)
173
          tx_addr[1] = tx_addr[2] = tx_addr[3] = tx_addr[4] = RX_ADDR_P1_B0_DEFAULT_VAL;
174
          tx_addr[0] = RX_ADDR_P5_DEFAULT_VAL;
175
          wl_module_set_TADDR(tx_addr);
176
          wl_module_set_RADDR(tx_addr);
177
          break;
178
      }
179
  
180
  PTX =0;
181
  TX_POWERUP;
182
  /*
183
    // Start receiver 
184
    PTX = 0;        // Start in receiving mode
185
    RX_POWERUP;     // Power up in receiving mode
186
    wl_module_CE_hi;     // Listening for pakets
187
  */
188
}
189
190
//sets the TX address in the TX_ADDR register
191
//unsigned char * address is the actual address to be used.  It should be sized
192
//  according to the tx_addr length specified to the nrf24l01.
193
//unsigned int len is the length of the address.  Its value should be specified
194
//  according to the tx_addr length specified to the nrf24l01.
195
extern void wl_module_set_tx_addr(uint8_t * address, uint8_t len)
196
{    
197
  wl_module_write_register(TX_ADDR, address, len);
198
}
199
200
//sets up the 24L01 as a transmitter
201
//this function takes the existing contents of the CONFIG register and simply
202
//  clears the PRIM_RX bit in the CONFIG register.
203
//note: if the read value of the CONFIG register already has the PRIM_RX bit cleared, this 
204
//  function exits in order to not make an unecessary register write.
205
extern void wl_module_set_as_tx()
206
{
207
  unsigned char config;
208
  
209
  wl_module_read_register(CONFIG, &config, 1);
210
  
211
  if((config & CONFIG_PRIM_RX) == 0)
212
    return;
213
  
214
  config &= (~CONFIG_PRIM_RX);
215
  
216
  wl_module_write_register(CONFIG, &config, 1);
217
218
  wl_module_CE_lo;
219
}
220
221
//powers down the 24L01
222
//this function takes the existing contents of the CONFIG register and simply
223
//  clears the PWR_UP bit in the CONFIG register.
224
//note: if the read value of the CONFIG register already has the PWR_UP bit cleared, this 
225
//  function exits in order to not make an unecessary register write.
226
extern void wl_module_power_down()
227
{
228
  unsigned char config;
229
  
230
  wl_module_read_register(CONFIG, &config, 1);
231
  
232
  if((config & CONFIG_PWR_UP) == 0)
233
    return;
234
  
235
  config &= (~CONFIG_PWR_UP);
236
  
237
  wl_module_write_register(CONFIG, &config, 1);
238
239
  wl_module_CE_lo;
240
}
241
242
//sets the RX address in the RX_ADDR register that is offset by rxpipenum
243
//unsigned char * address is the actual address to be used.  It should be sized
244
//  according to the rx_addr length that is being filled.
245
//unsigned int len is the length of the address.  Its value should be specified
246
//  according to the rx_addr length specified to the nrf24l01.
247
//unsigned char rxpipenum is the pipe number (zero to five) whose address is being
248
//  specified.  If an invalid address (greater than five) is supplied, the function
249
//  does nothing.
250
extern void wl_module_set_rx_addr(uint8_t * address, uint8_t len, uint8_t rxpipenum)
251
{  
252
  if(rxpipenum > 5)
253
    return;
254
    
255
  wl_module_write_register(RX_ADDR_P0 + rxpipenum, address, len);
256
}
257
258
extern void wl_module_get_rx_addr(uint8_t *data, uint8_t rxpipenum, uint8_t len)
259
{
260
  
261
  if((rxpipenum > 5))
262
    return;
263
    
264
  wl_module_read_register(RX_ADDR_P0 + rxpipenum, data, len);
265
  
266
  
267
}
268
269
extern void wl_module_get_tx_addr(uint8_t *data, uint8_t rxpipenum, uint8_t len)
270
{
271
  
272
  if((rxpipenum > 5))
273
  return;
274
  
275
  wl_module_read_register(TX_ADDR + rxpipenum, data, len);
276
  
277
  
278
}
279
280
//sets the RX payload width on the pipe offset by rxpipenum
281
//unsigned char payloadwidth is the length of the payload for the pipe referenced in
282
//  rxpipenum.  It must be less than or equal to 32.  If an invalid payload width is
283
//  specified, the function does nothing.
284
//unsigned char rxpipenum is the pipe number (zero to five) whose address is being
285
//  specified.  If an invalid address (greater than five) is supplied, the function
286
//  does nothing.
287
extern void wl_module_set_rx_pw(unsigned char payloadwidth, unsigned char rxpipenum)
288
{
289
  if((rxpipenum > 5) || (payloadwidth > 32))
290
    return;
291
    
292
  wl_module_write_register(RX_PW_P0 + rxpipenum, &payloadwidth, 1);
293
}
294
295
//gets the RX payload width on the pipe offset by rxpipenum
296
//unsigned char rxpipenum is the pipe number (zero to five) whose address is being
297
//  specified.  If an invalid address (greater than five) is supplied, the function
298
//  does nothing.
299
extern uint8_t wl_module_get_rx_pw(uint8_t rxpipenum)
300
{
301
  unsigned char data;
302
  
303
  if((rxpipenum > 5))
304
    return 0;
305
    
306
  wl_module_read_register(RX_PW_P0 + rxpipenum, &data, 1);
307
  
308
  return data;
309
}
310
311
//returns the current pipe in the 24L01's STATUS register
312
extern uint8_t wl_module_get_rx_pipe()
313
{
314
  return wl_module_get_rx_pipe_from_status(wl_module_get_status());
315
}
316
317
extern uint8_t wl_module_get_rx_pipe_from_status(uint8_t status)
318
{
319
  return ((status & 0xE) >> 1);
320
}
321
322
void wl_module_set_RADDR(uint8_t * adr) 
323
// Sets the receiving address
324
{
325
   // wl_module_CE_lo;                  //<----------- Wozu diese Bit wechsel ????
326
    wl_module_write_register(RX_ADDR_P0,adr,5);
327
   // wl_module_CE_hi;                  //<----------- Wozu diese Bit wechsel ????
328
}
329
330
void wl_module_set_TADDR(uint8_t * adr)
331
// Sets the transmitting address
332
{
333
    wl_module_write_register(TX_ADDR, adr,5);
334
}
335
336
337
338
extern uint8_t wl_module_data_ready() 
339
// Checks if data is available for reading
340
{
341
    if (PTX) return 0;
342
    uint8_t status;
343
    // Read wl_module status 
344
    wl_module_CSN_lo;                                // Pull down chip select
345
    status = spi_fast_shift(NOP);               // Read status register
346
    wl_module_CSN_hi;                                // Pull up chip select
347
    return status & (1<<RX_DR);
348
}
349
350
//returns true if TX_EMPTY bit in FIFO_STATUS register is set, false otherwise
351
extern uint8_t wl_module_fifo_tx_empty()
352
{
353
  uint8_t data;
354
  
355
  wl_module_read_register(FIFO_STATUS, &data, 1);
356
  
357
  
358
  return (data & FIFO_STATUS_TX_EMPTY);
359
}
360
361
//returns true if RX_EMPTY bit in FIFO_STATUS register is set, false otherwise
362
extern uint8_t wl_module_fifo_rx_empty()
363
{
364
  uint8_t data;
365
  
366
  wl_module_read_register(FIFO_STATUS, &data, 1);
367
  
368
  return (data & FIFO_STATUS_RX_EMPTY);
369
}
370
371
//returns the current RF channel in RF_CH register
372
extern uint8_t wl_module_get_rf_ch()
373
{
374
  uint8_t data;
375
  
376
  wl_module_read_register(RF_CH, &data, 1);
377
  
378
  return data;
379
}
380
381
//returns the current RF_SETUP Register
382
extern uint8_t wl_module_get_rf_setup()
383
{
384
  uint8_t data;
385
  
386
  wl_module_read_register(RF_SETUP, &data, 1);
387
  
388
  return data;
389
}
390
391
//returns the current PLOS_CNT value in OBSERVE_TX register
392
extern uint8_t wl_module_get_plos_cnt()
393
{
394
  uint8_t data;
395
  
396
  wl_module_read_register(OBSERVE_TX, &data, 1);
397
  
398
  return ((data & OBSERVE_TX_PLOS_CNT) >> 4);
399
}
400
401
//returns the current ARC_CNT value in OBSERVE_TX register
402
extern uint8_t wl_module_get_arc_cnt()
403
{
404
  uint8_t data;
405
  
406
  wl_module_read_register(OBSERVE_TX, &data, 1);
407
  
408
  return (data & OBSERVE_TX_ARC_CNT);
409
}
410
411
//return the value of the status register
412
extern uint8_t wl_module_get_status()
413
{
414
  return wl_module_get_one_byte(NOP);
415
}
416
417
extern uint8_t wl_module_get_rx_pipe_reading_status()
418
{
419
  uint8_t pipe;
420
  pipe = wl_module_get_one_byte(NOP);
421
  return ((pipe & 0x0E) >> 1);
422
}
423
424
extern uint8_t wl_module_get_one_byte(uint8_t command)
425
{
426
uint8_t status;
427
428
wl_module_CSN_lo;
429
status = spi_fast_shift(command);
430
wl_module_CSN_hi;
431
432
return status;
433
434
}
435
436
extern uint8_t wl_module_get_data(uint8_t * data) 
437
// Reads wl_module_PAYLOAD bytes into data array
438
{
439
  uint8_t status;
440
    wl_module_CSN_lo;                               // Pull down chip select
441
    status = spi_fast_shift( R_RX_PAYLOAD );            // Send cmd to read rx payload
442
    spi_transfer_sync(data,data,wl_module_PAYLOAD); // Read payload
443
    wl_module_CSN_hi;                               // Pull up chip select
444
    wl_module_config_register(STATUS,(1<<RX_DR));   // Reset status register
445
  return status;
446
}
447
448
void wl_module_config_register(uint8_t reg, uint8_t value)
449
// Clocks only one byte into the given wl-module register
450
{
451
    wl_module_CSN_lo;
452
    spi_fast_shift(W_REGISTER | (REGISTER_MASK & reg));
453
    spi_fast_shift(value);
454
    wl_module_CSN_hi;
455
}
456
457
void wl_module_read_register(uint8_t reg, uint8_t * value, uint8_t len)
458
// Reads an array of bytes from the given start position in the wl-module registers.
459
{
460
    wl_module_CSN_lo;
461
    spi_fast_shift(R_REGISTER | (REGISTER_MASK & reg));
462
    spi_transfer_sync(value,value,len);
463
    wl_module_CSN_hi;
464
}
465
466
void wl_module_write_register(uint8_t reg, uint8_t * value, uint8_t len) 
467
// Writes an array of bytes into inte the wl-module registers.
468
{
469
    wl_module_CSN_lo;
470
    spi_fast_shift(W_REGISTER | (REGISTER_MASK & reg));
471
    spi_transmit_sync(value,len);
472
    wl_module_CSN_hi;
473
}
474
475
476
void wl_module_send(uint8_t * value, uint8_t len) 
477
// Sends a data package to the default address. Be sure to send the correct
478
// amount of bytes as configured as payload on the receiver.
479
{
480
    while (PTX) {}                  // Wait until last paket is send
481
482
    wl_module_CE_lo;
483
484
    PTX = 1;                        // Set to transmitter mode
485
    TX_POWERUP;                     // Power up
486
    
487
    wl_module_CSN_lo;                    // Pull down chip select
488
    spi_fast_shift( FLUSH_TX );     // Write cmd to flush tx fifo
489
    wl_module_CSN_hi;                    // Pull up chip select
490
    
491
    wl_module_CSN_lo;                    // Pull down chip select
492
    spi_fast_shift( W_TX_PAYLOAD ); // Write cmd to write payload
493
    spi_transmit_sync(value,len);   // Write payload
494
    wl_module_CSN_hi;                    // Pull up chip select
495
    
496
    wl_module_CE_hi;                     // Start transmission
497
  _delay_us(10);            // Grünes Modul funktioniert nicht mit 10µs delay
498
  wl_module_CE_lo;
499
}