Maniacbug's nRF24L01 arduino library ported to mbed. Functional with minor issues.

Fork of nRF24L01P_Maniacbug by Christiaan M

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers nRF24L01P_Maniacbug.h Source File

nRF24L01P_Maniacbug.h

00001 /*
00002     Copyright (c) 2007 Stefan Engelke <mbox@stefanengelke.de>
00003 
00004     Permission is hereby granted, free of charge, to any person 
00005     obtaining a copy of this software and associated documentation 
00006     files (the "Software"), to deal in the Software without 
00007     restriction, including without limitation the rights to use, copy, 
00008     modify, merge, publish, distribute, sublicense, and/or sell copies 
00009     of the Software, and to permit persons to whom the Software is 
00010     furnished to do so, subject to the following conditions:
00011 
00012     The above copyright notice and this permission notice shall be 
00013     included in all copies or substantial portions of the Software.
00014 
00015     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
00016     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
00017     MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
00018     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 
00019     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 
00020     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
00021     OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
00022     DEALINGS IN THE SOFTWARE.
00023 */
00024 
00025 /*
00026  Copyright (C) 2011 J. Coliz <maniacbug@ymail.com>
00027 
00028  This program is free software; you can redistribute it and/or
00029  modify it under the terms of the GNU General Public License
00030  version 2 as published by the Free Software Foundation.
00031  */
00032 
00033 /**
00034  * @file RF24.h
00035  *
00036  * Class declaration for RF24 and helper enums
00037  */
00038 
00039 #ifndef __RF24_H__
00040 #define __RF24_H__
00041 
00042 #include <mbed.h>
00043 
00044 /**
00045  * Power Amplifier level.
00046  *
00047  * For use with setPALevel()
00048  */
00049 typedef enum { RF24_PA_MIN = 0,RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX, RF24_PA_ERROR } rf24_pa_dbm_e ;
00050 
00051 /**
00052  * Data rate.  How fast data moves through the air.
00053  *
00054  * For use with setDataRate()
00055  */
00056 typedef enum { RF24_1MBPS = 0, RF24_2MBPS, RF24_250KBPS } rf24_datarate_e;
00057 
00058 /**
00059  * CRC Length.  How big (if any) of a CRC is included.
00060  *
00061  * For use with setCRCLength()
00062  */
00063 typedef enum { RF24_CRC_DISABLED = 0, RF24_CRC_8, RF24_CRC_16 } rf24_crclength_e;
00064 
00065 /**
00066  * Driver for nRF24L01(+) 2.4GHz Wireless Transceiver
00067  */
00068 
00069 class RF24
00070 {
00071 private:
00072   DigitalOut ce_pin; /**< "Chip Enable" pin, activates the RX or TX role */
00073   DigitalOut csn_pin; /**< SPI Chip select */
00074   bool wide_band; /* 2Mbs data rate in use? */
00075   bool p_variant; /* False for RF24L01 and true for RF24L01P */
00076   uint8_t payload_size; /**< Fixed size of payloads */
00077   bool ack_payload_available; /**< Whether there is an ack payload waiting */
00078   bool dynamic_payloads_enabled; /**< Whether dynamic payloads are enabled. */ 
00079   uint8_t ack_payload_length; /**< Dynamic size of pending ack payload. */
00080   uint64_t pipe0_reading_address; /**< Last address set on pipe 0 for reading. */
00081   SPI spi;
00082   Timer mainTimer;
00083 
00084 protected:
00085   /**
00086    * @name Low-level internal interface.
00087    *
00088    *  Protected methods that address the chip directly.  Regular users cannot
00089    *  ever call these.  They are documented for completeness and for developers who
00090    *  may want to extend this class.
00091    */
00092   /**@{*/
00093 
00094   /**
00095    * Set chip select pin
00096    *
00097    * Running SPI bus at PI_CLOCK_DIV2 so we don't waste time transferring data
00098    * and best of all, we make use of the radio's FIFO buffers. A lower speed
00099    * means we're less likely to effectively leverage our FIFOs and pay a higher
00100    * AVR runtime cost as toll.
00101    *
00102    * @param mode HIGH to take this unit off the SPI bus, LOW to put it on
00103    */
00104   void csn(int mode);
00105 
00106   /**
00107    * Set chip enable
00108    *
00109    * @param level HIGH to actively begin transmission or LOW to put in standby.  Please see data sheet
00110    * for a much more detailed description of this pin.
00111    */
00112   void ce(int level);  
00113 
00114 
00115   /**
00116    * Read a chunk of data in from a register
00117    *
00118    * @param reg Which register. Use constants from nRF24L01.h
00119    * @param buf Where to put the data
00120    * @param len How many bytes of data to transfer
00121    * @return Current value of status register
00122    */
00123   uint8_t read_register(uint8_t reg, uint8_t* buf, uint8_t len);
00124 
00125   /**
00126    * Read single byte from a register
00127    *
00128    * @param reg Which register. Use constants from nRF24L01.h
00129    * @return Current value of register @p reg
00130    */
00131   uint8_t read_register(uint8_t reg);
00132 
00133   /**
00134    * Write a chunk of data to a register
00135    *
00136    * @param reg Which register. Use constants from nRF24L01.h
00137    * @param buf Where to get the data
00138    * @param len How many bytes of data to transfer
00139    * @return Current value of status register
00140    */
00141   uint8_t write_register(uint8_t reg, const uint8_t* buf, uint8_t len);
00142 
00143   /**
00144    * Write a single byte to a register
00145    *
00146    * @param reg Which register. Use constants from nRF24L01.h
00147    * @param value The new value to write
00148    * @return Current value of status register
00149    */
00150   uint8_t write_register(uint8_t reg, uint8_t value);
00151 
00152   /**
00153    * Write the transmit payload
00154    *
00155    * The size of data written is the fixed payload size, see getPayloadSize()
00156    *
00157    * @param buf Where to get the data
00158    * @param len Number of bytes to be sent
00159    * @return Current value of status register
00160    */
00161   uint8_t write_payload(const void* buf, uint8_t len);
00162 
00163   /**
00164    * Read the receive payload
00165    *
00166    * The size of data read is the fixed payload size, see getPayloadSize()
00167    *
00168    * @param buf Where to put the data
00169    * @param len Maximum number of bytes to read
00170    * @return Current value of status register
00171    */
00172   uint8_t read_payload(void* buf, uint8_t len);
00173 
00174 
00175   /**
00176    * Decode and print the given status to stdout
00177    *
00178    * @param status Status value to print
00179    *
00180    * @warning Does nothing if stdout is not defined.  See fdevopen in stdio.h
00181    */
00182   void print_status(uint8_t status);
00183 
00184   /**
00185    * Decode and print the given 'observe_tx' value to stdout
00186    *
00187    * @param value The observe_tx value to print
00188    *
00189    * @warning Does nothing if stdout is not defined.  See fdevopen in stdio.h
00190    */
00191   void print_observe_tx(uint8_t value);
00192 
00193   /**
00194    * Print the name and value of an 8-bit register to stdout
00195    *
00196    * Optionally it can print some quantity of successive
00197    * registers on the same line.  This is useful for printing a group
00198    * of related registers on one line.
00199    *
00200    * @param name Name of the register
00201    * @param reg Which register. Use constants from nRF24L01.h
00202    * @param qty How many successive registers to print
00203    */
00204   void print_byte_register(const char* name, uint8_t reg, uint8_t qty = 1);
00205 
00206   /**
00207    * Print the name and value of a 40-bit address register to stdout
00208    *
00209    * Optionally it can print some quantity of successive
00210    * registers on the same line.  This is useful for printing a group
00211    * of related registers on one line.
00212    *
00213    * @param name Name of the register
00214    * @param reg Which register. Use constants from nRF24L01.h
00215    * @param qty How many successive registers to print
00216    */
00217   void print_address_register(const char* name, uint8_t reg, uint8_t qty = 1);
00218 
00219   /**
00220    * Turn on or off the special features of the chip
00221    *
00222    * The chip has certain 'features' which are only available when the 'features'
00223    * are enabled.  See the datasheet for details.
00224    */
00225   void toggle_features(void);
00226   /**@}*/
00227 
00228 public:
00229   /**
00230    * @name Primary public interface
00231    *
00232    *  These are the main methods you need to operate the chip
00233    */
00234   /**@{*/
00235 
00236   /**
00237    * Constructor
00238    *
00239    * Creates a new instance of this driver.  Before using, you create an instance
00240    * and send in the unique pins that this chip is connected to.
00241    *
00242    * @param _cepin The pin attached to Chip Enable on the RF module
00243    * @param _cspin The pin attached to Chip Select
00244    */
00245   RF24(PinName mosi, PinName miso, PinName sck, PinName _csnpin, PinName _cepin);
00246 
00247   /**
00248    * Begin operation of the chip
00249    *
00250    * Call this in setup(), before calling any other methods.
00251    */
00252   void begin(void);
00253   
00254     /**
00255    * Retrieve the current status of the chip
00256    *
00257    * @return Current value of status register
00258    */
00259   uint8_t get_status(void);
00260     
00261   /**
00262    * Empty the receive buffer
00263    *
00264    * @return Current value of status register
00265    */
00266   uint8_t flush_rx(void);
00267 
00268   /**
00269    * Empty the transmit buffer
00270    *
00271    * @return Current value of status register
00272    */
00273   uint8_t flush_tx(void);
00274 
00275   /**
00276    * Start listening on the pipes opened for reading.
00277    *
00278    * Be sure to call openReadingPipe() first.  Do not call write() while
00279    * in this mode, without first calling stopListening().  Call
00280    * isAvailable() to check for incoming traffic, and read() to get it.
00281    */
00282   void startListening(void);
00283 
00284   /**
00285    * Stop listening for incoming messages
00286    *
00287    * Do this before calling write().
00288    */
00289   void stopListening(void);
00290 
00291   /**
00292    * Write to the open writing pipe
00293    *
00294    * Be sure to call openWritingPipe() first to set the destination
00295    * of where to write to.
00296    *
00297    * This blocks until the message is successfully acknowledged by
00298    * the receiver or the timeout/retransmit maxima are reached.  In
00299    * the current configuration, the max delay here is 60ms.
00300    *
00301    * The maximum size of data written is the fixed payload size, see
00302    * getPayloadSize().  However, you can write less, and the remainder
00303    * will just be filled with zeroes.
00304    *
00305    * @param buf Pointer to the data to be sent
00306    * @param len Number of bytes to be sent
00307    * @return True if the payload was delivered successfully false if not
00308    */
00309   bool write( const void* buf, uint8_t len );
00310 
00311   /**
00312    * Test whether there are bytes available to be read
00313    *
00314    * @return True if there is a payload available, false if none is
00315    */
00316   bool available(void);
00317 
00318   /**
00319    * Read the payload
00320    *
00321    * Return the last payload received
00322    *
00323    * The size of data read is the fixed payload size, see getPayloadSize()
00324    *
00325    * @note I specifically chose 'void*' as a data type to make it easier
00326    * for beginners to use.  No casting needed.
00327    *
00328    * @param buf Pointer to a buffer where the data should be written
00329    * @param len Maximum number of bytes to read into the buffer
00330    * @return True if the payload was delivered successfully false if not
00331    */
00332   bool read( void* buf, uint8_t len );
00333 
00334   /**
00335    * Open a pipe for writing
00336    *
00337    * Only one pipe can be open at once, but you can change the pipe
00338    * you'll listen to.  Do not call this while actively listening.
00339    * Remember to stopListening() first.
00340    *
00341    * Addresses are 40-bit hex values, e.g.:
00342    *
00343    * @code
00344    *   openWritingPipe(0xF0F0F0F0F0);
00345    * @endcode
00346    *
00347    * @param address The 40-bit address of the pipe to open.  This can be
00348    * any value whatsoever, as long as you are the only one writing to it
00349    * and only one other radio is listening to it.  Coordinate these pipe
00350    * addresses amongst nodes on the network.
00351    */
00352   void openWritingPipe(uint64_t address);
00353 
00354   /**
00355    * Open a pipe for reading
00356    *
00357    * Up to 6 pipes can be open for reading at once.  Open all the
00358    * reading pipes, and then call startListening().
00359    *
00360    * @see openWritingPipe
00361    *
00362    * @warning Pipes 1-5 should share the first 32 bits.
00363    * Only the least significant byte should be unique, e.g.
00364    * @code
00365    *   openReadingPipe(1,0xF0F0F0F0AA);
00366    *   openReadingPipe(2,0xF0F0F0F066);
00367    * @endcode
00368    *
00369    * @warning Pipe 0 is also used by the writing pipe.  So if you open
00370    * pipe 0 for reading, and then startListening(), it will overwrite the
00371    * writing pipe.  Ergo, do an openWritingPipe() again before write().
00372    *
00373    * @todo Enforce the restriction that pipes 1-5 must share the top 32 bits
00374    *
00375    * @param number Which pipe# to open, 0-5.
00376    * @param address The 40-bit address of the pipe to open.
00377    */
00378   void openReadingPipe(uint8_t number, uint64_t address);
00379 
00380   /**@}*/
00381   /**
00382    * @name Optional Configurators 
00383    *
00384    *  Methods you can use to get or set the configuration of the chip.
00385    *  None are required.  Calling begin() sets up a reasonable set of
00386    *  defaults.
00387    */
00388   /**@{*/
00389   /**
00390    * Set the number and delay of retries upon failed submit
00391    *
00392    * @param delay How long to wait between each retry, in multiples of 250us,
00393    * max is 15.  0 means 250us, 15 means 4000us.
00394    * @param count How many retries before giving up, max 15
00395    */
00396   void setRetries(uint8_t delay, uint8_t count);
00397 
00398   /**
00399    * Set RF communication channel
00400    *
00401    * @param channel Which RF channel to communicate on, 0-127
00402    */
00403   void setChannel(uint8_t channel);
00404 
00405   /**
00406    * Set Static Payload Size
00407    *
00408    * This implementation uses a pre-stablished fixed payload size for all
00409    * transmissions.  If this method is never called, the driver will always
00410    * transmit the maximum payload size (32 bytes), no matter how much
00411    * was sent to write().
00412    *
00413    * @todo Implement variable-sized payloads feature
00414    *
00415    * @param size The number of bytes in the payload
00416    */
00417   void setPayloadSize(uint8_t size);
00418 
00419   /**
00420    * Get Static Payload Size
00421    *
00422    * @see setPayloadSize()
00423    *
00424    * @return The number of bytes in the payload
00425    */
00426   uint8_t getPayloadSize(void);
00427 
00428   /**
00429    * Get Dynamic Payload Size
00430    *
00431    * For dynamic payloads, this pulls the size of the payload off
00432    * the chip
00433    *
00434    * @return Payload length of last-received dynamic payload
00435    */
00436   uint8_t getDynamicPayloadSize(void);
00437   
00438   /**
00439    * Enable custom payloads on the acknowledge packets
00440    *
00441    * Ack payloads are a handy way to return data back to senders without
00442    * manually changing the radio modes on both units.
00443    *
00444    * @see examples/pingpair_pl/pingpair_pl.pde
00445    */
00446   void enableAckPayload(void);
00447 
00448   /**
00449    * Enable dynamically-sized payloads
00450    *
00451    * This way you don't always have to send large packets just to send them
00452    * once in a while.  This enables dynamic payloads on ALL pipes.
00453    *
00454    * @see examples/pingpair_pl/pingpair_dyn.pde
00455    */
00456   void enableDynamicPayloads(void);
00457 
00458   /**
00459    * Determine whether the hardware is an nRF24L01+ or not.
00460    *
00461    * @return true if the hardware is nRF24L01+ (or compatible) and false
00462    * if its not.
00463    */
00464   bool isPVariant(void) ;
00465 
00466   /**
00467    * Enable or disable auto-acknowlede packets
00468    *
00469    * This is enabled by default, so it's only needed if you want to turn
00470    * it off for some reason.
00471    *
00472    * @param enable Whether to enable (true) or disable (false) auto-acks
00473    */
00474   void setAutoAck(bool enable);
00475 
00476   /**
00477    * Enable or disable auto-acknowlede packets on a per pipeline basis.
00478    *
00479    * AA is enabled by default, so it's only needed if you want to turn
00480    * it off/on for some reason on a per pipeline basis.
00481    *
00482    * @param pipe Which pipeline to modify
00483    * @param enable Whether to enable (true) or disable (false) auto-acks
00484    */
00485   void setAutoAck( uint8_t pipe, bool enable ) ;
00486 
00487   /**
00488    * Set Power Amplifier (PA) level to one of four levels.
00489    * Relative mnemonics have been used to allow for future PA level
00490    * changes. According to 6.5 of the nRF24L01+ specification sheet,
00491    * they translate to: RF24_PA_MIN=-18dBm, RF24_PA_LOW=-12dBm,
00492    * RF24_PA_MED=-6dBM, and RF24_PA_HIGH=0dBm.
00493    *
00494    * @param level Desired PA level.
00495    */
00496   void setPALevel( rf24_pa_dbm_e level ) ;
00497 
00498   /**
00499    * Fetches the current PA level.
00500    *
00501    * @return Returns a value from the rf24_pa_dbm_e enum describing
00502    * the current PA setting. Please remember, all values represented
00503    * by the enum mnemonics are negative dBm. See setPALevel for
00504    * return value descriptions.
00505    */
00506   rf24_pa_dbm_e getPALevel( void ) ;
00507 
00508   /**
00509    * Set the transmission data rate
00510    *
00511    * @warning setting RF24_250KBPS will fail for non-plus units
00512    *
00513    * @param speed RF24_250KBPS for 250kbs, RF24_1MBPS for 1Mbps, or RF24_2MBPS for 2Mbps
00514    * @return true if the change was successful
00515    */
00516   bool setDataRate(rf24_datarate_e speed);
00517   
00518   /**
00519    * Fetches the transmission data rate
00520    *
00521    * @return Returns the hardware's currently configured datarate. The value
00522    * is one of 250kbs, RF24_1MBPS for 1Mbps, or RF24_2MBPS, as defined in the
00523    * rf24_datarate_e enum.
00524    */
00525   rf24_datarate_e getDataRate( void ) ;
00526 
00527   /**
00528    * Set the CRC length
00529    *
00530    * @param length RF24_CRC_8 for 8-bit or RF24_CRC_16 for 16-bit
00531    */
00532   void setCRCLength(rf24_crclength_e length);
00533 
00534   /**
00535    * Get the CRC length
00536    *
00537    * @return RF24_DISABLED if disabled or RF24_CRC_8 for 8-bit or RF24_CRC_16 for 16-bit
00538    */
00539   rf24_crclength_e getCRCLength(void);
00540 
00541   /**
00542    * Disable CRC validation
00543    *
00544    */
00545   void disableCRC( void ) ;
00546 
00547   /**@}*/
00548   /**
00549    * @name Advanced Operation 
00550    *
00551    *  Methods you can use to drive the chip in more advanced ways 
00552    */
00553   /**@{*/
00554 
00555   /**
00556    * Print a giant block of debugging information to stdout
00557    *
00558    * @warning Does nothing if stdout is not defined.  See fdevopen in stdio.h
00559    */
00560   void printDetails(void);
00561 
00562   /**
00563    * Enter low-power mode
00564    *
00565    * To return to normal power mode, either write() some data or
00566    * startListening, or powerUp().
00567    */
00568   void powerDown(void);
00569 
00570   /**
00571    * Leave low-power mode - making radio more responsive
00572    *
00573    * To return to low power mode, call powerDown().
00574    */
00575   void powerUp(void) ;
00576 
00577   /**
00578    * Test whether there are bytes available to be read
00579    *
00580    * Use this version to discover on which pipe the message
00581    * arrived.
00582    *
00583    * @param[out] pipe_num Which pipe has the payload available
00584    * @return True if there is a payload available, false if none is
00585    */
00586   bool available(uint8_t* pipe_num);
00587 
00588   /**
00589    * Non-blocking write to the open writing pipe
00590    *
00591    * Just like write(), but it returns immediately. To find out what happened
00592    * to the send, catch the IRQ and then call whatHappened().
00593    *
00594    * @see write()
00595    * @see whatHappened()
00596    *
00597    * @param buf Pointer to the data to be sent
00598    * @param len Number of bytes to be sent
00599    * @return True if the payload was delivered successfully false if not
00600    */
00601   void startWrite( const void* buf, uint8_t len );
00602 
00603   /**
00604    * Write an ack payload for the specified pipe
00605    *
00606    * The next time a message is received on @p pipe, the data in @p buf will
00607    * be sent back in the acknowledgement.
00608    *
00609    * @warning According to the data sheet, only three of these can be pending
00610    * at any time.  I have not tested this.
00611    *
00612    * @param pipe Which pipe# (typically 1-5) will get this response.
00613    * @param buf Pointer to data that is sent
00614    * @param len Length of the data to send, up to 32 bytes max.  Not affected
00615    * by the static payload set by setPayloadSize().
00616    */
00617   void writeAckPayload(uint8_t pipe, const void* buf, uint8_t len);
00618 
00619   /**
00620    * Determine if an ack payload was received in the most recent call to
00621    * write().
00622    *
00623    * Call read() to retrieve the ack payload.
00624    *
00625    * @warning Calling this function clears the internal flag which indicates
00626    * a payload is available.  If it returns true, you must read the packet
00627    * out as the very next interaction with the radio, or the results are
00628    * undefined.
00629    *
00630    * @return True if an ack payload is available.
00631    */
00632   bool isAckPayloadAvailable(void);
00633 
00634   /**
00635    * Call this when you get an interrupt to find out why
00636    *
00637    * Tells you what caused the interrupt, and clears the state of
00638    * interrupts.
00639    *
00640    * @param[out] tx_ok The send was successful (TX_DS)
00641    * @param[out] tx_fail The send failed, too many retries (MAX_RT)
00642    * @param[out] rx_ready There is a message waiting to be read (RX_DS)
00643    */
00644   void whatHappened(bool& tx_ok,bool& tx_fail,bool& rx_ready);
00645 
00646   /**
00647    * Test whether there was a carrier on the line for the
00648    * previous listening period.
00649    *
00650    * Useful to check for interference on the current channel.
00651    *
00652    * @return true if was carrier, false if not
00653    */
00654   bool testCarrier(void);
00655 
00656   /**
00657    * Test whether a signal (carrier or otherwise) greater than
00658    * or equal to -64dBm is present on the channel. Valid only
00659    * on nRF24L01P (+) hardware. On nRF24L01, use testCarrier().
00660    *
00661    * Useful to check for interference on the current channel and
00662    * channel hopping strategies.
00663    *
00664    * @return true if signal => -64dBm, false if not
00665    */
00666   bool testRPD(void) ;
00667   
00668   uint8_t min(uint8_t, uint8_t);
00669 };
00670 
00671 
00672 #endif // __RF24_H__
00673 // vim:ai:cin:sts=2 sw=2 ft=cpp