Library for the nRF2401A Transceiver

Dependents:   nRF2401A_Hello_World nRF2401A_Wireless_Accelerometer_joypad nRF2401A_Gameduino_Invaders

Files at this revision

API Documentation at this revision

Comitter:
TheChrisyd
Date:
Sun Mar 09 11:57:33 2014 +0000
Parent:
8:fb7cb88e80a4
Commit message:
Update after feedback, parameters set to defaults, removed references ti this and added error checking to the functions instead, moved defines and updated documentation.

Changed in this revision

nRF2401A.cpp Show annotated file Show diff for this revision Revisions of this file
nRF2401A.h Show annotated file Show diff for this revision Revisions of this file
--- a/nRF2401A.cpp	Sat Oct 26 21:55:20 2013 +0000
+++ b/nRF2401A.cpp	Sun Mar 09 11:57:33 2014 +0000
@@ -26,13 +26,26 @@
 
 #include "nRF2401A.h"
 
+#define   Ts         1            /**< Setup time from data to rising clock edge on write (accualy 500 ns). */
+#define   Th         1            /**< Hold time from rising clock to data toggle/falling clock (accualy 500 ns). */
+#define   Tcs2data   5            /**< Min delay from CS assert to data, in us. */
+#define   Tce2data   5            /**< Min delay from CE assert to data, in us. */
+#define   Td         1            /**< Minimum delay between edges (actually 50 ns). */
+#define   Tpd2cfgm   3            /**< Minimum delay from power up of tranciever to configuration. */
+#define   Tsby2txSB  195          /**< Minimum delay from tx initation to air, in us. */
+#define   Tsby2rx    202          /**< Minimum delay from stanby to rx mode, in us. */
+#define   Thmin      5            /**< */
+#define   Tclk2data  1            /**< */
+#define   MAXIMUM_ADDR_LENGTH 40  /**< */
+
 
 nRF2401A::nRF2401A(PinName ce,
                    PinName cs,
                    PinName dr1,
                    PinName clk1,
                    PinName data)
-        : _ce(DigitalOut(ce)),
+        :
+        _ce(DigitalOut(ce)),
         _cs(DigitalOut(cs)),
         _dr1(DigitalIn(dr1)),
         _clk1(DigitalOut(clk1)),
@@ -41,9 +54,14 @@
         _rx_handler((nRF2401A_rx_handler_t) 0),
         _rx_handler_arg((void *) 0),
         _dr1_isr(InterruptIn(dr1))  {
-
+   
     // init member variables
     _data.output();
+    // set defaults
+    _ctrl_packet_buf.crc_config = NO_CRC;
+    _ctrl_packet_buf.rf_data_rate = BIT_RATE_250KBITS;
+    _ctrl_packet_buf.rf_channel = 0x02;
+    _ctrl_packet_buf.channel_1_data_payload_len = 0x20;
     // setup...
     _ctrl_packet = (uint8_t *) &_ctrl_packet_buf;
     _dr1_isr.rise(this, &nRF2401A::dataReadyHandler);
@@ -67,136 +85,316 @@
     return;
 }
 
-// Public functions
+/*          Public functions         */
 
-void nRF2401A::printControlPacket(Serial& port)
+/* Print control packet 
+ * Print the control packet to a serial port
+ * @param arg Pointer to the port to transmit on
+ * @return bool for correct parameters supplied
+ */    
+bool nRF2401A::printControlPacket(Serial& port)
 {
-    for(int i = 0; i < sizeof(_ctrl_packet_buf); i++)
-        port.printf("%02x ", _ctrl_packet[i]);
-    port.printf("\n\r");
-    return;
+    bool ok = false;
+    if (port != NULL)
+    {
+        for(int i = 0; i < sizeof(_ctrl_packet_buf); i++)
+        {    
+            port.printf("%02x ", _ctrl_packet[i]);
+        }
+        port.printf("\n\r");
+        ok = true;
+    }
+    return ok;
 }
 
-void nRF2401A::printDataPacket(Serial& port)
+/* Print data packet 
+ * Print the data packet to a serial port
+ * @param arg Pointer to the port to transmit on
+ * @return bool for correct parameters supplied
+ */  
+bool nRF2401A::printDataPacket(Serial& port)
 {
-    for(int i = 0; i < sizeof(_data_buf); i++)
-        port.printf("%02x ", _data_buf[i]);
-    port.printf("\r");
-    return;
+    bool ok = false;
+    if (port != NULL)
+    {
+        for(int i = 0; i < sizeof(_data_buf); i++)
+        {
+            port.printf("%02x ", _data_buf[i]);
+        }
+        port.printf("\r");
+        ok = true;
+    }
+    return ok;
 }
 
-nRF2401A& nRF2401A::flushControlPacket() {
+/* Send the control packet to the nRF2401A.
+ * This function transfer the control packet image to the nRF2401A.
+ * @return bool for successfull flushing of the packet
+ */
+bool nRF2401A::flushControlPacket() {
+    bool flush = false;
     switch (_state) {
         case nRF2401A::RX:
             pushCtrl(_ctrl_packet, 15 << 3 );
             _state = nRF2401A::RX;
             _ce = 1;
             _cs = 0;
+            flush = true;
             break;
         case nRF2401A::STANDBY:
             pushCtrl(_ctrl_packet, 15 << 3 );
             _state = nRF2401A::STANDBY;
             _ce = 0;
             _cs = 0;
+            flush = true;
             break;
         case nRF2401A::TX:
         default:
             _ce = 0;
             _cs = 0;
     }
-
-    return *this;
+    return flush;
 }
 
-nRF2401A& nRF2401A::attachRXHandler(nRF2401A_rx_handler_t handler, void *arg) 
+/* Register a receive action callback.
+ * Attach a callback that will be called when the tranceiver 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).
+ */  
+bool nRF2401A::attachRXHandler(nRF2401A_rx_handler_t handler, void *arg) 
 {
-    _rx_handler = handler;
-    _rx_handler_arg = arg;
-    return *this;
+    bool ok = false;
+    if (handler != NULL)
+    {
+        _rx_handler = handler;
+        _rx_handler_arg = arg;
+        ok = true;
+    }
+    return ok;
 }
 
-nRF2401A& nRF2401A::readMsg( uint8_t *msg_buf, uint8_t msg_len ) {
-    for(int i = 0; i < msg_len; i++)
+/* 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 void
+ */
+ void nRF2401A::setDataPayloadLength(uint8_t n) 
+{ 
+    _ctrl_packet_buf.channel_1_data_payload_len = n;  
+}  
+
+/*  Set the address of channel 1.
+ * The channel address is a up to 40 bit number identifying the tranceiver.
+ * @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 bool for correct settings supplied
+ */
+bool nRF2401A::setAddress(uint8_t addr4, uint8_t addr3, uint8_t addr2, uint8_t addr1, uint8_t addr0, uint8_t n_bits)
+{
+    bool ok = false;
+    if (n_bits <= MAXIMUM_ADDR_LENGTH)
     {
-        msg_buf[i] = _data_buf[i];
+        _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;
+        ok = true;
     }
-    return *this;
+    return ok;
 }
 
-nRF2401A& nRF2401A::readMsg_byte( uint8_t *msg_buf, uint8_t buf_index ) { 
-    *msg_buf = _data_buf[buf_index];
-    return *this;
+/* Set CRC use.
+ * Set the CRC mode field of the control packet. Defaults to no CRC.
+ * @param mode The CRC mode of choise.
+ * @return bool for correct parameter supplied
+ */
+bool nRF2401A::setCRCMode(CRC_T mode) 
+{ 
+    bool ok = false;
+    if (mode < INVALID_CRC)
+    {
+        _ctrl_packet_buf.crc_config = mode; 
+        ok = true;
+    }
+    return ok; 
 }
 
-nRF2401A& nRF2401A::sendMsg(nRF2401A::address_t addr, uint8_t addr_len, uint8_t *msg_buf, uint8_t msg_len) {
-    // point to start of address byte in address
-    uint8_t *aligned_addr = &addr[sizeof(address_t) - (addr_len / 8)];
-    // wait for tx completion
-    int Toa = (_ctrl_packet_buf.rf_data_rate == nRF2401A::BIT_RATE_1MBITS ? 1 : 4) * (addr_len + msg_len + 1 + 16);
+/* Set RF power use.
+ * Set the RF power field of the control packet. Defaults to full power.
+ * @param power The RF power of choise.
+ * @return bool for correct parameter supplied
+ */
+bool nRF2401A::setRFpower(RF_POWER_T power)
+{
+    bool ok = false;
+    if (power < INVALID_POWER)
+    {
+        _ctrl_packet_buf.rf_power = power; 
+        ok = true;
+    }
+    return ok;         
+}
+ 
+/* Set tranceiver data rate.
+ * Sets the data rate field to either 250 kbit/s or 1 Mbit/s data transfer rate.
+ * Defaults to 250 kbit/s.
+ * @param mode The data rate of choise.
+ * @return bool for correct parameter supplied
+ */
+bool nRF2401A::setDataRate(DATA_RATE_T data_rate)
+{
+    bool ok = false;
+    if ( data_rate < INVALID_RATE)
+    {
+        _ctrl_packet_buf.rf_data_rate = data_rate;
+        ok = true;
+    }
+    return ok;
+}
+
+/** 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. Defaults to channel 1.
+ * @param ch Channel number, from the range [0, 127].
+ * @return boolean to confirm valid parameters have been supplied
+ */
+bool nRF2401A::setChannel(uint8_t ch)
+{
+    bool result = false;
+    if (ch < 128)
+    {
+        _ctrl_packet_buf.rf_channel = ch;
+        result = true;
+    }
+    return result;
+}
 
-    switch (_state) {
-        case nRF2401A::STANDBY:
-            //come out of standby into RX mode
-            standby_mode(true);
-        case nRF2401A::TX:
-            //add a wait while in tx mode
-            while (_state == nRF2401A::TX ) {
-            }
-        case nRF2401A::RX:
-            // switch to transmit
-            transmit_mode();
-            // push out the bits
-            _data = nRF2401A::TX_MODE;
-            wait_us(Ts);
-            _clk1 = 1;
-            wait_us(Th);
-            _clk1 = 0;
-            // wait Td
-            wait_us(Td);
-            // deassert CS/CE and done...
-            _cs = 0;
-            _ce = 0;
+/* Read a message.
+ * This routine will transfer the data from the receive buffer to the buffer
+ *  supplied. It will transfer a number of Bytes equal to the specified length.
+ * @param msg_buf Message buffer.
+ * @param msg_len Length of message,  in bytes.
+ * @return boolean to confirm if valid parameters have been supplied
+ */
+bool nRF2401A::readMsg( uint8_t *msg_buf, uint8_t msg_len ) {
+    bool result = false;
+    if ((msg_buf != NULL) && (msg_len <= DATA_BUFFER_SIZE))
+    {
+        for(int i = 0; i < msg_len; i++)
+        {
+            msg_buf[i] = _data_buf[i];
+        }
+        result = true;
+    }
+    return result;
+}
+
+/* Read a byte from message.
+ * This routine will transfer the data from the receive buffer to the buffer
+ *  supplied. It will transfer one Bytes at index buf_index.
+ * @param msg_buf Message body.
+ * @param buf_index index of byte to be read.
+ * @return one Byte of the message buffer
+ */
+uint8_t nRF2401A::readMsg_byte( uint8_t buf_index ) { 
+    return _data_buf[buf_index];
+}
 
-            // zero control and data lines
-            _clk1 = 0;
-            _data = 0;
-            // wait Td
-            wait_us(Td);
-            // assert CE and wait Tcs2data
-            _ce = 1;
-            wait_us(Tce2data);
-            // push out the address bits
-            for (int i = 0; i < addr_len; i++) {
-                _data = ((0x80 >> (i % 8)) & aligned_addr[i / 8]) ? 0x1 : 0x0;
+/** 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).
+ */
+bool nRF2401A::sendMsg(nRF2401A::address_t addr, uint8_t addr_len, uint8_t *msg_buf, uint8_t msg_len) {
+    bool sent = false;
+    if ((msg_buf != NULL) && (addr_len <= MAXIMUM_ADDR_LENGTH))
+    {
+        // point to start of address byte in address
+        uint8_t *aligned_addr = &addr[sizeof(address_t) - (addr_len / 8)];
+        // wait for tx completion
+        int Toa = (_ctrl_packet_buf.rf_data_rate == nRF2401A::BIT_RATE_1MBITS ? 1 : 4) * (addr_len + msg_len + 1 + 16);
+
+        switch (_state) {
+            case nRF2401A::STANDBY:
+                //come out of standby into RX mode
+                standby_mode(true);
+            case nRF2401A::TX:
+                //wait while in tx mode
+                while (_state == nRF2401A::TX ) {
+                }
+            case nRF2401A::RX:
+                // switch to transmit
+                transmit_mode();
+                // push out the bits
+                _data = nRF2401A::TX_MODE;
                 wait_us(Ts);
                 _clk1 = 1;
                 wait_us(Th);
                 _clk1 = 0;
-            }
-            // push out the message bits
-            for (int i = 0; i < msg_len; i++) {
-                _data = ((0x80 >> (i % 8)) & msg_buf[i / 8]) ? 0x1 : 0x0;
-                wait_us(Ts);
-                _clk1 = 1;
-                wait_us(Th);
+                // wait Td
+                wait_us(Td);
+                // deassert CS/CE and done...
+                _cs = 0;
+                _ce = 0;
+
+                // zero control and data lines
                 _clk1 = 0;
-            }
-            // reset data
-            _data = 0;
-            // deassert CE will initiate transmission
-            _ce = 0;
-            wait_us(Tsby2txSB + Toa);
+                _data = 0;
+                // wait Td
+                wait_us(Td);
+                // assert CE and wait Tcs2data
+                _ce = 1;
+                wait_us(Tce2data);
+                // push out the address bits
+                for (int i = 0; i < addr_len; i++) {
+                    _data = ((0x80 >> (i % 8)) & aligned_addr[i / 8]) ? 0x1 : 0x0;
+                    wait_us(Ts);
+                    _clk1 = 1;
+                    wait_us(Th);
+                    _clk1 = 0;
+                }
+                // push out the message bits
+                for (int i = 0; i < msg_len; i++) {
+                    _data = ((0x80 >> (i % 8)) & msg_buf[i / 8]) ? 0x1 : 0x0;
+                    wait_us(Ts);
+                    _clk1 = 1;
+                    wait_us(Th);
+                    _clk1 = 0;
+                }
+                // reset data
+                _data = 0;
+                // deassert CE will initiate transmission
+                _ce = 0;
+                wait_us(Tsby2txSB + Toa);
 
-            // switch back to receive
-            receive_mode();
-            break;
+                // switch back to receive
+                receive_mode();
+                sent = true;
+                break;
+        }
     }
-    return *this;
+    return sent;
 }
 
 
-
-nRF2401A& nRF2401A::standby_mode(bool active) {
+/* Put the tranceiver into, or bring out of standby.
+ * Tx mode 10.5mA, RX mode 18mA, Standby 400nA.
+ * @param active set standby state
+ */
+nRF2401A::STATE_T nRF2401A::standby_mode(bool active) {
     switch (_state) {
         case nRF2401A::TX:
             //wait while in tx mode
@@ -207,6 +405,7 @@
                 _state = nRF2401A::STANDBY;
                 _ce = 0;
                 _cs = 0;
+                wait_us(Tsby2rx);
             }
             break;
         case nRF2401A::STANDBY:
@@ -217,11 +416,15 @@
             }
             break;
     }
-    return *this;
+    return _state;
 }
 
-// Private functions
+/*              Private functions             */
 
+/* transmit_mode
+ *
+ * put the transceiver into transmit mode
+ */
 void nRF2401A::transmit_mode( void ) {        
     _ce = 0;
     _cs = 0;
@@ -233,6 +436,10 @@
     _state = nRF2401A::TX;
 }
 
+/* receive_mode
+ *
+ * put the transceiver into receive mode
+ */
 void nRF2401A::receive_mode( void ) {
     wait_us(Td);
     // assert CS/CE and wait Tcs2data
@@ -256,7 +463,10 @@
     _state = nRF2401A::RX;
 }
 
-
+/* dataReadyHandler
+ *
+ * handle the incoming data and call callback
+ */
 void nRF2401A::dataReadyHandler(void) {
     switch (_state) {
         case nRF2401A::RX:
@@ -271,6 +481,10 @@
     return;
 }
 
+/* pull
+ *
+ * Pull the data from the transceiver
+ */
 int nRF2401A::pull(uint8_t *buf) {
     int n = 0;
     
@@ -302,6 +516,10 @@
     return n;
 }
 
+/* pushCtrl
+ *
+ * Push the data to the transceiver
+ */
 void nRF2401A::pushCtrl(uint8_t *buf, uint8_t n_bits, bool is_ctrl) {
 
     DigitalOut  &ctrl_pin = is_ctrl ? _cs : _ce;
--- a/nRF2401A.h	Sat Oct 26 21:55:20 2013 +0000
+++ b/nRF2401A.h	Sun Mar 09 11:57:33 2014 +0000
@@ -29,15 +29,9 @@
 
 #include <mbed.h>
 #include <inttypes.h>
-#define   Ts         1     /**< Setup time from data to rising clock edge on write (accualy 500 ns). */
-#define   Th         1     /**< Hold time from rising clock to data toggle/falling clock (accualy 500 ns). */
-#define   Tcs2data   5     /**< Min delay from CS assert to data, in us. */
-#define   Tce2data   5     /**< Min delay from CE assert to data, in us. */
-#define   Td         1     /**< Minimum delay between edges (actually 50 ns). */
-#define   Tpd2cfgm   3     /**< Minimum delay from power up of tranciever to configuration. */
-#define   Tsby2txSB  195   /**< Minimum delay from tx initation to air, in us. */
-#define   Thmin      5     /**< */
-#define   Tclk2data  1     /**< */
+
+#define DATA_BUFFER_SIZE 32
+
 
 /** ISR handler prototype for receiving messages.
  * A function of this type is registered and called when the DR pin on the
@@ -48,13 +42,18 @@
 
 /** nRF2401 Class 
  *
+ *  A class supporting the nRF2401A nordic 2.4Ghz transciever
+ * Supports shock burts mode only.
+ * multi channel mode is not supported as it is not on the breakout header.
+ *
  * Example:
  * @code
  * #include "mbed.h"
  * #include "nRF2401A.h"
  * 
  * // comment these out depending on the job of the mbed. If your only using one mbed leave both uncommented. 
- * //#define TX
+ * 
+ * #define TX
  * #define RX
  * 
  * // If using the FRDM-KL25Z uncomment this line 
@@ -75,7 +74,7 @@
  * #ifdef FRDMKL25Z
  * nRF2401A    rf2(PTD0, PTD5, PTA13, PTC12, PTC13);
  * #else
- * nRF2401A    rf2(p10, p11, p12, p13, p14);
+ * nRF2401A    rf2(p25, p24, p23, p22, p21);
  * #endif
  * 
  * bool rx_recieved = false;
@@ -91,29 +90,21 @@
  *     pc.printf("Hello nRF2401A\n\r");
  *     
  * #ifdef TX  
- *     // initialise the nRF2401A with payload size, address, CRC, bit rate and channel
- *     rf1.setDataPayloadLength(4 << 3)
- *        .setAddress(0x0, 0x0, 0xa6, 0xa6, 0xa6, 3 << 3)
- *        .setCRCMode(nRF2401A::NO_CRC)
- *        .setDataRate(nRF2401A::BIT_RATE_250KBITS)
- *        .setChannel(0x02);
- *        
+ *     // initialise the nRF2401A with payload size and address 
+ *     rf1.setAddress(0x0, 0x0, 0xa6, 0xa6, 0xa6, 3 << 3);
+ *     
  *     rf1.printControlPacket(pc);
  *     rf1.flushControlPacket();
  *     
- *     // initialise variables to use for tranmission
+ *     // initialise variables to use for tranmission 
  *     nRF2401A::address_t rf2_addr = {0x0, 0x0, 0x53, 0x53, 0x53};
  *     uint8_t msg[] = {0x01, 0x01, 0x01, 0x01};
  *     uint32_t *msg32 = (uint32_t *) msg;
  * #endif
  * 
  * #ifdef RX   
- *     // initialise the nRF2401A with payload size, address, CRC, bit rate and channel 
- *     rf2.setDataPayloadLength(4 << 3)
- *        .setAddress(0x0, 0x0, 0x53, 0x53, 0x53, 3 << 3)
- *        .setCRCMode(nRF2401A::NO_CRC)
- *        .setDataRate(nRF2401A::BIT_RATE_250KBITS)
- *        .setChannel(0x02);
+ *     // initialise the nRF2401A with payload size and address  
+ *     rf2.setAddress(0x0, 0x0, 0x53, 0x53, 0x53, 3 << 3);
  *        
  *     rf2.printControlPacket(pc);
  *     rf2.flushControlPacket();   
@@ -129,7 +120,7 @@
  *         myled = 0;
  *         wait(0.25);  
  *         
- *         send the message to the nRF2401A         
+ *         // send the message to the nRF2401A 
  *         rf1.sendMsg(rf2_addr, 3 << 3, msg, 4 << 3);
  *         *msg32 += 1;
  *         
@@ -146,7 +137,7 @@
  *             
  *             // send a single byte from the read buffer to the serial port 
  *             uint8_t rx_msg = 0;
- *             rf2.readMsg_byte(&rx_msg,  0 );
+ *             rx_msg = rf2.readMsg_byte( 0 );
  *             pc.printf("\n\r%d\n\r", rx_msg);
  *             
  *             // read the read buffer , then send to the serial port 
@@ -199,17 +190,99 @@
  */
         virtual ~nRF2401A() { return; }
         
+        
+ /** 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. */
+            INVALID_CRC     /* must be last in the list for error check in setCRCMode */
+        } CRC_T;       
+         
+/** Transceiver state
+ * type covering the states of the transceiver
+ */
+        typedef enum
+        { 
+            RX,         /**< The tranceiver is in receive mode. Default mode. */
+            TX,         /**< The tranceiver is transmitting. */
+            STANDBY,    /**< The tranceiver goes into stanby mode. */
+            INVALID_STATE
+        } STATE_T;       
+               
+/** Data rate settings.
+ * Type covering the allowed settings for the tranceiver data rate.
+ */
+        typedef enum
+        {
+            BIT_RATE_250KBITS = 0x0,    /**< 250kbits data rate default */
+            BIT_RATE_1MBITS = 0x1,      /**< 1Mbit data rate */
+            INVALID_RATE                /* must be last in the list for error check on set data rate */  
+        } DATA_RATE_T;
+
+/** RF power settings
+ * Type covering the allowed settings for RF power
+ */
+        typedef enum
+        {
+            MINUS_TWENTY_DB = 0,     /**< -20dB */
+            MINUS_TEN_DB    = 1,     /**< -10dB */
+            MINUS_FIVE_DB   = 2,     /**< -5dB */
+            ZERO_DB         = 3,     /**< 0dB */
+            INVALID_POWER            /* must be last in the list for error check on set RF power */
+        } RF_POWER_T;
+
+/** Put the tranceiver into, or bring out of standby.
+ * Tx mode 10.5mA, RX mode 18mA, Standby 400nA.
+ * @param active set standby state
+ */
+        STATE_T standby_mode(bool active = true);
+        
+/**
+ *
+ */
+        typedef uint8_t address_t[5];
+        
+ /** Print control packet 
+ * Print the control packet to a serial port
+ * @param arg Pointer to the port to transmit on
+ * @return bool for correct parameters supplied
+ */          
+        bool printControlPacket(Serial& port);
+     
+/** Print data packet 
+ * Print the data packet to a serial port
+ * @param arg Pointer to the port to transmit on
+ * @return bool for correct parameters supplied
+ */  
+        bool printDataPacket(Serial& port);
+           
+/** Send the control packet to the nRF2401A.
+ * This function transfer the control packet image to the nRF2401A.
+ * @return bool for successfull flushing of the packet
+ */
+        bool flushControlPacket();
+         
+/** Register a receive action callback.
+ * Attach a callback that will be called when the tranceiver 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).
+ */     
+        bool attachRXHandler(nRF2401A_rx_handler_t handler, void *arg);
+ 
 /** 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).
+ * @return void
  */
-        nRF2401A& setDataPayloadLength(uint8_t n) 
-        { 
-            _ctrl_packet_buf.channel_1_data_payload_len = n; 
-            return *this; 
-        }
-        
+        void setDataPayloadLength(uint8_t n);
+                
 /** Set the address of channel 1.
  * The channel address is a up to 40 bit number identifying the tranceiver.
  * @param addr4 Bits 39-32 of the address.
@@ -220,105 +293,56 @@
  * @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.
+        bool setAddress(uint8_t addr4, uint8_t addr3, uint8_t addr2, uint8_t addr1, uint8_t addr0, uint8_t n_bits);
+
+/** Set CRC use.
+ * Set the CRC mode field of the control packet. Defaults to no CRC.
+ * @param mode The CRC mode of choise.
+ * @return bool for correct parameter supplied
  */
-        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;
-        typedef uint8_t read_msg;
-/** 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).
+        bool setCRCMode(CRC_T mode); 
+ 
+ /** Set RF power use.
+ * Set the RF power field of the control packet. Defaults to full power.
+ * @param power The RF power of choice.
+ * @return bool for correct parameter supplied
  */
-        nRF2401A& setCRCMode(CRC_T mode) 
-        { 
-            _ctrl_packet_buf.crc_config = mode; 
-            return *this; 
-        }
-        
-/** Data rate settings.
- * Type covering the allowed settings for the tranceiver data rate.
- */
-        typedef enum
-        {
-            BIT_RATE_250KBITS = 0x0,    /**< */
-            BIT_RATE_1MBITS = 0x1       /**< */
-        } DATA_RATE_T;
-        
+        bool setRFpower(RF_POWER_T power); 
+ 
 /** Set tranceiver data rate.
  * Sets the data rate field to either 250 kbit/s or 1 Mbit/s data transfer rate.
+ * Defaults to 250 kbit/s.
  * @param mode The data rate of choise.
- * @return Reference to the invoked object (for chaining operations).
+ * @return bool for correct parameter supplied
  */
-        nRF2401A& setDataRate(DATA_RATE_T data_rate)
-        {
-            _ctrl_packet_buf.rf_data_rate = data_rate;
-            return *this;
-        }
+        bool setDataRate(DATA_RATE_T data_rate);
+
         
 /** 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.
+ * representing channel frequencies equal to (2400 + channel number) MHz. Defaults to channel 1.
  * @param ch Channel number, from the range [0, 127].
- * @return Reference to the invoked object (for chaining operations).
+ * @return boolean to confirm valid parameters have been supplied
  */
-        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();
-        
-/** Put the tranceiver into, or bring out of standby.
- * Tx mode 10.5mA, RX mode 18mA, Standby 400nA.
- * @param active set standby state
- */
-        nRF2401A& standby_mode(bool active = true);
-        
-/**
- *
- */
-        typedef uint8_t address_t[5];
+        bool setChannel(uint8_t ch);
 
 /** Read a message.
  * This routine will transfer the data from the receive buffer to the buffer
  *  supplied. It will transfer a number of Bytes equal to the specified length.
  * @param msg_buf Message buffer.
- * @param msg_len Length of message,  in bits.
- * @return Reference to the invoked object (for chaining operations).
+ * @param msg_len Length of message,  in bytes.
+ * @return boolean to confirm if valid parameters have been supplied
  */
-        nRF2401A& readMsg( uint8_t *msg_buf, uint8_t msg_len );
+        bool readMsg( uint8_t *msg_buf, uint8_t msg_len );
 
 /** Read a byte from message.
  * This routine will transfer the data from the receive buffer to the buffer
  *  supplied. It will transfer one Bytes at index buf_index.
  * @param msg_buf Message body.
  * @param buf_index index of byte to be read.
- * @return Reference to the invoked object (for chaining operations).
+ * @return one Byte of the message buffer
  */
-        nRF2401A& readMsg_byte( uint8_t *msg_buf, uint8_t buf_index );
+        uint8_t readMsg_byte( uint8_t buf_index ); //uint8_t *msg_buf, 
          
 /** Send a message.
  * This routine will transfer the data from the supplied buffer and send
@@ -329,21 +353,8 @@
  * @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 tranceiver 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);
-        
+        bool sendMsg(address_t addr, uint8_t addr_len, uint8_t *msg_buf, uint8_t msg_len);
+    
     private:
     
         DigitalOut      _ce;    /**< Chip Enable pin. */
@@ -352,18 +363,16 @@
         DigitalOut      _clk1;  /**< Clock 1 pin. */
         DigitalInOut    _data;  /**< Data pin. */
         
-/**
+
+/*
  *
  */
         typedef enum 
         { 
-            RX,         /**< The tranceiver is in receive mode. Default mode. */
-            TX,         /**< The tranceiver is transmitting. */
-            STANDBY     /**< The tranceiver goes into stanby mode. */
-        } STATE_T;
-        
-        STATE_T  _state;
-        
+            RX_MODE = 0x1, 
+            TX_MODE = 0x0 
+        } TXR_T;
+             
 /** Contol packet data.
  *
  */
@@ -386,32 +395,30 @@
             uint8_t     txr_switch : 1;                 /**< */
             uint8_t     rf_channel : 7;                 /**< */
             
-        }                                       _ctrl_packet_buf;   /**< */
+        }  _ctrl_packet_buf;   /**< */
         
         uint8_t         *_ctrl_packet;  /**< */
         
-        uint8_t         _data_buf[32];  /**< */       
+        uint8_t         _data_buf[DATA_BUFFER_SIZE];  /**< */       
+        
+        STATE_T  _state;
         
         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.