nRF24L01 driver
Dependents: Nucleo_IOT1 wireless
nRF24L01P.h@6:952996e3abdb, 2016-09-14 (annotated)
- 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?
User | Revision | Line number | New 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 |