ISR UC / ISR_Mini-explorer

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

Dependents:   Mapping

Committer:
ISR
Date:
Thu Feb 02 12:21:11 2017 +0000
Revision:
0:15a30802e719
Initial commit.

Who changed what in which revision?

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