Energy harvesting mobile robot. Developed at Institute of Systems and Robotics — University of Coimbra.

Fork of ISR_Mini-explorer by ISR UC

Committer:
Bisca
Date:
Wed Mar 29 12:15:03 2017 +0000
Revision:
1:9e5152aa1bb7
Parent:
0:15a30802e719
v1

Who changed what in which revision?

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