Library for the nRF2401A Transceiver
Dependents: nRF2401A_Hello_World nRF2401A_Wireless_Accelerometer_joypad nRF2401A_Gameduino_Invaders
nRF2401A.h
- Committer:
- TheChrisyd
- Date:
- 2014-03-09
- Revision:
- 9:7245524e37e4
- Parent:
- 8:fb7cb88e80a4
File content as of revision 9:7245524e37e4:
/** *@section DESCRIPTION * mbed nRF2401A Library *@section LICENSE * Copyright (c) 2011, Per Söderstam * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * @file "nRF2401A.h" */ #ifndef _nRF2401A_H #define _nRF2401A_H #include <mbed.h> #include <inttypes.h> #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 * 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 *); /** 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 RX * * // If using the FRDM-KL25Z uncomment this line * //#define FRDMKL25Z * * Serial pc(USBTX, USBRX); * DigitalOut myled(LED1); * * #ifdef TX * #ifdef FRDMKL25Z * nRF2401A rf1(PTD0, PTD5, PTA13, PTC12, PTC13); //ce, cs, dr1, clk1, data * #else * nRF2401A rf1(p10, p11, p12, p13, p14); * #endif * #endif * * #ifdef RX * #ifdef FRDMKL25Z * nRF2401A rf2(PTD0, PTD5, PTA13, PTC12, PTC13); * #else * nRF2401A rf2(p25, p24, p23, p22, p21); * #endif * * bool rx_recieved = false; * * void nRF2401A_rx (void *arg) * { * rx_recieved = true; * } * #endif * int main() * { * wait(0.005); * pc.printf("Hello nRF2401A\n\r"); * * #ifdef TX * // 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 * 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 and address * rf2.setAddress(0x0, 0x0, 0x53, 0x53, 0x53, 3 << 3); * * rf2.printControlPacket(pc); * rf2.flushControlPacket(); * * // attach receive callback * rf2.attachRXHandler(&nRF2401A_rx, 0); * #endif * * while(1) * { * * #ifdef TX * myled = 0; * wait(0.25); * * // send the message to the nRF2401A * rf1.sendMsg(rf2_addr, 3 << 3, msg, 4 << 3); * *msg32 += 1; * * myled = 1; * wait(0.25); * #endif * * * #ifdef RX * if (rx_recieved) * { * // send the read buffer directly to the serial port * rf2.printDataPacket(pc); * * // send a single byte from the read buffer to the serial port * uint8_t 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 * uint8_t rx_buffer[32] = {0}; * rf2.readMsg( &rx_buffer[0], 32); * for(int i = 0; i < sizeof(rx_buffer); i++) * { * pc.printf("%02x ", rx_buffer[i]); * } * pc.printf("\r\n"); * * // clear flags and flash the led * rx_recieved = false; * myled = !myled; * } * #endif * * } * } * * @endcode */ /** * * */ 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. for the KL25Z, the Data Ready pin must be on ports A or C * @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; } /** 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 void */ 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. * @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). */ 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 */ 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 */ 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 bool for correct parameter supplied */ 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. Defaults to channel 1. * @param ch Channel number, from the range [0, 127]. * @return boolean to confirm valid parameters have been supplied */ 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 bytes. * @return boolean to confirm if valid parameters have been supplied */ 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 one Byte of the message buffer */ 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 * 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 sendMsg(address_t addr, uint8_t addr_len, uint8_t *msg_buf, uint8_t msg_len); 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 { RX_MODE = 0x1, TX_MODE = 0x0 } TXR_T; /** 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[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; /** 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 tranceiver. * Read until DR1 goes low. * @param buf Data buffer. * @return Number of bits read. */ int pull(uint8_t *buf); /** Set the tranceiver into transmit mode */ void transmit_mode( void ); /** Set the tranceiver into receive mode */ void receive_mode( void ); }; #endif