This is a work in progress for an NRF2401P

Dependents:   NRF_receiver sender locker4 Weather_Station_Ofiicial ... more

About

This is a simple library to drive the nRF24l01+.

Hardware

This uses the commonly available breakout. The connections are shown below /media/uploads/epgmdm/nrf24l01pinout.png

Software

Use case: For a simple transmitter

tx code snipet

#include "NRF2401P.h"
int main() {
*
*  long long addr1=0xAB00CD; // setup address - any 5 byte number - same as RX
*  int channel =0x12;  // [0-126] setup channel, must be same as RX
*  bool txOK;
*  char msg[32];
*  char ackData[32];
*  char len;
*
*  // Setup 
*  NRF2401P nrf1(PTD6,PTD7, PTD5,PTD4, PTC12); //mosi, miso, sclk, csn, ce)
*  nrf1.quickTxSetup(channel, addr1); // sets nrf24l01+ as transmitter
*
*  // transmit
*  strcpy (msg, "Hello"); 
*  txOK= nrf1.transmitData(msg,strlen(msg));
*
*  // read ack data if available
*  if (nrf1.isAckData()) { 
*      len= nrf1.getRxData(ackData); // len is number of bytes in ackData
*   }
*}

Use case: For a simple receiver

rx code snipet

#include "NRF2401P.h"
*int main(){
*        
*  long long addr1=0xAB00CD; // setup address - any 5 byte number - same as TX
*  int channel =0x12;  // [0-126] setup channel, must be same as TX
*  bool txOK;
*  char msg[32];
*  char ackData[32];
*  char len;
*
*  // Setup 
*  NRF2401P nrf1(PTD6,PTD7, PTD5,PTD4, PTC12); //mosi, miso, sclk, csn, ce)
*  nrf1.quickRxSetup(channel, addr1); // sets nrf24l01+ as  receiver, using pipe 1
*
*  // set ack data
*  sprintf(ackData,"Ack data");
*  nrf1.acknowledgeData(ackData, strlen(ackData),1); // ack for pipe 1
*    
*  // receive
*  while (! nrf1.isRxData()); // note this blocks until RX data
*  len= nrf1.getRxData(msg); // gets the message, len is length of msg
*
*}
Committer:
epgmdm
Date:
Thu Jun 18 20:54:25 2015 +0000
Revision:
15:9998698cb041
Parent:
4:e55807cf840b
Cleaned up code. most functions now return void. Status is tracked in the class. Use checkStatus().

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