mBed RFM12B module library
Fork of RF12B by
RFM12B Library
The main purpose of this library was to implement the RFM12B module in order to be able to establish communication with the Moteino (arduino clone that uses the RFM12B).
In order to achieve my goal I was highly inspired by RF12B library from pangsk https://mbed.org/users/pangsk/ and by RFM12B arduino library made by Felix Rusu (http://lowpowerlab.com/blog/2012/12/28/rfm12b-arduino-library/)
Who/What is Moteino? (http://lowpowerlab.com/moteino/)
RFM12B.h@6:52322349ee10, 2013-05-30 (annotated)
- Committer:
- hajesusrodrigues
- Date:
- Thu May 30 22:05:50 2013 +0000
- Revision:
- 6:52322349ee10
- Parent:
- RF12B.h@5:12d8175359f2
- Child:
- 7:19d9da22271a
Moteino Comunication Protocol Implementation
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
hajesusrodrigues | 6:52322349ee10 | 1 | /* |
hajesusrodrigues | 6:52322349ee10 | 2 | RFM12B Library. Based on work done by JeeLabs.org ported to mBed by SK Pang. |
hajesusrodrigues | 6:52322349ee10 | 3 | http://jeelabs.net/projects/cafe/wiki/RF12 |
hajesusrodrigues | 6:52322349ee10 | 4 | |
hajesusrodrigues | 6:52322349ee10 | 5 | http://opensource.org/licenses/mit-license.php |
hajesusrodrigues | 6:52322349ee10 | 6 | |
hajesusrodrigues | 6:52322349ee10 | 7 | Jan 2012 skpang.co.uk |
hajesusrodrigues | 6:52322349ee10 | 8 | |
hajesusrodrigues | 6:52322349ee10 | 9 | Modified by Hugo Rodrigues (May 2013) |
hajesusrodrigues | 6:52322349ee10 | 10 | |
hajesusrodrigues | 6:52322349ee10 | 11 | Permission is hereby granted, free of charge, to any person obtaining a copy |
hajesusrodrigues | 6:52322349ee10 | 12 | of this software and associated documentation files (the "Software"), to deal |
hajesusrodrigues | 6:52322349ee10 | 13 | in the Software without restriction, including without limitation the rights |
hajesusrodrigues | 6:52322349ee10 | 14 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
hajesusrodrigues | 6:52322349ee10 | 15 | copies of the Software, and to permit persons to whom the Software is |
hajesusrodrigues | 6:52322349ee10 | 16 | furnished to do so, subject to the following conditions: |
hajesusrodrigues | 6:52322349ee10 | 17 | |
hajesusrodrigues | 6:52322349ee10 | 18 | The above copyright notice and this permission notice shall be included in |
hajesusrodrigues | 6:52322349ee10 | 19 | all copies or substantial portions of the Software. |
hajesusrodrigues | 6:52322349ee10 | 20 | |
hajesusrodrigues | 6:52322349ee10 | 21 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
hajesusrodrigues | 6:52322349ee10 | 22 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
hajesusrodrigues | 6:52322349ee10 | 23 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
hajesusrodrigues | 6:52322349ee10 | 24 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
hajesusrodrigues | 6:52322349ee10 | 25 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
hajesusrodrigues | 6:52322349ee10 | 26 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
hajesusrodrigues | 6:52322349ee10 | 27 | THE SOFTWARE. |
hajesusrodrigues | 6:52322349ee10 | 28 | */ |
hajesusrodrigues | 6:52322349ee10 | 29 | |
hajesusrodrigues | 6:52322349ee10 | 30 | #ifndef _RFM12B_H |
hajesusrodrigues | 6:52322349ee10 | 31 | #define _RFM12B_H |
pangsk | 0:66fdbf2cc578 | 32 | |
pangsk | 0:66fdbf2cc578 | 33 | #include "mbed.h" |
hajesusrodrigues | 6:52322349ee10 | 34 | |
hajesusrodrigues | 6:52322349ee10 | 35 | /// RF12 Maximum message size in bytes. |
hajesusrodrigues | 6:52322349ee10 | 36 | #define RF12_MAXDATA 128 |
hajesusrodrigues | 6:52322349ee10 | 37 | /// Max transmit/receive buffer: 4 header + data + 2 crc bytes |
hajesusrodrigues | 6:52322349ee10 | 38 | #define RF_MAX (RF12_MAXDATA + 6) |
hajesusrodrigues | 6:52322349ee10 | 39 | |
pangsk | 4:cd581c12a4b9 | 40 | #define RF12_433MHZ 1 |
pangsk | 4:cd581c12a4b9 | 41 | #define RF12_868MHZ 2 |
pangsk | 4:cd581c12a4b9 | 42 | #define RF12_915MHZ 3 |
pangsk | 0:66fdbf2cc578 | 43 | |
hajesusrodrigues | 6:52322349ee10 | 44 | #define RF12_HDR_IDMASK 0x7F |
hajesusrodrigues | 6:52322349ee10 | 45 | #define RF12_HDR_ACKCTLMASK 0x80 |
hajesusrodrigues | 6:52322349ee10 | 46 | #define RF12_DESTID (rf12_hdr1 & RF12_HDR_IDMASK) |
hajesusrodrigues | 6:52322349ee10 | 47 | #define RF12_SOURCEID (rf12_hdr2 & RF12_HDR_IDMASK) |
hajesusrodrigues | 6:52322349ee10 | 48 | |
hajesusrodrigues | 6:52322349ee10 | 49 | // shorthands to simplify sending out the proper ACK when requested |
hajesusrodrigues | 6:52322349ee10 | 50 | #define RF12_WANTS_ACK ((rf12_hdr2 & RF12_HDR_ACKCTLMASK) && !(rf12_hdr1 & RF12_HDR_ACKCTLMASK)) |
pangsk | 0:66fdbf2cc578 | 51 | |
hajesusrodrigues | 6:52322349ee10 | 52 | /// Shorthand for RF12 group byte in rf12_buf. |
hajesusrodrigues | 6:52322349ee10 | 53 | #define rf12_grp rf12_buf[0] |
hajesusrodrigues | 6:52322349ee10 | 54 | /// pointer to 1st header byte in rf12_buf (CTL + DESTINATIONID) |
hajesusrodrigues | 6:52322349ee10 | 55 | #define rf12_hdr1 rf12_buf[1] |
hajesusrodrigues | 6:52322349ee10 | 56 | /// pointer to 2nd header byte in rf12_buf (ACK + SOURCEID) |
hajesusrodrigues | 6:52322349ee10 | 57 | #define rf12_hdr2 rf12_buf[2] |
pangsk | 0:66fdbf2cc578 | 58 | |
hajesusrodrigues | 6:52322349ee10 | 59 | /// Shorthand for RF12 length byte in rf12_buf. |
hajesusrodrigues | 6:52322349ee10 | 60 | #define rf12_len rf12_buf[3] |
hajesusrodrigues | 6:52322349ee10 | 61 | /// Shorthand for first RF12 data byte in rf12_buf. |
hajesusrodrigues | 6:52322349ee10 | 62 | #define rf12_data (rf12_buf + 4) |
pangsk | 0:66fdbf2cc578 | 63 | |
hajesusrodrigues | 6:52322349ee10 | 64 | // RF12 command codes |
hajesusrodrigues | 6:52322349ee10 | 65 | #define RF_RECEIVER_ON 0x82DD |
hajesusrodrigues | 6:52322349ee10 | 66 | #define RF_XMITTER_ON 0x823D |
hajesusrodrigues | 6:52322349ee10 | 67 | #define RF_IDLE_MODE 0x820D |
hajesusrodrigues | 6:52322349ee10 | 68 | #define RF_SLEEP_MODE 0x8205 |
hajesusrodrigues | 6:52322349ee10 | 69 | #define RF_WAKEUP_MODE 0x8207 |
hajesusrodrigues | 6:52322349ee10 | 70 | #define RF_TXREG_WRITE 0xB800 |
hajesusrodrigues | 6:52322349ee10 | 71 | #define RF_RX_FIFO_READ 0xB000 |
hajesusrodrigues | 6:52322349ee10 | 72 | #define RF_WAKEUP_TIMER 0xE000 |
pangsk | 0:66fdbf2cc578 | 73 | |
hajesusrodrigues | 6:52322349ee10 | 74 | //RF12 status bits |
hajesusrodrigues | 6:52322349ee10 | 75 | #define RF_LBD_BIT 0x0400 |
hajesusrodrigues | 6:52322349ee10 | 76 | #define RF_RSSI_BIT 0x0100 |
hajesusrodrigues | 6:52322349ee10 | 77 | |
hajesusrodrigues | 6:52322349ee10 | 78 | //#define DEBUG |
hajesusrodrigues | 6:52322349ee10 | 79 | |
hajesusrodrigues | 6:52322349ee10 | 80 | // transceiver states, these determine what to do with each interrupt |
hajesusrodrigues | 6:52322349ee10 | 81 | enum { |
hajesusrodrigues | 6:52322349ee10 | 82 | TXCRC1, TXCRC2, TXTAIL, TXDONE, TXIDLE, TXRECV, TXPRE1, TXPRE2, TXPRE3, TXSYN1, TXSYN2, |
hajesusrodrigues | 6:52322349ee10 | 83 | }; |
hajesusrodrigues | 6:52322349ee10 | 84 | |
hajesusrodrigues | 6:52322349ee10 | 85 | class RFM12B { |
hajesusrodrigues | 6:52322349ee10 | 86 | |
pangsk | 0:66fdbf2cc578 | 87 | public: |
pangsk | 0:66fdbf2cc578 | 88 | /* Constructor */ |
hajesusrodrigues | 6:52322349ee10 | 89 | RFM12B(PinName SDI, PinName SDO, PinName SCK, PinName NCS, PinName NIRQ, PinName NIRQ_LED); |
hajesusrodrigues | 6:52322349ee10 | 90 | |
hajesusrodrigues | 6:52322349ee10 | 91 | /* Initialises the RFM12B module */ |
hajesusrodrigues | 6:52322349ee10 | 92 | void Initialize(uint8_t nodeid, uint8_t freqBand, uint8_t groupid=0xAA, uint8_t txPower=0, uint8_t airKbps=0x08); |
hajesusrodrigues | 6:52322349ee10 | 93 | |
hajesusrodrigues | 6:52322349ee10 | 94 | void ReceiveStart(void); |
hajesusrodrigues | 6:52322349ee10 | 95 | bool ReceiveComplete(void); |
hajesusrodrigues | 6:52322349ee10 | 96 | bool CanSend(); |
hajesusrodrigues | 6:52322349ee10 | 97 | |
hajesusrodrigues | 6:52322349ee10 | 98 | void SendStart(uint8_t toNodeId, bool requestACK = false, bool sendACK = false); |
hajesusrodrigues | 6:52322349ee10 | 99 | void SendStart(uint8_t toNodeId, const void* sendBuf, uint8_t sendLen, bool requestACK = false, |
hajesusrodrigues | 6:52322349ee10 | 100 | bool sendACK = false); |
hajesusrodrigues | 6:52322349ee10 | 101 | void SendACK(const void* sendBuf = "", uint8_t sendLen = 0); |
hajesusrodrigues | 6:52322349ee10 | 102 | void Send(uint8_t toNodeId, const void* sendBuf, uint8_t sendLen, bool requestACK = false); |
hajesusrodrigues | 6:52322349ee10 | 103 | |
hajesusrodrigues | 6:52322349ee10 | 104 | volatile uint8_t * GetData(); |
hajesusrodrigues | 6:52322349ee10 | 105 | uint8_t GetDataLen(void); // how many bytes were received |
hajesusrodrigues | 6:52322349ee10 | 106 | uint8_t GetSender(void); |
hajesusrodrigues | 6:52322349ee10 | 107 | |
hajesusrodrigues | 6:52322349ee10 | 108 | bool ACKRequested(); |
hajesusrodrigues | 6:52322349ee10 | 109 | bool ACKReceived(uint8_t fromNodeID = 0); |
hajesusrodrigues | 6:52322349ee10 | 110 | |
hajesusrodrigues | 6:52322349ee10 | 111 | void Encryption(bool encrypt); // does en-/decryption |
hajesusrodrigues | 6:52322349ee10 | 112 | void SetEncryptionKey(const uint8_t* key); // set encryption key |
hajesusrodrigues | 6:52322349ee10 | 113 | |
hajesusrodrigues | 6:52322349ee10 | 114 | bool CRC_Pass(void); |
hajesusrodrigues | 6:52322349ee10 | 115 | |
pangsk | 0:66fdbf2cc578 | 116 | protected: |
pangsk | 0:66fdbf2cc578 | 117 | /* SPI module */ |
pangsk | 0:66fdbf2cc578 | 118 | SPI spi; |
hajesusrodrigues | 6:52322349ee10 | 119 | |
pangsk | 0:66fdbf2cc578 | 120 | /* Other digital pins */ |
pangsk | 0:66fdbf2cc578 | 121 | DigitalOut NCS; |
pangsk | 0:66fdbf2cc578 | 122 | InterruptIn NIRQ; |
pangsk | 0:66fdbf2cc578 | 123 | DigitalIn NIRQ_in; |
hajesusrodrigues | 6:52322349ee10 | 124 | DigitalOut NIRQ_LED; |
pangsk | 3:e926e54424cb | 125 | |
hajesusrodrigues | 6:52322349ee10 | 126 | volatile uint8_t nodeID; // address of this node |
hajesusrodrigues | 6:52322349ee10 | 127 | volatile uint8_t networkID; // network group |
hajesusrodrigues | 6:52322349ee10 | 128 | |
hajesusrodrigues | 6:52322349ee10 | 129 | volatile uint8_t* Data; |
hajesusrodrigues | 6:52322349ee10 | 130 | volatile uint8_t* DataLen; |
hajesusrodrigues | 6:52322349ee10 | 131 | |
hajesusrodrigues | 6:52322349ee10 | 132 | void InterruptHandler(); // interrupt routine for data reception |
pangsk | 0:66fdbf2cc578 | 133 | |
hajesusrodrigues | 6:52322349ee10 | 134 | int writeCmd(int cmd); // write a command to the RF module |
hajesusrodrigues | 6:52322349ee10 | 135 | uint16_t crc16_update(uint16_t crc, uint8_t data); |
hajesusrodrigues | 6:52322349ee10 | 136 | uint16_t xfer(uint16_t cmd); |
hajesusrodrigues | 6:52322349ee10 | 137 | uint8_t byte(uint8_t out); |
hajesusrodrigues | 6:52322349ee10 | 138 | |
hajesusrodrigues | 6:52322349ee10 | 139 | private: |
hajesusrodrigues | 6:52322349ee10 | 140 | volatile uint8_t rf12_buf[RF_MAX]; // recv/xmit buf, including hdr & crc bytes |
pangsk | 0:66fdbf2cc578 | 141 | |
hajesusrodrigues | 6:52322349ee10 | 142 | volatile uint8_t rxfill; // number of data bytes in rf12_buf |
hajesusrodrigues | 6:52322349ee10 | 143 | volatile int8_t rxstate; // current transceiver state |
hajesusrodrigues | 6:52322349ee10 | 144 | volatile uint16_t rf12_crc; // running crc value |
hajesusrodrigues | 6:52322349ee10 | 145 | uint32_t seqNum; // encrypted send sequence number |
hajesusrodrigues | 6:52322349ee10 | 146 | uint32_t cryptKey[4]; // encryption key to use |
hajesusrodrigues | 6:52322349ee10 | 147 | long rf12_seq; // seq number of encrypted packet (or -1) |
hajesusrodrigues | 6:52322349ee10 | 148 | |
hajesusrodrigues | 6:52322349ee10 | 149 | bool useEncryption; |
pangsk | 0:66fdbf2cc578 | 150 | }; |
pangsk | 0:66fdbf2cc578 | 151 | |
hajesusrodrigues | 6:52322349ee10 | 152 | #endif /* _RFM12B_H */ |