stable library for the Nordic NRF24L01+ radio transciever

Revision:
0:795de307e97f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nrf24l01p.h	Mon Nov 21 19:39:46 2016 +0000
@@ -0,0 +1,538 @@
+/* 
+* 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__
+