This is my own modified version of an already existing nRF24L01P library. I am adding some additional functionality, hoping to keep the library formatted the same way that I found it. This is not an attempt to fill out the library to completion - only to add what I need. Sorry!

Dependents:   mbed-os-example-blinky

Committer:
theterg
Date:
Wed Mar 23 19:22:31 2011 +0000
Revision:
0:be6480db326e
Added enableDynamicPayload and disableDynamicPayload to existing library

Who changed what in which revision?

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