Per Söderstam / Mbed 2 deprecated driver_nRF2401A

Dependencies:   mbed

Committer:
persoder
Date:
Mon Jul 08 21:08:46 2013 +0000
Revision:
1:d40d911b763a
Parent:
0:3fe71769ad07
This one works...! The trick was not to switch to receive before the hole message is sent. Didn't/missed to include time on air for the (implicitly) added address bits!

Who changed what in which revision?

UserRevisionLine numberNew contents of line
persoder 0:3fe71769ad07 1 /** \file
persoder 0:3fe71769ad07 2 * \brief
persoder 0:3fe71769ad07 3 *
persoder 1:d40d911b763a 4 * \author Per Söderstam © 2011, 2012
persoder 0:3fe71769ad07 5 */
persoder 0:3fe71769ad07 6
persoder 0:3fe71769ad07 7 #include <mbed.h>
persoder 0:3fe71769ad07 8 #include <inttypes.h>
persoder 0:3fe71769ad07 9
persoder 1:d40d911b763a 10 /** ISR handler prototype for receiving messages.
persoder 1:d40d911b763a 11 * A function of this type is registered and called when the DR pin on the
persoder 1:d40d911b763a 12 * nRF tranciever signals the reception of a message. The void * argument
persoder 1:d40d911b763a 13 * is likewise supplied when registering and is returned at call time.
persoder 1:d40d911b763a 14 */
persoder 1:d40d911b763a 15 typedef void (*nRF2401A_rx_handler_t)(void *);
persoder 1:d40d911b763a 16
persoder 0:3fe71769ad07 17 /**
persoder 0:3fe71769ad07 18 *
persoder 0:3fe71769ad07 19 *
persoder 0:3fe71769ad07 20 */
persoder 0:3fe71769ad07 21 class nRF2401A
persoder 0:3fe71769ad07 22 {
persoder 0:3fe71769ad07 23 public:
persoder 1:d40d911b763a 24 /** Class constructor.
persoder 1:d40d911b763a 25 * The constructor assigns the specified pinout, attatch the
persoder 1:d40d911b763a 26 * DR1 to a pin interrupt and sets up inmutable control packet
persoder 1:d40d911b763a 27 * fields.
persoder 1:d40d911b763a 28 * \param ce Chip Enable (CE) pin of the nRF2401A.
persoder 1:d40d911b763a 29 * \param c2 Chip Select (CS) pin of the nRF2401A.
persoder 1:d40d911b763a 30 * \param dr1 Data Ready 1 (DR1) pin of the nRF2401A.
persoder 1:d40d911b763a 31 * \param clk1 Clock 1 (CLK1) pin of the nRF2401A.
persoder 1:d40d911b763a 32 * \param data Data (DATA) pin of the nRF2401A.
persoder 0:3fe71769ad07 33 */
persoder 0:3fe71769ad07 34 nRF2401A(PinName ce,
persoder 0:3fe71769ad07 35 PinName cs,
persoder 0:3fe71769ad07 36 PinName dr1,
persoder 0:3fe71769ad07 37 PinName clk1,
persoder 1:d40d911b763a 38 PinName data);
persoder 1:d40d911b763a 39
persoder 1:d40d911b763a 40 /** Class destructor.
persoder 1:d40d911b763a 41 * Pretty much useless in the embedded world...
persoder 1:d40d911b763a 42 */
persoder 1:d40d911b763a 43 virtual ~nRF2401A() { return; }
persoder 1:d40d911b763a 44
persoder 1:d40d911b763a 45 /** Set the payload length, in bits.
persoder 1:d40d911b763a 46 * Set the control packet field for length, in number of bits, of the message payload.
persoder 1:d40d911b763a 47 * \param n Number of bits of the message payload.
persoder 1:d40d911b763a 48 * \return Reference to the invoked object (for chaining operations).
persoder 1:d40d911b763a 49 */
persoder 1:d40d911b763a 50 nRF2401A& setDataPayloadLength(uint8_t n)
persoder 1:d40d911b763a 51 {
persoder 1:d40d911b763a 52 _ctrl_packet_buf.channel_1_data_payload_len = n;
persoder 1:d40d911b763a 53 return *this;
persoder 0:3fe71769ad07 54 }
persoder 0:3fe71769ad07 55
persoder 1:d40d911b763a 56 /** Set the address of channel 1.
persoder 1:d40d911b763a 57 * The channel address is a up to 40 bit number identifying the tranciever.
persoder 1:d40d911b763a 58 * \param addr4 Bits 39-32 of the address.
persoder 1:d40d911b763a 59 * \param addr4 Bits 31-24 of the address.
persoder 1:d40d911b763a 60 * \param addr4 Bits 23-16 of the address.
persoder 1:d40d911b763a 61 * \param addr4 Bits 15-8 of the address.
persoder 1:d40d911b763a 62 * \param addr4 Bits 7-0 of the address.
persoder 1:d40d911b763a 63 * \param n_bits Number of bits used in the address.
persoder 1:d40d911b763a 64 * \return Reference to the invoked object (for chaining operations).
persoder 0:3fe71769ad07 65 */
persoder 0:3fe71769ad07 66 nRF2401A& setAddress(uint8_t addr4, uint8_t addr3, uint8_t addr2, uint8_t addr1, uint8_t addr0, uint8_t n_bits)
persoder 0:3fe71769ad07 67 {
persoder 0:3fe71769ad07 68 _ctrl_packet_buf.channel_1_address[0] = addr4;
persoder 0:3fe71769ad07 69 _ctrl_packet_buf.channel_1_address[1] = addr3;
persoder 0:3fe71769ad07 70 _ctrl_packet_buf.channel_1_address[2] = addr2;
persoder 0:3fe71769ad07 71 _ctrl_packet_buf.channel_1_address[3] = addr1;
persoder 0:3fe71769ad07 72 _ctrl_packet_buf.channel_1_address[4] = addr0;
persoder 0:3fe71769ad07 73 _ctrl_packet_buf.channel_address_len = n_bits;
persoder 0:3fe71769ad07 74
persoder 0:3fe71769ad07 75 return *this;
persoder 0:3fe71769ad07 76 }
persoder 0:3fe71769ad07 77
persoder 1:d40d911b763a 78 /** CRC settings.
persoder 1:d40d911b763a 79 * Type covering the allowed settings for use of CRC.
persoder 0:3fe71769ad07 80 */
persoder 1:d40d911b763a 81 typedef enum
persoder 1:d40d911b763a 82 {
persoder 1:d40d911b763a 83 NO_CRC = 0x0, /**< Do not use CRC. */
persoder 1:d40d911b763a 84 CRC_8 = 0x1, /**< Use a 8-bit CRC. */
persoder 1:d40d911b763a 85 CRC_16 = 0x3 /**< Use a 16-bit CRC. */
persoder 1:d40d911b763a 86 } CRC_T;
persoder 1:d40d911b763a 87
persoder 1:d40d911b763a 88 /** Set CRC use.
persoder 1:d40d911b763a 89 * Set the CRC mode field of the control packet.
persoder 1:d40d911b763a 90 * \param mode The CRC mode of choise.
persoder 1:d40d911b763a 91 * \return Reference to the invoked object (for chaining operations).
persoder 1:d40d911b763a 92 */
persoder 1:d40d911b763a 93 nRF2401A& setCRCMode(CRC_T mode)
persoder 1:d40d911b763a 94 {
persoder 1:d40d911b763a 95 _ctrl_packet_buf.crc_config = mode;
persoder 1:d40d911b763a 96 return *this;
persoder 1:d40d911b763a 97 }
persoder 0:3fe71769ad07 98
persoder 1:d40d911b763a 99 /** Data rate settings.
persoder 1:d40d911b763a 100 * Type covering the allowed settings for the tranciever data rate.
persoder 1:d40d911b763a 101 */
persoder 1:d40d911b763a 102 typedef enum
persoder 1:d40d911b763a 103 {
persoder 1:d40d911b763a 104 BIT_RATE_250KBITS = 0x0, /**< */
persoder 1:d40d911b763a 105 BIT_RATE_1MBITS = 0x1 /**< */
persoder 1:d40d911b763a 106 } DATA_RATE_T;
persoder 1:d40d911b763a 107
persoder 1:d40d911b763a 108 /** Set tranciever data rate.
persoder 1:d40d911b763a 109 * Sets the data rate field to either 250 kbit/s or 1 Mbit/s data transfer rate.
persoder 1:d40d911b763a 110 * \param mode The data rate of choise.
persoder 1:d40d911b763a 111 * \return Reference to the invoked object (for chaining operations).
persoder 0:3fe71769ad07 112 */
persoder 1:d40d911b763a 113 nRF2401A& setDataRate(DATA_RATE_T data_rate)
persoder 1:d40d911b763a 114 {
persoder 1:d40d911b763a 115 _ctrl_packet_buf.rf_data_rate = data_rate;
persoder 1:d40d911b763a 116 return *this;
persoder 1:d40d911b763a 117 }
persoder 1:d40d911b763a 118
persoder 1:d40d911b763a 119 /** Set RF channel.
persoder 1:d40d911b763a 120 * Sets the control packet field for channel number. Channel numbers are from 0 to 127
persoder 1:d40d911b763a 121 * representing channel frequencies equal to (2400 + channel number) MHz.
persoder 1:d40d911b763a 122 * \param ch Channel number, from the range [0, 127].
persoder 1:d40d911b763a 123 * \return Reference to the invoked object (for chaining operations).
persoder 1:d40d911b763a 124 */
persoder 1:d40d911b763a 125 nRF2401A& setChannel(uint8_t ch)
persoder 1:d40d911b763a 126 {
persoder 1:d40d911b763a 127 _ctrl_packet_buf.rf_channel = ch;
persoder 1:d40d911b763a 128 return *this;
persoder 1:d40d911b763a 129 }
persoder 1:d40d911b763a 130
persoder 1:d40d911b763a 131 /** Send the control packet to the nRF2401A.
persoder 1:d40d911b763a 132 * This function transfer the control packet image to the nRF2401A.
persoder 1:d40d911b763a 133 * \return Reference to the invoked object (for chaining operations).
persoder 1:d40d911b763a 134 */
persoder 1:d40d911b763a 135 nRF2401A& flushControlPacket();
persoder 0:3fe71769ad07 136
persoder 0:3fe71769ad07 137 /**
persoder 0:3fe71769ad07 138 *
persoder 0:3fe71769ad07 139 */
persoder 1:d40d911b763a 140 void activate(bool active = true);
persoder 0:3fe71769ad07 141
persoder 0:3fe71769ad07 142 /**
persoder 0:3fe71769ad07 143 *
persoder 0:3fe71769ad07 144 */
persoder 1:d40d911b763a 145 typedef uint8_t address_t[5];
persoder 1:d40d911b763a 146
persoder 1:d40d911b763a 147 /** Send a message.
persoder 1:d40d911b763a 148 * This routine will transfer the data from the supplied buffer and send
persoder 1:d40d911b763a 149 * it to the specified address using the current control packet settings.
persoder 1:d40d911b763a 150 * \param addr The address to send to.
persoder 1:d40d911b763a 151 * \param addr_len Length of address, in bits.
persoder 1:d40d911b763a 152 * \param msg_buf Message body.
persoder 1:d40d911b763a 153 * \param msg_len Length of message, in bits.
persoder 1:d40d911b763a 154 * \return Reference to the invoked object (for chaining operations).
persoder 1:d40d911b763a 155 */
persoder 1:d40d911b763a 156 nRF2401A& sendMsg(address_t addr, uint8_t addr_len, uint8_t *msg_buf, uint8_t msg_len);
persoder 0:3fe71769ad07 157
persoder 1:d40d911b763a 158 /** Register a receive action callback.
persoder 1:d40d911b763a 159 * Attach a callback that will be called when the tranciever intercept a
persoder 1:d40d911b763a 160 * message. This callback will be called in the context of an interrupt
persoder 1:d40d911b763a 161 * routine and should act accordingly.
persoder 1:d40d911b763a 162 * \param handler The callback, of type nRF2401_rx_handler_t.
persoder 1:d40d911b763a 163 * \param arg Pointer to data supplied to the handler at call time.
persoder 1:d40d911b763a 164 * \return Reference to the invoked object (for chaining operations).
persoder 1:d40d911b763a 165 */
persoder 1:d40d911b763a 166 nRF2401A& attachRXHandler(nRF2401A_rx_handler_t handler, void *arg);
persoder 1:d40d911b763a 167
persoder 1:d40d911b763a 168 void printControlPacket(Serial& port);
persoder 1:d40d911b763a 169 void printDataPacket(Serial& port);
persoder 0:3fe71769ad07 170
persoder 0:3fe71769ad07 171 private:
persoder 0:3fe71769ad07 172
persoder 1:d40d911b763a 173 DigitalOut _ce; /**< Chip Enable pin. */
persoder 1:d40d911b763a 174 DigitalOut _cs; /**< Chip select pin. */
persoder 1:d40d911b763a 175 DigitalIn _dr1; /**< Data Ready 1 pin. */
persoder 1:d40d911b763a 176 DigitalOut _clk1; /**< Clock 1 pin. */
persoder 1:d40d911b763a 177 DigitalInOut _data; /**< Data pin. */
persoder 0:3fe71769ad07 178
persoder 1:d40d911b763a 179 /**
persoder 1:d40d911b763a 180 *
persoder 1:d40d911b763a 181 */
persoder 1:d40d911b763a 182 typedef enum
persoder 1:d40d911b763a 183 {
persoder 1:d40d911b763a 184 UNDEF, /**< The start state. */
persoder 1:d40d911b763a 185 RX, /**< The tranciever is in receive mode. */
persoder 1:d40d911b763a 186 TX, /**< The tranciever is transmitting. */
persoder 1:d40d911b763a 187 STANDBY /**< The tranciever goes into stanby mode. */
persoder 1:d40d911b763a 188 } STATE_T;
persoder 1:d40d911b763a 189
persoder 1:d40d911b763a 190 STATE_T _state;
persoder 1:d40d911b763a 191
persoder 1:d40d911b763a 192 /** Contol packet data.
persoder 1:d40d911b763a 193 *
persoder 1:d40d911b763a 194 */
persoder 0:3fe71769ad07 195 struct nRF2401A_ctrl_packet_t
persoder 0:3fe71769ad07 196 {
persoder 0:3fe71769ad07 197 uint8_t channel_2_data_payload_len; /**< */
persoder 0:3fe71769ad07 198 uint8_t channel_1_data_payload_len; /**< */
persoder 0:3fe71769ad07 199 uint8_t channel_2_address[5]; /**< */
persoder 0:3fe71769ad07 200 uint8_t channel_1_address[5]; /**< */
persoder 0:3fe71769ad07 201
persoder 1:d40d911b763a 202 uint8_t crc_config : 2; /**< */
persoder 0:3fe71769ad07 203 uint8_t channel_address_len : 6; /**< */
persoder 0:3fe71769ad07 204
persoder 1:d40d911b763a 205 uint8_t rf_power : 2; /**< */
persoder 1:d40d911b763a 206 uint8_t xo_frequency : 3; /**< */
persoder 0:3fe71769ad07 207 uint8_t rf_data_rate : 1; /**< */
persoder 1:d40d911b763a 208 uint8_t communication_mode : 1; /**< */
persoder 1:d40d911b763a 209 uint8_t enable_dual_channel_mode : 1; /**< */
persoder 0:3fe71769ad07 210
persoder 1:d40d911b763a 211 uint8_t txr_switch : 1; /**< */
persoder 0:3fe71769ad07 212 uint8_t rf_channel : 7; /**< */
persoder 0:3fe71769ad07 213
persoder 0:3fe71769ad07 214 } _ctrl_packet_buf; /**< */
persoder 1:d40d911b763a 215
persoder 1:d40d911b763a 216 uint8_t *_ctrl_packet; /**< */
persoder 1:d40d911b763a 217
persoder 1:d40d911b763a 218 uint8_t _data_buf[32]; /**< */
persoder 1:d40d911b763a 219
persoder 1:d40d911b763a 220 nRF2401A_rx_handler_t _rx_handler; /**< */
persoder 1:d40d911b763a 221 void *_rx_handler_arg; /**< */
persoder 1:d40d911b763a 222
persoder 1:d40d911b763a 223 /** Receive ISR.
persoder 1:d40d911b763a 224 * This handler is attached to the rising flank of the DR1 pin. It
persoder 1:d40d911b763a 225 * will thus be called when the nRF2401A receives a packet in ShockBurst
persoder 1:d40d911b763a 226 * mode (the mode used). It will in turn call the attached handler.
persoder 1:d40d911b763a 227 */
persoder 1:d40d911b763a 228 void dataReadyHandler(void);
persoder 1:d40d911b763a 229
persoder 1:d40d911b763a 230 /**
persoder 1:d40d911b763a 231 *
persoder 1:d40d911b763a 232 */
persoder 1:d40d911b763a 233 InterruptIn _dr1_isr;
persoder 1:d40d911b763a 234
persoder 1:d40d911b763a 235 /*
persoder 1:d40d911b763a 236 *
persoder 1:d40d911b763a 237 */
persoder 1:d40d911b763a 238 typedef enum { RX_MODE = 0x1, TX_MODE = 0x0 } TXR_T;
persoder 1:d40d911b763a 239
persoder 1:d40d911b763a 240 /** Write to the data bus.
persoder 1:d40d911b763a 241 * Write n_bits bits on the DATA line.
persoder 1:d40d911b763a 242 * \param buf Data buffer.
persoder 1:d40d911b763a 243 * \param n_bits Number of bits to transfer.
persoder 1:d40d911b763a 244 * \param is_ctrl True if the tranfered data is control word, false if data.
persoder 1:d40d911b763a 245 */
persoder 1:d40d911b763a 246 void pushCtrl(uint8_t *buf, uint8_t n_bits, bool is_ctrl = true);
persoder 1:d40d911b763a 247
persoder 1:d40d911b763a 248 /** Read a message from the tranciever.
persoder 1:d40d911b763a 249 * Read until DR1 goes low.
persoder 1:d40d911b763a 250 * \param buf Data buffer.
persoder 1:d40d911b763a 251 * \return Number of bits read.
persoder 1:d40d911b763a 252 */
persoder 1:d40d911b763a 253 int pull(uint8_t *buf);
persoder 1:d40d911b763a 254 };