summaryrefslogtreecommitdiff
path: root/peripheral/libupm/src/nrf24l01/nrf24l01.hpp
blob: 9a386624d143a9b85e8197b8a8748960f10694a9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
/*
 * Author: Yevgeniy Kiveisha <yevgeniy.kiveisha@intel.com>
 * Copyright (c) 2014 Intel Corporation.
 * BLE Beaconing based on http://dmitry.gr/index.php?r=05.Projects&proj=11.%20Bluetooth%20LE%20fakery
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
#pragma once

#include <string>
#include <mraa/aio.hpp>
#include <mraa/common.hpp>

#include <mraa/gpio.hpp>

#include <mraa/spi.hpp>
#include <cstring>

#if defined(SWIGJAVA) || defined(JAVACALLBACK)
#include "Callback.hpp"
#endif

/* Memory Map */
#define CONFIG              0x00
#define EN_AA               0x01
#define EN_RXADDR           0x02
#define SETUP_AW            0x03
#define SETUP_RETR          0x04
#define RF_CH               0x05
#define RF_SETUP            0x06
#define STATUS              0x07
#define OBSERVE_TX          0x08
#define CD                  0x09
#define RX_ADDR_P0          0x0A
#define RX_ADDR_P1          0x0B
#define RX_ADDR_P2          0x0C
#define RX_ADDR_P3          0x0D
#define RX_ADDR_P4          0x0E
#define RX_ADDR_P5          0x0F
#define TX_ADDR             0x10
#define RX_PW_P0            0x11
#define RX_PW_P1            0x12
#define RX_PW_P2            0x13
#define RX_PW_P3            0x14
#define RX_PW_P4            0x15
#define RX_PW_P5            0x16
#define FIFO_STATUS         0x17
#define DYNPD               0x1C
#define FEATURE             0x1D

/* Bit Mnemonics */
#define MASK_RX_DR          6
#define MASK_TX_DS          5
#define MASK_MAX_RT         4
#define EN_CRC              3
#define CRCO                2
#define PWR_UP              1
#define PRIM_RX             0
#define ENAA_P5             5
#define ENAA_P4             4
#define ENAA_P3             3
#define ENAA_P2             2
#define ENAA_P1             1
#define ENAA_P0             0
#define ERX_P5              5
#define ERX_P4              4
#define ERX_P3              3
#define ERX_P2              2
#define ERX_P1              1
#define ERX_P0              0
#define AW                  0
#define ARD                 4
#define ARC                 0
#define PLL_LOCK            4
#define RF_DR               3
#define RF_PWR              1
#define LNA_HCURR           0
#define RX_DR               6
#define TX_DS               5
#define MAX_RT              4
#define RX_P_NO             1
#define TX_FULL             0
#define PLOS_CNT            4
#define ARC_CNT             0
#define TX_REUSE            6
#define FIFO_FULL           5
#define TX_EMPTY            4
#define RX_FULL             1
#define RX_EMPTY            0

/* Instruction Mnemonics */
#define R_REGISTER            0x00
#define W_REGISTER            0x20
#define REGISTER_MASK         0x1F
#define R_RX_PAYLOAD          0x61
#define W_TX_PAYLOAD          0xA0
#define FLUSH_TX              0xE1
#define FLUSH_RX              0xE2
#define REUSE_TX_PL           0xE3
#define NOP                   0xFF

#define RF_DR_LOW   5
#define RF_DR_HIGH  3
#define RF_PWR_LOW  1
#define RF_PWR_HIGH 2

/* Nrf24l settings */
#define ADDR_LEN        5
#define _CONFIG         ((1<<EN_CRC) | (0<<CRCO) )

#define MAX_BUFFER            32

#define HIGH                  1
#define LOW                    0

/* BLE beaconing */
#define BLE_MAC_0           0xEF
#define BLE_MAC_1           0xFF
#define BLE_MAC_2           0xC0
#define BLE_MAC_3           0xAA
#define BLE_MAC_4           0x18
#define BLE_MAC_5           0x00

#define BLE_PAYLOAD_OFFSET  13

namespace upm {

#if defined(SWIGJAVA) || defined(JAVACALLBACK)
typedef void (* funcPtrVoidVoid) (Callback *);
#else
typedef void (* funcPtrVoidVoid) ();
#endif

typedef enum {
    NRF_250KBPS = 0,
    NRF_1MBPS   = 1,
    NRF_2MBPS   = 2,
} speed_rate_t;

typedef enum {
    NRF_0DBM    = 0,
    NRF_6DBM    = 1,
    NRF_12DBM   = 2,
    NRF_18DBM   = 3,
} power_t;

/**
 * @brief NRF24L01 Transceiver library
 * @defgroup nrf24l01 libupm-nrf24l01
 * @ingroup seeed sparkfun spi wifi
 */
/**
 * @library nrf24l01
 * @sensor nrf24l01
 * @comname NRF24L01 Transceiver
 * @type wifi
 * @man seeed sparkfun
 * @web http://www.seeedstudio.com/depot/nRF24L01Module-p-1394.html
 * @con spi
 *
 * id
 * @brief API for the NRF24L01 Transceiver Module
 *
 * This module defines the NRF24L01 interface for libnrf24l01
 *
 * @image html nrf24l01.jpg
 * @snippet nrf24l01-receiver.cxx Interesting
 * @snippet nrf24l01-transmitter.cxx Interesting
 * @snippet nrf24l01-broadcast.cxx Interesting
 */
class NRF24L01 {
    public:
        /**
         * Instantiates an NRF24l01 object
         *
         * @param cs Chip select pin
         */
        NRF24L01 (uint8_t cs, uint8_t ce);

        /**
         * Returns the name of the component
         */
        std::string name()
        {
            return m_name;
        }

        /**
         * Initializes needed GPIO pins and SPI
         *
         * @param chipSelect Sets up the chip select pin
         * @param chipEnable Sets up the chip enable pin
         */
        void    init (uint8_t chipSelect, uint8_t chipEnable);

        /**
         * Configures the NRF24L01 transceiver
         */
        void    configure ();

        /**
         * Sends the buffer data
         *
         * @param *value Pointer to the buffer
         */
        void    send (uint8_t * value);

        /**
         * Sends the data located in an inner bufer; the user must fill the
         * m_txBuffer buffer
         */
        void    send ();

        /**
         * Sets a receiving address of the device
         *
         * @param addr 5-byte address
         */
        void    setSourceAddress (uint8_t * addr);

        /**
         * Sets a recipient address. The nrfSend method sends the data buffer
         * to this address
         *
         * @param addr 5-byte address
         */
        void    setDestinationAddress (uint8_t * addr);

        /**
         * Sets a broadcasting address
         *
         * @param addr 5-byte address
         */
        void    setBroadcastAddress (uint8_t * addr);

        /**
         * Sets the payload size
         *
         * @param load Size of the payload (MAX 32)
         */
        void    setPayload (uint8_t load);

#if defined(SWIGJAVA) || defined(JAVACALLBACK)
        /**
         * Sets the handler to be called when data has been
         * received
         * @param call_obj Object used for callback - Java
         */
        void setDataReceivedHandler (Callback *call_obj);
#else
        /**
         * Sets the handler to be called when data has been
         * received
         * @param handler Handler used for callback
         */
        void setDataReceivedHandler (funcPtrVoidVoid handler);
#endif
        /**
         * Checks if the data has arrived
         */
        bool    dataReady ();

        /**
         * Checks if the transceiver is in the sending mode
         */
        bool    dataSending ();

        /**
         * Sinks all the arrived data into a provided buffer
         *
         * @param load Size of the payload (MAX 32)
         */
        void    getData (uint8_t * data);

        /**
         * Checks the transceiver state
         */
        uint8_t getStatus ();

        /**
         * Checks if the receive stack is empty
         */
        bool    rxFifoEmpty ();

        /**
         * Powers the receiver up
         */
        void    rxPowerUp ();

        /**
         * Flushes the receive stack
         */
        void    rxFlushBuffer ();

        /**
         * Powers the transmitter up
         */
        void    txPowerUp ();

        /**
         * Powers everything down
         */
        void    powerDown ();

        void    setChannel (uint8_t channel);

        void    setPower (power_t power);

        uint8_t setSpeedRate (speed_rate_t rate);

        /**
         * Flushes the transmit stack
         */
        void    txFlushBuffer ();

        /**
         * Pulling the method listening for the arrived data,
         * dataRecievedHandler is triggered if data arrives
         */
        void    pollListener ();

        /**
         * Sets the chip enable pin to HIGH
         */
        mraa::Result ceHigh ();

        /**
         * Sets the chip enable pin to LOW
         */
        mraa::Result ceLow ();

        /**
         * Sets the chip select pin to LOW
         */
        mraa::Result csOn ();

        /**
         * Sets the chip select pin to HIGH
         */
        mraa::Result csOff ();

        /**
         * Configures the NRF24L01 transceiver to behave as a BLE
         * (Bluetooth Low Energy) beaconing devcie.
         */
        void setBeaconingMode ();

        /**
         * Beacons the provided message to BLE scanners.
         *
         * @param msg Beacons the provided message (max length is 16 bytes)
         */
        void sendBeaconingMsg (uint8_t * msg);

        uint8_t     m_rxBuffer[MAX_BUFFER]; /**< Receive buffer */
        uint8_t     m_txBuffer[MAX_BUFFER]; /**< Transmit buffer */
        uint8_t     m_bleBuffer [32];       /**< BLE buffer */

    private:
#if defined(SWIGJAVA) || defined(JAVACALLBACK)
        /**< Callback object to use for setting the handler from Java */
        Callback *callback_obj;
#endif
        funcPtrVoidVoid dataReceivedHandler; /**< Data arrived handler */

        /**
         * Writes bytes to an SPI device
         */
        void    writeBytes (uint8_t * dataout, uint8_t * datain, uint8_t len);
        /**
         * Sets the register value on an SPI device [one byte]
         */
        void    setRegister (uint8_t reg, uint8_t value);
        /**
         * Gets the register value from an SPI device [one byte]
         */
        uint8_t getRegister (uint8_t reg);
        /**
         * Reads an array of bytes from the given starting position in NRF24L01 registers
         */
        void    readRegister (uint8_t reg, uint8_t * value, uint8_t len);
        /**
         * Writes an array of bytes into NRF24L01 registers
         */
        void    writeRegister (uint8_t reg, uint8_t * value, uint8_t len);
        /**
         * Sends a command to NRF24L01
         */
        void    sendCommand (uint8_t cmd);

        void bleCrc (const uint8_t* data, uint8_t len, uint8_t* dst);

        void bleWhiten (uint8_t* data, uint8_t len, uint8_t whitenCoeff);

        void blePacketEncode(uint8_t* packet, uint8_t len, uint8_t chan);

        uint8_t swapbits (uint8_t a);

        mraa::Spi               m_spi;
        uint8_t                 m_ce;
        uint8_t                 m_csn;
        uint8_t                 m_channel;
        uint8_t                 m_power;
        uint8_t                 m_ptx;
        uint8_t                 m_payload;
        uint8_t                 m_localAddress[5];

        mraa::Gpio              m_csnPinCtx;
        mraa::Gpio              m_cePinCtx;

        std::string             m_name;
};

}