Home | History | Annotate | Download | only in nrf24l01
      1 /*
      2  * Author: Yevgeniy Kiveisha <yevgeniy.kiveisha (at) intel.com>
      3  * Copyright (c) 2014 Intel Corporation.
      4  * BLE Beaconing based on http://dmitry.gr/index.php?r=05.Projects&proj=11.%20Bluetooth%20LE%20fakery
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining
      7  * a copy of this software and associated documentation files (the
      8  * "Software"), to deal in the Software without restriction, including
      9  * without limitation the rights to use, copy, modify, merge, publish,
     10  * distribute, sublicense, and/or sell copies of the Software, and to
     11  * permit persons to whom the Software is furnished to do so, subject to
     12  * the following conditions:
     13  *
     14  * The above copyright notice and this permission notice shall be
     15  * included in all copies or substantial portions of the Software.
     16  *
     17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     18  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     20  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
     21  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
     22  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
     23  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     24  */
     25 #pragma once
     26 
     27 #include <string>
     28 #include <mraa/aio.hpp>
     29 #include <mraa/common.hpp>
     30 
     31 #include <mraa/gpio.hpp>
     32 
     33 #include <mraa/spi.hpp>
     34 #include <cstring>
     35 
     36 #if defined(SWIGJAVA) || defined(JAVACALLBACK)
     37 #include "Callback.h"
     38 #endif
     39 
     40 /* Memory Map */
     41 #define CONFIG              0x00
     42 #define EN_AA               0x01
     43 #define EN_RXADDR           0x02
     44 #define SETUP_AW            0x03
     45 #define SETUP_RETR          0x04
     46 #define RF_CH               0x05
     47 #define RF_SETUP            0x06
     48 #define STATUS              0x07
     49 #define OBSERVE_TX          0x08
     50 #define CD                  0x09
     51 #define RX_ADDR_P0          0x0A
     52 #define RX_ADDR_P1          0x0B
     53 #define RX_ADDR_P2          0x0C
     54 #define RX_ADDR_P3          0x0D
     55 #define RX_ADDR_P4          0x0E
     56 #define RX_ADDR_P5          0x0F
     57 #define TX_ADDR             0x10
     58 #define RX_PW_P0            0x11
     59 #define RX_PW_P1            0x12
     60 #define RX_PW_P2            0x13
     61 #define RX_PW_P3            0x14
     62 #define RX_PW_P4            0x15
     63 #define RX_PW_P5            0x16
     64 #define FIFO_STATUS         0x17
     65 #define DYNPD               0x1C
     66 #define FEATURE             0x1D
     67 
     68 /* Bit Mnemonics */
     69 #define MASK_RX_DR          6
     70 #define MASK_TX_DS          5
     71 #define MASK_MAX_RT         4
     72 #define EN_CRC              3
     73 #define CRCO                2
     74 #define PWR_UP              1
     75 #define PRIM_RX             0
     76 #define ENAA_P5             5
     77 #define ENAA_P4             4
     78 #define ENAA_P3             3
     79 #define ENAA_P2             2
     80 #define ENAA_P1             1
     81 #define ENAA_P0             0
     82 #define ERX_P5              5
     83 #define ERX_P4              4
     84 #define ERX_P3              3
     85 #define ERX_P2              2
     86 #define ERX_P1              1
     87 #define ERX_P0              0
     88 #define AW                  0
     89 #define ARD                 4
     90 #define ARC                 0
     91 #define PLL_LOCK            4
     92 #define RF_DR               3
     93 #define RF_PWR              1
     94 #define LNA_HCURR           0
     95 #define RX_DR               6
     96 #define TX_DS               5
     97 #define MAX_RT              4
     98 #define RX_P_NO             1
     99 #define TX_FULL             0
    100 #define PLOS_CNT            4
    101 #define ARC_CNT             0
    102 #define TX_REUSE            6
    103 #define FIFO_FULL           5
    104 #define TX_EMPTY            4
    105 #define RX_FULL             1
    106 #define RX_EMPTY            0
    107 
    108 /* Instruction Mnemonics */
    109 #define R_REGISTER            0x00
    110 #define W_REGISTER            0x20
    111 #define REGISTER_MASK         0x1F
    112 #define R_RX_PAYLOAD          0x61
    113 #define W_TX_PAYLOAD          0xA0
    114 #define FLUSH_TX              0xE1
    115 #define FLUSH_RX              0xE2
    116 #define REUSE_TX_PL           0xE3
    117 #define NOP                   0xFF
    118 
    119 #define RF_DR_LOW   5
    120 #define RF_DR_HIGH  3
    121 #define RF_PWR_LOW  1
    122 #define RF_PWR_HIGH 2
    123 
    124 /* Nrf24l settings */
    125 #define ADDR_LEN        5
    126 #define _CONFIG         ((1<<EN_CRC) | (0<<CRCO) )
    127 
    128 #define MAX_BUFFER            32
    129 
    130 #define HIGH                  1
    131 #define LOW                    0
    132 
    133 /* BLE beaconing */
    134 #define BLE_MAC_0           0xEF
    135 #define BLE_MAC_1           0xFF
    136 #define BLE_MAC_2           0xC0
    137 #define BLE_MAC_3           0xAA
    138 #define BLE_MAC_4           0x18
    139 #define BLE_MAC_5           0x00
    140 
    141 #define BLE_PAYLOAD_OFFSET  13
    142 
    143 namespace upm {
    144 
    145 #if defined(SWIGJAVA) || defined(JAVACALLBACK)
    146 typedef void (* funcPtrVoidVoid) (Callback *);
    147 #else
    148 typedef void (* funcPtrVoidVoid) ();
    149 #endif
    150 
    151 typedef enum {
    152     NRF_250KBPS = 0,
    153     NRF_1MBPS   = 1,
    154     NRF_2MBPS   = 2,
    155 } speed_rate_t;
    156 
    157 typedef enum {
    158     NRF_0DBM    = 0,
    159     NRF_6DBM    = 1,
    160     NRF_12DBM   = 2,
    161     NRF_18DBM   = 3,
    162 } power_t;
    163 
    164 /**
    165  * @brief NRF24L01 Transceiver library
    166  * @defgroup nrf24l01 libupm-nrf24l01
    167  * @ingroup seeed sparkfun spi wifi
    168  */
    169 /**
    170  * @library nrf24l01
    171  * @sensor nrf24l01
    172  * @comname NRF24L01 Transceiver
    173  * @type wifi
    174  * @man seeed sparkfun
    175  * @web http://www.seeedstudio.com/depot/nRF24L01Module-p-1394.html
    176  * @con spi
    177  *
    178  * id
    179  * @brief API for the NRF24L01 Transceiver Module
    180  *
    181  * This module defines the NRF24L01 interface for libnrf24l01
    182  *
    183  * @image html nrf24l01.jpg
    184  * @snippet nrf24l01-receiver.cxx Interesting
    185  * @snippet nrf24l01-transmitter.cxx Interesting
    186  * @snippet nrf24l01-broadcast.cxx Interesting
    187  */
    188 class NRF24L01 {
    189     public:
    190         /**
    191          * Instantiates an NRF24l01 object
    192          *
    193          * @param cs Chip select pin
    194          */
    195         NRF24L01 (uint8_t cs, uint8_t ce);
    196 
    197         /**
    198          * Returns the name of the component
    199          */
    200         std::string name()
    201         {
    202             return m_name;
    203         }
    204 
    205         /**
    206          * Initializes needed GPIO pins and SPI
    207          *
    208          * @param chipSelect Sets up the chip select pin
    209          * @param chipEnable Sets up the chip enable pin
    210          */
    211         void    init (uint8_t chipSelect, uint8_t chipEnable);
    212 
    213         /**
    214          * Configures the NRF24L01 transceiver
    215          */
    216         void    configure ();
    217 
    218         /**
    219          * Sends the buffer data
    220          *
    221          * @param *value Pointer to the buffer
    222          */
    223         void    send (uint8_t * value);
    224 
    225         /**
    226          * Sends the data located in an inner bufer; the user must fill the
    227          * m_txBuffer buffer
    228          */
    229         void    send ();
    230 
    231         /**
    232          * Sets a receiving address of the device
    233          *
    234          * @param addr 5-byte address
    235          */
    236         void    setSourceAddress (uint8_t * addr);
    237 
    238         /**
    239          * Sets a recipient address. The nrfSend method sends the data buffer
    240          * to this address
    241          *
    242          * @param addr 5-byte address
    243          */
    244         void    setDestinationAddress (uint8_t * addr);
    245 
    246         /**
    247          * Sets a broadcasting address
    248          *
    249          * @param addr 5-byte address
    250          */
    251         void    setBroadcastAddress (uint8_t * addr);
    252 
    253         /**
    254          * Sets the payload size
    255          *
    256          * @param load Size of the payload (MAX 32)
    257          */
    258         void    setPayload (uint8_t load);
    259 
    260 #if defined(SWIGJAVA) || defined(JAVACALLBACK)
    261         /**
    262          * Sets the handler to be called when data has been
    263          * received
    264          * @param call_obj Object used for callback - Java
    265          */
    266         void setDataReceivedHandler (Callback *call_obj);
    267 #else
    268         /**
    269          * Sets the handler to be called when data has been
    270          * received
    271          * @param handler Handler used for callback
    272          */
    273         void setDataReceivedHandler (funcPtrVoidVoid handler);
    274 #endif
    275         /**
    276          * Checks if the data has arrived
    277          */
    278         bool    dataReady ();
    279 
    280         /**
    281          * Checks if the transceiver is in the sending mode
    282          */
    283         bool    dataSending ();
    284 
    285         /**
    286          * Sinks all the arrived data into a provided buffer
    287          *
    288          * @param load Size of the payload (MAX 32)
    289          */
    290         void    getData (uint8_t * data);
    291 
    292         /**
    293          * Checks the transceiver state
    294          */
    295         uint8_t getStatus ();
    296 
    297         /**
    298          * Checks if the receive stack is empty
    299          */
    300         bool    rxFifoEmpty ();
    301 
    302         /**
    303          * Powers the receiver up
    304          */
    305         void    rxPowerUp ();
    306 
    307         /**
    308          * Flushes the receive stack
    309          */
    310         void    rxFlushBuffer ();
    311 
    312         /**
    313          * Powers the transmitter up
    314          */
    315         void    txPowerUp ();
    316 
    317         /**
    318          * Powers everything down
    319          */
    320         void    powerDown ();
    321 
    322         void    setChannel (uint8_t channel);
    323 
    324         void    setPower (power_t power);
    325 
    326         uint8_t setSpeedRate (speed_rate_t rate);
    327 
    328         /**
    329          * Flushes the transmit stack
    330          */
    331         void    txFlushBuffer ();
    332 
    333         /**
    334          * Pulling the method listening for the arrived data,
    335          * dataRecievedHandler is triggered if data arrives
    336          */
    337         void    pollListener ();
    338 
    339         /**
    340          * Sets the chip enable pin to HIGH
    341          */
    342         mraa::Result ceHigh ();
    343 
    344         /**
    345          * Sets the chip enable pin to LOW
    346          */
    347         mraa::Result ceLow ();
    348 
    349         /**
    350          * Sets the chip select pin to LOW
    351          */
    352         mraa::Result csOn ();
    353 
    354         /**
    355          * Sets the chip select pin to HIGH
    356          */
    357         mraa::Result csOff ();
    358 
    359         /**
    360          * Configures the NRF24L01 transceiver to behave as a BLE
    361          * (Bluetooth Low Energy) beaconing devcie.
    362          */
    363         void setBeaconingMode ();
    364 
    365         /**
    366          * Beacons the provided message to BLE scanners.
    367          *
    368          * @param msg Beacons the provided message (max length is 16 bytes)
    369          */
    370         void sendBeaconingMsg (uint8_t * msg);
    371 
    372         uint8_t     m_rxBuffer[MAX_BUFFER]; /**< Receive buffer */
    373         uint8_t     m_txBuffer[MAX_BUFFER]; /**< Transmit buffer */
    374         uint8_t     m_bleBuffer [32];       /**< BLE buffer */
    375 
    376     private:
    377 #if defined(SWIGJAVA) || defined(JAVACALLBACK)
    378         /**< Callback object to use for setting the handler from Java */
    379         Callback *callback_obj;
    380 #endif
    381         funcPtrVoidVoid dataReceivedHandler; /**< Data arrived handler */
    382 
    383         /**
    384          * Writes bytes to an SPI device
    385          */
    386         void    writeBytes (uint8_t * dataout, uint8_t * datain, uint8_t len);
    387         /**
    388          * Sets the register value on an SPI device [one byte]
    389          */
    390         void    setRegister (uint8_t reg, uint8_t value);
    391         /**
    392          * Gets the register value from an SPI device [one byte]
    393          */
    394         uint8_t getRegister (uint8_t reg);
    395         /**
    396          * Reads an array of bytes from the given starting position in NRF24L01 registers
    397          */
    398         void    readRegister (uint8_t reg, uint8_t * value, uint8_t len);
    399         /**
    400          * Writes an array of bytes into NRF24L01 registers
    401          */
    402         void    writeRegister (uint8_t reg, uint8_t * value, uint8_t len);
    403         /**
    404          * Sends a command to NRF24L01
    405          */
    406         void    sendCommand (uint8_t cmd);
    407 
    408         void bleCrc (const uint8_t* data, uint8_t len, uint8_t* dst);
    409 
    410         void bleWhiten (uint8_t* data, uint8_t len, uint8_t whitenCoeff);
    411 
    412         void blePacketEncode(uint8_t* packet, uint8_t len, uint8_t chan);
    413 
    414         uint8_t swapbits (uint8_t a);
    415 
    416         mraa::Spi               m_spi;
    417         uint8_t                 m_ce;
    418         uint8_t                 m_csn;
    419         uint8_t                 m_channel;
    420         uint8_t                 m_power;
    421         uint8_t                 m_ptx;
    422         uint8_t                 m_payload;
    423         uint8_t                 m_localAddress[5];
    424 
    425         mraa::Gpio              m_csnPinCtx;
    426         mraa::Gpio              m_cePinCtx;
    427 
    428         std::string             m_name;
    429 };
    430 
    431 }
    432