This is for our FYDP project. 2 MPU6050s are used

Dependencies:   Servo mbed

Committer:
majik
Date:
Sat Mar 21 21:31:29 2015 +0000
Revision:
0:21019d94ad33
Both IMUs work now

Who changed what in which revision?

UserRevisionLine numberNew contents of line
majik 0:21019d94ad33 1 /**
majik 0:21019d94ad33 2 * @file nRF24L01P.cpp
majik 0:21019d94ad33 3 *
majik 0:21019d94ad33 4 * @author Owen Edwards
majik 0:21019d94ad33 5 *
majik 0:21019d94ad33 6 * @section LICENSE
majik 0:21019d94ad33 7 *
majik 0:21019d94ad33 8 * Copyright (c) 2010 Owen Edwards
majik 0:21019d94ad33 9 *
majik 0:21019d94ad33 10 * This program is free software: you can redistribute it and/or modify
majik 0:21019d94ad33 11 * it under the terms of the GNU General Public License as published by
majik 0:21019d94ad33 12 * the Free Software Foundation, either version 3 of the License, or
majik 0:21019d94ad33 13 * (at your option) any later version.
majik 0:21019d94ad33 14 *
majik 0:21019d94ad33 15 * This program is distributed in the hope that it will be useful,
majik 0:21019d94ad33 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
majik 0:21019d94ad33 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
majik 0:21019d94ad33 18 * GNU General Public License for more details.
majik 0:21019d94ad33 19 *
majik 0:21019d94ad33 20 * You should have received a copy of the GNU General Public License
majik 0:21019d94ad33 21 * along with this program. If not, see <http://www.gnu.org/licenses/>.
majik 0:21019d94ad33 22 *
majik 0:21019d94ad33 23 * The above copyright notice and this permission notice shall be included in
majik 0:21019d94ad33 24 * all copies or substantial portions of the Software.
majik 0:21019d94ad33 25 *
majik 0:21019d94ad33 26 * @section DESCRIPTION
majik 0:21019d94ad33 27 *
majik 0:21019d94ad33 28 * nRF24L01+ Single Chip 2.4GHz Transceiver from Nordic Semiconductor.
majik 0:21019d94ad33 29 *
majik 0:21019d94ad33 30 * Datasheet:
majik 0:21019d94ad33 31 *
majik 0:21019d94ad33 32 * http://www.nordicsemi.no/files/Product/data_sheet/nRF24L01P_Product_Specification_1_0.pdf
majik 0:21019d94ad33 33 */
majik 0:21019d94ad33 34
majik 0:21019d94ad33 35 /**
majik 0:21019d94ad33 36 * Includes
majik 0:21019d94ad33 37 */
majik 0:21019d94ad33 38 #include "nRF24L01P.h"
majik 0:21019d94ad33 39
majik 0:21019d94ad33 40 /**
majik 0:21019d94ad33 41 * Defines
majik 0:21019d94ad33 42 *
majik 0:21019d94ad33 43 * (Note that all defines here start with an underscore, e.g. '_NRF24L01P_MODE_UNKNOWN',
majik 0:21019d94ad33 44 * and are local to this library. The defines in the nRF24L01P.h file do not start
majik 0:21019d94ad33 45 * with the underscore, and can be used by code to access this library.)
majik 0:21019d94ad33 46 */
majik 0:21019d94ad33 47
majik 0:21019d94ad33 48 typedef enum {
majik 0:21019d94ad33 49 _NRF24L01P_MODE_UNKNOWN,
majik 0:21019d94ad33 50 _NRF24L01P_MODE_POWER_DOWN,
majik 0:21019d94ad33 51 _NRF24L01P_MODE_STANDBY,
majik 0:21019d94ad33 52 _NRF24L01P_MODE_RX,
majik 0:21019d94ad33 53 _NRF24L01P_MODE_TX,
majik 0:21019d94ad33 54 } nRF24L01P_Mode_Type;
majik 0:21019d94ad33 55
majik 0:21019d94ad33 56 /*
majik 0:21019d94ad33 57 * The following FIFOs are present in nRF24L01+:
majik 0:21019d94ad33 58 * TX three level, 32 byte FIFO
majik 0:21019d94ad33 59 * RX three level, 32 byte FIFO
majik 0:21019d94ad33 60 */
majik 0:21019d94ad33 61 #define _NRF24L01P_TX_FIFO_COUNT 3
majik 0:21019d94ad33 62 #define _NRF24L01P_RX_FIFO_COUNT 3
majik 0:21019d94ad33 63
majik 0:21019d94ad33 64 #define _NRF24L01P_TX_FIFO_SIZE 32
majik 0:21019d94ad33 65 #define _NRF24L01P_RX_FIFO_SIZE 32
majik 0:21019d94ad33 66
majik 0:21019d94ad33 67 #define _NRF24L01P_SPI_MAX_DATA_RATE 10000000
majik 0:21019d94ad33 68
majik 0:21019d94ad33 69 #define _NRF24L01P_SPI_CMD_RD_REG 0x00
majik 0:21019d94ad33 70 #define _NRF24L01P_SPI_CMD_WR_REG 0x20
majik 0:21019d94ad33 71 #define _NRF24L01P_SPI_CMD_RD_RX_PAYLOAD 0x61
majik 0:21019d94ad33 72 #define _NRF24L01P_SPI_CMD_WR_TX_PAYLOAD 0xa0
majik 0:21019d94ad33 73 #define _NRF24L01P_SPI_CMD_FLUSH_TX 0xe1
majik 0:21019d94ad33 74 #define _NRF24L01P_SPI_CMD_FLUSH_RX 0xe2
majik 0:21019d94ad33 75 #define _NRF24L01P_SPI_CMD_REUSE_TX_PL 0xe3
majik 0:21019d94ad33 76 #define _NRF24L01P_SPI_CMD_R_RX_PL_WID 0x60
majik 0:21019d94ad33 77 #define _NRF24L01P_SPI_CMD_W_ACK_PAYLOAD 0xa8
majik 0:21019d94ad33 78 #define _NRF24L01P_SPI_CMD_W_TX_PYLD_NO_ACK 0xb0
majik 0:21019d94ad33 79 #define _NRF24L01P_SPI_CMD_NOP 0xff
majik 0:21019d94ad33 80
majik 0:21019d94ad33 81
majik 0:21019d94ad33 82 #define _NRF24L01P_REG_CONFIG 0x00
majik 0:21019d94ad33 83 #define _NRF24L01P_REG_EN_AA 0x01
majik 0:21019d94ad33 84 #define _NRF24L01P_REG_EN_RXADDR 0x02
majik 0:21019d94ad33 85 #define _NRF24L01P_REG_SETUP_AW 0x03
majik 0:21019d94ad33 86 #define _NRF24L01P_REG_SETUP_RETR 0x04
majik 0:21019d94ad33 87 #define _NRF24L01P_REG_RF_CH 0x05
majik 0:21019d94ad33 88 #define _NRF24L01P_REG_RF_SETUP 0x06
majik 0:21019d94ad33 89 #define _NRF24L01P_REG_STATUS 0x07
majik 0:21019d94ad33 90 #define _NRF24L01P_REG_OBSERVE_TX 0x08
majik 0:21019d94ad33 91 #define _NRF24L01P_REG_RPD 0x09
majik 0:21019d94ad33 92 #define _NRF24L01P_REG_RX_ADDR_P0 0x0a
majik 0:21019d94ad33 93 #define _NRF24L01P_REG_RX_ADDR_P1 0x0b
majik 0:21019d94ad33 94 #define _NRF24L01P_REG_RX_ADDR_P2 0x0c
majik 0:21019d94ad33 95 #define _NRF24L01P_REG_RX_ADDR_P3 0x0d
majik 0:21019d94ad33 96 #define _NRF24L01P_REG_RX_ADDR_P4 0x0e
majik 0:21019d94ad33 97 #define _NRF24L01P_REG_RX_ADDR_P5 0x0f
majik 0:21019d94ad33 98 #define _NRF24L01P_REG_TX_ADDR 0x10
majik 0:21019d94ad33 99 #define _NRF24L01P_REG_RX_PW_P0 0x11
majik 0:21019d94ad33 100 #define _NRF24L01P_REG_RX_PW_P1 0x12
majik 0:21019d94ad33 101 #define _NRF24L01P_REG_RX_PW_P2 0x13
majik 0:21019d94ad33 102 #define _NRF24L01P_REG_RX_PW_P3 0x14
majik 0:21019d94ad33 103 #define _NRF24L01P_REG_RX_PW_P4 0x15
majik 0:21019d94ad33 104 #define _NRF24L01P_REG_RX_PW_P5 0x16
majik 0:21019d94ad33 105 #define _NRF24L01P_REG_FIFO_STATUS 0x17
majik 0:21019d94ad33 106 #define _NRF24L01P_REG_DYNPD 0x1c
majik 0:21019d94ad33 107 #define _NRF24L01P_REG_FEATURE 0x1d
majik 0:21019d94ad33 108
majik 0:21019d94ad33 109 #define _NRF24L01P_REG_ADDRESS_MASK 0x1f
majik 0:21019d94ad33 110
majik 0:21019d94ad33 111 // CONFIG register:
majik 0:21019d94ad33 112 #define _NRF24L01P_CONFIG_PRIM_RX (1<<0)
majik 0:21019d94ad33 113 #define _NRF24L01P_CONFIG_PWR_UP (1<<1)
majik 0:21019d94ad33 114 #define _NRF24L01P_CONFIG_CRC0 (1<<2)
majik 0:21019d94ad33 115 #define _NRF24L01P_CONFIG_EN_CRC (1<<3)
majik 0:21019d94ad33 116 #define _NRF24L01P_CONFIG_MASK_MAX_RT (1<<4)
majik 0:21019d94ad33 117 #define _NRF24L01P_CONFIG_MASK_TX_DS (1<<5)
majik 0:21019d94ad33 118 #define _NRF24L01P_CONFIG_MASK_RX_DR (1<<6)
majik 0:21019d94ad33 119
majik 0:21019d94ad33 120 #define _NRF24L01P_CONFIG_CRC_MASK (_NRF24L01P_CONFIG_EN_CRC|_NRF24L01P_CONFIG_CRC0)
majik 0:21019d94ad33 121 #define _NRF24L01P_CONFIG_CRC_NONE (0)
majik 0:21019d94ad33 122 #define _NRF24L01P_CONFIG_CRC_8BIT (_NRF24L01P_CONFIG_EN_CRC)
majik 0:21019d94ad33 123 #define _NRF24L01P_CONFIG_CRC_16BIT (_NRF24L01P_CONFIG_EN_CRC|_NRF24L01P_CONFIG_CRC0)
majik 0:21019d94ad33 124
majik 0:21019d94ad33 125 // EN_AA register:
majik 0:21019d94ad33 126 #define _NRF24L01P_EN_AA_NONE 0
majik 0:21019d94ad33 127
majik 0:21019d94ad33 128 // EN_RXADDR register:
majik 0:21019d94ad33 129 #define _NRF24L01P_EN_RXADDR_NONE 0
majik 0:21019d94ad33 130
majik 0:21019d94ad33 131 // SETUP_AW register:
majik 0:21019d94ad33 132 #define _NRF24L01P_SETUP_AW_AW_MASK (0x3<<0)
majik 0:21019d94ad33 133 #define _NRF24L01P_SETUP_AW_AW_3BYTE (0x1<<0)
majik 0:21019d94ad33 134 #define _NRF24L01P_SETUP_AW_AW_4BYTE (0x2<<0)
majik 0:21019d94ad33 135 #define _NRF24L01P_SETUP_AW_AW_5BYTE (0x3<<0)
majik 0:21019d94ad33 136
majik 0:21019d94ad33 137 // SETUP_RETR register:
majik 0:21019d94ad33 138 #define _NRF24L01P_SETUP_RETR_NONE 0
majik 0:21019d94ad33 139
majik 0:21019d94ad33 140 // RF_SETUP register:
majik 0:21019d94ad33 141 #define _NRF24L01P_RF_SETUP_RF_PWR_MASK (0x3<<1)
majik 0:21019d94ad33 142 #define _NRF24L01P_RF_SETUP_RF_PWR_0DBM (0x3<<1)
majik 0:21019d94ad33 143 #define _NRF24L01P_RF_SETUP_RF_PWR_MINUS_6DBM (0x2<<1)
majik 0:21019d94ad33 144 #define _NRF24L01P_RF_SETUP_RF_PWR_MINUS_12DBM (0x1<<1)
majik 0:21019d94ad33 145 #define _NRF24L01P_RF_SETUP_RF_PWR_MINUS_18DBM (0x0<<1)
majik 0:21019d94ad33 146
majik 0:21019d94ad33 147 #define _NRF24L01P_RF_SETUP_RF_DR_HIGH_BIT (1 << 3)
majik 0:21019d94ad33 148 #define _NRF24L01P_RF_SETUP_RF_DR_LOW_BIT (1 << 5)
majik 0:21019d94ad33 149 #define _NRF24L01P_RF_SETUP_RF_DR_MASK (_NRF24L01P_RF_SETUP_RF_DR_LOW_BIT|_NRF24L01P_RF_SETUP_RF_DR_HIGH_BIT)
majik 0:21019d94ad33 150 #define _NRF24L01P_RF_SETUP_RF_DR_250KBPS (_NRF24L01P_RF_SETUP_RF_DR_LOW_BIT)
majik 0:21019d94ad33 151 #define _NRF24L01P_RF_SETUP_RF_DR_1MBPS (0)
majik 0:21019d94ad33 152 #define _NRF24L01P_RF_SETUP_RF_DR_2MBPS (_NRF24L01P_RF_SETUP_RF_DR_HIGH_BIT)
majik 0:21019d94ad33 153
majik 0:21019d94ad33 154 // STATUS register:
majik 0:21019d94ad33 155 #define _NRF24L01P_STATUS_TX_FULL (1<<0)
majik 0:21019d94ad33 156 #define _NRF24L01P_STATUS_RX_P_NO (0x7<<1)
majik 0:21019d94ad33 157 #define _NRF24L01P_STATUS_MAX_RT (1<<4)
majik 0:21019d94ad33 158 #define _NRF24L01P_STATUS_TX_DS (1<<5)
majik 0:21019d94ad33 159 #define _NRF24L01P_STATUS_RX_DR (1<<6)
majik 0:21019d94ad33 160
majik 0:21019d94ad33 161 // RX_PW_P0..RX_PW_P5 registers:
majik 0:21019d94ad33 162 #define _NRF24L01P_RX_PW_Px_MASK 0x3F
majik 0:21019d94ad33 163
majik 0:21019d94ad33 164 #define _NRF24L01P_TIMING_Tundef2pd_us 100000 // 100mS
majik 0:21019d94ad33 165 #define _NRF24L01P_TIMING_Tstby2a_us 130 // 130uS
majik 0:21019d94ad33 166 #define _NRF24L01P_TIMING_Thce_us 10 // 10uS
majik 0:21019d94ad33 167 #define _NRF24L01P_TIMING_Tpd2stby_us 4500 // 4.5mS worst case
majik 0:21019d94ad33 168 #define _NRF24L01P_TIMING_Tpece2csn_us 4 // 4uS
majik 0:21019d94ad33 169
majik 0:21019d94ad33 170 /**
majik 0:21019d94ad33 171 * Methods
majik 0:21019d94ad33 172 */
majik 0:21019d94ad33 173
majik 0:21019d94ad33 174 nRF24L01P::nRF24L01P(PinName mosi,
majik 0:21019d94ad33 175 PinName miso,
majik 0:21019d94ad33 176 PinName sck,
majik 0:21019d94ad33 177 PinName csn,
majik 0:21019d94ad33 178 PinName ce,
majik 0:21019d94ad33 179 PinName irq) : spi_(mosi, miso, sck), nCS_(csn), ce_(ce), nIRQ_(irq) {
majik 0:21019d94ad33 180
majik 0:21019d94ad33 181 mode = _NRF24L01P_MODE_UNKNOWN;
majik 0:21019d94ad33 182
majik 0:21019d94ad33 183 disable();
majik 0:21019d94ad33 184
majik 0:21019d94ad33 185 nCS_ = 1;
majik 0:21019d94ad33 186
majik 0:21019d94ad33 187 spi_.frequency(_NRF24L01P_SPI_MAX_DATA_RATE/5); // 2Mbit, 1/5th the maximum transfer rate for the SPI bus
majik 0:21019d94ad33 188 spi_.format(8,0); // 8-bit, ClockPhase = 0, ClockPolarity = 0
majik 0:21019d94ad33 189
majik 0:21019d94ad33 190 wait_us(_NRF24L01P_TIMING_Tundef2pd_us); // Wait for Power-on reset
majik 0:21019d94ad33 191
majik 0:21019d94ad33 192 setRegister(_NRF24L01P_REG_CONFIG, 0); // Power Down
majik 0:21019d94ad33 193
majik 0:21019d94ad33 194 setRegister(_NRF24L01P_REG_STATUS, _NRF24L01P_STATUS_MAX_RT|_NRF24L01P_STATUS_TX_DS|_NRF24L01P_STATUS_RX_DR); // Clear any pending interrupts
majik 0:21019d94ad33 195
majik 0:21019d94ad33 196 //
majik 0:21019d94ad33 197 // Setup default configuration
majik 0:21019d94ad33 198 //
majik 0:21019d94ad33 199 disableAllRxPipes();
majik 0:21019d94ad33 200 setRfFrequency();
majik 0:21019d94ad33 201 setRfOutputPower();
majik 0:21019d94ad33 202 setAirDataRate();
majik 0:21019d94ad33 203 setCrcWidth();
majik 0:21019d94ad33 204 setTxAddress();
majik 0:21019d94ad33 205 setRxAddress();
majik 0:21019d94ad33 206 disableAutoAcknowledge();
majik 0:21019d94ad33 207 disableAutoRetransmit();
majik 0:21019d94ad33 208 setTransferSize();
majik 0:21019d94ad33 209
majik 0:21019d94ad33 210 mode = _NRF24L01P_MODE_POWER_DOWN;
majik 0:21019d94ad33 211
majik 0:21019d94ad33 212 }
majik 0:21019d94ad33 213
majik 0:21019d94ad33 214
majik 0:21019d94ad33 215 void nRF24L01P::powerUp(void) {
majik 0:21019d94ad33 216
majik 0:21019d94ad33 217 int config = getRegister(_NRF24L01P_REG_CONFIG);
majik 0:21019d94ad33 218
majik 0:21019d94ad33 219 config |= _NRF24L01P_CONFIG_PWR_UP;
majik 0:21019d94ad33 220
majik 0:21019d94ad33 221 setRegister(_NRF24L01P_REG_CONFIG, config);
majik 0:21019d94ad33 222
majik 0:21019d94ad33 223 // Wait until the nRF24L01+ powers up
majik 0:21019d94ad33 224 wait_us( _NRF24L01P_TIMING_Tpd2stby_us );
majik 0:21019d94ad33 225
majik 0:21019d94ad33 226 mode = _NRF24L01P_MODE_STANDBY;
majik 0:21019d94ad33 227
majik 0:21019d94ad33 228 }
majik 0:21019d94ad33 229
majik 0:21019d94ad33 230
majik 0:21019d94ad33 231 void nRF24L01P::powerDown(void) {
majik 0:21019d94ad33 232
majik 0:21019d94ad33 233 int config = getRegister(_NRF24L01P_REG_CONFIG);
majik 0:21019d94ad33 234
majik 0:21019d94ad33 235 config &= ~_NRF24L01P_CONFIG_PWR_UP;
majik 0:21019d94ad33 236
majik 0:21019d94ad33 237 setRegister(_NRF24L01P_REG_CONFIG, config);
majik 0:21019d94ad33 238
majik 0:21019d94ad33 239 // Wait until the nRF24L01+ powers down
majik 0:21019d94ad33 240 wait_us( _NRF24L01P_TIMING_Tpd2stby_us ); // This *may* not be necessary (no timing is shown in the Datasheet), but just to be safe
majik 0:21019d94ad33 241
majik 0:21019d94ad33 242 mode = _NRF24L01P_MODE_POWER_DOWN;
majik 0:21019d94ad33 243
majik 0:21019d94ad33 244 }
majik 0:21019d94ad33 245
majik 0:21019d94ad33 246
majik 0:21019d94ad33 247 void nRF24L01P::setReceiveMode(void) {
majik 0:21019d94ad33 248
majik 0:21019d94ad33 249 if ( _NRF24L01P_MODE_POWER_DOWN == mode ) powerUp();
majik 0:21019d94ad33 250
majik 0:21019d94ad33 251 int config = getRegister(_NRF24L01P_REG_CONFIG);
majik 0:21019d94ad33 252
majik 0:21019d94ad33 253 config |= _NRF24L01P_CONFIG_PRIM_RX;
majik 0:21019d94ad33 254
majik 0:21019d94ad33 255 setRegister(_NRF24L01P_REG_CONFIG, config);
majik 0:21019d94ad33 256
majik 0:21019d94ad33 257 mode = _NRF24L01P_MODE_RX;
majik 0:21019d94ad33 258
majik 0:21019d94ad33 259 }
majik 0:21019d94ad33 260
majik 0:21019d94ad33 261
majik 0:21019d94ad33 262 void nRF24L01P::setTransmitMode(void) {
majik 0:21019d94ad33 263
majik 0:21019d94ad33 264 if ( _NRF24L01P_MODE_POWER_DOWN == mode ) powerUp();
majik 0:21019d94ad33 265
majik 0:21019d94ad33 266 int config = getRegister(_NRF24L01P_REG_CONFIG);
majik 0:21019d94ad33 267
majik 0:21019d94ad33 268 config &= ~_NRF24L01P_CONFIG_PRIM_RX;
majik 0:21019d94ad33 269
majik 0:21019d94ad33 270 setRegister(_NRF24L01P_REG_CONFIG, config);
majik 0:21019d94ad33 271
majik 0:21019d94ad33 272 mode = _NRF24L01P_MODE_TX;
majik 0:21019d94ad33 273
majik 0:21019d94ad33 274 }
majik 0:21019d94ad33 275
majik 0:21019d94ad33 276
majik 0:21019d94ad33 277 void nRF24L01P::enable(void) {
majik 0:21019d94ad33 278
majik 0:21019d94ad33 279 ce_ = 1;
majik 0:21019d94ad33 280 wait_us( _NRF24L01P_TIMING_Tpece2csn_us );
majik 0:21019d94ad33 281
majik 0:21019d94ad33 282 }
majik 0:21019d94ad33 283
majik 0:21019d94ad33 284
majik 0:21019d94ad33 285 void nRF24L01P::disable(void) {
majik 0:21019d94ad33 286
majik 0:21019d94ad33 287 ce_ = 0;
majik 0:21019d94ad33 288
majik 0:21019d94ad33 289 }
majik 0:21019d94ad33 290
majik 0:21019d94ad33 291 void nRF24L01P::setRfFrequency(int frequency) {
majik 0:21019d94ad33 292
majik 0:21019d94ad33 293 if ( ( frequency < NRF24L01P_MIN_RF_FREQUENCY ) || ( frequency > NRF24L01P_MAX_RF_FREQUENCY ) ) {
majik 0:21019d94ad33 294
majik 0:21019d94ad33 295 error( "nRF24L01P: Invalid RF Frequency setting %d\r\n", frequency );
majik 0:21019d94ad33 296 return;
majik 0:21019d94ad33 297
majik 0:21019d94ad33 298 }
majik 0:21019d94ad33 299
majik 0:21019d94ad33 300 int channel = ( frequency - NRF24L01P_MIN_RF_FREQUENCY ) & 0x7F;
majik 0:21019d94ad33 301
majik 0:21019d94ad33 302 setRegister(_NRF24L01P_REG_RF_CH, channel);
majik 0:21019d94ad33 303
majik 0:21019d94ad33 304 }
majik 0:21019d94ad33 305
majik 0:21019d94ad33 306
majik 0:21019d94ad33 307 int nRF24L01P::getRfFrequency(void) {
majik 0:21019d94ad33 308
majik 0:21019d94ad33 309 int channel = getRegister(_NRF24L01P_REG_RF_CH) & 0x7F;
majik 0:21019d94ad33 310
majik 0:21019d94ad33 311 return ( channel + NRF24L01P_MIN_RF_FREQUENCY );
majik 0:21019d94ad33 312
majik 0:21019d94ad33 313 }
majik 0:21019d94ad33 314
majik 0:21019d94ad33 315
majik 0:21019d94ad33 316 void nRF24L01P::setRfOutputPower(int power) {
majik 0:21019d94ad33 317
majik 0:21019d94ad33 318 int rfSetup = getRegister(_NRF24L01P_REG_RF_SETUP) & ~_NRF24L01P_RF_SETUP_RF_PWR_MASK;
majik 0:21019d94ad33 319
majik 0:21019d94ad33 320 switch ( power ) {
majik 0:21019d94ad33 321
majik 0:21019d94ad33 322 case NRF24L01P_TX_PWR_ZERO_DB:
majik 0:21019d94ad33 323 rfSetup |= _NRF24L01P_RF_SETUP_RF_PWR_0DBM;
majik 0:21019d94ad33 324 break;
majik 0:21019d94ad33 325
majik 0:21019d94ad33 326 case NRF24L01P_TX_PWR_MINUS_6_DB:
majik 0:21019d94ad33 327 rfSetup |= _NRF24L01P_RF_SETUP_RF_PWR_MINUS_6DBM;
majik 0:21019d94ad33 328 break;
majik 0:21019d94ad33 329
majik 0:21019d94ad33 330 case NRF24L01P_TX_PWR_MINUS_12_DB:
majik 0:21019d94ad33 331 rfSetup |= _NRF24L01P_RF_SETUP_RF_PWR_MINUS_12DBM;
majik 0:21019d94ad33 332 break;
majik 0:21019d94ad33 333
majik 0:21019d94ad33 334 case NRF24L01P_TX_PWR_MINUS_18_DB:
majik 0:21019d94ad33 335 rfSetup |= _NRF24L01P_RF_SETUP_RF_PWR_MINUS_18DBM;
majik 0:21019d94ad33 336 break;
majik 0:21019d94ad33 337
majik 0:21019d94ad33 338 default:
majik 0:21019d94ad33 339 error( "nRF24L01P: Invalid RF Output Power setting %d\r\n", power );
majik 0:21019d94ad33 340 return;
majik 0:21019d94ad33 341
majik 0:21019d94ad33 342 }
majik 0:21019d94ad33 343
majik 0:21019d94ad33 344 setRegister(_NRF24L01P_REG_RF_SETUP, rfSetup);
majik 0:21019d94ad33 345
majik 0:21019d94ad33 346 }
majik 0:21019d94ad33 347
majik 0:21019d94ad33 348
majik 0:21019d94ad33 349 int nRF24L01P::getRfOutputPower(void) {
majik 0:21019d94ad33 350
majik 0:21019d94ad33 351 int rfPwr = getRegister(_NRF24L01P_REG_RF_SETUP) & _NRF24L01P_RF_SETUP_RF_PWR_MASK;
majik 0:21019d94ad33 352
majik 0:21019d94ad33 353 switch ( rfPwr ) {
majik 0:21019d94ad33 354
majik 0:21019d94ad33 355 case _NRF24L01P_RF_SETUP_RF_PWR_0DBM:
majik 0:21019d94ad33 356 return NRF24L01P_TX_PWR_ZERO_DB;
majik 0:21019d94ad33 357
majik 0:21019d94ad33 358 case _NRF24L01P_RF_SETUP_RF_PWR_MINUS_6DBM:
majik 0:21019d94ad33 359 return NRF24L01P_TX_PWR_MINUS_6_DB;
majik 0:21019d94ad33 360
majik 0:21019d94ad33 361 case _NRF24L01P_RF_SETUP_RF_PWR_MINUS_12DBM:
majik 0:21019d94ad33 362 return NRF24L01P_TX_PWR_MINUS_12_DB;
majik 0:21019d94ad33 363
majik 0:21019d94ad33 364 case _NRF24L01P_RF_SETUP_RF_PWR_MINUS_18DBM:
majik 0:21019d94ad33 365 return NRF24L01P_TX_PWR_MINUS_18_DB;
majik 0:21019d94ad33 366
majik 0:21019d94ad33 367 default:
majik 0:21019d94ad33 368 error( "nRF24L01P: Unknown RF Output Power value %d\r\n", rfPwr );
majik 0:21019d94ad33 369 return 0;
majik 0:21019d94ad33 370
majik 0:21019d94ad33 371 }
majik 0:21019d94ad33 372 }
majik 0:21019d94ad33 373
majik 0:21019d94ad33 374
majik 0:21019d94ad33 375 void nRF24L01P::setAirDataRate(int rate) {
majik 0:21019d94ad33 376
majik 0:21019d94ad33 377 int rfSetup = getRegister(_NRF24L01P_REG_RF_SETUP) & ~_NRF24L01P_RF_SETUP_RF_DR_MASK;
majik 0:21019d94ad33 378
majik 0:21019d94ad33 379 switch ( rate ) {
majik 0:21019d94ad33 380
majik 0:21019d94ad33 381 case NRF24L01P_DATARATE_250_KBPS:
majik 0:21019d94ad33 382 rfSetup |= _NRF24L01P_RF_SETUP_RF_DR_250KBPS;
majik 0:21019d94ad33 383 break;
majik 0:21019d94ad33 384
majik 0:21019d94ad33 385 case NRF24L01P_DATARATE_1_MBPS:
majik 0:21019d94ad33 386 rfSetup |= _NRF24L01P_RF_SETUP_RF_DR_1MBPS;
majik 0:21019d94ad33 387 break;
majik 0:21019d94ad33 388
majik 0:21019d94ad33 389 case NRF24L01P_DATARATE_2_MBPS:
majik 0:21019d94ad33 390 rfSetup |= _NRF24L01P_RF_SETUP_RF_DR_2MBPS;
majik 0:21019d94ad33 391 break;
majik 0:21019d94ad33 392
majik 0:21019d94ad33 393 default:
majik 0:21019d94ad33 394 error( "nRF24L01P: Invalid Air Data Rate setting %d\r\n", rate );
majik 0:21019d94ad33 395 return;
majik 0:21019d94ad33 396
majik 0:21019d94ad33 397 }
majik 0:21019d94ad33 398
majik 0:21019d94ad33 399 setRegister(_NRF24L01P_REG_RF_SETUP, rfSetup);
majik 0:21019d94ad33 400
majik 0:21019d94ad33 401 }
majik 0:21019d94ad33 402
majik 0:21019d94ad33 403
majik 0:21019d94ad33 404 int nRF24L01P::getAirDataRate(void) {
majik 0:21019d94ad33 405
majik 0:21019d94ad33 406 int rfDataRate = getRegister(_NRF24L01P_REG_RF_SETUP) & _NRF24L01P_RF_SETUP_RF_DR_MASK;
majik 0:21019d94ad33 407
majik 0:21019d94ad33 408 switch ( rfDataRate ) {
majik 0:21019d94ad33 409
majik 0:21019d94ad33 410 case _NRF24L01P_RF_SETUP_RF_DR_250KBPS:
majik 0:21019d94ad33 411 return NRF24L01P_DATARATE_250_KBPS;
majik 0:21019d94ad33 412
majik 0:21019d94ad33 413 case _NRF24L01P_RF_SETUP_RF_DR_1MBPS:
majik 0:21019d94ad33 414 return NRF24L01P_DATARATE_1_MBPS;
majik 0:21019d94ad33 415
majik 0:21019d94ad33 416 case _NRF24L01P_RF_SETUP_RF_DR_2MBPS:
majik 0:21019d94ad33 417 return NRF24L01P_DATARATE_2_MBPS;
majik 0:21019d94ad33 418
majik 0:21019d94ad33 419 default:
majik 0:21019d94ad33 420 error( "nRF24L01P: Unknown Air Data Rate value %d\r\n", rfDataRate );
majik 0:21019d94ad33 421 return 0;
majik 0:21019d94ad33 422
majik 0:21019d94ad33 423 }
majik 0:21019d94ad33 424 }
majik 0:21019d94ad33 425
majik 0:21019d94ad33 426
majik 0:21019d94ad33 427 void nRF24L01P::setCrcWidth(int width) {
majik 0:21019d94ad33 428
majik 0:21019d94ad33 429 int config = getRegister(_NRF24L01P_REG_CONFIG) & ~_NRF24L01P_CONFIG_CRC_MASK;
majik 0:21019d94ad33 430
majik 0:21019d94ad33 431 switch ( width ) {
majik 0:21019d94ad33 432
majik 0:21019d94ad33 433 case NRF24L01P_CRC_NONE:
majik 0:21019d94ad33 434 config |= _NRF24L01P_CONFIG_CRC_NONE;
majik 0:21019d94ad33 435 break;
majik 0:21019d94ad33 436
majik 0:21019d94ad33 437 case NRF24L01P_CRC_8_BIT:
majik 0:21019d94ad33 438 config |= _NRF24L01P_CONFIG_CRC_8BIT;
majik 0:21019d94ad33 439 break;
majik 0:21019d94ad33 440
majik 0:21019d94ad33 441 case NRF24L01P_CRC_16_BIT:
majik 0:21019d94ad33 442 config |= _NRF24L01P_CONFIG_CRC_16BIT;
majik 0:21019d94ad33 443 break;
majik 0:21019d94ad33 444
majik 0:21019d94ad33 445 default:
majik 0:21019d94ad33 446 error( "nRF24L01P: Invalid CRC Width setting %d\r\n", width );
majik 0:21019d94ad33 447 return;
majik 0:21019d94ad33 448
majik 0:21019d94ad33 449 }
majik 0:21019d94ad33 450
majik 0:21019d94ad33 451 setRegister(_NRF24L01P_REG_CONFIG, config);
majik 0:21019d94ad33 452
majik 0:21019d94ad33 453 }
majik 0:21019d94ad33 454
majik 0:21019d94ad33 455
majik 0:21019d94ad33 456 int nRF24L01P::getCrcWidth(void) {
majik 0:21019d94ad33 457
majik 0:21019d94ad33 458 int crcWidth = getRegister(_NRF24L01P_REG_CONFIG) & _NRF24L01P_CONFIG_CRC_MASK;
majik 0:21019d94ad33 459
majik 0:21019d94ad33 460 switch ( crcWidth ) {
majik 0:21019d94ad33 461
majik 0:21019d94ad33 462 case _NRF24L01P_CONFIG_CRC_NONE:
majik 0:21019d94ad33 463 return NRF24L01P_CRC_NONE;
majik 0:21019d94ad33 464
majik 0:21019d94ad33 465 case _NRF24L01P_CONFIG_CRC_8BIT:
majik 0:21019d94ad33 466 return NRF24L01P_CRC_8_BIT;
majik 0:21019d94ad33 467
majik 0:21019d94ad33 468 case _NRF24L01P_CONFIG_CRC_16BIT:
majik 0:21019d94ad33 469 return NRF24L01P_CRC_16_BIT;
majik 0:21019d94ad33 470
majik 0:21019d94ad33 471 default:
majik 0:21019d94ad33 472 error( "nRF24L01P: Unknown CRC Width value %d\r\n", crcWidth );
majik 0:21019d94ad33 473 return 0;
majik 0:21019d94ad33 474
majik 0:21019d94ad33 475 }
majik 0:21019d94ad33 476 }
majik 0:21019d94ad33 477
majik 0:21019d94ad33 478
majik 0:21019d94ad33 479 void nRF24L01P::setTransferSize(int size, int pipe) {
majik 0:21019d94ad33 480
majik 0:21019d94ad33 481 if ( ( pipe < NRF24L01P_PIPE_P0 ) || ( pipe > NRF24L01P_PIPE_P5 ) ) {
majik 0:21019d94ad33 482
majik 0:21019d94ad33 483 error( "nRF24L01P: Invalid Transfer Size pipe number %d\r\n", pipe );
majik 0:21019d94ad33 484 return;
majik 0:21019d94ad33 485
majik 0:21019d94ad33 486 }
majik 0:21019d94ad33 487
majik 0:21019d94ad33 488 if ( ( size < 0 ) || ( size > _NRF24L01P_RX_FIFO_SIZE ) ) {
majik 0:21019d94ad33 489
majik 0:21019d94ad33 490 error( "nRF24L01P: Invalid Transfer Size setting %d\r\n", size );
majik 0:21019d94ad33 491 return;
majik 0:21019d94ad33 492
majik 0:21019d94ad33 493 }
majik 0:21019d94ad33 494
majik 0:21019d94ad33 495 int rxPwPxRegister = _NRF24L01P_REG_RX_PW_P0 + ( pipe - NRF24L01P_PIPE_P0 );
majik 0:21019d94ad33 496
majik 0:21019d94ad33 497 setRegister(rxPwPxRegister, ( size & _NRF24L01P_RX_PW_Px_MASK ) );
majik 0:21019d94ad33 498
majik 0:21019d94ad33 499 }
majik 0:21019d94ad33 500
majik 0:21019d94ad33 501
majik 0:21019d94ad33 502 int nRF24L01P::getTransferSize(int pipe) {
majik 0:21019d94ad33 503
majik 0:21019d94ad33 504 if ( ( pipe < NRF24L01P_PIPE_P0 ) || ( pipe > NRF24L01P_PIPE_P5 ) ) {
majik 0:21019d94ad33 505
majik 0:21019d94ad33 506 error( "nRF24L01P: Invalid Transfer Size pipe number %d\r\n", pipe );
majik 0:21019d94ad33 507 return 0;
majik 0:21019d94ad33 508
majik 0:21019d94ad33 509 }
majik 0:21019d94ad33 510
majik 0:21019d94ad33 511 int rxPwPxRegister = _NRF24L01P_REG_RX_PW_P0 + ( pipe - NRF24L01P_PIPE_P0 );
majik 0:21019d94ad33 512
majik 0:21019d94ad33 513 int size = getRegister(rxPwPxRegister);
majik 0:21019d94ad33 514
majik 0:21019d94ad33 515 return ( size & _NRF24L01P_RX_PW_Px_MASK );
majik 0:21019d94ad33 516
majik 0:21019d94ad33 517 }
majik 0:21019d94ad33 518
majik 0:21019d94ad33 519
majik 0:21019d94ad33 520 void nRF24L01P::disableAllRxPipes(void) {
majik 0:21019d94ad33 521
majik 0:21019d94ad33 522 setRegister(_NRF24L01P_REG_EN_RXADDR, _NRF24L01P_EN_RXADDR_NONE);
majik 0:21019d94ad33 523
majik 0:21019d94ad33 524 }
majik 0:21019d94ad33 525
majik 0:21019d94ad33 526
majik 0:21019d94ad33 527 void nRF24L01P::disableAutoAcknowledge(void) {
majik 0:21019d94ad33 528
majik 0:21019d94ad33 529 setRegister(_NRF24L01P_REG_EN_AA, _NRF24L01P_EN_AA_NONE);
majik 0:21019d94ad33 530
majik 0:21019d94ad33 531 }
majik 0:21019d94ad33 532
majik 0:21019d94ad33 533
majik 0:21019d94ad33 534 void nRF24L01P::enableAutoAcknowledge(int pipe) {
majik 0:21019d94ad33 535
majik 0:21019d94ad33 536 if ( ( pipe < NRF24L01P_PIPE_P0 ) || ( pipe > NRF24L01P_PIPE_P5 ) ) {
majik 0:21019d94ad33 537
majik 0:21019d94ad33 538 error( "nRF24L01P: Invalid Enable AutoAcknowledge pipe number %d\r\n", pipe );
majik 0:21019d94ad33 539 return;
majik 0:21019d94ad33 540
majik 0:21019d94ad33 541 }
majik 0:21019d94ad33 542
majik 0:21019d94ad33 543 int enAA = getRegister(_NRF24L01P_REG_EN_AA);
majik 0:21019d94ad33 544
majik 0:21019d94ad33 545 enAA |= ( 1 << (pipe - NRF24L01P_PIPE_P0) );
majik 0:21019d94ad33 546
majik 0:21019d94ad33 547 setRegister(_NRF24L01P_REG_EN_AA, enAA);
majik 0:21019d94ad33 548
majik 0:21019d94ad33 549 }
majik 0:21019d94ad33 550
majik 0:21019d94ad33 551
majik 0:21019d94ad33 552 void nRF24L01P::disableAutoRetransmit(void) {
majik 0:21019d94ad33 553
majik 0:21019d94ad33 554 setRegister(_NRF24L01P_REG_SETUP_RETR, _NRF24L01P_SETUP_RETR_NONE);
majik 0:21019d94ad33 555
majik 0:21019d94ad33 556 }
majik 0:21019d94ad33 557
majik 0:21019d94ad33 558 void nRF24L01P::setRxAddress(unsigned long long address, int width, int pipe) {
majik 0:21019d94ad33 559
majik 0:21019d94ad33 560 if ( ( pipe < NRF24L01P_PIPE_P0 ) || ( pipe > NRF24L01P_PIPE_P5 ) ) {
majik 0:21019d94ad33 561
majik 0:21019d94ad33 562 error( "nRF24L01P: Invalid setRxAddress pipe number %d\r\n", pipe );
majik 0:21019d94ad33 563 return;
majik 0:21019d94ad33 564
majik 0:21019d94ad33 565 }
majik 0:21019d94ad33 566
majik 0:21019d94ad33 567 if ( ( pipe == NRF24L01P_PIPE_P0 ) || ( pipe == NRF24L01P_PIPE_P1 ) ) {
majik 0:21019d94ad33 568
majik 0:21019d94ad33 569 int setupAw = getRegister(_NRF24L01P_REG_SETUP_AW) & ~_NRF24L01P_SETUP_AW_AW_MASK;
majik 0:21019d94ad33 570
majik 0:21019d94ad33 571 switch ( width ) {
majik 0:21019d94ad33 572
majik 0:21019d94ad33 573 case 3:
majik 0:21019d94ad33 574 setupAw |= _NRF24L01P_SETUP_AW_AW_3BYTE;
majik 0:21019d94ad33 575 break;
majik 0:21019d94ad33 576
majik 0:21019d94ad33 577 case 4:
majik 0:21019d94ad33 578 setupAw |= _NRF24L01P_SETUP_AW_AW_4BYTE;
majik 0:21019d94ad33 579 break;
majik 0:21019d94ad33 580
majik 0:21019d94ad33 581 case 5:
majik 0:21019d94ad33 582 setupAw |= _NRF24L01P_SETUP_AW_AW_5BYTE;
majik 0:21019d94ad33 583 break;
majik 0:21019d94ad33 584
majik 0:21019d94ad33 585 default:
majik 0:21019d94ad33 586 error( "nRF24L01P: Invalid setRxAddress width setting %d\r\n", width );
majik 0:21019d94ad33 587 return;
majik 0:21019d94ad33 588
majik 0:21019d94ad33 589 }
majik 0:21019d94ad33 590
majik 0:21019d94ad33 591 setRegister(_NRF24L01P_REG_SETUP_AW, setupAw);
majik 0:21019d94ad33 592
majik 0:21019d94ad33 593 } else {
majik 0:21019d94ad33 594
majik 0:21019d94ad33 595 width = 1;
majik 0:21019d94ad33 596
majik 0:21019d94ad33 597 }
majik 0:21019d94ad33 598
majik 0:21019d94ad33 599 int rxAddrPxRegister = _NRF24L01P_REG_RX_ADDR_P0 + ( pipe - NRF24L01P_PIPE_P0 );
majik 0:21019d94ad33 600
majik 0:21019d94ad33 601 int cn = (_NRF24L01P_SPI_CMD_WR_REG | (rxAddrPxRegister & _NRF24L01P_REG_ADDRESS_MASK));
majik 0:21019d94ad33 602
majik 0:21019d94ad33 603 nCS_ = 0;
majik 0:21019d94ad33 604
majik 0:21019d94ad33 605 int status = spi_.write(cn);
majik 0:21019d94ad33 606
majik 0:21019d94ad33 607 while ( width-- > 0 ) {
majik 0:21019d94ad33 608
majik 0:21019d94ad33 609 //
majik 0:21019d94ad33 610 // LSByte first
majik 0:21019d94ad33 611 //
majik 0:21019d94ad33 612 spi_.write((int) (address & 0xFF));
majik 0:21019d94ad33 613 address >>= 8;
majik 0:21019d94ad33 614
majik 0:21019d94ad33 615 }
majik 0:21019d94ad33 616
majik 0:21019d94ad33 617 nCS_ = 1;
majik 0:21019d94ad33 618
majik 0:21019d94ad33 619 int enRxAddr = getRegister(_NRF24L01P_REG_EN_RXADDR);
majik 0:21019d94ad33 620
majik 0:21019d94ad33 621 enRxAddr |= (1 << ( pipe - NRF24L01P_PIPE_P0 ) );
majik 0:21019d94ad33 622
majik 0:21019d94ad33 623 setRegister(_NRF24L01P_REG_EN_RXADDR, enRxAddr);
majik 0:21019d94ad33 624 }
majik 0:21019d94ad33 625
majik 0:21019d94ad33 626 /*
majik 0:21019d94ad33 627 * This version of setRxAddress is just a wrapper for the version that takes 'long long's,
majik 0:21019d94ad33 628 * in case the main code doesn't want to deal with long long's.
majik 0:21019d94ad33 629 */
majik 0:21019d94ad33 630 void nRF24L01P::setRxAddress(unsigned long msb_address, unsigned long lsb_address, int width, int pipe) {
majik 0:21019d94ad33 631
majik 0:21019d94ad33 632 unsigned long long address = ( ( (unsigned long long) msb_address ) << 32 ) | ( ( (unsigned long long) lsb_address ) << 0 );
majik 0:21019d94ad33 633
majik 0:21019d94ad33 634 setRxAddress(address, width, pipe);
majik 0:21019d94ad33 635
majik 0:21019d94ad33 636 }
majik 0:21019d94ad33 637
majik 0:21019d94ad33 638
majik 0:21019d94ad33 639 /*
majik 0:21019d94ad33 640 * This version of setTxAddress is just a wrapper for the version that takes 'long long's,
majik 0:21019d94ad33 641 * in case the main code doesn't want to deal with long long's.
majik 0:21019d94ad33 642 */
majik 0:21019d94ad33 643 void nRF24L01P::setTxAddress(unsigned long msb_address, unsigned long lsb_address, int width) {
majik 0:21019d94ad33 644
majik 0:21019d94ad33 645 unsigned long long address = ( ( (unsigned long long) msb_address ) << 32 ) | ( ( (unsigned long long) lsb_address ) << 0 );
majik 0:21019d94ad33 646
majik 0:21019d94ad33 647 setTxAddress(address, width);
majik 0:21019d94ad33 648
majik 0:21019d94ad33 649 }
majik 0:21019d94ad33 650
majik 0:21019d94ad33 651
majik 0:21019d94ad33 652 void nRF24L01P::setTxAddress(unsigned long long address, int width) {
majik 0:21019d94ad33 653
majik 0:21019d94ad33 654 int setupAw = getRegister(_NRF24L01P_REG_SETUP_AW) & ~_NRF24L01P_SETUP_AW_AW_MASK;
majik 0:21019d94ad33 655
majik 0:21019d94ad33 656 switch ( width ) {
majik 0:21019d94ad33 657
majik 0:21019d94ad33 658 case 3:
majik 0:21019d94ad33 659 setupAw |= _NRF24L01P_SETUP_AW_AW_3BYTE;
majik 0:21019d94ad33 660 break;
majik 0:21019d94ad33 661
majik 0:21019d94ad33 662 case 4:
majik 0:21019d94ad33 663 setupAw |= _NRF24L01P_SETUP_AW_AW_4BYTE;
majik 0:21019d94ad33 664 break;
majik 0:21019d94ad33 665
majik 0:21019d94ad33 666 case 5:
majik 0:21019d94ad33 667 setupAw |= _NRF24L01P_SETUP_AW_AW_5BYTE;
majik 0:21019d94ad33 668 break;
majik 0:21019d94ad33 669
majik 0:21019d94ad33 670 default:
majik 0:21019d94ad33 671 error( "nRF24L01P: Invalid setTxAddress width setting %d\r\n", width );
majik 0:21019d94ad33 672 return;
majik 0:21019d94ad33 673
majik 0:21019d94ad33 674 }
majik 0:21019d94ad33 675
majik 0:21019d94ad33 676 setRegister(_NRF24L01P_REG_SETUP_AW, setupAw);
majik 0:21019d94ad33 677
majik 0:21019d94ad33 678 int cn = (_NRF24L01P_SPI_CMD_WR_REG | (_NRF24L01P_REG_TX_ADDR & _NRF24L01P_REG_ADDRESS_MASK));
majik 0:21019d94ad33 679
majik 0:21019d94ad33 680 nCS_ = 0;
majik 0:21019d94ad33 681
majik 0:21019d94ad33 682 int status = spi_.write(cn);
majik 0:21019d94ad33 683
majik 0:21019d94ad33 684 while ( width-- > 0 ) {
majik 0:21019d94ad33 685
majik 0:21019d94ad33 686 //
majik 0:21019d94ad33 687 // LSByte first
majik 0:21019d94ad33 688 //
majik 0:21019d94ad33 689 spi_.write((int) (address & 0xFF));
majik 0:21019d94ad33 690 address >>= 8;
majik 0:21019d94ad33 691
majik 0:21019d94ad33 692 }
majik 0:21019d94ad33 693
majik 0:21019d94ad33 694 nCS_ = 1;
majik 0:21019d94ad33 695
majik 0:21019d94ad33 696 }
majik 0:21019d94ad33 697
majik 0:21019d94ad33 698
majik 0:21019d94ad33 699 unsigned long long nRF24L01P::getRxAddress(int pipe) {
majik 0:21019d94ad33 700
majik 0:21019d94ad33 701 if ( ( pipe < NRF24L01P_PIPE_P0 ) || ( pipe > NRF24L01P_PIPE_P5 ) ) {
majik 0:21019d94ad33 702
majik 0:21019d94ad33 703 error( "nRF24L01P: Invalid setRxAddress pipe number %d\r\n", pipe );
majik 0:21019d94ad33 704 return 0;
majik 0:21019d94ad33 705
majik 0:21019d94ad33 706 }
majik 0:21019d94ad33 707
majik 0:21019d94ad33 708 int width;
majik 0:21019d94ad33 709
majik 0:21019d94ad33 710 if ( ( pipe == NRF24L01P_PIPE_P0 ) || ( pipe == NRF24L01P_PIPE_P1 ) ) {
majik 0:21019d94ad33 711
majik 0:21019d94ad33 712 int setupAw = getRegister(_NRF24L01P_REG_SETUP_AW) & _NRF24L01P_SETUP_AW_AW_MASK;
majik 0:21019d94ad33 713
majik 0:21019d94ad33 714 switch ( setupAw ) {
majik 0:21019d94ad33 715
majik 0:21019d94ad33 716 case _NRF24L01P_SETUP_AW_AW_3BYTE:
majik 0:21019d94ad33 717 width = 3;
majik 0:21019d94ad33 718 break;
majik 0:21019d94ad33 719
majik 0:21019d94ad33 720 case _NRF24L01P_SETUP_AW_AW_4BYTE:
majik 0:21019d94ad33 721 width = 4;
majik 0:21019d94ad33 722 break;
majik 0:21019d94ad33 723
majik 0:21019d94ad33 724 case _NRF24L01P_SETUP_AW_AW_5BYTE:
majik 0:21019d94ad33 725 width = 5;
majik 0:21019d94ad33 726 break;
majik 0:21019d94ad33 727
majik 0:21019d94ad33 728 default:
majik 0:21019d94ad33 729 error( "nRF24L01P: Unknown getRxAddress width value %d\r\n", setupAw );
majik 0:21019d94ad33 730 return 0;
majik 0:21019d94ad33 731
majik 0:21019d94ad33 732 }
majik 0:21019d94ad33 733
majik 0:21019d94ad33 734 } else {
majik 0:21019d94ad33 735
majik 0:21019d94ad33 736 width = 1;
majik 0:21019d94ad33 737
majik 0:21019d94ad33 738 }
majik 0:21019d94ad33 739
majik 0:21019d94ad33 740 int rxAddrPxRegister = _NRF24L01P_REG_RX_ADDR_P0 + ( pipe - NRF24L01P_PIPE_P0 );
majik 0:21019d94ad33 741
majik 0:21019d94ad33 742 int cn = (_NRF24L01P_SPI_CMD_RD_REG | (rxAddrPxRegister & _NRF24L01P_REG_ADDRESS_MASK));
majik 0:21019d94ad33 743
majik 0:21019d94ad33 744 unsigned long long address = 0;
majik 0:21019d94ad33 745
majik 0:21019d94ad33 746 nCS_ = 0;
majik 0:21019d94ad33 747
majik 0:21019d94ad33 748 int status = spi_.write(cn);
majik 0:21019d94ad33 749
majik 0:21019d94ad33 750 for ( int i=0; i<width; i++ ) {
majik 0:21019d94ad33 751
majik 0:21019d94ad33 752 //
majik 0:21019d94ad33 753 // LSByte first
majik 0:21019d94ad33 754 //
majik 0:21019d94ad33 755 address |= ( ( (unsigned long long)( spi_.write(_NRF24L01P_SPI_CMD_NOP) & 0xFF ) ) << (i*8) );
majik 0:21019d94ad33 756
majik 0:21019d94ad33 757 }
majik 0:21019d94ad33 758
majik 0:21019d94ad33 759 nCS_ = 1;
majik 0:21019d94ad33 760
majik 0:21019d94ad33 761 if ( !( ( pipe == NRF24L01P_PIPE_P0 ) || ( pipe == NRF24L01P_PIPE_P1 ) ) ) {
majik 0:21019d94ad33 762
majik 0:21019d94ad33 763 address |= ( getRxAddress(NRF24L01P_PIPE_P1) & ~((unsigned long long) 0xFF) );
majik 0:21019d94ad33 764
majik 0:21019d94ad33 765 }
majik 0:21019d94ad33 766
majik 0:21019d94ad33 767 return address;
majik 0:21019d94ad33 768
majik 0:21019d94ad33 769 }
majik 0:21019d94ad33 770
majik 0:21019d94ad33 771
majik 0:21019d94ad33 772 unsigned long long nRF24L01P::getTxAddress(void) {
majik 0:21019d94ad33 773
majik 0:21019d94ad33 774 int setupAw = getRegister(_NRF24L01P_REG_SETUP_AW) & _NRF24L01P_SETUP_AW_AW_MASK;
majik 0:21019d94ad33 775
majik 0:21019d94ad33 776 int width;
majik 0:21019d94ad33 777
majik 0:21019d94ad33 778 switch ( setupAw ) {
majik 0:21019d94ad33 779
majik 0:21019d94ad33 780 case _NRF24L01P_SETUP_AW_AW_3BYTE:
majik 0:21019d94ad33 781 width = 3;
majik 0:21019d94ad33 782 break;
majik 0:21019d94ad33 783
majik 0:21019d94ad33 784 case _NRF24L01P_SETUP_AW_AW_4BYTE:
majik 0:21019d94ad33 785 width = 4;
majik 0:21019d94ad33 786 break;
majik 0:21019d94ad33 787
majik 0:21019d94ad33 788 case _NRF24L01P_SETUP_AW_AW_5BYTE:
majik 0:21019d94ad33 789 width = 5;
majik 0:21019d94ad33 790 break;
majik 0:21019d94ad33 791
majik 0:21019d94ad33 792 default:
majik 0:21019d94ad33 793 error( "nRF24L01P: Unknown getTxAddress width value %d\r\n", setupAw );
majik 0:21019d94ad33 794 return 0;
majik 0:21019d94ad33 795
majik 0:21019d94ad33 796 }
majik 0:21019d94ad33 797
majik 0:21019d94ad33 798 int cn = (_NRF24L01P_SPI_CMD_RD_REG | (_NRF24L01P_REG_TX_ADDR & _NRF24L01P_REG_ADDRESS_MASK));
majik 0:21019d94ad33 799
majik 0:21019d94ad33 800 unsigned long long address = 0;
majik 0:21019d94ad33 801
majik 0:21019d94ad33 802 nCS_ = 0;
majik 0:21019d94ad33 803
majik 0:21019d94ad33 804 int status = spi_.write(cn);
majik 0:21019d94ad33 805
majik 0:21019d94ad33 806 for ( int i=0; i<width; i++ ) {
majik 0:21019d94ad33 807
majik 0:21019d94ad33 808 //
majik 0:21019d94ad33 809 // LSByte first
majik 0:21019d94ad33 810 //
majik 0:21019d94ad33 811 address |= ( ( (unsigned long long)( spi_.write(_NRF24L01P_SPI_CMD_NOP) & 0xFF ) ) << (i*8) );
majik 0:21019d94ad33 812
majik 0:21019d94ad33 813 }
majik 0:21019d94ad33 814
majik 0:21019d94ad33 815 nCS_ = 1;
majik 0:21019d94ad33 816
majik 0:21019d94ad33 817 return address;
majik 0:21019d94ad33 818 }
majik 0:21019d94ad33 819
majik 0:21019d94ad33 820
majik 0:21019d94ad33 821 bool nRF24L01P::readable(int pipe) {
majik 0:21019d94ad33 822
majik 0:21019d94ad33 823 if ( ( pipe < NRF24L01P_PIPE_P0 ) || ( pipe > NRF24L01P_PIPE_P5 ) ) {
majik 0:21019d94ad33 824
majik 0:21019d94ad33 825 error( "nRF24L01P: Invalid readable pipe number %d\r\n", pipe );
majik 0:21019d94ad33 826 return false;
majik 0:21019d94ad33 827
majik 0:21019d94ad33 828 }
majik 0:21019d94ad33 829
majik 0:21019d94ad33 830 int status = getStatusRegister();
majik 0:21019d94ad33 831
majik 0:21019d94ad33 832 return ( ( status & _NRF24L01P_STATUS_RX_DR ) && ( ( ( status & _NRF24L01P_STATUS_RX_P_NO ) >> 1 ) == ( pipe & 0x7 ) ) );
majik 0:21019d94ad33 833
majik 0:21019d94ad33 834 }
majik 0:21019d94ad33 835
majik 0:21019d94ad33 836
majik 0:21019d94ad33 837 int nRF24L01P::write(int pipe, char *data, int count) {
majik 0:21019d94ad33 838
majik 0:21019d94ad33 839 // Note: the pipe number is ignored in a Transmit / write
majik 0:21019d94ad33 840
majik 0:21019d94ad33 841 //
majik 0:21019d94ad33 842 // Save the CE state
majik 0:21019d94ad33 843 //
majik 0:21019d94ad33 844 int originalCe = ce_;
majik 0:21019d94ad33 845 disable();
majik 0:21019d94ad33 846
majik 0:21019d94ad33 847 if ( count <= 0 ) return 0;
majik 0:21019d94ad33 848
majik 0:21019d94ad33 849 if ( count > _NRF24L01P_TX_FIFO_SIZE ) count = _NRF24L01P_TX_FIFO_SIZE;
majik 0:21019d94ad33 850
majik 0:21019d94ad33 851 // Clear the Status bit
majik 0:21019d94ad33 852 setRegister(_NRF24L01P_REG_STATUS, _NRF24L01P_STATUS_TX_DS);
majik 0:21019d94ad33 853
majik 0:21019d94ad33 854 nCS_ = 0;
majik 0:21019d94ad33 855
majik 0:21019d94ad33 856 int status = spi_.write(_NRF24L01P_SPI_CMD_WR_TX_PAYLOAD);
majik 0:21019d94ad33 857
majik 0:21019d94ad33 858 for ( int i = 0; i < count; i++ ) {
majik 0:21019d94ad33 859
majik 0:21019d94ad33 860 spi_.write(*data++);
majik 0:21019d94ad33 861
majik 0:21019d94ad33 862 }
majik 0:21019d94ad33 863
majik 0:21019d94ad33 864 nCS_ = 1;
majik 0:21019d94ad33 865
majik 0:21019d94ad33 866 int originalMode = mode;
majik 0:21019d94ad33 867 setTransmitMode();
majik 0:21019d94ad33 868
majik 0:21019d94ad33 869 enable();
majik 0:21019d94ad33 870 wait_us(_NRF24L01P_TIMING_Thce_us);
majik 0:21019d94ad33 871 disable();
majik 0:21019d94ad33 872
majik 0:21019d94ad33 873 while ( !( getStatusRegister() & _NRF24L01P_STATUS_TX_DS ) ) {
majik 0:21019d94ad33 874
majik 0:21019d94ad33 875 // Wait for the transfer to complete
majik 0:21019d94ad33 876
majik 0:21019d94ad33 877 }
majik 0:21019d94ad33 878
majik 0:21019d94ad33 879 // Clear the Status bit
majik 0:21019d94ad33 880 setRegister(_NRF24L01P_REG_STATUS, _NRF24L01P_STATUS_TX_DS);
majik 0:21019d94ad33 881
majik 0:21019d94ad33 882 if ( originalMode == _NRF24L01P_MODE_RX ) {
majik 0:21019d94ad33 883
majik 0:21019d94ad33 884 setReceiveMode();
majik 0:21019d94ad33 885
majik 0:21019d94ad33 886 }
majik 0:21019d94ad33 887
majik 0:21019d94ad33 888 ce_ = originalCe;
majik 0:21019d94ad33 889 wait_us( _NRF24L01P_TIMING_Tpece2csn_us );
majik 0:21019d94ad33 890
majik 0:21019d94ad33 891 return count;
majik 0:21019d94ad33 892
majik 0:21019d94ad33 893 }
majik 0:21019d94ad33 894
majik 0:21019d94ad33 895
majik 0:21019d94ad33 896 int nRF24L01P::read(int pipe, char *data, int count) {
majik 0:21019d94ad33 897
majik 0:21019d94ad33 898 if ( ( pipe < NRF24L01P_PIPE_P0 ) || ( pipe > NRF24L01P_PIPE_P5 ) ) {
majik 0:21019d94ad33 899
majik 0:21019d94ad33 900 error( "nRF24L01P: Invalid read pipe number %d\r\n", pipe );
majik 0:21019d94ad33 901 return -1;
majik 0:21019d94ad33 902
majik 0:21019d94ad33 903 }
majik 0:21019d94ad33 904
majik 0:21019d94ad33 905 if ( count <= 0 ) return 0;
majik 0:21019d94ad33 906
majik 0:21019d94ad33 907 if ( count > _NRF24L01P_RX_FIFO_SIZE ) count = _NRF24L01P_RX_FIFO_SIZE;
majik 0:21019d94ad33 908
majik 0:21019d94ad33 909 if ( readable(pipe) ) {
majik 0:21019d94ad33 910
majik 0:21019d94ad33 911 nCS_ = 0;
majik 0:21019d94ad33 912
majik 0:21019d94ad33 913 int status = spi_.write(_NRF24L01P_SPI_CMD_R_RX_PL_WID);
majik 0:21019d94ad33 914
majik 0:21019d94ad33 915 int rxPayloadWidth = spi_.write(_NRF24L01P_SPI_CMD_NOP);
majik 0:21019d94ad33 916
majik 0:21019d94ad33 917 nCS_ = 1;
majik 0:21019d94ad33 918
majik 0:21019d94ad33 919 if ( ( rxPayloadWidth < 0 ) || ( rxPayloadWidth > _NRF24L01P_RX_FIFO_SIZE ) ) {
majik 0:21019d94ad33 920
majik 0:21019d94ad33 921 // Received payload error: need to flush the FIFO
majik 0:21019d94ad33 922
majik 0:21019d94ad33 923 nCS_ = 0;
majik 0:21019d94ad33 924
majik 0:21019d94ad33 925 int status = spi_.write(_NRF24L01P_SPI_CMD_FLUSH_RX);
majik 0:21019d94ad33 926
majik 0:21019d94ad33 927 int rxPayloadWidth = spi_.write(_NRF24L01P_SPI_CMD_NOP);
majik 0:21019d94ad33 928
majik 0:21019d94ad33 929 nCS_ = 1;
majik 0:21019d94ad33 930
majik 0:21019d94ad33 931 //
majik 0:21019d94ad33 932 // At this point, we should retry the reception,
majik 0:21019d94ad33 933 // but for now we'll just fall through...
majik 0:21019d94ad33 934 //
majik 0:21019d94ad33 935
majik 0:21019d94ad33 936 } else {
majik 0:21019d94ad33 937
majik 0:21019d94ad33 938 if ( rxPayloadWidth < count ) count = rxPayloadWidth;
majik 0:21019d94ad33 939
majik 0:21019d94ad33 940 nCS_ = 0;
majik 0:21019d94ad33 941
majik 0:21019d94ad33 942 int status = spi_.write(_NRF24L01P_SPI_CMD_RD_RX_PAYLOAD);
majik 0:21019d94ad33 943
majik 0:21019d94ad33 944 for ( int i = 0; i < count; i++ ) {
majik 0:21019d94ad33 945
majik 0:21019d94ad33 946 *data++ = spi_.write(_NRF24L01P_SPI_CMD_NOP);
majik 0:21019d94ad33 947
majik 0:21019d94ad33 948 }
majik 0:21019d94ad33 949
majik 0:21019d94ad33 950 nCS_ = 1;
majik 0:21019d94ad33 951
majik 0:21019d94ad33 952 // Clear the Status bit
majik 0:21019d94ad33 953 setRegister(_NRF24L01P_REG_STATUS, _NRF24L01P_STATUS_RX_DR);
majik 0:21019d94ad33 954
majik 0:21019d94ad33 955 return count;
majik 0:21019d94ad33 956
majik 0:21019d94ad33 957 }
majik 0:21019d94ad33 958
majik 0:21019d94ad33 959 } else {
majik 0:21019d94ad33 960
majik 0:21019d94ad33 961 //
majik 0:21019d94ad33 962 // What should we do if there is no 'readable' data?
majik 0:21019d94ad33 963 // We could wait for data to arrive, but for now, we'll
majik 0:21019d94ad33 964 // just return with no data.
majik 0:21019d94ad33 965 //
majik 0:21019d94ad33 966 return 0;
majik 0:21019d94ad33 967
majik 0:21019d94ad33 968 }
majik 0:21019d94ad33 969
majik 0:21019d94ad33 970 //
majik 0:21019d94ad33 971 // We get here because an error condition occured;
majik 0:21019d94ad33 972 // We could wait for data to arrive, but for now, we'll
majik 0:21019d94ad33 973 // just return with no data.
majik 0:21019d94ad33 974 //
majik 0:21019d94ad33 975 return -1;
majik 0:21019d94ad33 976
majik 0:21019d94ad33 977 }
majik 0:21019d94ad33 978
majik 0:21019d94ad33 979 void nRF24L01P::setRegister(int regAddress, int regData) {
majik 0:21019d94ad33 980
majik 0:21019d94ad33 981 //
majik 0:21019d94ad33 982 // Save the CE state
majik 0:21019d94ad33 983 //
majik 0:21019d94ad33 984 int originalCe = ce_;
majik 0:21019d94ad33 985 disable();
majik 0:21019d94ad33 986
majik 0:21019d94ad33 987 int cn = (_NRF24L01P_SPI_CMD_WR_REG | (regAddress & _NRF24L01P_REG_ADDRESS_MASK));
majik 0:21019d94ad33 988
majik 0:21019d94ad33 989 nCS_ = 0;
majik 0:21019d94ad33 990
majik 0:21019d94ad33 991 int status = spi_.write(cn);
majik 0:21019d94ad33 992
majik 0:21019d94ad33 993 spi_.write(regData & 0xFF);
majik 0:21019d94ad33 994
majik 0:21019d94ad33 995 nCS_ = 1;
majik 0:21019d94ad33 996
majik 0:21019d94ad33 997 ce_ = originalCe;
majik 0:21019d94ad33 998 wait_us( _NRF24L01P_TIMING_Tpece2csn_us );
majik 0:21019d94ad33 999
majik 0:21019d94ad33 1000 }
majik 0:21019d94ad33 1001
majik 0:21019d94ad33 1002
majik 0:21019d94ad33 1003 int nRF24L01P::getRegister(int regAddress) {
majik 0:21019d94ad33 1004
majik 0:21019d94ad33 1005 int cn = (_NRF24L01P_SPI_CMD_RD_REG | (regAddress & _NRF24L01P_REG_ADDRESS_MASK));
majik 0:21019d94ad33 1006
majik 0:21019d94ad33 1007 nCS_ = 0;
majik 0:21019d94ad33 1008
majik 0:21019d94ad33 1009 int status = spi_.write(cn);
majik 0:21019d94ad33 1010
majik 0:21019d94ad33 1011 int dn = spi_.write(_NRF24L01P_SPI_CMD_NOP);
majik 0:21019d94ad33 1012
majik 0:21019d94ad33 1013 nCS_ = 1;
majik 0:21019d94ad33 1014
majik 0:21019d94ad33 1015 return dn;
majik 0:21019d94ad33 1016
majik 0:21019d94ad33 1017 }
majik 0:21019d94ad33 1018
majik 0:21019d94ad33 1019 int nRF24L01P::getStatusRegister(void) {
majik 0:21019d94ad33 1020
majik 0:21019d94ad33 1021 nCS_ = 0;
majik 0:21019d94ad33 1022
majik 0:21019d94ad33 1023 int status = spi_.write(_NRF24L01P_SPI_CMD_NOP);
majik 0:21019d94ad33 1024
majik 0:21019d94ad33 1025 nCS_ = 1;
majik 0:21019d94ad33 1026
majik 0:21019d94ad33 1027 return status;
majik 0:21019d94ad33 1028
majik 0:21019d94ad33 1029 }