This is a work in progress for an NRF2401P

Dependencies:   mbed

Fork of NRF2401P by Malcolm McCulloch

Committer:
epgmdm
Date:
Thu Jun 11 23:38:01 2015 +0000
Revision:
3:afe8d307b5c3
Parent:
2:ca0a3c0bba70
Child:
4:e55807cf840b
No debug, transmitData returns bool not char - flushesTX if max RT

Who changed what in which revision?

UserRevisionLine numberNew contents of line
epgmdm 0:8fd0531ae0be 1 /**
epgmdm 0:8fd0531ae0be 2 *@section DESCRIPTION
epgmdm 0:8fd0531ae0be 3 * mbed NRF2401+ Library
epgmdm 0:8fd0531ae0be 4 *@section LICENSE
epgmdm 0:8fd0531ae0be 5 * Copyright (c) 2015, Malcolm McCulloch
epgmdm 0:8fd0531ae0be 6 *
epgmdm 0:8fd0531ae0be 7 * Permission is hereby granted, free of charge, to any person obtaining a copy
epgmdm 0:8fd0531ae0be 8 * of this software and associated documentation files (the "Software"), to deal
epgmdm 0:8fd0531ae0be 9 * in the Software without restriction, including without limitation the rights
epgmdm 0:8fd0531ae0be 10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
epgmdm 0:8fd0531ae0be 11 * copies of the Software, and to permit persons to whom the Software is
epgmdm 0:8fd0531ae0be 12 * furnished to do so, subject to the following conditions:
epgmdm 0:8fd0531ae0be 13 *
epgmdm 0:8fd0531ae0be 14 * The above copyright notice and this permission notice shall be included in
epgmdm 0:8fd0531ae0be 15 * all copies or substantial portions of the Software.
epgmdm 0:8fd0531ae0be 16 *
epgmdm 0:8fd0531ae0be 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
epgmdm 0:8fd0531ae0be 18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
epgmdm 0:8fd0531ae0be 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
epgmdm 0:8fd0531ae0be 20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
epgmdm 0:8fd0531ae0be 21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
epgmdm 0:8fd0531ae0be 22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
epgmdm 0:8fd0531ae0be 23 * THE SOFTWARE.
epgmdm 0:8fd0531ae0be 24 * @file "NRF2401P.cpp"
epgmdm 0:8fd0531ae0be 25 */
epgmdm 2:ca0a3c0bba70 26 #include "mbed.h"
epgmdm 2:ca0a3c0bba70 27 #include "NRF2401P.h"
epgmdm 2:ca0a3c0bba70 28 #include "nRF24l01.h"
epgmdm 0:8fd0531ae0be 29
epgmdm 0:8fd0531ae0be 30
epgmdm 0:8fd0531ae0be 31 NRF2401P::NRF2401P ( PinName mosi, PinName miso, PinName sclk, PinName _csn, PinName _ce ) :
epgmdm 0:8fd0531ae0be 32 csn( DigitalOut( _csn ) ), ce( DigitalOut( _ce ) )
epgmdm 0:8fd0531ae0be 33 {
epgmdm 0:8fd0531ae0be 34 addressWidth = 5;
epgmdm 0:8fd0531ae0be 35 pc = new Serial( USBTX, USBRX ); // tx, rx
epgmdm 0:8fd0531ae0be 36 sprintf(logMsg, "Initialise " );
epgmdm 0:8fd0531ae0be 37 log(logMsg);
epgmdm 0:8fd0531ae0be 38 spi = new SPI( mosi, miso, sclk, NC ); //SPI (PinName mosi, PinName miso, PinName sclk, PinName _unused=NC)
epgmdm 0:8fd0531ae0be 39 spi->frequency( 10000000 ); // 1MHZ max 10 MHz
epgmdm 0:8fd0531ae0be 40 spi->format( 8, 0 ); // 0: 0e 08; 1: 0e 00; 2:0e 00 ;3:1c 00
epgmdm 0:8fd0531ae0be 41 csn = 1;
epgmdm 0:8fd0531ae0be 42 ce = 0;
epgmdm 0:8fd0531ae0be 43 dynamic = false;
epgmdm 3:afe8d307b5c3 44 debug=false;
epgmdm 0:8fd0531ae0be 45
epgmdm 0:8fd0531ae0be 46 };
epgmdm 0:8fd0531ae0be 47
epgmdm 0:8fd0531ae0be 48 /**
epgmdm 0:8fd0531ae0be 49 * writes to pc and waits
epgmdm 0:8fd0531ae0be 50 */
epgmdm 0:8fd0531ae0be 51 void NRF2401P::log (char *msg)
epgmdm 0:8fd0531ae0be 52 {
epgmdm 0:8fd0531ae0be 53 if(debug) {
epgmdm 2:ca0a3c0bba70 54 printf("\t <%s \t %s>\n\r",statusString(), msg);
epgmdm 1:ff53b1ac3bad 55 wait(0.01);
epgmdm 0:8fd0531ae0be 56 };
epgmdm 0:8fd0531ae0be 57 }
epgmdm 0:8fd0531ae0be 58
epgmdm 0:8fd0531ae0be 59 void NRF2401P::scratch()
epgmdm 0:8fd0531ae0be 60 {
epgmdm 0:8fd0531ae0be 61 int status = 0;
epgmdm 0:8fd0531ae0be 62 int register1 = 0;
epgmdm 0:8fd0531ae0be 63 ce = 0;
epgmdm 0:8fd0531ae0be 64 for ( char i = 0; i < 24; i++ ) {
epgmdm 0:8fd0531ae0be 65 csn = 0;
epgmdm 0:8fd0531ae0be 66 //wait_us(100);
epgmdm 0:8fd0531ae0be 67 status = spi->write( i );
epgmdm 0:8fd0531ae0be 68 register1 = spi->write( 0x00 );
epgmdm 0:8fd0531ae0be 69 csn = 1;
epgmdm 0:8fd0531ae0be 70 sprintf(logMsg, " register %02x (%02x) = %02x", i, status, register1 );
epgmdm 0:8fd0531ae0be 71 log(logMsg);
epgmdm 0:8fd0531ae0be 72 }
epgmdm 0:8fd0531ae0be 73
epgmdm 0:8fd0531ae0be 74 }
epgmdm 0:8fd0531ae0be 75 /**
epgmdm 2:ca0a3c0bba70 76 * start here to configure the basics of the NRF
epgmdm 2:ca0a3c0bba70 77 */
epgmdm 2:ca0a3c0bba70 78
epgmdm 2:ca0a3c0bba70 79 void NRF2401P::start()
epgmdm 2:ca0a3c0bba70 80 {
epgmdm 2:ca0a3c0bba70 81 writeReg( CONFIG, 0x0c ); // set 16 bit crc
epgmdm 2:ca0a3c0bba70 82 setTxRetry(0x01,0x0f); // 500 uS, 15 retries
epgmdm 2:ca0a3c0bba70 83 setRadio(0,0x03); // 1MB/S 0dB
epgmdm 2:ca0a3c0bba70 84 setDynamicPayload();
epgmdm 2:ca0a3c0bba70 85 setChannel(76); // should be clear?
epgmdm 2:ca0a3c0bba70 86 setAddressWidth(5);
epgmdm 2:ca0a3c0bba70 87 flushRx();
epgmdm 2:ca0a3c0bba70 88 flushTx();
epgmdm 2:ca0a3c0bba70 89 setPwrUp();
epgmdm 2:ca0a3c0bba70 90 setTxMode(); // just make sure no spurious reads....
epgmdm 2:ca0a3c0bba70 91
epgmdm 2:ca0a3c0bba70 92 }
epgmdm 2:ca0a3c0bba70 93 /**
epgmdm 0:8fd0531ae0be 94 * Sets up a reciever using shockburst and dynamic payload. Uses pipe 1
epgmdm 0:8fd0531ae0be 95 * defaults to 5 bytes
epgmdm 0:8fd0531ae0be 96 */
epgmdm 2:ca0a3c0bba70 97 void NRF2401P::quickRxSetup(int channel,long long addrRx)
epgmdm 0:8fd0531ae0be 98 {
epgmdm 2:ca0a3c0bba70 99 start();
epgmdm 0:8fd0531ae0be 100 setChannel(channel);
epgmdm 2:ca0a3c0bba70 101 setRxAddress(addrRx,1);
epgmdm 0:8fd0531ae0be 102 setRxMode();
epgmdm 0:8fd0531ae0be 103 ce=1;
epgmdm 2:ca0a3c0bba70 104 wait (0.001f);
epgmdm 0:8fd0531ae0be 105 }
epgmdm 0:8fd0531ae0be 106 /**
epgmdm 0:8fd0531ae0be 107 * Sets up for receive of a message to address 0XA0A0A0
epgmdm 0:8fd0531ae0be 108 */
epgmdm 0:8fd0531ae0be 109
epgmdm 0:8fd0531ae0be 110 char NRF2401P::testReceive()
epgmdm 0:8fd0531ae0be 111 {
epgmdm 0:8fd0531ae0be 112 char message[64];
epgmdm 0:8fd0531ae0be 113 char width;
epgmdm 0:8fd0531ae0be 114 int channel = 0x12;
epgmdm 0:8fd0531ae0be 115 long long addr=0xA0B0C0;
epgmdm 0:8fd0531ae0be 116 debug = true;
epgmdm 0:8fd0531ae0be 117 quickRxSetup(channel, addr);
epgmdm 0:8fd0531ae0be 118
epgmdm 0:8fd0531ae0be 119 while (1) {
epgmdm 0:8fd0531ae0be 120 while (!isRxData()) {
epgmdm 0:8fd0531ae0be 121 //wait(0.5);
epgmdm 0:8fd0531ae0be 122 };
epgmdm 0:8fd0531ae0be 123 width=getRxData(message);
epgmdm 0:8fd0531ae0be 124 message[width]='\0';
epgmdm 0:8fd0531ae0be 125 sprintf(logMsg,"Received= [%s]",message);
epgmdm 0:8fd0531ae0be 126 log(logMsg);
epgmdm 0:8fd0531ae0be 127 };
epgmdm 0:8fd0531ae0be 128 }
epgmdm 0:8fd0531ae0be 129
epgmdm 0:8fd0531ae0be 130 /**
epgmdm 2:ca0a3c0bba70 131 * Sets the number and the timimg of TX retries
epgmdm 2:ca0a3c0bba70 132 */
epgmdm 2:ca0a3c0bba70 133
epgmdm 2:ca0a3c0bba70 134 void NRF2401P::setTxRetry(char delay, char numTries)
epgmdm 2:ca0a3c0bba70 135 {
epgmdm 2:ca0a3c0bba70 136 char val = (delay&0xf)<<4 | (numTries&0xf);
epgmdm 2:ca0a3c0bba70 137 writeReg (SETUP_RETR, val);
epgmdm 2:ca0a3c0bba70 138 }
epgmdm 2:ca0a3c0bba70 139
epgmdm 2:ca0a3c0bba70 140
epgmdm 2:ca0a3c0bba70 141 /**
epgmdm 0:8fd0531ae0be 142 * Sets up a transmitter using shockburst and dynamic payload. Uses pipe 1
epgmdm 0:8fd0531ae0be 143 * defaults to 5 bytes
epgmdm 0:8fd0531ae0be 144 */
epgmdm 0:8fd0531ae0be 145 void NRF2401P::quickTxSetup(int channel,long long addr)
epgmdm 0:8fd0531ae0be 146 {
epgmdm 2:ca0a3c0bba70 147 start();
epgmdm 0:8fd0531ae0be 148 setChannel(channel);
epgmdm 2:ca0a3c0bba70 149 setTxAddress(addr);
epgmdm 0:8fd0531ae0be 150 setTxMode();
epgmdm 0:8fd0531ae0be 151 ce=1;
epgmdm 0:8fd0531ae0be 152 wait (0.0016f); // wait for pll to settle
epgmdm 0:8fd0531ae0be 153 }
epgmdm 0:8fd0531ae0be 154
epgmdm 0:8fd0531ae0be 155 /**
epgmdm 0:8fd0531ae0be 156 * Sets up for transmit of a message to address 0XA0A0A0
epgmdm 0:8fd0531ae0be 157 */
epgmdm 0:8fd0531ae0be 158
epgmdm 0:8fd0531ae0be 159 char NRF2401P::testTransmit()
epgmdm 0:8fd0531ae0be 160 {
epgmdm 0:8fd0531ae0be 161 long long addr=0xA0B0C0;
epgmdm 0:8fd0531ae0be 162 int channel = 0x12;
epgmdm 0:8fd0531ae0be 163 char data[32] ;
epgmdm 0:8fd0531ae0be 164 int i=0;
epgmdm 0:8fd0531ae0be 165 quickRxSetup(channel, addr);
epgmdm 0:8fd0531ae0be 166 while (1) {
epgmdm 0:8fd0531ae0be 167 sprintf(data," packet %03d", i++ |100);
epgmdm 0:8fd0531ae0be 168 transmitData(data,18);
epgmdm 0:8fd0531ae0be 169 wait (1.0);
epgmdm 0:8fd0531ae0be 170 }
epgmdm 0:8fd0531ae0be 171
epgmdm 0:8fd0531ae0be 172 }
epgmdm 0:8fd0531ae0be 173 /**
epgmdm 0:8fd0531ae0be 174 *Speed :
epgmdm 0:8fd0531ae0be 175 ‘0x00’ – 1Mbps
epgmdm 0:8fd0531ae0be 176 ‘0x01’ – 2Mbps
epgmdm 0:8fd0531ae0be 177 ‘0x02’ – 250kbps
epgmdm 0:8fd0531ae0be 178 ‘0x03’ – Reserved
epgmdm 0:8fd0531ae0be 179 Power:
epgmdm 0:8fd0531ae0be 180 '0x00' – -18dBm
epgmdm 0:8fd0531ae0be 181 '0x01' – -12dBm
epgmdm 0:8fd0531ae0be 182 '0x02' – -6dBm
epgmdm 0:8fd0531ae0be 183 '0x03' – 0dBm
epgmdm 0:8fd0531ae0be 184 */
epgmdm 0:8fd0531ae0be 185 char NRF2401P::setRadio(char speed,char power)
epgmdm 0:8fd0531ae0be 186 {
epgmdm 0:8fd0531ae0be 187 char val=0;
epgmdm 0:8fd0531ae0be 188 sprintf(logMsg, "Set radio");
epgmdm 0:8fd0531ae0be 189 log(logMsg);
epgmdm 0:8fd0531ae0be 190 if (speed & 0x02) {
epgmdm 0:8fd0531ae0be 191 val |= (1<<5);
epgmdm 0:8fd0531ae0be 192 }
epgmdm 0:8fd0531ae0be 193 val |= (speed & 0x01)<<3;
epgmdm 0:8fd0531ae0be 194
epgmdm 0:8fd0531ae0be 195 val |= ((power &0x03)<<1);
epgmdm 0:8fd0531ae0be 196 writeReg (0x06,val);
epgmdm 0:8fd0531ae0be 197
epgmdm 0:8fd0531ae0be 198 }
epgmdm 0:8fd0531ae0be 199 /**
epgmdm 0:8fd0531ae0be 200 Set RF_CH = chan;
epgmdm 0:8fd0531ae0be 201
epgmdm 0:8fd0531ae0be 202 F0= 2400 + chan [MHz]
epgmdm 0:8fd0531ae0be 203 */
epgmdm 0:8fd0531ae0be 204 char NRF2401P::setChannel(char chan)
epgmdm 0:8fd0531ae0be 205 {
epgmdm 0:8fd0531ae0be 206 sprintf(logMsg, "Set channel");
epgmdm 0:8fd0531ae0be 207 log(logMsg);
epgmdm 0:8fd0531ae0be 208 writeReg (0x05,(chan&0x7f));
epgmdm 0:8fd0531ae0be 209 }
epgmdm 0:8fd0531ae0be 210 /**
epgmdm 0:8fd0531ae0be 211 * Transmits width bytes of data. width <32
epgmdm 3:afe8d307b5c3 212 * returns 1 if succeful
epgmdm 0:8fd0531ae0be 213 */
epgmdm 3:afe8d307b5c3 214 bool NRF2401P::transmitData( char *data, char width )
epgmdm 0:8fd0531ae0be 215 {
epgmdm 3:afe8d307b5c3 216 if (width>32) return 0;
epgmdm 3:afe8d307b5c3 217
epgmdm 2:ca0a3c0bba70 218 //clearStatus();
epgmdm 2:ca0a3c0bba70 219 //ce = 1;
epgmdm 0:8fd0531ae0be 220 csn = 0;
epgmdm 0:8fd0531ae0be 221 char address = 0XA0;
epgmdm 0:8fd0531ae0be 222 int i;
epgmdm 0:8fd0531ae0be 223 // set up for writing
epgmdm 0:8fd0531ae0be 224 status = spi->write( address );
epgmdm 0:8fd0531ae0be 225 for ( i = 0; i <width; i++ ) {
epgmdm 0:8fd0531ae0be 226 spi->write( data[ i ] );
epgmdm 0:8fd0531ae0be 227 }
epgmdm 0:8fd0531ae0be 228 csn = 1;
epgmdm 3:afe8d307b5c3 229 wait(0.001);
epgmdm 3:afe8d307b5c3 230 checkStatus();
epgmdm 3:afe8d307b5c3 231 if ((status>>4)&1) { // Max retries - flush tx
epgmdm 3:afe8d307b5c3 232 flushTx();
epgmdm 3:afe8d307b5c3 233 }
epgmdm 3:afe8d307b5c3 234 if (debug) {
epgmdm 3:afe8d307b5c3 235 sprintf(logMsg, " Transmit data %d bytes to %02x (%02x) = %10s", width, address, status, *data );
epgmdm 3:afe8d307b5c3 236 log(logMsg);
epgmdm 2:ca0a3c0bba70 237 }
epgmdm 0:8fd0531ae0be 238 return status;
epgmdm 0:8fd0531ae0be 239
epgmdm 0:8fd0531ae0be 240 }
epgmdm 0:8fd0531ae0be 241
epgmdm 0:8fd0531ae0be 242 /**
epgmdm 0:8fd0531ae0be 243 * sets acknowledge data width bytes of data. width <32
epgmdm 0:8fd0531ae0be 244 */
epgmdm 1:ff53b1ac3bad 245 char NRF2401P::acknowledgeData( char *data, char width, char pipe )
epgmdm 0:8fd0531ae0be 246 {
epgmdm 0:8fd0531ae0be 247 ce = 1;
epgmdm 0:8fd0531ae0be 248 csn = 0;
epgmdm 2:ca0a3c0bba70 249 //writeReg(0x1d,0x06); // enable payload with ack
epgmdm 2:ca0a3c0bba70 250 char address = W_ACK_PAYLOAD | (pipe&0x07);
epgmdm 0:8fd0531ae0be 251 int i;
epgmdm 0:8fd0531ae0be 252 // set up for writing
epgmdm 3:afe8d307b5c3 253 csn = 0;
epgmdm 0:8fd0531ae0be 254 status = spi->write( address );
epgmdm 0:8fd0531ae0be 255 for ( i = 0; i <width; i++ ) {
epgmdm 0:8fd0531ae0be 256 spi->write( data[ i ] );
epgmdm 0:8fd0531ae0be 257 }
epgmdm 0:8fd0531ae0be 258 csn = 1;
epgmdm 3:afe8d307b5c3 259 if (debug) {
epgmdm 3:afe8d307b5c3 260 sprintf(logMsg, " acknowledge data %d bytes to %02x (%02x) = %c", width, address, status, *data );
epgmdm 3:afe8d307b5c3 261 log(logMsg);
epgmdm 2:ca0a3c0bba70 262 }
epgmdm 0:8fd0531ae0be 263 return status;
epgmdm 0:8fd0531ae0be 264
epgmdm 0:8fd0531ae0be 265 }
epgmdm 0:8fd0531ae0be 266 /**
epgmdm 0:8fd0531ae0be 267 * Writes 1 byte data to a register
epgmdm 0:8fd0531ae0be 268 **/
epgmdm 0:8fd0531ae0be 269 char NRF2401P::writeReg( char address, char data )
epgmdm 0:8fd0531ae0be 270 {
epgmdm 0:8fd0531ae0be 271 char status = 0;
epgmdm 0:8fd0531ae0be 272 char reg;
epgmdm 0:8fd0531ae0be 273 csn = 0;
epgmdm 0:8fd0531ae0be 274 address &= 0x1F;
epgmdm 0:8fd0531ae0be 275 reg = address | 0x20;
epgmdm 0:8fd0531ae0be 276 status = spi->write( reg );
epgmdm 0:8fd0531ae0be 277 spi->write( data );
epgmdm 0:8fd0531ae0be 278 csn = 1;
epgmdm 0:8fd0531ae0be 279 sprintf(logMsg, " register write %02x (%02x) = %02x", address, status, data );
epgmdm 0:8fd0531ae0be 280 log(logMsg);
epgmdm 0:8fd0531ae0be 281 return status;
epgmdm 0:8fd0531ae0be 282 }
epgmdm 0:8fd0531ae0be 283 /**
epgmdm 0:8fd0531ae0be 284 * Writes width bytes data to a register, ls byte to ms byte /for adressess
epgmdm 0:8fd0531ae0be 285 **/
epgmdm 0:8fd0531ae0be 286 char NRF2401P::writeReg( char address, char *data, char width )
epgmdm 0:8fd0531ae0be 287 {
epgmdm 0:8fd0531ae0be 288 char reg;
epgmdm 0:8fd0531ae0be 289 csn = 0;
epgmdm 0:8fd0531ae0be 290 int i;
epgmdm 0:8fd0531ae0be 291 // set up for writing
epgmdm 0:8fd0531ae0be 292 address &= 0x1F;
epgmdm 0:8fd0531ae0be 293 reg = address| 0x20;
epgmdm 0:8fd0531ae0be 294 status = spi->write( reg );
epgmdm 0:8fd0531ae0be 295 for ( i = width - 1; i >= 0; i-- ) {
epgmdm 0:8fd0531ae0be 296 spi->write( data[ i ] );
epgmdm 0:8fd0531ae0be 297 }
epgmdm 0:8fd0531ae0be 298 csn = 1;
epgmdm 2:ca0a3c0bba70 299 if (debug) {
epgmdm 2:ca0a3c0bba70 300 sprintf(logMsg, " register write %d bytes to %02x (%02x) = %02x %02x %02x", width, address, status, data[0], data[1], data[2] );
epgmdm 2:ca0a3c0bba70 301 log(logMsg);
epgmdm 2:ca0a3c0bba70 302 }
epgmdm 0:8fd0531ae0be 303 return status;
epgmdm 0:8fd0531ae0be 304 }
epgmdm 0:8fd0531ae0be 305 /**
epgmdm 0:8fd0531ae0be 306 * Reads 1 byte from a register
epgmdm 0:8fd0531ae0be 307 **/
epgmdm 0:8fd0531ae0be 308 char NRF2401P::readReg( char address, char *data )
epgmdm 0:8fd0531ae0be 309 {
epgmdm 0:8fd0531ae0be 310 csn = 0;
epgmdm 0:8fd0531ae0be 311 address &= 0x1F;
epgmdm 0:8fd0531ae0be 312 status = spi->write( address );
epgmdm 0:8fd0531ae0be 313 *data = spi->write( 0x00 );
epgmdm 0:8fd0531ae0be 314 csn = 1;
epgmdm 0:8fd0531ae0be 315 // sprintf(logMsg, " register read %02x (%02x) = %02x", address, status, *data );
epgmdm 0:8fd0531ae0be 316 // log(logMsg);
epgmdm 0:8fd0531ae0be 317 return status;
epgmdm 0:8fd0531ae0be 318 }
epgmdm 0:8fd0531ae0be 319 /**
epgmdm 0:8fd0531ae0be 320 * Clears the status flags RX_DR, TX_DS, MAX_RT
epgmdm 0:8fd0531ae0be 321 */
epgmdm 0:8fd0531ae0be 322 bool NRF2401P::clearStatus()
epgmdm 0:8fd0531ae0be 323 {
epgmdm 2:ca0a3c0bba70 324 status = writeReg(STATUS,0x70);
epgmdm 2:ca0a3c0bba70 325 if (debug) {
epgmdm 2:ca0a3c0bba70 326 sprintf(logMsg, "Clear status (%02x)", status );
epgmdm 2:ca0a3c0bba70 327 log(logMsg);
epgmdm 2:ca0a3c0bba70 328 }
epgmdm 0:8fd0531ae0be 329 }
epgmdm 0:8fd0531ae0be 330 /**
epgmdm 0:8fd0531ae0be 331 * flushes TX FIFO and resets status flags
epgmdm 0:8fd0531ae0be 332 */
epgmdm 0:8fd0531ae0be 333 bool NRF2401P::flushTx()
epgmdm 0:8fd0531ae0be 334 {
epgmdm 0:8fd0531ae0be 335 csn = 0;
epgmdm 2:ca0a3c0bba70 336 status = spi->write( FLUSH_TX );
epgmdm 0:8fd0531ae0be 337 csn = 1;
epgmdm 0:8fd0531ae0be 338 clearStatus();
epgmdm 2:ca0a3c0bba70 339 if (debug) {
epgmdm 2:ca0a3c0bba70 340 sprintf(logMsg, "Flush TX FIFO (%02x)", status );
epgmdm 2:ca0a3c0bba70 341 log(logMsg);
epgmdm 2:ca0a3c0bba70 342 }
epgmdm 0:8fd0531ae0be 343 return;
epgmdm 0:8fd0531ae0be 344 }
epgmdm 0:8fd0531ae0be 345
epgmdm 0:8fd0531ae0be 346 /**
epgmdm 0:8fd0531ae0be 347 * flushes RX FIFO and resets status flags
epgmdm 0:8fd0531ae0be 348 */
epgmdm 0:8fd0531ae0be 349 bool NRF2401P::flushRx()
epgmdm 0:8fd0531ae0be 350 {
epgmdm 0:8fd0531ae0be 351 csn = 0;
epgmdm 2:ca0a3c0bba70 352 status = spi->write( FLUSH_RX );
epgmdm 0:8fd0531ae0be 353 csn = 1;
epgmdm 2:ca0a3c0bba70 354 clearStatus();
epgmdm 2:ca0a3c0bba70 355 if (debug) {
epgmdm 2:ca0a3c0bba70 356 sprintf(logMsg, "Flush RX FIFO (%02x)", status );
epgmdm 2:ca0a3c0bba70 357 log(logMsg);
epgmdm 2:ca0a3c0bba70 358 }
epgmdm 0:8fd0531ae0be 359 }
epgmdm 0:8fd0531ae0be 360 /**
epgmdm 0:8fd0531ae0be 361 * Sets PRIM_RX = 0;
epgmdm 0:8fd0531ae0be 362 */
epgmdm 0:8fd0531ae0be 363 bool NRF2401P::setTxMode()
epgmdm 0:8fd0531ae0be 364 {
epgmdm 0:8fd0531ae0be 365 char data;
epgmdm 0:8fd0531ae0be 366 char bit;
epgmdm 2:ca0a3c0bba70 367 if (debug) {
epgmdm 2:ca0a3c0bba70 368 sprintf(logMsg, "Set Tx Mode");
epgmdm 2:ca0a3c0bba70 369 log(logMsg);
epgmdm 2:ca0a3c0bba70 370 }
epgmdm 2:ca0a3c0bba70 371 readReg( CONFIG, &data );
epgmdm 0:8fd0531ae0be 372 data &= ~( 1 << 0 );
epgmdm 2:ca0a3c0bba70 373 flushTx();
epgmdm 2:ca0a3c0bba70 374 flushRx();
epgmdm 2:ca0a3c0bba70 375 writeReg( CONFIG, data );
epgmdm 3:afe8d307b5c3 376 writeReg( RX_ADDR_P0, txAdd, addressWidth ); // reset p0
epgmdm 2:ca0a3c0bba70 377 writeReg(EN_RXADDR,0x01); // enable pipe 0 for reading
epgmdm 0:8fd0531ae0be 378 // check
epgmdm 0:8fd0531ae0be 379 readReg( 0x00, &data );
epgmdm 0:8fd0531ae0be 380 bit = ( data >> 0 ) & 1;
epgmdm 2:ca0a3c0bba70 381
epgmdm 0:8fd0531ae0be 382 ce=1;
epgmdm 0:8fd0531ae0be 383 wait(0.003);
epgmdm 0:8fd0531ae0be 384 return ( bit == 0 );
epgmdm 0:8fd0531ae0be 385 }
epgmdm 0:8fd0531ae0be 386
epgmdm 0:8fd0531ae0be 387 /**
epgmdm 0:8fd0531ae0be 388 * Sets the number of bytes of the address width = 3,4,5
epgmdm 0:8fd0531ae0be 389 */
epgmdm 0:8fd0531ae0be 390 bool NRF2401P::setAddressWidth( char width )
epgmdm 0:8fd0531ae0be 391 {
epgmdm 0:8fd0531ae0be 392 addressWidth = width;
epgmdm 0:8fd0531ae0be 393 if ( ( width > 5 ) || ( width < 3 ) )
epgmdm 0:8fd0531ae0be 394 return false;
epgmdm 0:8fd0531ae0be 395 width -= 2;
epgmdm 0:8fd0531ae0be 396 return writeReg( 0x03, width );
epgmdm 0:8fd0531ae0be 397
epgmdm 0:8fd0531ae0be 398 }
epgmdm 0:8fd0531ae0be 399 /**
epgmdm 0:8fd0531ae0be 400 * Sets the address, uses addess width set (either 3,4 or 5)
epgmdm 0:8fd0531ae0be 401 */
epgmdm 0:8fd0531ae0be 402 char NRF2401P::setTxAddress( char *address )
epgmdm 0:8fd0531ae0be 403 {
epgmdm 2:ca0a3c0bba70 404 memcpy (txAdd,address, addressWidth);
epgmdm 0:8fd0531ae0be 405 writeReg( 0x0A, address, addressWidth ); //Write to RX_ADDR_P0
epgmdm 0:8fd0531ae0be 406 return writeReg( 0x10, address, addressWidth ); //Write to TX_ADDR
epgmdm 0:8fd0531ae0be 407
epgmdm 0:8fd0531ae0be 408 }
epgmdm 0:8fd0531ae0be 409
epgmdm 0:8fd0531ae0be 410 /**
epgmdm 0:8fd0531ae0be 411 * Sets the address, uses addess width set (either 3,4 or 5)
epgmdm 0:8fd0531ae0be 412 */
epgmdm 0:8fd0531ae0be 413 char NRF2401P::setTxAddress( long long address )
epgmdm 0:8fd0531ae0be 414 {
epgmdm 0:8fd0531ae0be 415
epgmdm 0:8fd0531ae0be 416 char buff[ 5 ];
epgmdm 0:8fd0531ae0be 417 buff[ 0 ] = address & 0xff;
epgmdm 0:8fd0531ae0be 418 buff[ 1 ] = ( address >> 8 ) & 0xFF;
epgmdm 0:8fd0531ae0be 419 buff[ 2 ] = ( address >> 16 ) & 0xFF;
epgmdm 0:8fd0531ae0be 420 buff[ 3 ] = ( address >> 24 ) & 0xFF;
epgmdm 0:8fd0531ae0be 421 buff[ 4 ] = ( address >> 32 ) & 0xFF;
epgmdm 0:8fd0531ae0be 422 return setTxAddress( buff );
epgmdm 0:8fd0531ae0be 423
epgmdm 0:8fd0531ae0be 424 }
epgmdm 0:8fd0531ae0be 425
epgmdm 0:8fd0531ae0be 426 /**
epgmdm 0:8fd0531ae0be 427 * Sets the address, uses addess width set (either 3,4 or 5)
epgmdm 2:ca0a3c0bba70 428 * Enables pipe for receiving;
epgmdm 0:8fd0531ae0be 429 */
epgmdm 0:8fd0531ae0be 430 char NRF2401P::setRxAddress( char *address, char pipe )
epgmdm 0:8fd0531ae0be 431 {
epgmdm 2:ca0a3c0bba70 432 if(debug) {
epgmdm 2:ca0a3c0bba70 433 log ("Set Rx Address");
epgmdm 2:ca0a3c0bba70 434 }
epgmdm 2:ca0a3c0bba70 435 if (pipe>5) return 0xff;
epgmdm 2:ca0a3c0bba70 436 if (pipe ==0) {
epgmdm 2:ca0a3c0bba70 437 memcpy (pipe0Add,address, addressWidth);
epgmdm 2:ca0a3c0bba70 438 }
epgmdm 2:ca0a3c0bba70 439
epgmdm 0:8fd0531ae0be 440 char reg = 0x0A + pipe;
epgmdm 0:8fd0531ae0be 441 switch ( pipe ) {
epgmdm 0:8fd0531ae0be 442 case ( 0 ) :
epgmdm 0:8fd0531ae0be 443 case ( 1 ) : {
epgmdm 0:8fd0531ae0be 444 status = writeReg( reg, address, addressWidth ); //Write to RX_ADDR_P0 or _P1
epgmdm 0:8fd0531ae0be 445 break;
epgmdm 0:8fd0531ae0be 446 }
epgmdm 0:8fd0531ae0be 447 case ( 2 ) :
epgmdm 0:8fd0531ae0be 448 case ( 3 ) :
epgmdm 0:8fd0531ae0be 449 case ( 4 ) :
epgmdm 0:8fd0531ae0be 450 case ( 5 ) : {
epgmdm 0:8fd0531ae0be 451 status = writeReg( reg, address, 1 ); //Write to RX_ADDR_P2 ... _P5
epgmdm 0:8fd0531ae0be 452 break;
epgmdm 0:8fd0531ae0be 453 }
epgmdm 0:8fd0531ae0be 454
epgmdm 0:8fd0531ae0be 455 }
epgmdm 2:ca0a3c0bba70 456 readReg(EN_RXADDR,&reg);
epgmdm 2:ca0a3c0bba70 457 reg |= (1<<pipe);
epgmdm 2:ca0a3c0bba70 458 writeReg( EN_RXADDR,reg ); //Enable the pipe
epgmdm 0:8fd0531ae0be 459 return status;
epgmdm 0:8fd0531ae0be 460
epgmdm 0:8fd0531ae0be 461 }
epgmdm 0:8fd0531ae0be 462
epgmdm 0:8fd0531ae0be 463 /**
epgmdm 0:8fd0531ae0be 464 * Sets the address of pipe (<=5), uses addess width set (either 3,4 or 5)
epgmdm 0:8fd0531ae0be 465 */
epgmdm 0:8fd0531ae0be 466 char NRF2401P::setRxAddress( long long address, char pipe )
epgmdm 0:8fd0531ae0be 467 {
epgmdm 0:8fd0531ae0be 468 char buff[ 5 ];
epgmdm 0:8fd0531ae0be 469 buff[ 0 ] = address & 0xff;
epgmdm 0:8fd0531ae0be 470 buff[ 1 ] = ( address >> 8 ) & 0xFF;
epgmdm 0:8fd0531ae0be 471 buff[ 2 ] = ( address >> 16 ) & 0xFF;
epgmdm 0:8fd0531ae0be 472 buff[ 3 ] = ( address >> 24 ) & 0xFF;
epgmdm 0:8fd0531ae0be 473 buff[ 4 ] = ( address >> 32 ) & 0xFF;
epgmdm 0:8fd0531ae0be 474 return setRxAddress( buff, pipe );
epgmdm 0:8fd0531ae0be 475 }
epgmdm 1:ff53b1ac3bad 476 /**
epgmdm 1:ff53b1ac3bad 477 *checks the status flag
epgmdm 1:ff53b1ac3bad 478 */
epgmdm 1:ff53b1ac3bad 479 char NRF2401P::checkStatus()
epgmdm 1:ff53b1ac3bad 480 {
epgmdm 1:ff53b1ac3bad 481 readReg(0x07,&status);
epgmdm 1:ff53b1ac3bad 482 return status;
epgmdm 1:ff53b1ac3bad 483 }
epgmdm 1:ff53b1ac3bad 484 /**
epgmdm 1:ff53b1ac3bad 485 * checks if Ack data available.
epgmdm 1:ff53b1ac3bad 486 */
epgmdm 1:ff53b1ac3bad 487 bool NRF2401P::isAckData()
epgmdm 1:ff53b1ac3bad 488 {
epgmdm 1:ff53b1ac3bad 489 char fifo;
epgmdm 1:ff53b1ac3bad 490 readReg(0x17,&fifo);
epgmdm 1:ff53b1ac3bad 491 bool isData = !(fifo&0x01);
epgmdm 1:ff53b1ac3bad 492 return isData;
epgmdm 1:ff53b1ac3bad 493 }
epgmdm 0:8fd0531ae0be 494
epgmdm 1:ff53b1ac3bad 495 /**
epgmdm 1:ff53b1ac3bad 496 * checks if RX data available.
epgmdm 1:ff53b1ac3bad 497 */
epgmdm 0:8fd0531ae0be 498 bool NRF2401P::isRxData()
epgmdm 0:8fd0531ae0be 499 {
epgmdm 1:ff53b1ac3bad 500 checkStatus();
epgmdm 0:8fd0531ae0be 501 bool isData = (status>>6)&0x01;
epgmdm 0:8fd0531ae0be 502 return isData;
epgmdm 0:8fd0531ae0be 503 }
epgmdm 0:8fd0531ae0be 504 /**
epgmdm 0:8fd0531ae0be 505 * returns the width of the dynamic payload
epgmdm 0:8fd0531ae0be 506 */
epgmdm 0:8fd0531ae0be 507 char NRF2401P::getRxWidth()
epgmdm 0:8fd0531ae0be 508 {
epgmdm 0:8fd0531ae0be 509 char width;
epgmdm 0:8fd0531ae0be 510 if (dynamic) {
epgmdm 0:8fd0531ae0be 511 csn = 0;
epgmdm 0:8fd0531ae0be 512 status = spi->write( 0x60 );
epgmdm 0:8fd0531ae0be 513 width = spi->write(0x00);
epgmdm 0:8fd0531ae0be 514 csn = 1;
epgmdm 0:8fd0531ae0be 515
epgmdm 0:8fd0531ae0be 516 if (width>32) {
epgmdm 0:8fd0531ae0be 517 flushRx();
epgmdm 0:8fd0531ae0be 518 width=0;
epgmdm 0:8fd0531ae0be 519 }
epgmdm 0:8fd0531ae0be 520 } else {
epgmdm 0:8fd0531ae0be 521 status = readReg(0x12,&width); // width of p1
epgmdm 0:8fd0531ae0be 522
epgmdm 0:8fd0531ae0be 523 }
epgmdm 1:ff53b1ac3bad 524 // width=18;
epgmdm 0:8fd0531ae0be 525 return width;
epgmdm 0:8fd0531ae0be 526 }
epgmdm 0:8fd0531ae0be 527 /**
epgmdm 0:8fd0531ae0be 528 * return message in buffer, mem for buffer must have been allocated.
epgmdm 0:8fd0531ae0be 529 * Return value is number of bytes of buffer
epgmdm 0:8fd0531ae0be 530 */
epgmdm 0:8fd0531ae0be 531 char NRF2401P::getRxData(char * buffer)
epgmdm 0:8fd0531ae0be 532 {
epgmdm 0:8fd0531ae0be 533 char address = 0x61;
epgmdm 0:8fd0531ae0be 534 char width;
epgmdm 0:8fd0531ae0be 535 width = getRxWidth();
epgmdm 0:8fd0531ae0be 536 bool isData = (status>>6)&0x01;
epgmdm 0:8fd0531ae0be 537 if (isData) {
epgmdm 0:8fd0531ae0be 538 csn = 0;
epgmdm 0:8fd0531ae0be 539 int i;
epgmdm 0:8fd0531ae0be 540 // set up for reading
epgmdm 0:8fd0531ae0be 541 status = spi->write( address );
epgmdm 0:8fd0531ae0be 542 for ( i = 0; i <= width; i++ ) {
epgmdm 0:8fd0531ae0be 543 buffer[i]=spi->write(0x00 );
epgmdm 0:8fd0531ae0be 544 }
epgmdm 0:8fd0531ae0be 545 csn = 1;
epgmdm 0:8fd0531ae0be 546 sprintf(logMsg, "Receive data %d bytes", width );
epgmdm 0:8fd0531ae0be 547 log(logMsg);
epgmdm 0:8fd0531ae0be 548 clearStatus();
epgmdm 0:8fd0531ae0be 549 return width;
epgmdm 0:8fd0531ae0be 550
epgmdm 0:8fd0531ae0be 551 } else {
epgmdm 0:8fd0531ae0be 552 sprintf(logMsg, "Receive NO data %d bytes", width );
epgmdm 0:8fd0531ae0be 553 log(logMsg);
epgmdm 0:8fd0531ae0be 554 clearStatus();
epgmdm 0:8fd0531ae0be 555 return 0;
epgmdm 0:8fd0531ae0be 556 }
epgmdm 0:8fd0531ae0be 557
epgmdm 0:8fd0531ae0be 558 }
epgmdm 0:8fd0531ae0be 559
epgmdm 0:8fd0531ae0be 560 /**
epgmdm 0:8fd0531ae0be 561 * Sets all the receive pipes to dynamic payload length
epgmdm 0:8fd0531ae0be 562 */
epgmdm 2:ca0a3c0bba70 563 void NRF2401P::setDynamicPayload()
epgmdm 0:8fd0531ae0be 564 {
epgmdm 0:8fd0531ae0be 565 dynamic = true;
epgmdm 1:ff53b1ac3bad 566
epgmdm 2:ca0a3c0bba70 567 writeReg(FEATURE,0x07); // Enable Dyn payload, Payload with Ack and w_tx_noack command
epgmdm 2:ca0a3c0bba70 568 writeReg(EN_AA,0x3f); // EN_AA regi for P1 and P0
epgmdm 2:ca0a3c0bba70 569 writeReg(DYNPD, 0x1F);
epgmdm 0:8fd0531ae0be 570 }
epgmdm 2:ca0a3c0bba70 571
epgmdm 0:8fd0531ae0be 572 /**
epgmdm 0:8fd0531ae0be 573 * Sets PWR_UP = 1;
epgmdm 0:8fd0531ae0be 574 */
epgmdm 0:8fd0531ae0be 575 bool NRF2401P::setPwrUp()
epgmdm 0:8fd0531ae0be 576 {
epgmdm 0:8fd0531ae0be 577 char data;
epgmdm 0:8fd0531ae0be 578 char bit;
epgmdm 0:8fd0531ae0be 579 ce=1;
epgmdm 2:ca0a3c0bba70 580 readReg( CONFIG, &data );
epgmdm 2:ca0a3c0bba70 581 if ((data>>1) &0x01) {
epgmdm 2:ca0a3c0bba70 582 return true; // Already powered up
epgmdm 2:ca0a3c0bba70 583 };
epgmdm 0:8fd0531ae0be 584 data |= ( 0x02 );
epgmdm 0:8fd0531ae0be 585 writeReg( 0x00, data );
epgmdm 0:8fd0531ae0be 586 // check
epgmdm 0:8fd0531ae0be 587 readReg( 0x00, &data );
epgmdm 0:8fd0531ae0be 588 bit = ( data >> 1 ) & 1;
epgmdm 2:ca0a3c0bba70 589
epgmdm 0:8fd0531ae0be 590 wait(0.005); // wait 5ms
epgmdm 2:ca0a3c0bba70 591 if(debug) {
epgmdm 2:ca0a3c0bba70 592 sprintf(logMsg, "Set PWR_UP to %x", bit);
epgmdm 2:ca0a3c0bba70 593 log(logMsg);
epgmdm 2:ca0a3c0bba70 594 }
epgmdm 2:ca0a3c0bba70 595
epgmdm 0:8fd0531ae0be 596 return ( bit == 1 );
epgmdm 0:8fd0531ae0be 597 }
epgmdm 0:8fd0531ae0be 598 /**
epgmdm 0:8fd0531ae0be 599 * Sets PRIM_RX = 0;
epgmdm 0:8fd0531ae0be 600 */
epgmdm 0:8fd0531ae0be 601 bool NRF2401P::setRxMode()
epgmdm 0:8fd0531ae0be 602 {
epgmdm 0:8fd0531ae0be 603 char data;
epgmdm 0:8fd0531ae0be 604 char bit;
epgmdm 0:8fd0531ae0be 605 ce=1;
epgmdm 0:8fd0531ae0be 606 readReg( 0x00, &data );
epgmdm 2:ca0a3c0bba70 607 data |= ( 0x01 );
epgmdm 2:ca0a3c0bba70 608
epgmdm 0:8fd0531ae0be 609 writeReg( 0x00, data );
epgmdm 3:afe8d307b5c3 610 if (pipe0Add[0]|pipe0Add[1]|pipe0Add[2]|pipe0Add[3]|pipe0Add[4] >0) {
epgmdm 3:afe8d307b5c3 611 setRxAddress(pipe0Add,0);
epgmdm 2:ca0a3c0bba70 612 }
epgmdm 0:8fd0531ae0be 613 // check
epgmdm 0:8fd0531ae0be 614 readReg( 0x00, &data );
epgmdm 0:8fd0531ae0be 615 bit = ( data >> 0 ) & 1;
epgmdm 2:ca0a3c0bba70 616
epgmdm 2:ca0a3c0bba70 617 wait (0.001);
epgmdm 0:8fd0531ae0be 618 flushRx();
epgmdm 2:ca0a3c0bba70 619 flushTx();
epgmdm 2:ca0a3c0bba70 620 if (debug) {
epgmdm 2:ca0a3c0bba70 621 sprintf(logMsg, " set PRIM_RX to %x", bit);
epgmdm 2:ca0a3c0bba70 622 log(logMsg);
epgmdm 2:ca0a3c0bba70 623 }
epgmdm 0:8fd0531ae0be 624 return ( bit == 1 );
epgmdm 0:8fd0531ae0be 625 }
epgmdm 0:8fd0531ae0be 626 /**
epgmdm 0:8fd0531ae0be 627 * Prints status string
epgmdm 0:8fd0531ae0be 628 */
epgmdm 0:8fd0531ae0be 629 char * NRF2401P::statusString()
epgmdm 0:8fd0531ae0be 630 {
epgmdm 0:8fd0531ae0be 631 char *msg;
epgmdm 0:8fd0531ae0be 632 msg = statusS;
epgmdm 0:8fd0531ae0be 633 if (((status>>1) & 0x07)==0x07) {
epgmdm 0:8fd0531ae0be 634 sprintf(msg,"RX empty");
epgmdm 0:8fd0531ae0be 635 } else {
epgmdm 0:8fd0531ae0be 636 sprintf(msg,"pipe %02x",(status>>1) & 0x07);
epgmdm 0:8fd0531ae0be 637 }
epgmdm 0:8fd0531ae0be 638
epgmdm 0:8fd0531ae0be 639 if ((status>>6)&0x01) strcat(msg," RX_DR,");
epgmdm 0:8fd0531ae0be 640 if ((status>>5)&0x01) strcat(msg," TX_DS,");
epgmdm 0:8fd0531ae0be 641 if ((status>>4)&0x01) strcat(msg," MAX_RT,");
epgmdm 0:8fd0531ae0be 642 if ((status>>0)&0x01) strcat(msg," TX_FLL,");
epgmdm 0:8fd0531ae0be 643
epgmdm 0:8fd0531ae0be 644 return msg;
epgmdm 0:8fd0531ae0be 645 }