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 11 17:00:18 2015 +0000
Revision:
1:ff53b1ac3bad
Parent:
0:8fd0531ae0be
Child:
2:ca0a3c0bba70
Added a few extras

Who changed what in which revision?

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