stable library for the Nordic NRF24L01+ radio transciever
nrf24l01p.h
- Committer:
- emoninet2
- Date:
- 2016-11-21
- Revision:
- 0:795de307e97f
File content as of revision 0:795de307e97f:
/* * nrf24l01p.h * * Created: 29-Mar-16 10:57:14 PM * Author: emon1 */ #ifndef __NRF24L01P_H__ #define __NRF24L01P_H__ #include "mbed.h" //#include "nrf24l01p_arch_driver.h" #define _nrf24l01p_delay_us wait_us #define _nrf24l01p_delay_ms wait_ms #define set_bit(reg,bit) reg|= (1<<bit) #define clr_bit(reg,bit) reg&= ~(1<<bit) #define tgl_bit(reg,bit) reg^= (1<<bit) #define _NRF24L01P_TX_FIFO_COUNT 3 #define _NRF24L01P_RX_FIFO_COUNT 3 #define _NRF24L01P_TX_FIFO_SIZE 32 #define _NRF24L01P_RX_FIFO_SIZE 32 #define _NRF24L01P_SPI_MAX_DATA_RATE 10000000 #define _NRF24L01P_EN_AA_NONE 0 #define _NRF24L01P_EN_RXADDR_NONE 0 #define _NRF24L01P_SETUP_AW_AW_MASK (0x3<<0) #define _NRF24L01P_MIN_RF_FREQUENCY 2400 #define _NRF24L01P_MAX_RF_FREQUENCY 2525 #define _NRF24L01P_DUMMYBYTE 0x65 /** @name NRF24L01+ commands * These are the commands */ /**@{*/ #define _NRF24L01P_SPI_CMD_RD_REG 0x00 #define _NRF24L01P_SPI_CMD_WR_REG 0x20 #define _NRF24L01P_SPI_CMD_RD_RX_PAYLOAD 0x61 #define _NRF24L01P_SPI_CMD_WR_TX_PAYLOAD 0xa0 #define _NRF24L01P_SPI_CMD_FLUSH_TX 0xe1 #define _NRF24L01P_SPI_CMD_FLUSH_RX 0xe2 #define _NRF24L01P_SPI_CMD_REUSE_TX_PL 0xe3 #define _NRF24L01P_SPI_CMD_R_RX_PL_WID 0x60 #define _NRF24L01P_SPI_CMD_W_ACK_PAYLOAD 0xa8 #define _NRF24L01P_SPI_CMD_W_TX_PYLD_NO_ACK 0xb0 #define _NRF24L01P_SPI_CMD_NOP 0xff /**@}*/ /** @name NRF24L01+ register address * These are the registers */ /**@{*/ #define _NRF24L01P_REG_CONFIG 0x00 #define _NRF24L01P_REG_EN_AA 0x01 #define _NRF24L01P_REG_EN_RXADDR 0x02 #define _NRF24L01P_REG_SETUP_AW 0x03 #define _NRF24L01P_REG_SETUP_RETR 0x04 #define _NRF24L01P_REG_RF_CH 0x05 #define _NRF24L01P_REG_RF_SETUP 0x06 #define _NRF24L01P_REG_STATUS 0x07 #define _NRF24L01P_REG_OBSERVE_TX 0x08 #define _NRF24L01P_REG_RPD 0x09 #define _NRF24L01P_REG_RX_ADDR_P0 0x0a #define _NRF24L01P_REG_RX_ADDR_P1 0x0b #define _NRF24L01P_REG_RX_ADDR_P2 0x0c #define _NRF24L01P_REG_RX_ADDR_P3 0x0d #define _NRF24L01P_REG_RX_ADDR_P4 0x0e #define _NRF24L01P_REG_RX_ADDR_P5 0x0f #define _NRF24L01P_REG_TX_ADDR 0x10 #define _NRF24L01P_REG_RX_PW_P0 0x11 #define _NRF24L01P_REG_RX_PW_P1 0x12 #define _NRF24L01P_REG_RX_PW_P2 0x13 #define _NRF24L01P_REG_RX_PW_P3 0x14 #define _NRF24L01P_REG_RX_PW_P4 0x15 #define _NRF24L01P_REG_RX_PW_P5 0x16 #define _NRF24L01P_REG_FIFO_STATUS 0x17 #define _NRF24L01P_REG_DYNPD 0x1c #define _NRF24L01P_REG_FEATURE 0x1d #define _NRF24L01P_REG_ADDRESS_MASK 0x1f /**@}*/ /** @name NRF24L01+ config address * These are the congig registers */ /**@{*/ #define _NRF24L01P_CONFIG_PRIM_RX (1<<0) #define _NRF24L01P_CONFIG_PWR_UP (1<<1) #define _NRF24L01P_CONFIG_CRC0 (1<<2) #define _NRF24L01P_CONFIG_EN_CRC (1<<3) #define _NRF24L01P_CONFIG_MASK_MAX_RT (1<<4) #define _NRF24L01P_CONFIG_MASK_TX_DS (1<<5) #define _NRF24L01P_CONFIG_MASK_RX_DR (1<<6) #define _NRF24L01P_CONFIG_CRC_MASK (_NRF24L01P_CONFIG_EN_CRC|_NRF24L01P_CONFIG_CRC0) /**@}*/ /** @name NRF24L01+ setup register * These are bits of the setup register */ /**@{*/ #define _NRF24L01P_RF_SETUP_RF_PWR_MASK (0x3<<1) #define _NRF24L01P_RF_SETUP_RF_DR_HIGH_BIT (1 << 3) #define _NRF24L01P_RF_SETUP_RF_DR_LOW_BIT (1 << 5) #define _NRF24L01P_RF_SETUP_RF_DR_MASK (_NRF24L01P_RF_SETUP_RF_DR_LOW_BIT|_NRF24L01P_RF_SETUP_RF_DR_HIGH_BIT) /**@}*/ /** @name NRF24L01+ status register * These are bits of the status register */ /**@{*/ #define _NRF24L01P_STATUS_TX_FULL (1<<0) #define _NRF24L01P_STATUS_RX_P_NO (0x7<<1) #define _NRF24L01P_STATUS_MAX_RT (1<<4) #define _NRF24L01P_STATUS_TX_DS (1<<5) #define _NRF24L01P_STATUS_RX_DR (1<<6) /**@}*/ /** @name NRF24L01+ observe register * These are bits of the observe register */ /**@{*/ #define _NRF24L01P_OBSERVE_TX_ARC_CNT_BP 0 #define _NRF24L01P_OBSERVE_TX_ARC_CNT_MASK 0x0F #define _NRF24L01P_OBSERVE_TX_PLOS_CNT_BP 4 #define _NRF24L01P_OBSERVE_TX_PLOS_CNT_MASK 0xF0 /**@}*/ /** @name NRF24L01+ fifo status register * These are bits of the fifo status register */ /**@{*/ #define _NRF24L01P_FIFO_STATUS_RX_EMPTY (1<<0) #define _NRF24L01P_FIFO_STATUS_RX_FULL (1<<1) #define _NRF24L01P_FIFO_STATUS_TX_EMPTY (1<<4) #define _NRF24L01P_FIFO_STATUS_TX_FULL (1<<5) #define _NRF24L01P_FIFO_STATUS_RX_REUSE (1<<6) /**@}*/ /** @name NRF24L01+ feature register * These are bits of the feature register */ /**@{*/ #define _NRF24L01_FEATURE_EN_DPL (1<<2) #define _NRF24L01_FEATURE_EN_ACK_PAY (1<<1) #define _NRF24L01_FEATURE_EN_DYN_ACK (1<<0) /**@}*/ #define _NRF24L01P_RX_PW_Px_MASK 0x3F /** @name NRF24L01+ config register * These are bits of the config register */ /**@{*/ #define _NRF24L01P_TIMING_PowerOnReset_ms 100 // 100mS #define _NRF24L01P_TIMING_Tundef2pd_us 100000 // 100mS #define _NRF24L01P_TIMING_Tstby2a_us 130 // 130uS #define _NRF24L01P_TIMING_Thce_us 10 // 10uS #define _NRF24L01P_TIMING_Tpd2stby_us 4500 // 4.5mS worst case #define _NRF24L01P_TIMING_Tpece2csn_us 4 // 4uS /**@}*/ /** @name NRF24L01+ default values * These are bits of the default values */ /**@{*/ #define DEFAULT_NRF24L01P_ADDRESS ((unsigned long long) 0xE7E7E7E7E7 ) #define DEFAULT_NRF24L01P_ADDRESS_WIDTH 5 #define DEFAULT_NRF24L01P_CRC NRF24L01P_CRC_8_BIT #define DEFAULT_NRF24L01P_RF_FREQUENCY (NRF24L01P_MIN_RF_FREQUENCY + 2) #define DEFAULT_NRF24L01P_DATARATE NRF24L01P_DATARATE_1_MBPS #define DEFAULT_NRF24L01P_TX_PWR NRF24L01P_TX_PWR_ZERO_DB #define DEFAULT_NRF24L01P_TRANSFER_SIZE 4 /**@}*/ /** * @brief pipe address datatype * data type for the pipe address */ #define pipeAddrType_t uint64_t /** * @brief CRC options * camn be 8 bit or 16 bit CRC */ typedef enum _nrf24l01p_crc_enum{ _NRF24L01P_CONFIG_CRC_NONE = (0), _NRF24L01P_CONFIG_CRC_8BIT = (_NRF24L01P_CONFIG_EN_CRC), _NRF24L01P_CONFIG_CRC_16BIT = (_NRF24L01P_CONFIG_EN_CRC|_NRF24L01P_CONFIG_CRC0), }_nrf24l01p_crc_t; /** * @brief address width options * address width can be 3 , 4 or 5 bytes */ typedef enum _nrf24l01p_aw_enum{ _NRF24L01P_SETUP_AW_AW_3BYTE = (0x1<<0),/**< 3 bytes address width */ _NRF24L01P_SETUP_AW_AW_4BYTE = (0x2<<0),/**< 4 bytes address width */ _NRF24L01P_SETUP_AW_AW_5BYTE = (0x3<<0),/**< 5 bytes address width */ }_nrf24l01p_aw_t; /** * @brief rf power enumeration * antenna power options */ typedef enum _nrf24l01p_RF_power_enum{ _NRF24L01P_RF_SETUP_RF_PWR_0DBM = (0x3<<1), _NRF24L01P_RF_SETUP_RF_PWR_MINUS_6DBM = (0x2<<1), _NRF24L01P_RF_SETUP_RF_PWR_MINUS_12DBM = (0x1<<1), _NRF24L01P_RF_SETUP_RF_PWR_MINUS_18DBM = (0x0<<1), }_nrf24l01p_RFpower_t; /** * @brief data rate enumeration * choose data rate between 250kbps, 1mbps or 2mbps */ typedef enum _nrf24l01p_datarate_enum{ _NRF24L01P_RF_SETUP_RF_DR_250KBPS = (_NRF24L01P_RF_SETUP_RF_DR_LOW_BIT), _NRF24L01P_RF_SETUP_RF_DR_1MBPS = (0), _NRF24L01P_RF_SETUP_RF_DR_2MBPS = (_NRF24L01P_RF_SETUP_RF_DR_HIGH_BIT), }_nrf24l01p_datarate_t; /** * @brief pipe numbers enumeration * these are the available pipe numbers */ typedef enum _nrf24l01p_pipe_enum{ _NRF24L01P_PIPE_P0 = 0,/**< Pipe 0 */ _NRF24L01P_PIPE_P1 = 1,/**< Pipe 1 */ _NRF24L01P_PIPE_P2 = 2,/**< Pipe 2 */ _NRF24L01P_PIPE_P3 = 3,/**< Pipe 3 */ _NRF24L01P_PIPE_P4 = 4,/**< Pipe 4 */ _NRF24L01P_PIPE_P5 = 5,/**< Pipe 5 */ }_nrf24l01p_pipe_t; /** * @brief this is brief enum. * brief enum continued. * * expect detailed enum here. * @note can also have note.wow */ typedef enum { _NRF24L01P_MODE_UNKNOWN,/**< NRF24L01+ unknown mode */ _NRF24L01P_MODE_POWER_DOWN,/**< NRF24L01+ Power Down mode */ _NRF24L01P_MODE_STANDBY,/**< NRF24L01+ Standby mode */ _NRF24L01P_MODE_RX,/**< NRF24L01+ RX mode */ _NRF24L01P_MODE_TX,/**< NRF24L01+ TX mode */ } nRF24L01P_Mode_Type; class nrf24l01p { //variables public: protected: private: SPI spi_; DigitalOut nCS_; DigitalOut ce_; InterruptIn nIRQ_; nRF24L01P_Mode_Type _nrf24l01p_mode;/**< state of the radio */ //functions public: nrf24l01p(); nrf24l01p(PinName mosi, PinName miso, PinName sck, PinName csn, PinName ce, PinName irq = NC); void arch_nrf24l01p_ce_pin(bool state); void arch_nrf24l01p_csn_pin(bool state); void arch_nrf24l01p_initialize(); void arch_spi_master_transcieve(uint8_t *data, int len); /** * @brief CE Pin * this function handles the CE pin value_com * @param state logic high or low */ void ce_pin(bool state); /** * @brief CSN Pin * this function handles the CE pin value_com * @param state logic high or low */ void csn_pin(bool state); /** * @brief Read Registers * this function reads the registers * @param address address of the register to read * @param dataout address of array to read into * @param len number of bytes to read * @return none. */ void read_register(uint8_t address, uint8_t *dataout, int len); /** * @brief Write Registers * this function writes into the registers * @param address address of the register to write into * @param dataout address of array which holds data to write * @param len number of bytes to write * @return none. */ void write_register(uint8_t address, uint8_t *datain, int len); /** * @brief Read RX payload * this function reads the payload from the RX FIFO * @param dataout address of array to read payload data into * @param paylen number of bytes to read from the payload * @return none. */ void read_rx_payload(uint8_t *dataout, int pay_len); /** * @brief Write RX payload * this function writes the payload into TX FIFO * @param datain address of array containing the data to write * @param paylen number of bytes to write into the payload * @return none. */ void write_tx_payload(uint8_t *datain, int pay_len); /** * @brief Flush TX * this function flushes the TX FIFO buffer */ void flush_tx(); /** * @brief Flush RX * this function flushes the TX FIFO buffer */ void flush_rx(); /** * @brief Reuse TX * this function reuses the last data in the TX FIFO * * if the FIFO buffer is not flushed, this command resends the payload * can be used by software when failed to recieve ACK from receiver * saves CPU time since the payload need not be written all over again */ void reuse_tx_payload(); /** * @brief Read payload width * reads the number of byte in the last FIFO payload * * can only be used if dynamic payload is enabled in FEATURE register * @see _nrf24l01p_enable_dynamic_payload() */ int read_rx_payload_width(); /** * @brief write ACK payload * payload data to send along with ack * * this is done prior to recieving data on a pipe. * when an ack payload is written for a specific pipe * and that pipe is enabled and auto ack is enableds as well * on receiving a data on that pipe, it will send this data * on the payload along with an ack. If nothing is written on * this payload, then it will send 0 bytes along with the ack * @param pipe pipe number agains which the ack payload is written * @param datain address of array containing the data to write * @param paylen number of bytes to write into the payload */ void write_ack_payload(_nrf24l01p_pipe_t pipe, uint8_t *datain, int pay_len); /** * @brief write ACK no payload * payload data to send without an ACK * * @param datain address of array containing the data to write * @param paylen number of bytes to write into the payload */ void write_tx_payload_noack(uint8_t *datain, int pay_len); /** * @brief Get Status * reads the status of the NRF24L01+ * @return status of the NRF24L01+ */ int get_status(); /**@}*/ /** * @name NRF24L01+ register control functions */ /**@{*/ void power_up(); void power_down(); void rx_mode(); void tx_mode(); void set_CRC(_nrf24l01p_crc_t opt); void enable_auto_ack(_nrf24l01p_pipe_t pipe); void disable_auto_ack(_nrf24l01p_pipe_t pipe); void disable_auto_ack_all_pipes(); void enable_rx_on_pipe(_nrf24l01p_pipe_t pipe); void disable_rx_on_pipe(_nrf24l01p_pipe_t pipe); void set_address_width(_nrf24l01p_aw_t width); _nrf24l01p_aw_t get_address_width(); void set_auto_retransmission_count(uint8_t count); uint8_t read_auto_retransmission_count(); void set_auto_retransmission_delay(uint8_t times250us); uint8_t read_auto_retransmission_delay(); void set_frequency_offset(uint8_t offset); uint8_t get_frequency_offset(); void set_DataRate(_nrf24l01p_datarate_t DataRate); _nrf24l01p_datarate_t get_DataRate(); void set_RF_Power(_nrf24l01p_RFpower_t RFpower); _nrf24l01p_RFpower_t get_RF_Power(); bool get_tx_fifo_full_flag(); bool get_max_retry_flag(); void clear_max_retry_flag(); bool get_data_sent_flag(); void clear_data_sent_flag(); bool get_data_ready_flag(); void clear_data_ready_flag(); _nrf24l01p_pipe_t get_rx_payload_pipe(); uint8_t get_arc_count(); uint8_t get_plos_count(); void clear_plos_count(); bool get_rpd(); void set_RX_pipe_address(_nrf24l01p_pipe_t pipe,pipeAddrType_t address); pipeAddrType_t get_RX_pipe_address(_nrf24l01p_pipe_t pipe); void set_TX_pipe_address(pipeAddrType_t address); pipeAddrType_t get_TX_pipe_address(); uint8_t get_RX_pipe_width(_nrf24l01p_pipe_t pipe); bool get_fifo_flag_rx_empty(); bool get_fifo_flag_rx_full(); bool get_fifo_flag_tx_empty(); bool get_fifo_flag_tx_full(); bool get_fifo_flag_tx_reuse(); void enable_dynamic_payload_pipe(_nrf24l01p_pipe_t pipe); void disable_dynamic_payload_pipe(_nrf24l01p_pipe_t pipe); void disable_dynamic_payload_all_pipe(); void enable_dynamic_payload(); void disable_dynamic_payload(); void enable_payload_with_ack(); void disable_payload_with_ack(); void enable_dynamic_payload_with_ack(); void disable_dynamic_payload_with_ack(); /**@}*/ /** * @brief Initialize * hardware initialization of the NRF24L01+ */ void init(); int startup(); int default_config(); int stateMode(nRF24L01P_Mode_Type mode); bool readable(); bool writable(); int send(uint8_t *data, int datalen); int send_to_address(pipeAddrType_t address, uint8_t *data, int datalen); int send_to_address_ack(pipeAddrType_t address, uint8_t *data, int datalen); bool readableOnPipe(_nrf24l01p_pipe_t pipe); int read(_nrf24l01p_pipe_t pipe, uint8_t *data, int datalen); int read_dyn_pld(_nrf24l01p_pipe_t pipe, uint8_t *data); void write_ack(_nrf24l01p_pipe_t pipe, uint8_t *data, int datalen); void PTX(); void PRX(); /**@}*/ ~nrf24l01p(); protected: private: nrf24l01p( const nrf24l01p &c ); nrf24l01p& operator=( const nrf24l01p &c ); }; //nrf24l01p #endif //__NRF24L01P_H__