Per Söderstam / Mbed 2 deprecated driver_nRF2401A

Dependencies:   mbed

nRF2401A.h

Committer:
persoder
Date:
2013-07-08
Revision:
1:d40d911b763a
Parent:
0:3fe71769ad07

File content as of revision 1:d40d911b763a:

/** \file
 * \brief
 *
 * \author Per Söderstam © 2011, 2012
 */

#include <mbed.h>
#include <inttypes.h>

/** ISR handler prototype for receiving messages.
 * A function of this type is registered and called when the DR pin on the
 * nRF tranciever signals the reception of a message. The void * argument
 * is likewise supplied when registering and is returned at call time.
 */
typedef void (*nRF2401A_rx_handler_t)(void *);

/**
 *
 *
 */
class nRF2401A
{
    public:
        /** Class constructor.
         * The constructor assigns the specified pinout, attatch the
         * DR1 to a pin interrupt and sets up inmutable control packet
         * fields.
         * \param ce Chip Enable (CE) pin of the nRF2401A.
         * \param c2 Chip Select (CS) pin of the nRF2401A.
         * \param dr1 Data Ready 1 (DR1) pin of the nRF2401A.
         * \param clk1 Clock 1 (CLK1) pin of the nRF2401A.
         * \param data Data (DATA) pin of the nRF2401A.
         */
        nRF2401A(PinName ce,
                 PinName cs,
                 PinName dr1,
                 PinName clk1,
                 PinName data);
                 
        /** Class destructor.
         * Pretty much useless in the embedded world...
         */
        virtual ~nRF2401A() { return; }
        
        /** Set the payload length, in bits.
         * Set the control packet field for length, in number of bits, of the message payload.
         * \param n Number of bits of the message payload.
         * \return Reference to the invoked object (for chaining operations).
         */
        nRF2401A& setDataPayloadLength(uint8_t n) 
        { 
            _ctrl_packet_buf.channel_1_data_payload_len = n; 
            return *this; 
        }
        
        /** Set the address of channel 1.
         * The channel address is a up to 40 bit number identifying the tranciever.
         * \param addr4 Bits 39-32 of the address.
         * \param addr4 Bits 31-24 of the address.
         * \param addr4 Bits 23-16 of the address.
         * \param addr4 Bits 15-8 of the address.
         * \param addr4 Bits 7-0 of the address.
         * \param n_bits Number of bits used in the address.
         * \return Reference to the invoked object (for chaining operations).
         */
        nRF2401A& setAddress(uint8_t addr4, uint8_t addr3, uint8_t addr2, uint8_t addr1, uint8_t addr0, uint8_t n_bits)
        {
            _ctrl_packet_buf.channel_1_address[0] = addr4;
            _ctrl_packet_buf.channel_1_address[1] = addr3;
            _ctrl_packet_buf.channel_1_address[2] = addr2;
            _ctrl_packet_buf.channel_1_address[3] = addr1;
            _ctrl_packet_buf.channel_1_address[4] = addr0;
            _ctrl_packet_buf.channel_address_len = n_bits;
            
            return *this;
        }
        
        /** CRC settings.
         * Type covering the allowed settings for use of CRC.
         */
        typedef enum 
        {
            NO_CRC = 0x0,   /**< Do not use CRC. */
            CRC_8 = 0x1,    /**< Use a 8-bit CRC. */
            CRC_16 = 0x3    /**< Use a 16-bit CRC. */
        } CRC_T;
        
        /** Set CRC use.
         * Set the CRC mode field of the control packet.
         * \param mode The CRC mode of choise.
         * \return Reference to the invoked object (for chaining operations).
         */
        nRF2401A& setCRCMode(CRC_T mode) 
        { 
            _ctrl_packet_buf.crc_config = mode; 
            return *this; 
        }
        
        /** Data rate settings.
         * Type covering the allowed settings for the tranciever data rate.
         */
        typedef enum
        {
            BIT_RATE_250KBITS = 0x0,    /**< */
            BIT_RATE_1MBITS = 0x1       /**< */
        } DATA_RATE_T;
        
        /** Set tranciever data rate.
         * Sets the data rate field to either 250 kbit/s or 1 Mbit/s data transfer rate.
         * \param mode The data rate of choise.
         * \return Reference to the invoked object (for chaining operations).
         */
        nRF2401A& setDataRate(DATA_RATE_T data_rate)
        {
            _ctrl_packet_buf.rf_data_rate = data_rate;
            return *this;
        }
        
        /** Set RF channel.
         * Sets the control packet field for channel number. Channel numbers are from 0 to 127
         * representing channel frequencies equal to (2400 + channel number) MHz.
         * \param ch Channel number, from the range [0, 127].
         * \return Reference to the invoked object (for chaining operations).
         */
        nRF2401A& setChannel(uint8_t ch)
        {
            _ctrl_packet_buf.rf_channel = ch;
            return *this;
        }
        
        /** Send the control packet to the nRF2401A.
         * This function transfer the control packet image to the nRF2401A.
         * \return Reference to the invoked object (for chaining operations).
         */
        nRF2401A& flushControlPacket();
        
        /**
         *
         */
        void activate(bool active = true);
        
        /**
         *
         */
        typedef uint8_t address_t[5];
        
        /** Send a message.
         * This routine will transfer the data from the supplied buffer and send
         * it to the specified address using the current control packet settings.
         * \param addr The address to send to.
         * \param addr_len Length of address, in bits.
         * \param msg_buf Message body.
         * \param msg_len Length of message,  in bits.
         * \return Reference to the invoked object (for chaining operations).
         */
        nRF2401A& sendMsg(address_t addr, uint8_t addr_len, uint8_t *msg_buf, uint8_t msg_len);
        
        /** Register a receive action callback.
         * Attach a callback that will be called when the tranciever intercept a
         * message. This callback will be called in the context of an interrupt
         * routine and should act accordingly.
         * \param handler The callback, of type nRF2401_rx_handler_t.
         * \param arg Pointer to data supplied to the handler at call time.
         * \return Reference to the invoked object (for chaining operations).
         */     
        nRF2401A& attachRXHandler(nRF2401A_rx_handler_t handler, void *arg);
        
        void printControlPacket(Serial& port);
        void printDataPacket(Serial& port);
        
    private:
    
        DigitalOut      _ce;    /**< Chip Enable pin. */
        DigitalOut      _cs;    /**< Chip select pin. */
        DigitalIn       _dr1;   /**< Data Ready 1 pin. */
        DigitalOut      _clk1;  /**< Clock 1 pin. */
        DigitalInOut    _data;  /**< Data pin. */
        
        /**
         *
         */
        typedef enum 
        { 
            UNDEF,      /**< The start state. */
            RX,         /**< The tranciever is in receive mode. */
            TX,         /**< The tranciever is transmitting. */
            STANDBY     /**< The tranciever goes into stanby mode. */
        } STATE_T;
        
        STATE_T  _state;
        
        /** Contol packet data.
         *
         */
        struct nRF2401A_ctrl_packet_t
        {
            uint8_t     channel_2_data_payload_len;     /**< */
            uint8_t     channel_1_data_payload_len;     /**< */
            uint8_t     channel_2_address[5];           /**< */
            uint8_t     channel_1_address[5];           /**< */
            
            uint8_t     crc_config : 2;                 /**< */
            uint8_t     channel_address_len : 6;        /**< */
            
            uint8_t     rf_power : 2;                   /**< */
            uint8_t     xo_frequency : 3;               /**< */
            uint8_t     rf_data_rate : 1;               /**< */
            uint8_t     communication_mode : 1;         /**< */
            uint8_t     enable_dual_channel_mode : 1;   /**< */
            
            uint8_t     txr_switch : 1;                 /**< */
            uint8_t     rf_channel : 7;                 /**< */
            
        }                                       _ctrl_packet_buf;   /**< */
        
        uint8_t         *_ctrl_packet;  /**< */
        
        uint8_t         _data_buf[32];  /**< */        
        
        nRF2401A_rx_handler_t   _rx_handler;        /**< */
        void                    *_rx_handler_arg;   /**< */
        
        /** Receive ISR.
         * This handler is attached to the rising flank of the DR1 pin. It
         * will thus be called when the nRF2401A receives a packet in ShockBurst
         * mode (the mode used). It will in turn call the attached handler.
         */
        void dataReadyHandler(void);
        
        /**
         *
         */
        InterruptIn     _dr1_isr;
        
        /*
         *
         */
        typedef enum { RX_MODE = 0x1, TX_MODE = 0x0 } TXR_T;
        
        /** Write to the data bus.
         * Write n_bits bits on the DATA line.
         * \param buf Data buffer.
         * \param n_bits Number of bits to transfer.
         * \param is_ctrl True if the tranfered data is control word, false if data.
         */
        void pushCtrl(uint8_t *buf, uint8_t n_bits, bool is_ctrl = true);
        
        /** Read a message from the tranciever.
         * Read until DR1 goes low.
         * \param buf Data buffer.
         * \return Number of bits read.
         */
        int pull(uint8_t *buf);
};