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
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 * *}
NRF2401P.cpp@20:e61edde5680d, 2016-02-25 (annotated)
- Committer:
- epgmdm
- Date:
- Thu Feb 25 09:44:11 2016 +0000
- Revision:
- 20:e61edde5680d
- Parent:
- 19:813161fd59a2
Minor updates to make all returns void if possible
Who changed what in which revision?
User | Revision | Line number | New 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 | NRF2401P::NRF2401P ( PinName mosi, PinName miso, PinName sclk, PinName _csn, PinName _ce ) : |
epgmdm | 20:e61edde5680d | 31 | csn( DigitalOut( _csn ) ), ce( DigitalOut( _ce ) ) |
epgmdm | 0:8fd0531ae0be | 32 | { |
epgmdm | 0:8fd0531ae0be | 33 | addressWidth = 5; |
epgmdm | 19:813161fd59a2 | 34 | //pc = new Serial( USBTX, USBRX ); // tx, rx |
nixonkj | 6:77ead8abdd1c | 35 | if (debug) { |
nixonkj | 6:77ead8abdd1c | 36 | sprintf(logMsg, "Initialise" ); |
nixonkj | 6:77ead8abdd1c | 37 | log(logMsg); |
nixonkj | 6:77ead8abdd1c | 38 | } |
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; |
nixonkj | 6:77ead8abdd1c | 45 | debug = false; |
nixonkj | 6:77ead8abdd1c | 46 | } |
epgmdm | 0:8fd0531ae0be | 47 | |
nixonkj | 6:77ead8abdd1c | 48 | void NRF2401P::log(char *msg) |
epgmdm | 0:8fd0531ae0be | 49 | { |
epgmdm | 0:8fd0531ae0be | 50 | if(debug) { |
nixonkj | 8:3e027705ce23 | 51 | printf("\t <%s \t %s>\n\r", statusString(), msg); |
epgmdm | 1:ff53b1ac3bad | 52 | wait(0.01); |
nixonkj | 6:77ead8abdd1c | 53 | } |
epgmdm | 0:8fd0531ae0be | 54 | } |
epgmdm | 0:8fd0531ae0be | 55 | |
epgmdm | 0:8fd0531ae0be | 56 | void NRF2401P::scratch() |
epgmdm | 0:8fd0531ae0be | 57 | { |
epgmdm | 0:8fd0531ae0be | 58 | int status = 0; |
epgmdm | 0:8fd0531ae0be | 59 | int register1 = 0; |
epgmdm | 0:8fd0531ae0be | 60 | ce = 0; |
epgmdm | 0:8fd0531ae0be | 61 | for ( char i = 0; i < 24; i++ ) { |
epgmdm | 0:8fd0531ae0be | 62 | csn = 0; |
epgmdm | 0:8fd0531ae0be | 63 | //wait_us(100); |
epgmdm | 0:8fd0531ae0be | 64 | status = spi->write( i ); |
epgmdm | 0:8fd0531ae0be | 65 | register1 = spi->write( 0x00 ); |
epgmdm | 0:8fd0531ae0be | 66 | csn = 1; |
epgmdm | 0:8fd0531ae0be | 67 | sprintf(logMsg, " register %02x (%02x) = %02x", i, status, register1 ); |
epgmdm | 0:8fd0531ae0be | 68 | log(logMsg); |
epgmdm | 0:8fd0531ae0be | 69 | } |
nixonkj | 6:77ead8abdd1c | 70 | } |
epgmdm | 0:8fd0531ae0be | 71 | |
epgmdm | 0:8fd0531ae0be | 72 | /** |
epgmdm | 2:ca0a3c0bba70 | 73 | * start here to configure the basics of the NRF |
epgmdm | 2:ca0a3c0bba70 | 74 | */ |
epgmdm | 2:ca0a3c0bba70 | 75 | void NRF2401P::start() |
epgmdm | 2:ca0a3c0bba70 | 76 | { |
nixonkj | 8:3e027705ce23 | 77 | writeReg(CONFIG, 0x0c); // set 16 bit crc |
epgmdm | 17:b132fc1a27d2 | 78 | setTxRetry(0x05, 0x0f); // 500 uS, 15 retries |
nixonkj | 8:3e027705ce23 | 79 | setRadio(0, 0x03); // 1MB/S 0dB |
epgmdm | 2:ca0a3c0bba70 | 80 | setDynamicPayload(); |
epgmdm | 2:ca0a3c0bba70 | 81 | setChannel(76); // should be clear? |
epgmdm | 2:ca0a3c0bba70 | 82 | setAddressWidth(5); |
epgmdm | 2:ca0a3c0bba70 | 83 | flushRx(); |
epgmdm | 2:ca0a3c0bba70 | 84 | flushTx(); |
epgmdm | 2:ca0a3c0bba70 | 85 | setPwrUp(); |
epgmdm | 2:ca0a3c0bba70 | 86 | setTxMode(); // just make sure no spurious reads.... |
nixonkj | 6:77ead8abdd1c | 87 | } |
epgmdm | 2:ca0a3c0bba70 | 88 | |
epgmdm | 2:ca0a3c0bba70 | 89 | /** |
epgmdm | 16:a9b83d2b6915 | 90 | * Sets up a receiver using shockburst and dynamic payload. Uses pipe 0 |
epgmdm | 0:8fd0531ae0be | 91 | * defaults to 5 bytes |
epgmdm | 0:8fd0531ae0be | 92 | */ |
epgmdm | 2:ca0a3c0bba70 | 93 | void NRF2401P::quickRxSetup(int channel,long long addrRx) |
epgmdm | 0:8fd0531ae0be | 94 | { |
epgmdm | 2:ca0a3c0bba70 | 95 | start(); |
epgmdm | 0:8fd0531ae0be | 96 | setChannel(channel); |
epgmdm | 16:a9b83d2b6915 | 97 | // setRxAddress(addrRx,1); |
epgmdm | 16:a9b83d2b6915 | 98 | setRxAddress(addrRx,0); |
epgmdm | 0:8fd0531ae0be | 99 | setRxMode(); |
epgmdm | 0:8fd0531ae0be | 100 | ce=1; |
nixonkj | 6:77ead8abdd1c | 101 | wait(0.001f); |
epgmdm | 16:a9b83d2b6915 | 102 | writeReg(FEATURE,0x06); // Enable dynamic ack packets |
epgmdm | 0:8fd0531ae0be | 103 | } |
nixonkj | 6:77ead8abdd1c | 104 | |
epgmdm | 0:8fd0531ae0be | 105 | /** |
epgmdm | 0:8fd0531ae0be | 106 | * Sets up for receive of a message to address 0XA0A0A0 |
epgmdm | 0:8fd0531ae0be | 107 | */ |
epgmdm | 20:e61edde5680d | 108 | void NRF2401P::testReceive() |
epgmdm | 0:8fd0531ae0be | 109 | { |
epgmdm | 0:8fd0531ae0be | 110 | char message[64]; |
epgmdm | 0:8fd0531ae0be | 111 | char width; |
epgmdm | 0:8fd0531ae0be | 112 | int channel = 0x12; |
epgmdm | 0:8fd0531ae0be | 113 | long long addr=0xA0B0C0; |
epgmdm | 0:8fd0531ae0be | 114 | debug = true; |
epgmdm | 0:8fd0531ae0be | 115 | quickRxSetup(channel, addr); |
epgmdm | 0:8fd0531ae0be | 116 | |
epgmdm | 0:8fd0531ae0be | 117 | while (1) { |
epgmdm | 0:8fd0531ae0be | 118 | while (!isRxData()) { |
epgmdm | 0:8fd0531ae0be | 119 | //wait(0.5); |
epgmdm | 0:8fd0531ae0be | 120 | }; |
epgmdm | 0:8fd0531ae0be | 121 | width=getRxData(message); |
epgmdm | 0:8fd0531ae0be | 122 | message[width]='\0'; |
epgmdm | 0:8fd0531ae0be | 123 | sprintf(logMsg,"Received= [%s]",message); |
epgmdm | 0:8fd0531ae0be | 124 | log(logMsg); |
nixonkj | 6:77ead8abdd1c | 125 | } |
epgmdm | 0:8fd0531ae0be | 126 | } |
epgmdm | 0:8fd0531ae0be | 127 | |
epgmdm | 20:e61edde5680d | 128 | void NRF2401P::setTxRetry(char delay, char numTries) |
epgmdm | 2:ca0a3c0bba70 | 129 | { |
epgmdm | 2:ca0a3c0bba70 | 130 | char val = (delay&0xf)<<4 | (numTries&0xf); |
nixonkj | 8:3e027705ce23 | 131 | writeReg(SETUP_RETR, val); |
epgmdm | 2:ca0a3c0bba70 | 132 | } |
epgmdm | 2:ca0a3c0bba70 | 133 | |
epgmdm | 2:ca0a3c0bba70 | 134 | /** |
epgmdm | 0:8fd0531ae0be | 135 | * Sets up a transmitter using shockburst and dynamic payload. Uses pipe 1 |
epgmdm | 0:8fd0531ae0be | 136 | * defaults to 5 bytes |
epgmdm | 0:8fd0531ae0be | 137 | */ |
epgmdm | 0:8fd0531ae0be | 138 | void NRF2401P::quickTxSetup(int channel,long long addr) |
epgmdm | 0:8fd0531ae0be | 139 | { |
epgmdm | 2:ca0a3c0bba70 | 140 | start(); |
epgmdm | 0:8fd0531ae0be | 141 | setChannel(channel); |
epgmdm | 2:ca0a3c0bba70 | 142 | setTxAddress(addr); |
epgmdm | 0:8fd0531ae0be | 143 | setTxMode(); |
epgmdm | 16:a9b83d2b6915 | 144 | writeReg(FEATURE,0x06); |
epgmdm | 0:8fd0531ae0be | 145 | ce=1; |
epgmdm | 0:8fd0531ae0be | 146 | wait (0.0016f); // wait for pll to settle |
epgmdm | 16:a9b83d2b6915 | 147 | flushTx(); |
epgmdm | 16:a9b83d2b6915 | 148 | clearStatus(); |
epgmdm | 0:8fd0531ae0be | 149 | } |
epgmdm | 0:8fd0531ae0be | 150 | |
epgmdm | 0:8fd0531ae0be | 151 | /** |
epgmdm | 0:8fd0531ae0be | 152 | * Sets up for transmit of a message to address 0XA0A0A0 |
epgmdm | 0:8fd0531ae0be | 153 | */ |
epgmdm | 20:e61edde5680d | 154 | void NRF2401P::testTransmit() |
epgmdm | 0:8fd0531ae0be | 155 | { |
epgmdm | 0:8fd0531ae0be | 156 | long long addr=0xA0B0C0; |
epgmdm | 0:8fd0531ae0be | 157 | int channel = 0x12; |
epgmdm | 0:8fd0531ae0be | 158 | char data[32] ; |
epgmdm | 0:8fd0531ae0be | 159 | int i=0; |
epgmdm | 0:8fd0531ae0be | 160 | quickRxSetup(channel, addr); |
epgmdm | 0:8fd0531ae0be | 161 | while (1) { |
epgmdm | 0:8fd0531ae0be | 162 | sprintf(data," packet %03d", i++ |100); |
epgmdm | 0:8fd0531ae0be | 163 | transmitData(data,18); |
epgmdm | 0:8fd0531ae0be | 164 | wait (1.0); |
epgmdm | 0:8fd0531ae0be | 165 | } |
nixonkj | 6:77ead8abdd1c | 166 | } |
epgmdm | 0:8fd0531ae0be | 167 | |
epgmdm | 20:e61edde5680d | 168 | void NRF2401P::setRadio(char speed, char power) |
epgmdm | 0:8fd0531ae0be | 169 | { |
epgmdm | 20:e61edde5680d | 170 | char val=0; |
nixonkj | 8:3e027705ce23 | 171 | if (debug) { |
nixonkj | 8:3e027705ce23 | 172 | sprintf(logMsg, "Set radio"); |
nixonkj | 8:3e027705ce23 | 173 | log(logMsg); |
nixonkj | 8:3e027705ce23 | 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 | |
nixonkj | 6:77ead8abdd1c | 180 | val |= ((power & 0x03)<<1); |
nixonkj | 6:77ead8abdd1c | 181 | printf("\n\r"); |
nixonkj | 6:77ead8abdd1c | 182 | |
nixonkj | 8:3e027705ce23 | 183 | writeReg(RF_SETUP, val); |
epgmdm | 0:8fd0531ae0be | 184 | } |
nixonkj | 6:77ead8abdd1c | 185 | |
epgmdm | 20:e61edde5680d | 186 | void NRF2401P::setChannel(char chan) |
epgmdm | 0:8fd0531ae0be | 187 | { |
nixonkj | 6:77ead8abdd1c | 188 | char chk=0; |
nixonkj | 6:77ead8abdd1c | 189 | if (debug) { |
nixonkj | 6:77ead8abdd1c | 190 | sprintf(logMsg, "Set channel"); |
nixonkj | 6:77ead8abdd1c | 191 | log(logMsg); |
nixonkj | 6:77ead8abdd1c | 192 | } |
nixonkj | 8:3e027705ce23 | 193 | writeReg(RF_CH, (chan&0x7f)); |
nixonkj | 8:3e027705ce23 | 194 | readReg(RF_CH, &chk); |
epgmdm | 20:e61edde5680d | 195 | |
epgmdm | 0:8fd0531ae0be | 196 | } |
nixonkj | 6:77ead8abdd1c | 197 | |
nixonkj | 13:5cbc726f2bbb | 198 | bool NRF2401P::isRPDset() |
nixonkj | 13:5cbc726f2bbb | 199 | { |
nixonkj | 13:5cbc726f2bbb | 200 | char val=0; |
nixonkj | 13:5cbc726f2bbb | 201 | if (debug) { |
nixonkj | 13:5cbc726f2bbb | 202 | sprintf(logMsg, "Get RPD"); |
nixonkj | 13:5cbc726f2bbb | 203 | log(logMsg); |
nixonkj | 13:5cbc726f2bbb | 204 | } |
nixonkj | 13:5cbc726f2bbb | 205 | readReg(RPD, &val); |
nixonkj | 13:5cbc726f2bbb | 206 | if (val == 1) { |
nixonkj | 13:5cbc726f2bbb | 207 | return true; |
nixonkj | 13:5cbc726f2bbb | 208 | } else { |
nixonkj | 13:5cbc726f2bbb | 209 | return false; |
nixonkj | 13:5cbc726f2bbb | 210 | } |
nixonkj | 13:5cbc726f2bbb | 211 | } |
nixonkj | 13:5cbc726f2bbb | 212 | |
epgmdm | 0:8fd0531ae0be | 213 | /** |
epgmdm | 0:8fd0531ae0be | 214 | * Transmits width bytes of data. width <32 |
epgmdm | 0:8fd0531ae0be | 215 | */ |
nixonkj | 6:77ead8abdd1c | 216 | char NRF2401P::transmitData( char *data, char width ) |
epgmdm | 0:8fd0531ae0be | 217 | { |
nixonkj | 6:77ead8abdd1c | 218 | if (width>32) |
nixonkj | 6:77ead8abdd1c | 219 | return 0; |
nixonkj | 6:77ead8abdd1c | 220 | checkStatus(); |
epgmdm | 20:e61edde5680d | 221 | if ((status>>MAX_RT)&1) { // Max retries - flush tx |
nixonkj | 6:77ead8abdd1c | 222 | flushTx(); |
nixonkj | 6:77ead8abdd1c | 223 | } |
epgmdm | 2:ca0a3c0bba70 | 224 | //clearStatus(); |
epgmdm | 2:ca0a3c0bba70 | 225 | //ce = 1; |
epgmdm | 0:8fd0531ae0be | 226 | csn = 0; |
nixonkj | 8:3e027705ce23 | 227 | char address = 0xA0; |
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 | 3:afe8d307b5c3 | 235 | wait(0.001); |
epgmdm | 3:afe8d307b5c3 | 236 | if (debug) { |
nixonkj | 6:77ead8abdd1c | 237 | sprintf(logMsg, " Transmit data %d bytes to %02x (%02x) = %10s", width, address, status, data ); |
epgmdm | 3:afe8d307b5c3 | 238 | log(logMsg); |
epgmdm | 2:ca0a3c0bba70 | 239 | } |
epgmdm | 0:8fd0531ae0be | 240 | return status; |
epgmdm | 0:8fd0531ae0be | 241 | } |
epgmdm | 0:8fd0531ae0be | 242 | |
epgmdm | 0:8fd0531ae0be | 243 | /** |
epgmdm | 18:220df99d2d41 | 244 | * re Transmits data |
epgmdm | 18:220df99d2d41 | 245 | */ |
epgmdm | 20:e61edde5680d | 246 | void NRF2401P::retransmitData( ) |
epgmdm | 18:220df99d2d41 | 247 | { |
epgmdm | 18:220df99d2d41 | 248 | checkStatus(); |
epgmdm | 18:220df99d2d41 | 249 | if ((status>>4)&1) { // Max retries - flush tx |
epgmdm | 18:220df99d2d41 | 250 | flushTx(); |
epgmdm | 18:220df99d2d41 | 251 | } |
epgmdm | 18:220df99d2d41 | 252 | //clearStatus(); |
epgmdm | 18:220df99d2d41 | 253 | //ce = 1; |
epgmdm | 18:220df99d2d41 | 254 | csn = 0; |
epgmdm | 18:220df99d2d41 | 255 | char address = REUSE_TX_PL; //REUSE_TX_PL |
epgmdm | 18:220df99d2d41 | 256 | // set up for writing |
epgmdm | 18:220df99d2d41 | 257 | status = spi->write( address ); |
epgmdm | 18:220df99d2d41 | 258 | csn = 1; |
epgmdm | 18:220df99d2d41 | 259 | if (debug) { |
epgmdm | 18:220df99d2d41 | 260 | sprintf(logMsg, "Reransmit data" ); |
epgmdm | 18:220df99d2d41 | 261 | log(logMsg); |
epgmdm | 18:220df99d2d41 | 262 | } |
epgmdm | 18:220df99d2d41 | 263 | } |
epgmdm | 18:220df99d2d41 | 264 | /** |
epgmdm | 0:8fd0531ae0be | 265 | * sets acknowledge data width bytes of data. width <32 |
epgmdm | 0:8fd0531ae0be | 266 | */ |
epgmdm | 20:e61edde5680d | 267 | void NRF2401P::acknowledgeData( char *data, char width, char pipe ) |
epgmdm | 0:8fd0531ae0be | 268 | { |
epgmdm | 0:8fd0531ae0be | 269 | ce = 1; |
epgmdm | 0:8fd0531ae0be | 270 | csn = 0; |
epgmdm | 2:ca0a3c0bba70 | 271 | //writeReg(0x1d,0x06); // enable payload with ack |
epgmdm | 2:ca0a3c0bba70 | 272 | char address = W_ACK_PAYLOAD | (pipe&0x07); |
epgmdm | 20:e61edde5680d | 273 | char i; |
epgmdm | 0:8fd0531ae0be | 274 | // set up for writing |
epgmdm | 3:afe8d307b5c3 | 275 | csn = 0; |
epgmdm | 0:8fd0531ae0be | 276 | status = spi->write( address ); |
epgmdm | 0:8fd0531ae0be | 277 | for ( i = 0; i <width; i++ ) { |
epgmdm | 0:8fd0531ae0be | 278 | spi->write( data[ i ] ); |
epgmdm | 0:8fd0531ae0be | 279 | } |
epgmdm | 0:8fd0531ae0be | 280 | csn = 1; |
epgmdm | 3:afe8d307b5c3 | 281 | if (debug) { |
epgmdm | 3:afe8d307b5c3 | 282 | sprintf(logMsg, " acknowledge data %d bytes to %02x (%02x) = %c", width, address, status, *data ); |
epgmdm | 3:afe8d307b5c3 | 283 | log(logMsg); |
epgmdm | 2:ca0a3c0bba70 | 284 | } |
nixonkj | 6:77ead8abdd1c | 285 | } |
epgmdm | 0:8fd0531ae0be | 286 | |
epgmdm | 0:8fd0531ae0be | 287 | /** |
epgmdm | 0:8fd0531ae0be | 288 | * Writes 1 byte data to a register |
epgmdm | 0:8fd0531ae0be | 289 | **/ |
nixonkj | 6:77ead8abdd1c | 290 | void NRF2401P::writeReg( char address, char data ) |
epgmdm | 0:8fd0531ae0be | 291 | { |
epgmdm | 0:8fd0531ae0be | 292 | char reg; |
epgmdm | 0:8fd0531ae0be | 293 | csn = 0; |
epgmdm | 0:8fd0531ae0be | 294 | address &= 0x1F; |
nixonkj | 8:3e027705ce23 | 295 | reg = address | W_REGISTER; |
epgmdm | 0:8fd0531ae0be | 296 | status = spi->write( reg ); |
epgmdm | 0:8fd0531ae0be | 297 | spi->write( data ); |
epgmdm | 0:8fd0531ae0be | 298 | csn = 1; |
nixonkj | 6:77ead8abdd1c | 299 | if (debug) { |
nixonkj | 6:77ead8abdd1c | 300 | sprintf(logMsg, " register write %02x (%02x) = %02x", address, status, data ); |
nixonkj | 6:77ead8abdd1c | 301 | log(logMsg); |
nixonkj | 6:77ead8abdd1c | 302 | } |
epgmdm | 0:8fd0531ae0be | 303 | } |
nixonkj | 6:77ead8abdd1c | 304 | |
epgmdm | 0:8fd0531ae0be | 305 | /** |
epgmdm | 0:8fd0531ae0be | 306 | * Writes width bytes data to a register, ls byte to ms byte /for adressess |
epgmdm | 0:8fd0531ae0be | 307 | **/ |
nixonkj | 6:77ead8abdd1c | 308 | void NRF2401P::writeReg( char address, char *data, char width ) |
epgmdm | 0:8fd0531ae0be | 309 | { |
epgmdm | 0:8fd0531ae0be | 310 | char reg; |
epgmdm | 0:8fd0531ae0be | 311 | csn = 0; |
epgmdm | 0:8fd0531ae0be | 312 | int i; |
epgmdm | 0:8fd0531ae0be | 313 | // set up for writing |
epgmdm | 0:8fd0531ae0be | 314 | address &= 0x1F; |
nixonkj | 8:3e027705ce23 | 315 | reg = address| W_REGISTER; |
epgmdm | 0:8fd0531ae0be | 316 | status = spi->write( reg ); |
epgmdm | 0:8fd0531ae0be | 317 | for ( i = width - 1; i >= 0; i-- ) { |
epgmdm | 0:8fd0531ae0be | 318 | spi->write( data[ i ] ); |
epgmdm | 0:8fd0531ae0be | 319 | } |
epgmdm | 0:8fd0531ae0be | 320 | csn = 1; |
epgmdm | 2:ca0a3c0bba70 | 321 | if (debug) { |
epgmdm | 2:ca0a3c0bba70 | 322 | sprintf(logMsg, " register write %d bytes to %02x (%02x) = %02x %02x %02x", width, address, status, data[0], data[1], data[2] ); |
epgmdm | 2:ca0a3c0bba70 | 323 | log(logMsg); |
epgmdm | 2:ca0a3c0bba70 | 324 | } |
epgmdm | 0:8fd0531ae0be | 325 | } |
nixonkj | 6:77ead8abdd1c | 326 | |
epgmdm | 0:8fd0531ae0be | 327 | /** |
epgmdm | 0:8fd0531ae0be | 328 | * Reads 1 byte from a register |
epgmdm | 0:8fd0531ae0be | 329 | **/ |
nixonkj | 6:77ead8abdd1c | 330 | void NRF2401P::readReg( char address, char *data ) |
epgmdm | 0:8fd0531ae0be | 331 | { |
epgmdm | 0:8fd0531ae0be | 332 | csn = 0; |
epgmdm | 0:8fd0531ae0be | 333 | address &= 0x1F; |
epgmdm | 0:8fd0531ae0be | 334 | status = spi->write( address ); |
epgmdm | 0:8fd0531ae0be | 335 | *data = spi->write( 0x00 ); |
epgmdm | 0:8fd0531ae0be | 336 | csn = 1; |
nixonkj | 6:77ead8abdd1c | 337 | if (debug && address != 0x07) { // In debug mode: print out anything other than a status request |
nixonkj | 6:77ead8abdd1c | 338 | sprintf(logMsg, " register read %02x (%02x) = %02x", address, status, *data ); |
nixonkj | 6:77ead8abdd1c | 339 | log(logMsg); |
nixonkj | 6:77ead8abdd1c | 340 | } |
epgmdm | 0:8fd0531ae0be | 341 | } |
nixonkj | 6:77ead8abdd1c | 342 | |
epgmdm | 0:8fd0531ae0be | 343 | /** |
nixonkj | 10:8a217441c38e | 344 | * Reads n bytes from a register |
nixonkj | 10:8a217441c38e | 345 | **/ |
nixonkj | 10:8a217441c38e | 346 | void NRF2401P::readReg( char address, char *data, char width ) |
epgmdm | 16:a9b83d2b6915 | 347 | { |
nixonkj | 10:8a217441c38e | 348 | char reg; |
nixonkj | 10:8a217441c38e | 349 | csn = 0; |
nixonkj | 10:8a217441c38e | 350 | int i; |
nixonkj | 10:8a217441c38e | 351 | // set up for writing |
nixonkj | 10:8a217441c38e | 352 | address &= 0x1F; |
nixonkj | 10:8a217441c38e | 353 | reg = address| R_REGISTER; |
nixonkj | 10:8a217441c38e | 354 | status = spi->write( reg ); |
nixonkj | 10:8a217441c38e | 355 | for ( i = width - 1; i >= 0; i-- ) { |
nixonkj | 10:8a217441c38e | 356 | data[i] = spi->write( 0x00 ); |
nixonkj | 10:8a217441c38e | 357 | } |
nixonkj | 10:8a217441c38e | 358 | csn = 1; |
nixonkj | 10:8a217441c38e | 359 | if (debug) { |
nixonkj | 10:8a217441c38e | 360 | sprintf(logMsg, " register read %d bytes from %02x (%02x) = ", width, address, status ); |
nixonkj | 10:8a217441c38e | 361 | for ( i=0; i<width; i++) |
nixonkj | 10:8a217441c38e | 362 | sprintf(logMsg, "%s %02x", logMsg, data[i]); |
nixonkj | 10:8a217441c38e | 363 | log(logMsg); |
nixonkj | 10:8a217441c38e | 364 | } |
nixonkj | 10:8a217441c38e | 365 | } |
nixonkj | 10:8a217441c38e | 366 | |
nixonkj | 10:8a217441c38e | 367 | /** |
epgmdm | 0:8fd0531ae0be | 368 | * Clears the status flags RX_DR, TX_DS, MAX_RT |
epgmdm | 0:8fd0531ae0be | 369 | */ |
nixonkj | 6:77ead8abdd1c | 370 | void NRF2401P::clearStatus() |
epgmdm | 0:8fd0531ae0be | 371 | { |
nixonkj | 8:3e027705ce23 | 372 | writeReg(STATUS, 0x70); |
epgmdm | 2:ca0a3c0bba70 | 373 | if (debug) { |
epgmdm | 2:ca0a3c0bba70 | 374 | sprintf(logMsg, "Clear status (%02x)", status ); |
epgmdm | 2:ca0a3c0bba70 | 375 | log(logMsg); |
epgmdm | 2:ca0a3c0bba70 | 376 | } |
epgmdm | 0:8fd0531ae0be | 377 | } |
nixonkj | 6:77ead8abdd1c | 378 | |
epgmdm | 0:8fd0531ae0be | 379 | /** |
epgmdm | 0:8fd0531ae0be | 380 | * flushes TX FIFO and resets status flags |
epgmdm | 0:8fd0531ae0be | 381 | */ |
nixonkj | 6:77ead8abdd1c | 382 | void NRF2401P::flushTx() |
epgmdm | 0:8fd0531ae0be | 383 | { |
epgmdm | 0:8fd0531ae0be | 384 | csn = 0; |
epgmdm | 2:ca0a3c0bba70 | 385 | status = spi->write( FLUSH_TX ); |
epgmdm | 0:8fd0531ae0be | 386 | csn = 1; |
epgmdm | 0:8fd0531ae0be | 387 | clearStatus(); |
epgmdm | 2:ca0a3c0bba70 | 388 | if (debug) { |
epgmdm | 2:ca0a3c0bba70 | 389 | sprintf(logMsg, "Flush TX FIFO (%02x)", status ); |
epgmdm | 2:ca0a3c0bba70 | 390 | log(logMsg); |
epgmdm | 2:ca0a3c0bba70 | 391 | } |
epgmdm | 0:8fd0531ae0be | 392 | } |
epgmdm | 0:8fd0531ae0be | 393 | |
epgmdm | 0:8fd0531ae0be | 394 | /** |
epgmdm | 0:8fd0531ae0be | 395 | * flushes RX FIFO and resets status flags |
epgmdm | 0:8fd0531ae0be | 396 | */ |
nixonkj | 6:77ead8abdd1c | 397 | void NRF2401P::flushRx() |
epgmdm | 0:8fd0531ae0be | 398 | { |
epgmdm | 0:8fd0531ae0be | 399 | csn = 0; |
epgmdm | 2:ca0a3c0bba70 | 400 | status = spi->write( FLUSH_RX ); |
epgmdm | 0:8fd0531ae0be | 401 | csn = 1; |
epgmdm | 2:ca0a3c0bba70 | 402 | clearStatus(); |
epgmdm | 2:ca0a3c0bba70 | 403 | if (debug) { |
epgmdm | 2:ca0a3c0bba70 | 404 | sprintf(logMsg, "Flush RX FIFO (%02x)", status ); |
epgmdm | 2:ca0a3c0bba70 | 405 | log(logMsg); |
epgmdm | 2:ca0a3c0bba70 | 406 | } |
epgmdm | 0:8fd0531ae0be | 407 | } |
nixonkj | 6:77ead8abdd1c | 408 | |
epgmdm | 0:8fd0531ae0be | 409 | /** |
epgmdm | 0:8fd0531ae0be | 410 | * Sets PRIM_RX = 0; |
epgmdm | 0:8fd0531ae0be | 411 | */ |
epgmdm | 20:e61edde5680d | 412 | void NRF2401P::setTxMode() |
epgmdm | 0:8fd0531ae0be | 413 | { |
epgmdm | 0:8fd0531ae0be | 414 | char data; |
epgmdm | 2:ca0a3c0bba70 | 415 | if (debug) { |
epgmdm | 2:ca0a3c0bba70 | 416 | sprintf(logMsg, "Set Tx Mode"); |
epgmdm | 2:ca0a3c0bba70 | 417 | log(logMsg); |
epgmdm | 2:ca0a3c0bba70 | 418 | } |
nixonkj | 8:3e027705ce23 | 419 | readReg(CONFIG, &data); |
epgmdm | 0:8fd0531ae0be | 420 | data &= ~( 1 << 0 ); |
epgmdm | 2:ca0a3c0bba70 | 421 | flushTx(); |
epgmdm | 2:ca0a3c0bba70 | 422 | flushRx(); |
nixonkj | 8:3e027705ce23 | 423 | writeReg(CONFIG, data); |
nixonkj | 8:3e027705ce23 | 424 | writeReg(RX_ADDR_P0, txAdd, addressWidth); // reset p0 |
nixonkj | 8:3e027705ce23 | 425 | writeReg(EN_RXADDR, 0x01); // enable pipe 0 for reading |
epgmdm | 0:8fd0531ae0be | 426 | // check |
nixonkj | 8:3e027705ce23 | 427 | readReg(CONFIG, &data); |
epgmdm | 20:e61edde5680d | 428 | |
epgmdm | 0:8fd0531ae0be | 429 | ce=1; |
epgmdm | 0:8fd0531ae0be | 430 | wait(0.003); |
epgmdm | 0:8fd0531ae0be | 431 | } |
epgmdm | 0:8fd0531ae0be | 432 | |
epgmdm | 0:8fd0531ae0be | 433 | /** |
epgmdm | 0:8fd0531ae0be | 434 | * Sets the number of bytes of the address width = 3,4,5 |
epgmdm | 0:8fd0531ae0be | 435 | */ |
epgmdm | 20:e61edde5680d | 436 | void NRF2401P::setAddressWidth( char width ) |
epgmdm | 0:8fd0531ae0be | 437 | { |
nixonkj | 6:77ead8abdd1c | 438 | char chk=0; |
epgmdm | 0:8fd0531ae0be | 439 | addressWidth = width; |
epgmdm | 0:8fd0531ae0be | 440 | if ( ( width > 5 ) || ( width < 3 ) ) |
epgmdm | 20:e61edde5680d | 441 | return ; |
epgmdm | 0:8fd0531ae0be | 442 | width -= 2; |
nixonkj | 8:3e027705ce23 | 443 | writeReg(SETUP_AW, width); |
nixonkj | 8:3e027705ce23 | 444 | readReg(SETUP_AW, &chk); |
epgmdm | 0:8fd0531ae0be | 445 | } |
nixonkj | 6:77ead8abdd1c | 446 | |
epgmdm | 0:8fd0531ae0be | 447 | /** |
nixonkj | 6:77ead8abdd1c | 448 | * Sets the address, uses address width set (either 3,4 or 5) |
epgmdm | 0:8fd0531ae0be | 449 | */ |
epgmdm | 20:e61edde5680d | 450 | void NRF2401P::setTxAddress( char *address ) |
epgmdm | 0:8fd0531ae0be | 451 | { |
epgmdm | 2:ca0a3c0bba70 | 452 | memcpy (txAdd,address, addressWidth); |
nixonkj | 8:3e027705ce23 | 453 | writeReg(RX_ADDR_P0, address, addressWidth); |
nixonkj | 8:3e027705ce23 | 454 | writeReg(TX_ADDR, address, addressWidth); |
epgmdm | 0:8fd0531ae0be | 455 | } |
epgmdm | 0:8fd0531ae0be | 456 | |
epgmdm | 0:8fd0531ae0be | 457 | /** |
epgmdm | 0:8fd0531ae0be | 458 | * Sets the address, uses addess width set (either 3,4 or 5) |
epgmdm | 0:8fd0531ae0be | 459 | */ |
epgmdm | 20:e61edde5680d | 460 | void NRF2401P::setTxAddress( long long address ) |
epgmdm | 0:8fd0531ae0be | 461 | { |
epgmdm | 0:8fd0531ae0be | 462 | char buff[ 5 ]; |
epgmdm | 17:b132fc1a27d2 | 463 | char width = addressWidth; |
epgmdm | 17:b132fc1a27d2 | 464 | |
epgmdm | 20:e61edde5680d | 465 | for (char w=0; w<width; w++) { |
epgmdm | 17:b132fc1a27d2 | 466 | char ww = width -w-1; // Reverse bytes |
epgmdm | 17:b132fc1a27d2 | 467 | buff[w] = ( address >> (8*ww )) &0xFF; |
epgmdm | 17:b132fc1a27d2 | 468 | } |
epgmdm | 20:e61edde5680d | 469 | setTxAddress( buff ); |
epgmdm | 0:8fd0531ae0be | 470 | } |
epgmdm | 0:8fd0531ae0be | 471 | |
epgmdm | 0:8fd0531ae0be | 472 | /** |
nixonkj | 9:c21b80aaf250 | 473 | * Sets the address, uses address width set (either 3,4 or 5) |
epgmdm | 2:ca0a3c0bba70 | 474 | * Enables pipe for receiving; |
epgmdm | 0:8fd0531ae0be | 475 | */ |
epgmdm | 20:e61edde5680d | 476 | void NRF2401P::setRxAddress( char *address, char pipe ) |
epgmdm | 0:8fd0531ae0be | 477 | { |
epgmdm | 2:ca0a3c0bba70 | 478 | if(debug) { |
epgmdm | 2:ca0a3c0bba70 | 479 | log ("Set Rx Address"); |
epgmdm | 2:ca0a3c0bba70 | 480 | } |
epgmdm | 20:e61edde5680d | 481 | if (pipe>5) return; |
epgmdm | 2:ca0a3c0bba70 | 482 | if (pipe ==0) { |
nixonkj | 8:3e027705ce23 | 483 | memcpy(pipe0Add,address, addressWidth); |
epgmdm | 2:ca0a3c0bba70 | 484 | } |
epgmdm | 2:ca0a3c0bba70 | 485 | |
epgmdm | 0:8fd0531ae0be | 486 | char reg = 0x0A + pipe; |
epgmdm | 0:8fd0531ae0be | 487 | switch ( pipe ) { |
epgmdm | 20:e61edde5680d | 488 | case ( 0 ) : |
epgmdm | 0:8fd0531ae0be | 489 | case ( 1 ) : { |
epgmdm | 20:e61edde5680d | 490 | writeReg(reg, address, addressWidth); //Write to RX_ADDR_P0 or _P1 |
epgmdm | 20:e61edde5680d | 491 | break; |
epgmdm | 20:e61edde5680d | 492 | } |
epgmdm | 20:e61edde5680d | 493 | case ( 2 ) : |
epgmdm | 20:e61edde5680d | 494 | case ( 3 ) : |
epgmdm | 20:e61edde5680d | 495 | case ( 4 ) : |
epgmdm | 20:e61edde5680d | 496 | case ( 5 ) : { |
epgmdm | 20:e61edde5680d | 497 | writeReg(reg, address, 1); //Write to RX_ADDR_P2 ... _P5 |
epgmdm | 20:e61edde5680d | 498 | break; |
epgmdm | 20:e61edde5680d | 499 | } |
epgmdm | 0:8fd0531ae0be | 500 | |
epgmdm | 0:8fd0531ae0be | 501 | } |
nixonkj | 8:3e027705ce23 | 502 | readReg(EN_RXADDR, ®); |
epgmdm | 2:ca0a3c0bba70 | 503 | reg |= (1<<pipe); |
nixonkj | 8:3e027705ce23 | 504 | writeReg(EN_RXADDR, reg); //Enable the pipe |
epgmdm | 0:8fd0531ae0be | 505 | } |
epgmdm | 0:8fd0531ae0be | 506 | |
epgmdm | 0:8fd0531ae0be | 507 | /** |
epgmdm | 0:8fd0531ae0be | 508 | * Sets the address of pipe (<=5), uses addess width set (either 3,4 or 5) |
epgmdm | 0:8fd0531ae0be | 509 | */ |
epgmdm | 20:e61edde5680d | 510 | void NRF2401P::setRxAddress( long long address, char pipe ) |
epgmdm | 0:8fd0531ae0be | 511 | { |
epgmdm | 0:8fd0531ae0be | 512 | char buff[ 5 ]; |
epgmdm | 17:b132fc1a27d2 | 513 | char width = addressWidth; |
epgmdm | 20:e61edde5680d | 514 | if (pipe>1) { |
epgmdm | 17:b132fc1a27d2 | 515 | width = 1; |
epgmdm | 17:b132fc1a27d2 | 516 | } |
epgmdm | 20:e61edde5680d | 517 | for (char w=0; w<width; w++) { |
epgmdm | 17:b132fc1a27d2 | 518 | char ww = width -w-1; // Reverse bytes |
epgmdm | 17:b132fc1a27d2 | 519 | buff[w] = ( address >> (8*ww ) )&0xFF; |
epgmdm | 17:b132fc1a27d2 | 520 | } |
epgmdm | 20:e61edde5680d | 521 | setRxAddress( buff, pipe ); |
epgmdm | 0:8fd0531ae0be | 522 | } |
nixonkj | 6:77ead8abdd1c | 523 | |
epgmdm | 1:ff53b1ac3bad | 524 | /** |
epgmdm | 1:ff53b1ac3bad | 525 | *checks the status flag |
epgmdm | 1:ff53b1ac3bad | 526 | */ |
epgmdm | 1:ff53b1ac3bad | 527 | char NRF2401P::checkStatus() |
epgmdm | 1:ff53b1ac3bad | 528 | { |
nixonkj | 8:3e027705ce23 | 529 | readReg(STATUS, &status); |
epgmdm | 1:ff53b1ac3bad | 530 | return status; |
epgmdm | 1:ff53b1ac3bad | 531 | } |
nixonkj | 6:77ead8abdd1c | 532 | |
epgmdm | 1:ff53b1ac3bad | 533 | /** |
epgmdm | 1:ff53b1ac3bad | 534 | * checks if Ack data available. |
epgmdm | 1:ff53b1ac3bad | 535 | */ |
epgmdm | 1:ff53b1ac3bad | 536 | bool NRF2401P::isAckData() |
epgmdm | 1:ff53b1ac3bad | 537 | { |
epgmdm | 1:ff53b1ac3bad | 538 | char fifo; |
nixonkj | 8:3e027705ce23 | 539 | readReg(FIFO_STATUS, &fifo); |
epgmdm | 1:ff53b1ac3bad | 540 | bool isData = !(fifo&0x01); |
epgmdm | 1:ff53b1ac3bad | 541 | return isData; |
epgmdm | 1:ff53b1ac3bad | 542 | } |
epgmdm | 0:8fd0531ae0be | 543 | |
epgmdm | 1:ff53b1ac3bad | 544 | /** |
epgmdm | 1:ff53b1ac3bad | 545 | * checks if RX data available. |
epgmdm | 1:ff53b1ac3bad | 546 | */ |
epgmdm | 0:8fd0531ae0be | 547 | bool NRF2401P::isRxData() |
epgmdm | 0:8fd0531ae0be | 548 | { |
epgmdm | 1:ff53b1ac3bad | 549 | checkStatus(); |
epgmdm | 0:8fd0531ae0be | 550 | bool isData = (status>>6)&0x01; |
epgmdm | 0:8fd0531ae0be | 551 | return isData; |
epgmdm | 0:8fd0531ae0be | 552 | } |
nixonkj | 6:77ead8abdd1c | 553 | |
epgmdm | 0:8fd0531ae0be | 554 | char NRF2401P::getRxWidth() |
epgmdm | 0:8fd0531ae0be | 555 | { |
epgmdm | 0:8fd0531ae0be | 556 | char width; |
epgmdm | 0:8fd0531ae0be | 557 | if (dynamic) { |
epgmdm | 0:8fd0531ae0be | 558 | csn = 0; |
nixonkj | 14:976a876819ae | 559 | status = spi->write( R_RX_PL_WID ); |
epgmdm | 0:8fd0531ae0be | 560 | width = spi->write(0x00); |
epgmdm | 0:8fd0531ae0be | 561 | csn = 1; |
epgmdm | 0:8fd0531ae0be | 562 | |
nixonkj | 14:976a876819ae | 563 | if (width>32) { // as per product spec |
epgmdm | 0:8fd0531ae0be | 564 | flushRx(); |
nixonkj | 14:976a876819ae | 565 | wait(0.002f); // little delay (KJN) |
epgmdm | 0:8fd0531ae0be | 566 | width=0; |
epgmdm | 0:8fd0531ae0be | 567 | } |
epgmdm | 0:8fd0531ae0be | 568 | } else { |
nixonkj | 8:3e027705ce23 | 569 | readReg(RX_PW_P1, &width); // width of p1 |
epgmdm | 0:8fd0531ae0be | 570 | } |
epgmdm | 16:a9b83d2b6915 | 571 | |
epgmdm | 0:8fd0531ae0be | 572 | return width; |
epgmdm | 0:8fd0531ae0be | 573 | } |
nixonkj | 6:77ead8abdd1c | 574 | |
epgmdm | 0:8fd0531ae0be | 575 | /** |
epgmdm | 0:8fd0531ae0be | 576 | * return message in buffer, mem for buffer must have been allocated. |
epgmdm | 0:8fd0531ae0be | 577 | * Return value is number of bytes of buffer |
epgmdm | 0:8fd0531ae0be | 578 | */ |
epgmdm | 0:8fd0531ae0be | 579 | char NRF2401P::getRxData(char * buffer) |
epgmdm | 0:8fd0531ae0be | 580 | { |
epgmdm | 0:8fd0531ae0be | 581 | char address = 0x61; |
epgmdm | 0:8fd0531ae0be | 582 | char width; |
epgmdm | 0:8fd0531ae0be | 583 | width = getRxWidth(); |
epgmdm | 0:8fd0531ae0be | 584 | bool isData = (status>>6)&0x01; |
epgmdm | 0:8fd0531ae0be | 585 | if (isData) { |
epgmdm | 0:8fd0531ae0be | 586 | csn = 0; |
epgmdm | 0:8fd0531ae0be | 587 | int i; |
epgmdm | 0:8fd0531ae0be | 588 | // set up for reading |
epgmdm | 0:8fd0531ae0be | 589 | status = spi->write( address ); |
epgmdm | 0:8fd0531ae0be | 590 | for ( i = 0; i <= width; i++ ) { |
epgmdm | 0:8fd0531ae0be | 591 | buffer[i]=spi->write(0x00 ); |
epgmdm | 0:8fd0531ae0be | 592 | } |
epgmdm | 0:8fd0531ae0be | 593 | csn = 1; |
nixonkj | 6:77ead8abdd1c | 594 | if (debug) { |
nixonkj | 6:77ead8abdd1c | 595 | sprintf(logMsg, "Receive data %d bytes", width ); |
nixonkj | 6:77ead8abdd1c | 596 | log(logMsg); |
nixonkj | 6:77ead8abdd1c | 597 | } |
epgmdm | 0:8fd0531ae0be | 598 | clearStatus(); |
epgmdm | 0:8fd0531ae0be | 599 | return width; |
epgmdm | 0:8fd0531ae0be | 600 | } else { |
nixonkj | 6:77ead8abdd1c | 601 | if (debug) { |
nixonkj | 6:77ead8abdd1c | 602 | sprintf(logMsg, "Receive NO data %d bytes", width ); |
nixonkj | 6:77ead8abdd1c | 603 | log(logMsg); |
nixonkj | 6:77ead8abdd1c | 604 | } |
epgmdm | 0:8fd0531ae0be | 605 | clearStatus(); |
epgmdm | 0:8fd0531ae0be | 606 | return 0; |
epgmdm | 0:8fd0531ae0be | 607 | } |
epgmdm | 0:8fd0531ae0be | 608 | } |
epgmdm | 0:8fd0531ae0be | 609 | |
epgmdm | 0:8fd0531ae0be | 610 | /** |
epgmdm | 0:8fd0531ae0be | 611 | * Sets all the receive pipes to dynamic payload length |
epgmdm | 0:8fd0531ae0be | 612 | */ |
epgmdm | 2:ca0a3c0bba70 | 613 | void NRF2401P::setDynamicPayload() |
epgmdm | 0:8fd0531ae0be | 614 | { |
epgmdm | 0:8fd0531ae0be | 615 | dynamic = true; |
nixonkj | 8:3e027705ce23 | 616 | writeReg(FEATURE, 0x07); // Enable Dyn payload, Payload with Ack and w_tx_noack command |
nixonkj | 8:3e027705ce23 | 617 | writeReg(EN_AA, 0x3f); // EN_AA regi for P1 and P0 |
nixonkj | 9:c21b80aaf250 | 618 | writeReg(DYNPD, 0x3F); // KJN - should be 0x3F for all pipes |
epgmdm | 0:8fd0531ae0be | 619 | } |
epgmdm | 2:ca0a3c0bba70 | 620 | |
epgmdm | 0:8fd0531ae0be | 621 | /** |
epgmdm | 17:b132fc1a27d2 | 622 | * Sets PWR_UP = 0; |
epgmdm | 17:b132fc1a27d2 | 623 | * return 0 on success |
epgmdm | 17:b132fc1a27d2 | 624 | */ |
epgmdm | 20:e61edde5680d | 625 | void NRF2401P::setPwrDown() |
epgmdm | 17:b132fc1a27d2 | 626 | { |
epgmdm | 17:b132fc1a27d2 | 627 | char data; |
epgmdm | 17:b132fc1a27d2 | 628 | char bit; |
epgmdm | 17:b132fc1a27d2 | 629 | ce=1; |
epgmdm | 17:b132fc1a27d2 | 630 | readReg(CONFIG, &data); |
epgmdm | 17:b132fc1a27d2 | 631 | if (!((data>>1) &0x01)) { |
epgmdm | 20:e61edde5680d | 632 | return; // Already powered up |
epgmdm | 17:b132fc1a27d2 | 633 | }; |
epgmdm | 17:b132fc1a27d2 | 634 | data &= (0xFD); // clear bit 2 |
epgmdm | 17:b132fc1a27d2 | 635 | writeReg(CONFIG, data); |
epgmdm | 17:b132fc1a27d2 | 636 | // check |
epgmdm | 17:b132fc1a27d2 | 637 | readReg(CONFIG, &data); |
epgmdm | 17:b132fc1a27d2 | 638 | bit = ( data >> 1 ) & 1; |
epgmdm | 17:b132fc1a27d2 | 639 | |
epgmdm | 17:b132fc1a27d2 | 640 | wait(0.005); // wait 5ms |
epgmdm | 17:b132fc1a27d2 | 641 | if(debug) { |
epgmdm | 17:b132fc1a27d2 | 642 | sprintf(logMsg, "Set PWR_UP to %x", bit); |
epgmdm | 17:b132fc1a27d2 | 643 | log(logMsg); |
epgmdm | 17:b132fc1a27d2 | 644 | } |
epgmdm | 17:b132fc1a27d2 | 645 | } |
epgmdm | 17:b132fc1a27d2 | 646 | /** |
epgmdm | 0:8fd0531ae0be | 647 | * Sets PWR_UP = 1; |
nixonkj | 6:77ead8abdd1c | 648 | * return 0 on success |
epgmdm | 0:8fd0531ae0be | 649 | */ |
epgmdm | 20:e61edde5680d | 650 | void NRF2401P::setPwrUp() |
epgmdm | 0:8fd0531ae0be | 651 | { |
epgmdm | 0:8fd0531ae0be | 652 | char data; |
epgmdm | 0:8fd0531ae0be | 653 | char bit; |
epgmdm | 0:8fd0531ae0be | 654 | ce=1; |
nixonkj | 8:3e027705ce23 | 655 | readReg(CONFIG, &data); |
epgmdm | 2:ca0a3c0bba70 | 656 | if ((data>>1) &0x01) { |
epgmdm | 20:e61edde5680d | 657 | return; // Already powered up |
epgmdm | 2:ca0a3c0bba70 | 658 | }; |
nixonkj | 8:3e027705ce23 | 659 | data |= (0x02); |
nixonkj | 8:3e027705ce23 | 660 | writeReg(CONFIG, data); |
epgmdm | 0:8fd0531ae0be | 661 | // check |
nixonkj | 8:3e027705ce23 | 662 | readReg(CONFIG, &data); |
epgmdm | 0:8fd0531ae0be | 663 | bit = ( data >> 1 ) & 1; |
epgmdm | 2:ca0a3c0bba70 | 664 | |
epgmdm | 0:8fd0531ae0be | 665 | wait(0.005); // wait 5ms |
epgmdm | 2:ca0a3c0bba70 | 666 | if(debug) { |
epgmdm | 2:ca0a3c0bba70 | 667 | sprintf(logMsg, "Set PWR_UP to %x", bit); |
epgmdm | 2:ca0a3c0bba70 | 668 | log(logMsg); |
epgmdm | 2:ca0a3c0bba70 | 669 | } |
nixonkj | 6:77ead8abdd1c | 670 | } |
epgmdm | 0:8fd0531ae0be | 671 | /** |
epgmdm | 0:8fd0531ae0be | 672 | * Sets PRIM_RX = 0; |
epgmdm | 0:8fd0531ae0be | 673 | */ |
epgmdm | 20:e61edde5680d | 674 | void NRF2401P::setRxMode() |
epgmdm | 0:8fd0531ae0be | 675 | { |
epgmdm | 0:8fd0531ae0be | 676 | char data; |
epgmdm | 0:8fd0531ae0be | 677 | char bit; |
epgmdm | 0:8fd0531ae0be | 678 | ce=1; |
nixonkj | 8:3e027705ce23 | 679 | readReg(CONFIG, &data); |
nixonkj | 8:3e027705ce23 | 680 | data |= (0x01); |
epgmdm | 2:ca0a3c0bba70 | 681 | |
nixonkj | 8:3e027705ce23 | 682 | writeReg(CONFIG, data); |
epgmdm | 3:afe8d307b5c3 | 683 | if (pipe0Add[0]|pipe0Add[1]|pipe0Add[2]|pipe0Add[3]|pipe0Add[4] >0) { |
epgmdm | 3:afe8d307b5c3 | 684 | setRxAddress(pipe0Add,0); |
epgmdm | 2:ca0a3c0bba70 | 685 | } |
epgmdm | 0:8fd0531ae0be | 686 | // check |
nixonkj | 8:3e027705ce23 | 687 | readReg(CONFIG, &data); |
epgmdm | 0:8fd0531ae0be | 688 | bit = ( data >> 0 ) & 1; |
epgmdm | 2:ca0a3c0bba70 | 689 | |
epgmdm | 2:ca0a3c0bba70 | 690 | wait (0.001); |
epgmdm | 0:8fd0531ae0be | 691 | flushRx(); |
epgmdm | 2:ca0a3c0bba70 | 692 | flushTx(); |
epgmdm | 2:ca0a3c0bba70 | 693 | if (debug) { |
epgmdm | 2:ca0a3c0bba70 | 694 | sprintf(logMsg, " set PRIM_RX to %x", bit); |
epgmdm | 2:ca0a3c0bba70 | 695 | log(logMsg); |
epgmdm | 2:ca0a3c0bba70 | 696 | } |
epgmdm | 20:e61edde5680d | 697 | |
epgmdm | 0:8fd0531ae0be | 698 | } |
nixonkj | 6:77ead8abdd1c | 699 | |
epgmdm | 0:8fd0531ae0be | 700 | /** |
epgmdm | 0:8fd0531ae0be | 701 | * Prints status string |
epgmdm | 0:8fd0531ae0be | 702 | */ |
epgmdm | 0:8fd0531ae0be | 703 | char * NRF2401P::statusString() |
epgmdm | 0:8fd0531ae0be | 704 | { |
epgmdm | 0:8fd0531ae0be | 705 | char *msg; |
epgmdm | 0:8fd0531ae0be | 706 | msg = statusS; |
epgmdm | 0:8fd0531ae0be | 707 | if (((status>>1) & 0x07)==0x07) { |
epgmdm | 0:8fd0531ae0be | 708 | sprintf(msg,"RX empty"); |
epgmdm | 0:8fd0531ae0be | 709 | } else { |
epgmdm | 0:8fd0531ae0be | 710 | sprintf(msg,"pipe %02x",(status>>1) & 0x07); |
epgmdm | 0:8fd0531ae0be | 711 | } |
epgmdm | 0:8fd0531ae0be | 712 | |
epgmdm | 0:8fd0531ae0be | 713 | if ((status>>6)&0x01) strcat(msg," RX_DR,"); |
epgmdm | 0:8fd0531ae0be | 714 | if ((status>>5)&0x01) strcat(msg," TX_DS,"); |
epgmdm | 0:8fd0531ae0be | 715 | if ((status>>4)&0x01) strcat(msg," MAX_RT,"); |
epgmdm | 0:8fd0531ae0be | 716 | if ((status>>0)&0x01) strcat(msg," TX_FLL,"); |
epgmdm | 0:8fd0531ae0be | 717 | |
epgmdm | 0:8fd0531ae0be | 718 | return msg; |
nixonkj | 9:c21b80aaf250 | 719 | } |
nixonkj | 9:c21b80aaf250 | 720 | |
nixonkj | 11:07f76589f00a | 721 | void NRF2401P::printReg(char* name, char address, bool newline) |
nixonkj | 9:c21b80aaf250 | 722 | { |
nixonkj | 9:c21b80aaf250 | 723 | char data; |
nixonkj | 11:07f76589f00a | 724 | readReg(address, &data); |
nixonkj | 11:07f76589f00a | 725 | printf("%s = 0x%02x", name, data); |
nixonkj | 11:07f76589f00a | 726 | if (newline) { |
nixonkj | 11:07f76589f00a | 727 | printf("\r\n"); |
nixonkj | 11:07f76589f00a | 728 | } |
epgmdm | 16:a9b83d2b6915 | 729 | } |
epgmdm | 16:a9b83d2b6915 | 730 | |
nixonkj | 11:07f76589f00a | 731 | void NRF2401P::printReg(char* name, char address, char width, bool newline) |
nixonkj | 11:07f76589f00a | 732 | { |
nixonkj | 11:07f76589f00a | 733 | char data[width]; |
nixonkj | 11:07f76589f00a | 734 | readReg(address, data, width); |
nixonkj | 11:07f76589f00a | 735 | printf("%s = 0x", name); |
nixonkj | 11:07f76589f00a | 736 | for (int i=width-1; i>=0; i--) { |
nixonkj | 11:07f76589f00a | 737 | printf("%02x", data[i]); |
nixonkj | 11:07f76589f00a | 738 | } |
nixonkj | 11:07f76589f00a | 739 | if (newline) { |
nixonkj | 11:07f76589f00a | 740 | printf("\r\n"); |
nixonkj | 11:07f76589f00a | 741 | } |
nixonkj | 11:07f76589f00a | 742 | } |
epgmdm | 17:b132fc1a27d2 | 743 | /* |
epgmdm | 17:b132fc1a27d2 | 744 | * Prints in reverse order for addresses |
epgmdm | 17:b132fc1a27d2 | 745 | */ |
epgmdm | 17:b132fc1a27d2 | 746 | void NRF2401P::printRegR(char* name, char address, char width, bool newline) |
epgmdm | 17:b132fc1a27d2 | 747 | { |
epgmdm | 17:b132fc1a27d2 | 748 | char data[width]; |
epgmdm | 17:b132fc1a27d2 | 749 | readReg(address, data, width); |
epgmdm | 17:b132fc1a27d2 | 750 | printf("%s = 0x", name); |
epgmdm | 17:b132fc1a27d2 | 751 | for (int i=0; i<width; i++) { |
epgmdm | 17:b132fc1a27d2 | 752 | printf("%02x", data[i]); |
epgmdm | 17:b132fc1a27d2 | 753 | } |
epgmdm | 17:b132fc1a27d2 | 754 | if (newline) { |
epgmdm | 17:b132fc1a27d2 | 755 | printf("\r\n"); |
epgmdm | 17:b132fc1a27d2 | 756 | } |
epgmdm | 17:b132fc1a27d2 | 757 | } |
epgmdm | 20:e61edde5680d | 758 | void NRF2401P::printDetails() |
epgmdm | 20:e61edde5680d | 759 | { |
nixonkj | 14:976a876819ae | 760 | status = checkStatus(); |
epgmdm | 17:b132fc1a27d2 | 761 | char w=1; |
nixonkj | 11:07f76589f00a | 762 | printf("STATUS = 0x%02x RX_DR=%x TX_DS=%x MAX_RT=%x RX_P_NO=%x TX_FULL=%x\r\n", status, |
nixonkj | 9:c21b80aaf250 | 763 | (status & (1<<MASK_RX_DR))?1:0, |
nixonkj | 9:c21b80aaf250 | 764 | (status & (1<<MASK_TX_DS))?1:0, |
nixonkj | 9:c21b80aaf250 | 765 | (status & (1<<MASK_MAX_RT))?1:0, |
nixonkj | 9:c21b80aaf250 | 766 | (status >> RX_P_NO) & 7, |
nixonkj | 9:c21b80aaf250 | 767 | (status & (1<<TX_FULL))?1:0 ); |
nixonkj | 9:c21b80aaf250 | 768 | |
epgmdm | 17:b132fc1a27d2 | 769 | printRegR("RX_ADDR_P0", RX_ADDR_P0, addressWidth); |
epgmdm | 17:b132fc1a27d2 | 770 | printRegR("RX_ADDR_P1", RX_ADDR_P1, addressWidth); |
epgmdm | 17:b132fc1a27d2 | 771 | printRegR("RX_ADDR_P2", RX_ADDR_P2, w); |
epgmdm | 17:b132fc1a27d2 | 772 | printRegR("RX_ADDR_P3", RX_ADDR_P3, w); |
epgmdm | 17:b132fc1a27d2 | 773 | printRegR("RX_ADDR_P4", RX_ADDR_P4, w); |
epgmdm | 17:b132fc1a27d2 | 774 | printRegR("RX_ADDR_P5", RX_ADDR_P5, w); |
epgmdm | 17:b132fc1a27d2 | 775 | printRegR("TX_ADDR", TX_ADDR, addressWidth); |
nixonkj | 10:8a217441c38e | 776 | |
nixonkj | 11:07f76589f00a | 777 | printReg("RX_PW_P0", RX_PW_P0, false); // false for no newline, save some space |
nixonkj | 11:07f76589f00a | 778 | printReg(" RX_PW_P1", RX_PW_P1, false); |
nixonkj | 11:07f76589f00a | 779 | printReg(" RX_PW_P2", RX_PW_P2); |
nixonkj | 11:07f76589f00a | 780 | printReg("RX_PW_P3", RX_PW_P3, false); |
nixonkj | 11:07f76589f00a | 781 | printReg(" RX_PW_P4", RX_PW_P4, false); |
nixonkj | 11:07f76589f00a | 782 | printReg(" RX_PW_P5", RX_PW_P5); |
nixonkj | 11:07f76589f00a | 783 | |
epgmdm | 17:b132fc1a27d2 | 784 | |
epgmdm | 17:b132fc1a27d2 | 785 | printReg("SETUP_RETR", SETUP_RETR); |
nixonkj | 11:07f76589f00a | 786 | printReg("EN_AA", EN_AA); |
nixonkj | 11:07f76589f00a | 787 | printReg("EN_RXADDR", EN_RXADDR); |
nixonkj | 11:07f76589f00a | 788 | printReg("RF_CH", RF_CH); |
nixonkj | 11:07f76589f00a | 789 | printReg("RF_SETUP", RF_SETUP); |
nixonkj | 12:ea1345de6478 | 790 | printReg("CONFIG", CONFIG); |
nixonkj | 11:07f76589f00a | 791 | printReg("DYNPD", DYNPD); |
nixonkj | 11:07f76589f00a | 792 | printReg("FEATURE", FEATURE); |
epgmdm | 0:8fd0531ae0be | 793 | } |