Library for the nRF2401A Transceiver

Dependents:   nRF2401A_Hello_World nRF2401A_Wireless_Accelerometer_joypad nRF2401A_Gameduino_Invaders

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers nRF2401A.h Source File

nRF2401A.h

Go to the documentation of this file.
00001 /** 
00002  *@section DESCRIPTION
00003  * mbed nRF2401A  Library
00004  *@section LICENSE
00005  * Copyright (c) 2011, Per Söderstam
00006  *
00007  * Permission is hereby granted, free of charge, to any person obtaining a copy
00008  * of this software and associated documentation files (the "Software"), to deal
00009  * in the Software without restriction, including without limitation the rights
00010  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00011  * copies of the Software, and to permit persons to whom the Software is
00012  * furnished to do so, subject to the following conditions:
00013  *
00014  * The above copyright notice and this permission notice shall be included in
00015  * all copies or substantial portions of the Software.
00016  *
00017  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00018  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00019  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00020  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00021  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00022  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00023  * THE SOFTWARE.
00024  * @file "nRF2401A.h"
00025  */
00026  
00027 #ifndef _nRF2401A_H
00028 #define _nRF2401A_H
00029 
00030 #include <mbed.h>
00031 #include <inttypes.h>
00032 
00033 #define DATA_BUFFER_SIZE 32
00034 
00035 
00036 /** ISR handler prototype for receiving messages.
00037  * A function of this type is registered and called when the DR pin on the
00038  * nRF tranciever signals the reception of a message. The void * argument
00039  * is likewise supplied when registering and is returned at call time.
00040  */
00041 typedef void (*nRF2401A_rx_handler_t)(void *);
00042 
00043 /** nRF2401 Class 
00044  *
00045  *  A class supporting the nRF2401A nordic 2.4Ghz transciever
00046  * Supports shock burts mode only.
00047  * multi channel mode is not supported as it is not on the breakout header.
00048  *
00049  * Example:
00050  * @code
00051  * #include "mbed.h"
00052  * #include "nRF2401A.h"
00053  * 
00054  * // comment these out depending on the job of the mbed. If your only using one mbed leave both uncommented. 
00055  * 
00056  * #define TX
00057  * #define RX
00058  * 
00059  * // If using the FRDM-KL25Z uncomment this line 
00060  * //#define FRDMKL25Z
00061  * 
00062  * Serial pc(USBTX, USBRX);
00063  * DigitalOut  myled(LED1);
00064  * 
00065  * #ifdef TX
00066  * #ifdef FRDMKL25Z
00067  * nRF2401A    rf1(PTD0, PTD5, PTA13, PTC12, PTC13); //ce, cs, dr1, clk1, data
00068  * #else
00069  * nRF2401A    rf1(p10, p11, p12, p13, p14);
00070  * #endif
00071  * #endif
00072  * 
00073  * #ifdef RX
00074  * #ifdef FRDMKL25Z
00075  * nRF2401A    rf2(PTD0, PTD5, PTA13, PTC12, PTC13);
00076  * #else
00077  * nRF2401A    rf2(p25, p24, p23, p22, p21);
00078  * #endif
00079  * 
00080  * bool rx_recieved = false;
00081  * 
00082  * void nRF2401A_rx (void *arg) 
00083  * {
00084  *      rx_recieved = true;
00085  * }
00086  * #endif
00087  * int main() 
00088  * {
00089  *     wait(0.005);
00090  *     pc.printf("Hello nRF2401A\n\r");
00091  *     
00092  * #ifdef TX  
00093  *     // initialise the nRF2401A with payload size and address 
00094  *     rf1.setAddress(0x0, 0x0, 0xa6, 0xa6, 0xa6, 3 << 3);
00095  *     
00096  *     rf1.printControlPacket(pc);
00097  *     rf1.flushControlPacket();
00098  *     
00099  *     // initialise variables to use for tranmission 
00100  *     nRF2401A::address_t rf2_addr = {0x0, 0x0, 0x53, 0x53, 0x53};
00101  *     uint8_t msg[] = {0x01, 0x01, 0x01, 0x01};
00102  *     uint32_t *msg32 = (uint32_t *) msg;
00103  * #endif
00104  * 
00105  * #ifdef RX   
00106  *     // initialise the nRF2401A with payload size and address  
00107  *     rf2.setAddress(0x0, 0x0, 0x53, 0x53, 0x53, 3 << 3);
00108  *        
00109  *     rf2.printControlPacket(pc);
00110  *     rf2.flushControlPacket();   
00111  *     
00112  *     // attach receive callback 
00113  *     rf2.attachRXHandler(&nRF2401A_rx, 0);
00114  * #endif
00115  *       
00116  *     while(1) 
00117  *     {
00118  *     
00119  * #ifdef TX  
00120  *         myled = 0;
00121  *         wait(0.25);  
00122  *         
00123  *         // send the message to the nRF2401A 
00124  *         rf1.sendMsg(rf2_addr, 3 << 3, msg, 4 << 3);
00125  *         *msg32 += 1;
00126  *         
00127  *         myled = 1;
00128  *         wait(0.25);
00129  * #endif
00130  * 
00131  *         
00132  * #ifdef RX  
00133  *         if (rx_recieved)
00134  *         {      
00135  *             // send the read buffer directly to the serial port 
00136  *             rf2.printDataPacket(pc);
00137  *             
00138  *             // send a single byte from the read buffer to the serial port 
00139  *             uint8_t rx_msg = 0;
00140  *             rx_msg = rf2.readMsg_byte( 0 );
00141  *             pc.printf("\n\r%d\n\r", rx_msg);
00142  *             
00143  *             // read the read buffer , then send to the serial port 
00144  *             uint8_t rx_buffer[32] = {0};
00145  *             rf2.readMsg( &rx_buffer[0], 32);
00146  *             for(int i = 0; i < sizeof(rx_buffer); i++)
00147  *             {
00148  *                 pc.printf("%02x ", rx_buffer[i]);
00149  *             }
00150  *             pc.printf("\r\n");
00151  *             
00152  *             // clear flags and flash the led 
00153  *             rx_recieved = false;
00154  *             myled = !myled;
00155  *         }
00156  * #endif 
00157  *       
00158  *     }
00159  * }
00160  * 
00161  * @endcode
00162  */
00163 
00164 
00165 /**
00166  *
00167  *
00168  */
00169 class nRF2401A
00170 {
00171     public:
00172 /** Class constructor.
00173  * The constructor assigns the specified pinout, attatch the
00174  * DR1 to a pin interrupt and sets up inmutable control packet
00175  * fields. for the KL25Z, the Data Ready pin must be on ports A or C
00176  * @param ce Chip Enable (CE) pin of the nRF2401A.
00177  * @param c2 Chip Select (CS) pin of the nRF2401A.
00178  * @param dr1 Data Ready 1 (DR1) pin of the nRF2401A.
00179  * @param clk1 Clock 1 (CLK1) pin of the nRF2401A.
00180  * @param data Data (DATA) pin of the nRF2401A.
00181  */
00182         nRF2401A(PinName ce,
00183                  PinName cs,
00184                  PinName dr1,
00185                  PinName clk1,
00186                  PinName data);
00187                  
00188 /** Class destructor.
00189  * Pretty much useless in the embedded world...
00190  */
00191         virtual ~nRF2401A() { return; }
00192         
00193         
00194  /** CRC settings.
00195  * Type covering the allowed settings for use of CRC.
00196  */
00197         typedef enum 
00198         {
00199             NO_CRC = 0x0,   /**< Do not use CRC. */
00200             CRC_8 = 0x1,    /**< Use a 8-bit CRC. */
00201             CRC_16 = 0x3,   /**< Use a 16-bit CRC. */
00202             INVALID_CRC     /* must be last in the list for error check in setCRCMode */
00203         } CRC_T;       
00204          
00205 /** Transceiver state
00206  * type covering the states of the transceiver
00207  */
00208         typedef enum
00209         { 
00210             RX,         /**< The tranceiver is in receive mode. Default mode. */
00211             TX,         /**< The tranceiver is transmitting. */
00212             STANDBY,    /**< The tranceiver goes into stanby mode. */
00213             INVALID_STATE
00214         } STATE_T;       
00215                
00216 /** Data rate settings.
00217  * Type covering the allowed settings for the tranceiver data rate.
00218  */
00219         typedef enum
00220         {
00221             BIT_RATE_250KBITS = 0x0,    /**< 250kbits data rate default */
00222             BIT_RATE_1MBITS = 0x1,      /**< 1Mbit data rate */
00223             INVALID_RATE                /* must be last in the list for error check on set data rate */  
00224         } DATA_RATE_T;
00225 
00226 /** RF power settings
00227  * Type covering the allowed settings for RF power
00228  */
00229         typedef enum
00230         {
00231             MINUS_TWENTY_DB = 0,     /**< -20dB */
00232             MINUS_TEN_DB    = 1,     /**< -10dB */
00233             MINUS_FIVE_DB   = 2,     /**< -5dB */
00234             ZERO_DB         = 3,     /**< 0dB */
00235             INVALID_POWER            /* must be last in the list for error check on set RF power */
00236         } RF_POWER_T;
00237 
00238 /** Put the tranceiver into, or bring out of standby.
00239  * Tx mode 10.5mA, RX mode 18mA, Standby 400nA.
00240  * @param active set standby state
00241  */
00242         STATE_T standby_mode(bool active = true);
00243         
00244 /**
00245  *
00246  */
00247         typedef uint8_t address_t[5];
00248         
00249  /** Print control packet 
00250  * Print the control packet to a serial port
00251  * @param arg Pointer to the port to transmit on
00252  * @return bool for correct parameters supplied
00253  */          
00254         bool printControlPacket(Serial& port);
00255      
00256 /** Print data packet 
00257  * Print the data packet to a serial port
00258  * @param arg Pointer to the port to transmit on
00259  * @return bool for correct parameters supplied
00260  */  
00261         bool printDataPacket(Serial& port);
00262            
00263 /** Send the control packet to the nRF2401A.
00264  * This function transfer the control packet image to the nRF2401A.
00265  * @return bool for successfull flushing of the packet
00266  */
00267         bool flushControlPacket();
00268          
00269 /** Register a receive action callback.
00270  * Attach a callback that will be called when the tranceiver intercept a
00271  * message. This callback will be called in the context of an interrupt
00272  * routine and should act accordingly.
00273  * @param handler The callback, of type nRF2401_rx_handler_t.
00274  * @param arg Pointer to data supplied to the handler at call time.
00275  * @return Reference to the invoked object (for chaining operations).
00276  */     
00277         bool attachRXHandler(nRF2401A_rx_handler_t handler, void *arg);
00278  
00279 /** Set the payload length, in bits.
00280  * Set the control packet field for length, in number of bits, of the message payload.
00281  * @param n Number of bits of the message payload.
00282  * @return void
00283  */
00284         void setDataPayloadLength(uint8_t n);
00285                 
00286 /** Set the address of channel 1.
00287  * The channel address is a up to 40 bit number identifying the tranceiver.
00288  * @param addr4 Bits 39-32 of the address.
00289  * @param addr4 Bits 31-24 of the address.
00290  * @param addr4 Bits 23-16 of the address.
00291  * @param addr4 Bits 15-8 of the address.
00292  * @param addr4 Bits 7-0 of the address.
00293  * @param n_bits Number of bits used in the address.
00294  * @return Reference to the invoked object (for chaining operations).
00295  */
00296         bool setAddress(uint8_t addr4, uint8_t addr3, uint8_t addr2, uint8_t addr1, uint8_t addr0, uint8_t n_bits);
00297 
00298 /** Set CRC use.
00299  * Set the CRC mode field of the control packet. Defaults to no CRC.
00300  * @param mode The CRC mode of choise.
00301  * @return bool for correct parameter supplied
00302  */
00303         bool setCRCMode(CRC_T mode); 
00304  
00305  /** Set RF power use.
00306  * Set the RF power field of the control packet. Defaults to full power.
00307  * @param power The RF power of choice.
00308  * @return bool for correct parameter supplied
00309  */
00310         bool setRFpower(RF_POWER_T power); 
00311  
00312 /** Set tranceiver data rate.
00313  * Sets the data rate field to either 250 kbit/s or 1 Mbit/s data transfer rate.
00314  * Defaults to 250 kbit/s.
00315  * @param mode The data rate of choise.
00316  * @return bool for correct parameter supplied
00317  */
00318         bool setDataRate(DATA_RATE_T data_rate);
00319 
00320         
00321 /** Set RF channel.
00322  * Sets the control packet field for channel number. Channel numbers are from 0 to 127
00323  * representing channel frequencies equal to (2400 + channel number) MHz. Defaults to channel 1.
00324  * @param ch Channel number, from the range [0, 127].
00325  * @return boolean to confirm valid parameters have been supplied
00326  */
00327         bool setChannel(uint8_t ch);
00328 
00329 /** Read a message.
00330  * This routine will transfer the data from the receive buffer to the buffer
00331  *  supplied. It will transfer a number of Bytes equal to the specified length.
00332  * @param msg_buf Message buffer.
00333  * @param msg_len Length of message,  in bytes.
00334  * @return boolean to confirm if valid parameters have been supplied
00335  */
00336         bool readMsg( uint8_t *msg_buf, uint8_t msg_len );
00337 
00338 /** Read a byte from message.
00339  * This routine will transfer the data from the receive buffer to the buffer
00340  *  supplied. It will transfer one Bytes at index buf_index.
00341  * @param msg_buf Message body.
00342  * @param buf_index index of byte to be read.
00343  * @return one Byte of the message buffer
00344  */
00345         uint8_t readMsg_byte( uint8_t buf_index ); //uint8_t *msg_buf, 
00346          
00347 /** Send a message.
00348  * This routine will transfer the data from the supplied buffer and send
00349  * it to the specified address using the current control packet settings.
00350  * @param addr The address to send to.
00351  * @param addr_len Length of address, in bits.
00352  * @param msg_buf Message body.
00353  * @param msg_len Length of message,  in bits.
00354  * @return Reference to the invoked object (for chaining operations).
00355  */
00356         bool sendMsg(address_t addr, uint8_t addr_len, uint8_t *msg_buf, uint8_t msg_len);
00357     
00358     private:
00359     
00360         DigitalOut      _ce;    /**< Chip Enable pin. */
00361         DigitalOut      _cs;    /**< Chip select pin. */
00362         DigitalIn       _dr1;   /**< Data Ready 1 pin. */
00363         DigitalOut      _clk1;  /**< Clock 1 pin. */
00364         DigitalInOut    _data;  /**< Data pin. */
00365         
00366 
00367 /*
00368  *
00369  */
00370         typedef enum 
00371         { 
00372             RX_MODE = 0x1, 
00373             TX_MODE = 0x0 
00374         } TXR_T;
00375              
00376 /** Contol packet data.
00377  *
00378  */
00379         struct nRF2401A_ctrl_packet_t
00380         {
00381             uint8_t     channel_2_data_payload_len;     /**< */
00382             uint8_t     channel_1_data_payload_len;     /**< */
00383             uint8_t     channel_2_address[5];           /**< */
00384             uint8_t     channel_1_address[5];           /**< */
00385             
00386             uint8_t     crc_config : 2;                 /**< */
00387             uint8_t     channel_address_len : 6;        /**< */
00388             
00389             uint8_t     rf_power : 2;                   /**< */
00390             uint8_t     xo_frequency : 3;               /**< */
00391             uint8_t     rf_data_rate : 1;               /**< */
00392             uint8_t     communication_mode : 1;         /**< */
00393             uint8_t     enable_dual_channel_mode : 1;   /**< */
00394             
00395             uint8_t     txr_switch : 1;                 /**< */
00396             uint8_t     rf_channel : 7;                 /**< */
00397             
00398         }  _ctrl_packet_buf;   /**< */
00399         
00400         uint8_t         *_ctrl_packet;  /**< */
00401         
00402         uint8_t         _data_buf[DATA_BUFFER_SIZE];  /**< */       
00403         
00404         STATE_T  _state;
00405         
00406         nRF2401A_rx_handler_t   _rx_handler;        /**< */
00407         void                    *_rx_handler_arg;   /**< */
00408      
00409          
00410 /** Receive ISR.
00411  * This handler is attached to the rising flank of the DR1 pin. It
00412  * will thus be called when the nRF2401A receives a packet in ShockBurst
00413  * mode (the mode used). It will in turn call the attached handler.
00414  */
00415         void dataReadyHandler(void);
00416            
00417 /**
00418  *
00419  */
00420         InterruptIn     _dr1_isr;
00421   
00422 /** Write to the data bus.
00423  * Write n_bits bits on the DATA line.
00424  * @param buf Data buffer.
00425  * @param n_bits Number of bits to transfer.
00426  * @param is_ctrl True if the tranfered data is control word, false if data.
00427  */
00428         void pushCtrl(uint8_t *buf, uint8_t n_bits, bool is_ctrl = true);
00429         
00430 /** Read a message from the tranceiver.
00431  * Read until DR1 goes low.
00432  * @param buf Data buffer.
00433  * @return Number of bits read.
00434  */
00435         int pull(uint8_t *buf);
00436  /** Set the tranceiver into transmit mode
00437  */ 
00438         void transmit_mode( void );
00439  /** Set the tranceiver into receive mode
00440  */       
00441         void receive_mode( void );
00442 };
00443 
00444 #endif