nRF24L01 driver

Dependents:   Nucleo_IOT1 wireless

Committer:
ianmcc
Date:
Wed Sep 14 14:43:13 2016 +0000
Revision:
6:952996e3abdb
Parent:
4:8f612189af31
bug fixes

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ianmcc 0:7313e63394c3 1 //
ianmcc 0:7313e63394c3 2 // Interface for Nordic Semiconductor nRF24L01 and nRF24L01+
ianmcc 0:7313e63394c3 3 // see http://www.nordicsemi.no/files/Product/data_sheet/nRF24L01P_Product_Specification_1_0.pdf
ianmcc 0:7313e63394c3 4 //
ianmcc 0:7313e63394c3 5 // This class exposes basic SPI functionality for the nRF24L01+
ianmcc 0:7313e63394c3 6 // A driver program is required to actually send or receive data.
ianmcc 0:7313e63394c3 7 // This class doesn't provide any CE line control
ianmcc 0:7313e63394c3 8 //
ianmcc 0:7313e63394c3 9 // Differences between nRF24L01 and nRF24L01+
ianmcc 0:7313e63394c3 10 // 1. The nRF24L01 doesn't support 250kHz air data rate
ianmcc 0:7313e63394c3 11 // 2. The nRF24L01 received_power_detector() works differently
ianmcc 0:7313e63394c3 12 //
ianmcc 0:7313e63394c3 13
ianmcc 0:7313e63394c3 14 #ifndef NRF24L01P_H
ianmcc 0:7313e63394c3 15 #define NRF24L01P_H
ianmcc 0:7313e63394c3 16
ianmcc 0:7313e63394c3 17 #include "mbed.h"
ianmcc 0:7313e63394c3 18 #include <stdint.h>
ianmcc 0:7313e63394c3 19
ianmcc 0:7313e63394c3 20 #define NRF24L01P_MIN_RF_FREQUENCY 2400
ianmcc 0:7313e63394c3 21 #define NRF24L01P_MAX_RF_FREQUENCY 2525
ianmcc 0:7313e63394c3 22
ianmcc 0:7313e63394c3 23 // timing constants
ianmcc 0:7313e63394c3 24 #define Tundef2pd_us 100000 // 100mS, time from reset to power-down mode
ianmcc 0:7313e63394c3 25 #define Tstby2a_us 130 // 130uS, time from standby mode to TX/RX mode
ianmcc 0:7313e63394c3 26 #define Thce_us 10 // 10uS, minimum time for CE high
ianmcc 0:7313e63394c3 27 #define Tpd2stby_us 4500 // 4.5mS worst case, time from power-down to standby
ianmcc 0:7313e63394c3 28 #define Tpece2csn_us 4 // 4uS, delay from CE positive edge to CSN low
ianmcc 0:7313e63394c3 29
ianmcc 0:7313e63394c3 30 class nRF24L01P
ianmcc 0:7313e63394c3 31 {
ianmcc 0:7313e63394c3 32 public:
ianmcc 0:7313e63394c3 33 nRF24L01P(PinName mosi, PinName miso, PinName sck, PinName csn, long SPIFrequency = 2000000);
ianmcc 0:7313e63394c3 34
ianmcc 0:7313e63394c3 35 // Clears the TX and RX FIFOs and resets all registers to their power-on values
ianmcc 0:7313e63394c3 36 void reset();
ianmcc 0:7313e63394c3 37
ianmcc 0:7313e63394c3 38 // change the SPI frequency
ianmcc 0:7313e63394c3 39 void set_spi_frequency(long Freq);
ianmcc 0:7313e63394c3 40
ianmcc 0:7313e63394c3 41 // register operations
ianmcc 0:7313e63394c3 42
ianmcc 0:7313e63394c3 43 // set the data rate in kb/s, valid values are 250 (nRF24L01+ only), 1000, 2000.
ianmcc 0:7313e63394c3 44 // DEFAULT:
ianmcc 0:7313e63394c3 45 void set_air_data_rate(int Rate);
ianmcc 0:7313e63394c3 46
ianmcc 0:7313e63394c3 47 // set the RF channel, 0 .. 125.
ianmcc 0:7313e63394c3 48 // The frequency in MHz is 2400 + Channel.
ianmcc 0:7313e63394c3 49 // In 2Mbps mode, you must use channels at least 2MHz appart to avoid overlap
ianmcc 4:8f612189af31 50 // DEFAULT: channel 2
ianmcc 0:7313e63394c3 51 void set_channel(int Channel);
ianmcc 0:7313e63394c3 52
ianmcc 0:7313e63394c3 53 // PRECONDITION: Mode = Receive. True if a signal higher than -64bB is detected by the receiver
ianmcc 0:7313e63394c3 54 bool received_power_detector();
ianmcc 0:7313e63394c3 55
ianmcc 0:7313e63394c3 56 // set the transmit power in dB. Valid values are 0, -6, -12, -18
ianmcc 6:952996e3abdb 57 // DEFAULT: 0dB
ianmcc 0:7313e63394c3 58 void set_tx_power(int Power);
ianmcc 0:7313e63394c3 59
ianmcc 0:7313e63394c3 60
ianmcc 0:7313e63394c3 61 // enable or disable dynamic payload size on the given pipe
ianmcc 4:8f612189af31 62 // DEFAULT: false
ianmcc 0:7313e63394c3 63 void enable_dynamic_payload(int Pipe, bool Enable);
ianmcc 0:7313e63394c3 64
ianmcc 0:7313e63394c3 65 // Enable including a payload with ACK
ianmcc 4:8f612189af31 66 // DEFAULT: false
ianmcc 0:7313e63394c3 67 void enable_ack_payload(bool Enable);
ianmcc 0:7313e63394c3 68
ianmcc 0:7313e63394c3 69 // enable the write_tx_payload_no_ack() command
ianmcc 0:7313e63394c3 70 // DEFAULT: disabled
ianmcc 0:7313e63394c3 71 void enable_no_ack(bool Enable);
ianmcc 0:7313e63394c3 72
ianmcc 0:7313e63394c3 73 //
ianmcc 0:7313e63394c3 74 // receive functionality
ianmcc 0:7313e63394c3 75 //
ianmcc 0:7313e63394c3 76
ianmcc 0:7313e63394c3 77 // set the width in bytes for addresses. Valid values are 3,4,5
ianmcc 0:7313e63394c3 78 // DEFAULT: 5
ianmcc 0:7313e63394c3 79 void set_address_width(int Width);
ianmcc 0:7313e63394c3 80
ianmcc 0:7313e63394c3 81 // returns the width in bytes for addresses. Valid values are 3,4,5
ianmcc 0:7313e63394c3 82 int get_address_width();
ianmcc 0:7313e63394c3 83
ianmcc 0:7313e63394c3 84 // set the receive address of the given pipe. Pipes 0,1 have 3,4 or 5 byte addresses
ianmcc 0:7313e63394c3 85 // as specified by set_address_width(). Pipes 2,3,4,5 can only set the low order byte of the
ianmcc 0:7313e63394c3 86 // address, the other bytes are shared with pipe 1.
ianmcc 0:7313e63394c3 87
ianmcc 0:7313e63394c3 88 // Set the rx address for pipe 0 or 1
ianmcc 0:7313e63394c3 89 void set_rx_address(int Pipe, uint64_t Address);
ianmcc 0:7313e63394c3 90
ianmcc 0:7313e63394c3 91 // Set the low byte of the address for pipe 2,3,4,5
ianmcc 0:7313e63394c3 92 void set_rx_address_low(int Pipe, uint8_t Address);
ianmcc 0:7313e63394c3 93
ianmcc 0:7313e63394c3 94 // Set the payload size for the receive buffer for the given pipe
ianmcc 0:7313e63394c3 95 // (not used if dynamic payload size is used)
ianmcc 0:7313e63394c3 96 void set_rx_payload_bytes(int Pipe, int Bytes);
ianmcc 0:7313e63394c3 97
ianmcc 0:7313e63394c3 98 // returns true if the receive FIFO is full
ianmcc 0:7313e63394c3 99 bool is_rx_full();
ianmcc 0:7313e63394c3 100
ianmcc 0:7313e63394c3 101 // returns true if the receive FIFO is empty
ianmcc 0:7313e63394c3 102 bool is_rx_empty();
ianmcc 0:7313e63394c3 103
ianmcc 0:7313e63394c3 104 // receive packet status
ianmcc 0:7313e63394c3 105
ianmcc 0:7313e63394c3 106 // read the status register and return true if there is a packet ready to be received (RX_DR)
ianmcc 0:7313e63394c3 107 bool is_rx_ready();
ianmcc 0:7313e63394c3 108
ianmcc 0:7313e63394c3 109 // clear the RX_DR bit
ianmcc 0:7313e63394c3 110 void clear_rx_ready();
ianmcc 0:7313e63394c3 111
ianmcc 0:7313e63394c3 112 // if Enable, reflect RX_DR as active low on the INT line. The procedure to read a packet is:
ianmcc 0:7313e63394c3 113 // 1) Read payload through SPI, 2) clear_rc_ready(), read is_rx_ready() to see if there is another
ianmcc 0:7313e63394c3 114 // packet waiting
ianmcc 0:7313e63394c3 115 // DEFAULT: enabled
ianmcc 0:7313e63394c3 116 void set_interrupt_rx_ready(bool Enable);
ianmcc 0:7313e63394c3 117
ianmcc 0:7313e63394c3 118 // returns true if the transmit FIFO is full
ianmcc 0:7313e63394c3 119 bool is_tx_full();
ianmcc 0:7313e63394c3 120
ianmcc 0:7313e63394c3 121 // returns true if the transmit FIFO is empty
ianmcc 0:7313e63394c3 122 bool is_tx_empty();
ianmcc 0:7313e63394c3 123
ianmcc 0:7313e63394c3 124 // transmit packet status
ianmcc 0:7313e63394c3 125
ianmcc 0:7313e63394c3 126 // reads the status register and returns true if a packet has been transmitted. (TX_DS) If auto-acknowledge
ianmcc 0:7313e63394c3 127 // is set, then this is only asserted when an ack is received.
ianmcc 0:7313e63394c3 128 bool is_tx_sent();
ianmcc 0:7313e63394c3 129
ianmcc 0:7313e63394c3 130 // Clear the TX_DS bit
ianmcc 0:7313e63394c3 131 void clear_tx_sent();
ianmcc 0:7313e63394c3 132
ianmcc 0:7313e63394c3 133 // if Enable, reflect TX_DS as active low on the INT line
ianmcc 0:7313e63394c3 134 // DEFAULT: enabled
ianmcc 0:7313e63394c3 135 void set_interrupt_tx(bool Enable);
ianmcc 0:7313e63394c3 136
ianmcc 0:7313e63394c3 137 // retransmit behaviour
ianmcc 0:7313e63394c3 138
ianmcc 0:7313e63394c3 139 // set the auto-retransmit delay, in units of 250 microseconds.
ianmcc 0:7313e63394c3 140 // Valid input is 0,1,...,15 (for 250 .. 4000 us)
ianmcc 4:8f612189af31 141 // DEFAULT: 0 (250us)
ianmcc 0:7313e63394c3 142 void set_retransmit_delay(int Delay);
ianmcc 0:7313e63394c3 143
ianmcc 0:7313e63394c3 144 // set the number of auto-retransmit attempts, 0 .. 15
ianmcc 4:8f612189af31 145 // DEFAULT: 3
ianmcc 0:7313e63394c3 146 void set_retransmit_attempts(int Attempts);
ianmcc 0:7313e63394c3 147
ianmcc 0:7313e63394c3 148 // returns true if we've hit the maximum number of restransmits
ianmcc 0:7313e63394c3 149 bool is_max_rt();
ianmcc 0:7313e63394c3 150
ianmcc 0:7313e63394c3 151 // clear the maximum number of retransmits flag.
ianmcc 0:7313e63394c3 152 void clear_max_rt();
ianmcc 0:7313e63394c3 153
ianmcc 0:7313e63394c3 154 // if Enable, reflect MAX_RT as active low on the INT line
ianmcc 0:7313e63394c3 155 // DEFAULT: enabled
ianmcc 0:7313e63394c3 156 void set_interrupt_max_rt(bool Enable);
ianmcc 0:7313e63394c3 157
ianmcc 0:7313e63394c3 158 // enable or disable the CRC check. Auto-acknowledge forces CRC enabled.
ianmcc 4:8f612189af31 159 // DEFAULT: true
ianmcc 0:7313e63394c3 160 void enable_crc(bool Enable);
ianmcc 0:7313e63394c3 161
ianmcc 0:7313e63394c3 162 // set the CRC width, either 1 byte or 2 bytes
ianmcc 4:8f612189af31 163 // DEFAULT: 1 byte
ianmcc 0:7313e63394c3 164 void set_crc_width(int width);
ianmcc 0:7313e63394c3 165
ianmcc 0:7313e63394c3 166 // set PWR_UP (move into standby mode)
ianmcc 0:7313e63394c3 167 void set_power_up();
ianmcc 0:7313e63394c3 168
ianmcc 0:7313e63394c3 169 // turn off power (PWR_UP=0)
ianmcc 0:7313e63394c3 170 void set_power_down();
ianmcc 0:7313e63394c3 171
ianmcc 0:7313e63394c3 172 // set as primary receiver (disables transmit mode)
ianmcc 0:7313e63394c3 173 void set_prx_mode();
ianmcc 0:7313e63394c3 174
ianmcc 0:7313e63394c3 175 // set as primary transmitter (disables receive mode)
ianmcc 0:7313e63394c3 176 void set_ptx_mode();
ianmcc 0:7313e63394c3 177
ianmcc 0:7313e63394c3 178 // Enable or disable receiving on the given pipe
ianmcc 0:7313e63394c3 179 // DEFAULT: Pipes 0,1 enabled, pipes 2,3,4,5 disabled.
ianmcc 0:7313e63394c3 180 void enable_rx_pipe(int Pipe, bool Enable);
ianmcc 0:7313e63394c3 181
ianmcc 0:7313e63394c3 182 // Enable or disable auto-acknowledge on the given pipe 0,1,2,3,4,5
ianmcc 0:7313e63394c3 183 // DEFAULT: Enabled on all pipes
ianmcc 0:7313e63394c3 184 void set_auto_acknowledge(int Pipe, bool Enable);
ianmcc 0:7313e63394c3 185
ianmcc 0:7313e63394c3 186 // returns the pipe number for the payload available on the rx pipe, or -1 if the rx fifo is empty
ianmcc 0:7313e63394c3 187 int which_rx_pipe();
ianmcc 0:7313e63394c3 188
ianmcc 0:7313e63394c3 189 // returns true if the transmit fifo is full
ianmcc 0:7313e63394c3 190 bool tx_full();
ianmcc 0:7313e63394c3 191
ianmcc 0:7313e63394c3 192 // returns the number of transmitted but lost packets. Capped at 15, reset by writing the channel number.
ianmcc 0:7313e63394c3 193 int num_lost_packets();
ianmcc 0:7313e63394c3 194
ianmcc 0:7313e63394c3 195 // returns the number of times the current packet has been retransmitted. Reset when a new packet starts
ianmcc 0:7313e63394c3 196 int num_retransmitted_packets();
ianmcc 0:7313e63394c3 197
ianmcc 0:7313e63394c3 198
ianmcc 0:7313e63394c3 199 // Set the tx address. Used only for a PTX, set this the same as the rx_address of pipe 0 to enable
ianmcc 0:7313e63394c3 200 // auto-acknowledge with Enhanced ShockBurst(TM)
ianmcc 4:8f612189af31 201 // DEFAULT: 0xE7E7E7E7E
ianmcc 0:7313e63394c3 202 void set_tx_address(uint64_t Address);
ianmcc 0:7313e63394c3 203
ianmcc 0:7313e63394c3 204 // commands
ianmcc 0:7313e63394c3 205
ianmcc 0:7313e63394c3 206 // read a byte from the given register
ianmcc 0:7313e63394c3 207 int read_register(int Register);
ianmcc 0:7313e63394c3 208
ianmcc 0:7313e63394c3 209 // read n bytes from the given register
ianmcc 0:7313e63394c3 210 int read_register_n(int Register, char* Buf, int Bytes);
ianmcc 0:7313e63394c3 211
ianmcc 0:7313e63394c3 212 // write one byte to the given register
ianmcc 0:7313e63394c3 213 int write_register(int Register, char x);
ianmcc 0:7313e63394c3 214
ianmcc 0:7313e63394c3 215 // write two bytes to a register
ianmcc 0:7313e63394c3 216 int write_register_16(int Register, uint16_t x);
ianmcc 0:7313e63394c3 217
ianmcc 0:7313e63394c3 218 // write five bytes to a register
ianmcc 0:7313e63394c3 219 int64_t write_register_40(int Register, uint64_t x);
ianmcc 0:7313e63394c3 220
ianmcc 0:7313e63394c3 221 // write some bytes to the given register
ianmcc 0:7313e63394c3 222 int write_register_bytes(int Register, char const* Buf, int Bytes);
ianmcc 0:7313e63394c3 223
ianmcc 0:7313e63394c3 224 // Write a transmit payload, 1-32 bytes
ianmcc 0:7313e63394c3 225 void write_tx_payload(char const* Buf, int Bytes);
ianmcc 0:7313e63394c3 226
ianmcc 0:7313e63394c3 227 // Write a transmit payload, 1-32 bytes, with ACK disabled.
ianmcc 0:7313e63394c3 228 // NOTE: enable_no_ack() must be enabled
ianmcc 0:7313e63394c3 229 void write_tx_payload_no_ack(char const* Buf, int Bytes);
ianmcc 0:7313e63394c3 230
ianmcc 0:7313e63394c3 231 // flush the transmit FIFO
ianmcc 0:7313e63394c3 232 void flush_tx_fifo();
ianmcc 0:7313e63394c3 233
ianmcc 0:7313e63394c3 234 // reuse the last transmitted payload. Payload reuse is activated until the next flush_tx_fifo() or write_tx_payload()
ianmcc 0:7313e63394c3 235 void reuse_tx_payload();
ianmcc 0:7313e63394c3 236
ianmcc 0:7313e63394c3 237 // returns the width of the receive payload. (If this isn't in the range 0..32 then the rx fifo should be flushed)
ianmcc 0:7313e63394c3 238 int rx_payload_width();
ianmcc 0:7313e63394c3 239
ianmcc 0:7313e63394c3 240 // read 1-32 bytes from the RX FIFO. The payload is deleted after it is read. The user must
ianmcc 0:7313e63394c3 241 // know how many bytes to read.
ianmcc 0:7313e63394c3 242 void read_rx_payload(char* Buf, int Bytes);
ianmcc 0:7313e63394c3 243
ianmcc 0:7313e63394c3 244 // this version reads the complete payload into Buf, and returns the number of bytes in the payload
ianmcc 0:7313e63394c3 245 int read_rx_payload(char* Buf);
ianmcc 0:7313e63394c3 246
ianmcc 0:7313e63394c3 247 // flush the receive FIFO
ianmcc 0:7313e63394c3 248 void flush_rx_fifo();
ianmcc 0:7313e63394c3 249
ianmcc 0:7313e63394c3 250 // set the ACK payload for the given pipe.
ianmcc 0:7313e63394c3 251 void write_ack_payload(int Pipe, char const* Buf, int Bytes);
ianmcc 0:7313e63394c3 252
ianmcc 0:7313e63394c3 253
ianmcc 0:7313e63394c3 254 private:
ianmcc 0:7313e63394c3 255 SPI Spi;
ianmcc 0:7313e63394c3 256 DigitalOut NCS;
ianmcc 0:7313e63394c3 257 };
ianmcc 0:7313e63394c3 258
ianmcc 0:7313e63394c3 259 #endif
ianmcc 0:7313e63394c3 260