nrf24.c


1
/*
2
* 
3
* ----------------------------------------------------------------------------
4
* “THE COFFEEWARE LICENSE” (Revision 1):
5
* <ihsan@kehribar.me> wrote this file. As long as you retain this notice you
6
* can do whatever you want with this stuff. If we meet some day, and you think
7
* this stuff is worth it, you can buy me a coffee in return.
8
* -----------------------------------------------------------------------------
9
* This library is based on this library: 
10
*   https://github.com/aaronds/arduino-nrf24l01
11
* Which is based on this library: 
12
*   http://www.tinkerer.eu/AVRLib/nRF24L01
13
* -----------------------------------------------------------------------------
14
*/
15
#include "nrf24.h"
16
17
uint8_t payload_len;
18
19
/* init the hardware pins */
20
void nrf24_init() 
21
{
22
  DDRB |= ((1<<CSN)|(1<<CE));
23
    wl_module_CE_lo;
24
    wl_module_CSN_hi; 
25
  
26
  spi_init(); 
27
}
28
29
/* configure the module */
30
void nrf24_config(uint8_t channel, uint8_t pay_length)//(2,4)
31
{
32
    /* Use static payload length ... */
33
    payload_len = pay_length;
34
35
    // Set RF channel
36
    nrf24_configRegister(RF_CH,channel);
37
38
    // Set length of incoming payload 
39
    nrf24_configRegister(RX_PW_P0, 0x00); // Auto-ACK pipe ...
40
    nrf24_configRegister(RX_PW_P1, payload_len); // Data payload pipe
41
    nrf24_configRegister(RX_PW_P2, 0x00); // Pipe not used 
42
    nrf24_configRegister(RX_PW_P3, 0x00); // Pipe not used 
43
    nrf24_configRegister(RX_PW_P4, 0x00); // Pipe not used 
44
    nrf24_configRegister(RX_PW_P5, 0x00); // Pipe not used 
45
46
    // 1 Mbps, TX gain: 0dbm
47
    nrf24_configRegister(RF_SETUP, (0<<RF_DR)|((0x03)<<RF_PWR));
48
49
    // CRC enable, 1 byte CRC length
50
    nrf24_configRegister(CONFIG,nrf24_CONFIG);
51
52
    // Auto Acknowledgment
53
    nrf24_configRegister(EN_AA,(1<<ENAA_P0)|(1<<ENAA_P1)|(0<<ENAA_P2)|(0<<ENAA_P3)|(0<<ENAA_P4)|(0<<ENAA_P5));
54
55
    // Enable RX addresses
56
    nrf24_configRegister(EN_RXADDR,(1<<ERX_P0)|(1<<ERX_P1)|(0<<ERX_P2)|(0<<ERX_P3)|(0<<ERX_P4)|(0<<ERX_P5));
57
58
    // Auto retransmit delay: 1000 us and Up to 15 retransmit trials
59
    nrf24_configRegister(SETUP_RETR,(0x04<<ARD)|(0x0F<<ARC));
60
61
    // Dynamic length configurations: No dynamic length
62
    nrf24_configRegister(DYNPD,(0<<DPL_P0)|(0<<DPL_P1)|(0<<DPL_P2)|(0<<DPL_P3)|(0<<DPL_P4)|(0<<DPL_P5));
63
64
    // Start listening
65
    nrf24_powerUpRx();
66
}
67
68
/* Set the RX address */
69
void nrf24_rx_address(uint8_t * adr) 
70
{
71
    wl_module_CE_lo;
72
    nrf24_writeRegister(RX_ADDR_P1,adr,nrf24_ADDR_LEN);
73
    wl_module_CE_hi;
74
}
75
76
/* Returns the payload length */
77
uint8_t nrf24_payload_length()
78
{
79
    return payload_len;
80
}
81
82
/* Set the TX address */
83
void nrf24_tx_address(uint8_t* adr)
84
{
85
    /* RX_ADDR_P0 must be set to the sending addr for auto ack to work. */
86
    nrf24_writeRegister(RX_ADDR_P0,adr,nrf24_ADDR_LEN);
87
    nrf24_writeRegister(TX_ADDR,adr,nrf24_ADDR_LEN);
88
}
89
90
/* Checks if data is available for reading */
91
/* Returns 1 if data is ready ... */
92
uint8_t nrf24_dataReady() 
93
{
94
    // See note in getData() function - just checking RX_DR isn't good enough
95
    uint8_t status = nrf24_getStatus();
96
97
    // We can short circuit on RX_DR, but if it's not set, we still need
98
    // to check the FIFO for any pending packets
99
    if ( status & (1 << RX_DR) ) 
100
    {
101
        return 1;
102
    }
103
104
    return !nrf24_rxFifoEmpty();;
105
}
106
107
/* Checks if receive FIFO is empty or not */
108
uint8_t nrf24_rxFifoEmpty()
109
{
110
    uint8_t fifoStatus;
111
112
    nrf24_readRegister(FIFO_STATUS,&fifoStatus,1);
113
    
114
    return (fifoStatus & (1 << RX_EMPTY));
115
}
116
117
/* Returns the length of data waiting in the RX fifo */
118
uint8_t nrf24_payloadLength()
119
{
120
    uint8_t status;
121
    wl_module_CSN_lo;
122
    spi_fast_shift(R_RX_PL_WID);
123
    status = spi_fast_shift(0x00);
124
    wl_module_CSN_hi;
125
    return status;
126
}
127
128
/* Reads payload bytes into data array */
129
void nrf24_getData(uint8_t* data) 
130
{
131
    /* Pull down chip select */
132
    wl_module_CSN_lo;                               
133
134
    /* Send cmd to read rx payload */
135
    spi_fast_shift( R_RX_PAYLOAD );
136
    
137
    /* Read payload */
138
    spi_transfer_sync(data,data,payload_len);
139
    
140
    /* Pull up chip select */
141
    wl_module_CSN_hi;
142
143
    /* Reset status register */
144
    nrf24_configRegister(STATUS,(1<<RX_DR));   
145
}
146
147
/* Returns the number of retransmissions occured for the last message */
148
uint8_t nrf24_retransmissionCount()
149
{
150
    uint8_t rv;
151
    nrf24_readRegister(OBSERVE_TX,&rv,1);
152
    rv = rv & 0x0F;
153
    return rv;
154
}
155
156
// Sends a data package to the default address. Be sure to send the correct
157
// amount of bytes as configured as payload on the receiver.
158
void nrf24_send(uint8_t* value) 
159
{    
160
    /* Go to Standby-I first */
161
    wl_module_CE_lo;
162
     
163
    /* Set to transmitter mode , Power up if needed */
164
    nrf24_powerUpTx();
165
166
    /* Do we really need to flush TX fifo each time ? */
167
    #if 1
168
        /* Pull down chip select */
169
        wl_module_CSN_lo;           
170
171
        /* Write cmd to flush transmit FIFO */
172
        spi_fast_shift(FLUSH_TX);     
173
174
        /* Pull up chip select */
175
        wl_module_CSN_hi;                    
176
    #endif 
177
178
    /* Pull down chip select */
179
    wl_module_CSN_lo;
180
181
    /* Write cmd to write payload */
182
    spi_fast_shift(W_TX_PAYLOAD);
183
184
    /* Write payload */
185
    spi_transmit_sync(value,payload_len);   
186
187
    /* Pull up chip select */
188
    wl_module_CSN_hi;
189
190
    /* Start the transmission */
191
    wl_module_CE_hi    
192
}
193
194
uint8_t nrf24_isSending()
195
{
196
    uint8_t status;
197
198
    /* read the current status */
199
    status = nrf24_getStatus();
200
                
201
    /* if sending successful (TX_DS) or max retries exceded (MAX_RT). */
202
    if((status & ((1 << TX_DS)  | (1 << MAX_RT))))
203
    {        
204
        return 0; /* false */
205
    }
206
207
    return 1; /* true */
208
209
}
210
211
uint8_t nrf24_getStatus()
212
{
213
    uint8_t rv;
214
    wl_module_CSN_lo;
215
    rv = spi_fast_shift(NOP);
216
    wl_module_CSN_hi;
217
    return rv;
218
}
219
220
uint8_t nrf24_lastMessageStatus()
221
{
222
    uint8_t rv;
223
224
    rv = nrf24_getStatus();
225
226
    /* Transmission went OK */
227
    if((rv & ((1 << TX_DS))))
228
    {
229
        return NRF24_TRANSMISSON_OK;
230
    }
231
    /* Maximum retransmission count is reached */
232
    /* Last message probably went missing ... */
233
    else if((rv & ((1 << MAX_RT))))
234
    {
235
        return NRF24_MESSAGE_LOST;
236
    }  
237
    /* Probably still sending ... */
238
    else
239
    {
240
        return 0xFF;
241
    }
242
}
243
244
void nrf24_powerUpRx()
245
{     
246
    wl_module_CSN_lo;
247
    spi_fast_shift(FLUSH_RX);
248
    wl_module_CSN_hi;
249
250
    nrf24_configRegister(STATUS,(1<<RX_DR)|(1<<TX_DS)|(1<<MAX_RT)); 
251
252
    wl_module_CE_lo;   
253
    nrf24_configRegister(CONFIG,nrf24_CONFIG|((1<<PWR_UP)|(1<<PRIM_RX)));    
254
    wl_module_CE_hi
255
}
256
257
void nrf24_powerUpTx()
258
{
259
    nrf24_configRegister(STATUS,(1<<RX_DR)|(1<<TX_DS)|(1<<MAX_RT)); 
260
261
    nrf24_configRegister(CONFIG,nrf24_CONFIG|((1<<PWR_UP)|(0<<PRIM_RX)));
262
}
263
264
void nrf24_powerDown()
265
{
266
    wl_module_CE_lo;
267
    nrf24_configRegister(CONFIG,nrf24_CONFIG);
268
}
269
270
/* Clocks only one byte into the given nrf24 register */
271
void nrf24_configRegister(uint8_t reg, uint8_t value)
272
{
273
    wl_module_CSN_lo;
274
    spi_fast_shift(W_REGISTER | (REGISTER_MASK & reg));
275
    spi_fast_shift(value);
276
    wl_module_CSN_hi;
277
}
278
279
/* Read single register from nrf24 */
280
void nrf24_readRegister(uint8_t reg, uint8_t* value, uint8_t len)
281
{
282
    wl_module_CSN_lo;
283
    spi_fast_shift(R_REGISTER | (REGISTER_MASK & reg));
284
    spi_transfer_sync(value,value,len);
285
    wl_module_CSN_hi;
286
}
287
288
/* Write to a single register of nrf24 */
289
void nrf24_writeRegister(uint8_t reg, uint8_t* value, uint8_t len) 
290
{
291
    wl_module_CSN_lo;
292
    spi_fast_shift(W_REGISTER | (REGISTER_MASK & reg));
293
    spi_transmit_sync(value,len);
294
    wl_module_CSN_hi;
295
}