Library for the nRF2401A Transceiver
Dependents: nRF2401A_Hello_World nRF2401A_Wireless_Accelerometer_joypad nRF2401A_Gameduino_Invaders
nRF2401A.h
- Committer:
- TheChrisyd
- Date:
- 2013-10-05
- Revision:
- 2:ca8602ee9e1d
- Parent:
- 1:8c57f88ff574
- Child:
- 3:7ae3a5e53a1f
File content as of revision 2:ca8602ee9e1d:
/** *@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 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 /**< */ /** nRF2401 Class * * Example: * @code * #include "mbed.h" * #include "nRF2401A.h" * * DigitalOut myled(LED1); * nRF2401A rf1(p10, p11, p12, p13, p14); * nRF2401A rf2(p21, p22, p23, p24, p25); * * Serial pc(USBTX, USBRX); * * int main() { * * wait(0.005); * * pc.printf("Hello nRF2401A\n\r"); * * rf1.setDataPayloadLength(4 << 3) * .setAddress(0x0, 0x0, 0xa6, 0xa6, 0xa6, 3 << 3) * .setCRCMode(nRF2401A::NO_CRC) * .setDataRate(nRF2401A::BIT_RATE_250KBITS) * .setChannel(0x02); * * rf1.printControlPacket(pc); * * rf2.setDataPayloadLength(4 << 3) * .setAddress(0x0, 0x0, 0x53, 0x53, 0x53, 3 << 3) * .setCRCMode(nRF2401A::NO_CRC) * .setDataRate(nRF2401A::BIT_RATE_250KBITS) * .setChannel(0x02); * * rf2.printControlPacket(pc); * * rf1.flushControlPacket(); * rf2.flushControlPacket(); * * nRF2401A::address_t rf2_addr = {0x0, 0x0, 0x53, 0x53, 0x53}; * uint8_t msg[] = {0x01, 0x01, 0x01, 0x01}; * uint32_t *msg32 = (uint32_t *) msg; * * while(1) { * * rf1.sendMsg(rf2_addr, 3 << 3, msg, 4 << 3); * *msg32 += 1; * * myled = 1; * wait(0.25); * * rf2.printDataPacket(pc); * * myled = 0; * wait(0.25); * } * } * @endcode */ /** 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 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). */ 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 tranceiver data rate. */ typedef enum { BIT_RATE_250KBITS = 0x0, /**< */ BIT_RATE_1MBITS = 0x1 /**< */ } DATA_RATE_T; /** Set tranceiver 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 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); 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 tranceiver is in receive mode. */ TX, /**< The tranceiver is transmitting. */ STANDBY /**< The tranceiver 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 tranceiver. * Read until DR1 goes low. * @param buf Data buffer. * @return Number of bits read. */ int pull(uint8_t *buf); }; #endif