├── README ├── examples ├── Basic_TwoWay │ └── Basic_TwoWay.pde ├── RX_only │ └── RX_only.pde └── TX_only │ └── TX_only.pde ├── mrf24j.cpp └── mrf24j.h /README: -------------------------------------------------------------------------------- 1 | The microchip mrf24j40ma is an 802.15.4 module, with a SPI interface. It's nice and cheap, and it is 2 | readily usable on a breadboard, unlike xbee modules. More information here: 3 | http://www.microchip.com/wwwproducts/Devices.aspx?dDocName=en535967 4 | 5 | This library provides a basic interface to send and receive packets using plain 802.15.4. beacon mode 6 | is not supported. 7 | -------------------------------------------------------------------------------- /examples/Basic_TwoWay/Basic_TwoWay.pde: -------------------------------------------------------------------------------- 1 | /** 2 | * Example code for using a microchip mrf24j40 module to send and receive 3 | * packets using plain 802.15.4 4 | * Requirements: 3 pins for spi, 3 pins for reset, chip select and interrupt 5 | * notifications 6 | * This example file is considered to be in the public domain 7 | * Originally written by Karl Palsson, karlp@tweak.net.au, March 2011 8 | */ 9 | #include 10 | #include 11 | 12 | const int pin_reset = 6; 13 | const int pin_cs = 10; // default CS pin on ATmega8/168/328 14 | const int pin_interrupt = 2; // default interrupt pin on ATmega8/168/328 15 | 16 | Mrf24j mrf(pin_reset, pin_cs, pin_interrupt); 17 | 18 | long last_time; 19 | long tx_interval = 1000; 20 | 21 | void setup() { 22 | Serial.begin(9600); 23 | 24 | mrf.reset(); 25 | mrf.init(); 26 | 27 | mrf.set_pan(0xcafe); 28 | // This is _our_ address 29 | mrf.address16_write(0x6001); 30 | 31 | // uncomment if you want to receive any packet on this channel 32 | //mrf.set_promiscuous(true); 33 | 34 | // uncomment if you want to enable PA/LNA external control 35 | //mrf.set_palna(true); 36 | 37 | // uncomment if you want to buffer all PHY Payload 38 | //mrf.set_bufferPHY(true); 39 | 40 | attachInterrupt(0, interrupt_routine, CHANGE); // interrupt 0 equivalent to pin 2(INT0) on ATmega8/168/328 41 | last_time = millis(); 42 | interrupts(); 43 | } 44 | 45 | void interrupt_routine() { 46 | mrf.interrupt_handler(); // mrf24 object interrupt routine 47 | } 48 | 49 | void loop() { 50 | mrf.check_flags(&handle_rx, &handle_tx); 51 | unsigned long current_time = millis(); 52 | if (current_time - last_time > tx_interval) { 53 | last_time = current_time; 54 | Serial.println("txxxing..."); 55 | mrf.send16(0x4202, "abcd"); 56 | } 57 | } 58 | 59 | void handle_rx() { 60 | Serial.print("received a packet ");Serial.print(mrf.get_rxinfo()->frame_length, DEC);Serial.println(" bytes long"); 61 | 62 | if(mrf.get_bufferPHY()){ 63 | Serial.println("Packet data (PHY Payload):"); 64 | for (int i = 0; i < mrf.get_rxinfo()->frame_length; i++) { 65 | Serial.print(mrf.get_rxbuf()[i]); 66 | } 67 | } 68 | 69 | Serial.println("\r\nASCII data (relevant data):"); 70 | for (int i = 0; i < mrf.rx_datalength(); i++) { 71 | Serial.write(mrf.get_rxinfo()->rx_data[i]); 72 | } 73 | 74 | Serial.print("\r\nLQI/RSSI="); 75 | Serial.print(mrf.get_rxinfo()->lqi, DEC); 76 | Serial.print("/"); 77 | Serial.println(mrf.get_rxinfo()->rssi, DEC); 78 | } 79 | 80 | void handle_tx() { 81 | if (mrf.get_txinfo()->tx_ok) { 82 | Serial.println("TX went ok, got ack"); 83 | } else { 84 | Serial.print("TX failed after ");Serial.print(mrf.get_txinfo()->retries);Serial.println(" retries\n"); 85 | } 86 | } -------------------------------------------------------------------------------- /examples/RX_only/RX_only.pde: -------------------------------------------------------------------------------- 1 | /** 2 | * Example code for using a microchip mrf24j40 module to receive only 3 | * packets using plain 802.15.4 4 | * Requirements: 3 pins for spi, 3 pins for reset, chip select and interrupt 5 | * notifications 6 | * This example file is considered to be in the public domain 7 | * Originally written by Karl Palsson, karlp@tweak.net.au, March 2011 8 | */ 9 | #include 10 | #include 11 | 12 | const int pin_reset = 6; 13 | const int pin_cs = 10; // default CS pin on ATmega8/168/328 14 | const int pin_interrupt = 2; // default interrupt pin on ATmega8/168/328 15 | 16 | Mrf24j mrf(pin_reset, pin_cs, pin_interrupt); 17 | 18 | void setup() { 19 | Serial.begin(9600); 20 | 21 | mrf.reset(); 22 | mrf.init(); 23 | 24 | mrf.set_pan(0xcafe); 25 | // This is _our_ address 26 | mrf.address16_write(0x6001); 27 | 28 | // uncomment if you want to receive any packet on this channel 29 | //mrf.set_promiscuous(true); 30 | 31 | // uncomment if you want to enable PA/LNA external control 32 | //mrf.set_palna(true); 33 | 34 | // uncomment if you want to buffer all PHY Payload 35 | //mrf.set_bufferPHY(true); 36 | 37 | attachInterrupt(0, interrupt_routine, CHANGE); // interrupt 0 equivalent to pin 2(INT0) on ATmega8/168/328 38 | interrupts(); 39 | } 40 | 41 | void interrupt_routine() { 42 | mrf.interrupt_handler(); // mrf24 object interrupt routine 43 | } 44 | 45 | void loop() { 46 | mrf.check_flags(&handle_rx, &handle_tx); 47 | } 48 | 49 | void handle_rx() { 50 | Serial.print("received a packet ");Serial.print(mrf.get_rxinfo()->frame_length, DEC);Serial.println(" bytes long"); 51 | 52 | if(mrf.get_bufferPHY()){ 53 | Serial.println("Packet data (PHY Payload):"); 54 | for (int i = 0; i < mrf.get_rxinfo()->frame_length; i++) { 55 | Serial.print(mrf.get_rxbuf()[i]); 56 | } 57 | } 58 | 59 | Serial.println("\r\nASCII data (relevant data):"); 60 | for (int i = 0; i < mrf.rx_datalength(); i++) { 61 | Serial.write(mrf.get_rxinfo()->rx_data[i]); 62 | } 63 | 64 | Serial.print("\r\nLQI/RSSI="); 65 | Serial.print(mrf.get_rxinfo()->lqi, DEC); 66 | Serial.print("/"); 67 | Serial.println(mrf.get_rxinfo()->rssi, DEC); 68 | } 69 | 70 | void handle_tx() { 71 | // code to transmit, nothing to do 72 | } -------------------------------------------------------------------------------- /examples/TX_only/TX_only.pde: -------------------------------------------------------------------------------- 1 | /** 2 | * Example code for using a microchip mrf24j40 module to send simple packets 3 | * 4 | * Requirements: 3 pins for spi, 3 pins for reset, chip select and interrupt 5 | * notifications 6 | * This example file is considered to be in the public domain 7 | * Originally written by Karl Palsson, karlp@tweak.net.au, March 2011 8 | */ 9 | #include 10 | #include 11 | 12 | const int pin_reset = 6; 13 | const int pin_cs = 10; // default CS pin on ATmega8/168/328 14 | const int pin_interrupt = 2; // default interrupt pin on ATmega8/168/328 15 | 16 | Mrf24j mrf(pin_reset, pin_cs, pin_interrupt); 17 | 18 | long last_time; 19 | long tx_interval = 1000; 20 | 21 | void setup() { 22 | Serial.begin(9600); 23 | 24 | mrf.reset(); 25 | mrf.init(); 26 | 27 | mrf.set_pan(0xcafe); 28 | // This is _our_ address 29 | mrf.address16_write(0x6001); 30 | 31 | // uncomment if you want to enable PA/LNA external control 32 | //mrf.set_palna(true); 33 | 34 | attachInterrupt(0, interrupt_routine, CHANGE); // interrupt 0 equivalent to pin 2(INT0) on ATmega8/168/328 35 | last_time = millis(); 36 | interrupts(); 37 | } 38 | 39 | void interrupt_routine() { 40 | mrf.interrupt_handler(); // mrf24 object interrupt routine 41 | } 42 | 43 | void loop() { 44 | mrf.check_flags(&handle_rx, &handle_tx); 45 | } 46 | 47 | void handle_rx() { 48 | // data to receive, nothing to do 49 | } 50 | 51 | void handle_tx() { 52 | if (mrf.get_txinfo()->tx_ok) { 53 | Serial.println("TX went ok, got ack"); 54 | } else { 55 | Serial.print("TX failed after ");Serial.print(mrf.get_txinfo()->retries);Serial.println(" retries\n"); 56 | } 57 | } -------------------------------------------------------------------------------- /mrf24j.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * mrf24j.cpp, Karl Palsson, 2011, karlp@tweak.net.au 3 | * modified bsd license / apache license 4 | */ 5 | 6 | #include "mrf24j.h" 7 | 8 | // aMaxPHYPacketSize = 127, from the 802.15.4-2006 standard. 9 | static uint8_t rx_buf[127]; 10 | 11 | // essential for obtaining the data frame only 12 | // bytes_MHR = 2 Frame control + 1 sequence number + 2 panid + 2 shortAddr Destination + 2 shortAddr Source 13 | static int bytes_MHR = 9; 14 | static int bytes_FCS = 2; // FCS length = 2 15 | static int bytes_nodata = bytes_MHR + bytes_FCS; // no_data bytes in PHY payload, header length + FCS 16 | 17 | static int ignoreBytes = 0; // bytes to ignore, some modules behaviour. 18 | 19 | static boolean bufPHY = false; // flag to buffer all bytes in PHY Payload, or not 20 | 21 | volatile uint8_t flag_got_rx; 22 | volatile uint8_t flag_got_tx; 23 | 24 | static rx_info_t rx_info; 25 | static tx_info_t tx_info; 26 | 27 | 28 | /** 29 | * Constructor MRF24J Object. 30 | * @param pin_reset, @param pin_chip_select, @param pin_interrupt 31 | */ 32 | Mrf24j::Mrf24j(int pin_reset, int pin_chip_select, int pin_interrupt) { 33 | _pin_reset = pin_reset; 34 | _pin_cs = pin_chip_select; 35 | _pin_int = pin_interrupt; 36 | 37 | pinMode(_pin_reset, OUTPUT); 38 | pinMode(_pin_cs, OUTPUT); 39 | pinMode(_pin_int, INPUT); 40 | 41 | SPI.setBitOrder(MSBFIRST) ; 42 | SPI.setDataMode(SPI_MODE0); 43 | SPI.begin(); 44 | } 45 | 46 | void Mrf24j::reset(void) { 47 | digitalWrite(_pin_reset, LOW); 48 | delay(10); // just my gut 49 | digitalWrite(_pin_reset, HIGH); 50 | delay(20); // from manual 51 | } 52 | 53 | byte Mrf24j::read_short(byte address) { 54 | digitalWrite(_pin_cs, LOW); 55 | // 0 top for short addressing, 0 bottom for read 56 | SPI.transfer(address<<1 & 0b01111110); 57 | byte ret = SPI.transfer(0x00); 58 | digitalWrite(_pin_cs, HIGH); 59 | return ret; 60 | } 61 | 62 | byte Mrf24j::read_long(word address) { 63 | digitalWrite(_pin_cs, LOW); 64 | byte ahigh = address >> 3; 65 | byte alow = address << 5; 66 | SPI.transfer(0x80 | ahigh); // high bit for long 67 | SPI.transfer(alow); 68 | byte ret = SPI.transfer(0); 69 | digitalWrite(_pin_cs, HIGH); 70 | return ret; 71 | } 72 | 73 | 74 | void Mrf24j::write_short(byte address, byte data) { 75 | digitalWrite(_pin_cs, LOW); 76 | // 0 for top short address, 1 bottom for write 77 | SPI.transfer((address<<1 & 0b01111110) | 0x01); 78 | SPI.transfer(data); 79 | digitalWrite(_pin_cs, HIGH); 80 | } 81 | 82 | void Mrf24j::write_long(word address, byte data) { 83 | digitalWrite(_pin_cs, LOW); 84 | byte ahigh = address >> 3; 85 | byte alow = address << 5; 86 | SPI.transfer(0x80 | ahigh); // high bit for long 87 | SPI.transfer(alow | 0x10); // last bit for write 88 | SPI.transfer(data); 89 | digitalWrite(_pin_cs, HIGH); 90 | } 91 | 92 | word Mrf24j::get_pan(void) { 93 | byte panh = read_short(MRF_PANIDH); 94 | return panh << 8 | read_short(MRF_PANIDL); 95 | } 96 | 97 | void Mrf24j::set_pan(word panid) { 98 | write_short(MRF_PANIDH, panid >> 8); 99 | write_short(MRF_PANIDL, panid & 0xff); 100 | } 101 | 102 | void Mrf24j::address16_write(word address16) { 103 | write_short(MRF_SADRH, address16 >> 8); 104 | write_short(MRF_SADRL, address16 & 0xff); 105 | } 106 | 107 | word Mrf24j::address16_read(void) { 108 | byte a16h = read_short(MRF_SADRH); 109 | return a16h << 8 | read_short(MRF_SADRL); 110 | } 111 | 112 | /** 113 | * Simple send 16, with acks, not much of anything.. assumes src16 and local pan only. 114 | * @param data 115 | */ 116 | void Mrf24j::send16(word dest16, char * data) { 117 | byte len = strlen(data); // get the length of the char* array 118 | int i = 0; 119 | write_long(i++, bytes_MHR); // header length 120 | // +ignoreBytes is because some module seems to ignore 2 bytes after the header?!. 121 | // default: ignoreBytes = 0; 122 | write_long(i++, bytes_MHR+ignoreBytes+len); 123 | 124 | // 0 | pan compression | ack | no security | no data pending | data frame[3 bits] 125 | write_long(i++, 0b01100001); // first byte of Frame Control 126 | // 16 bit source, 802.15.4 (2003), 16 bit dest, 127 | write_long(i++, 0b10001000); // second byte of frame control 128 | write_long(i++, 1); // sequence number 1 129 | 130 | word panid = get_pan(); 131 | 132 | write_long(i++, panid & 0xff); // dest panid 133 | write_long(i++, panid >> 8); 134 | write_long(i++, dest16 & 0xff); // dest16 low 135 | write_long(i++, dest16 >> 8); // dest16 high 136 | 137 | word src16 = address16_read(); 138 | write_long(i++, src16 & 0xff); // src16 low 139 | write_long(i++, src16 >> 8); // src16 high 140 | 141 | // All testing seems to indicate that the next two bytes are ignored. 142 | //2 bytes on FCS appended by TXMAC 143 | i+=ignoreBytes; 144 | for (int q = 0; q < len; q++) { 145 | write_long(i++, data[q]); 146 | } 147 | // ack on, and go! 148 | write_short(MRF_TXNCON, (1<> 6; 241 | tx_info.channel_busy = (tmp & (1 << CCAFAIL)); 242 | } 243 | } 244 | 245 | 246 | /** 247 | * Call this function periodically, it will invoke your nominated handlers 248 | */ 249 | void Mrf24j::check_flags(void (*rx_handler)(void), void (*tx_handler)(void)){ 250 | // TODO - we could check whether the flags are > 1 here, indicating data was lost? 251 | if (flag_got_rx) { 252 | flag_got_rx = 0; 253 | rx_handler(); 254 | } 255 | if (flag_got_tx) { 256 | flag_got_tx = 0; 257 | tx_handler(); 258 | } 259 | } 260 | 261 | /** 262 | * Set RX mode to promiscuous, or normal 263 | */ 264 | void Mrf24j::set_promiscuous(boolean enabled) { 265 | if (enabled) { 266 | write_short(MRF_RXMCR, 0x01); 267 | } else { 268 | write_short(MRF_RXMCR, 0x00); 269 | } 270 | } 271 | 272 | rx_info_t * Mrf24j::get_rxinfo(void) { 273 | return &rx_info; 274 | } 275 | 276 | tx_info_t * Mrf24j::get_txinfo(void) { 277 | return &tx_info; 278 | } 279 | 280 | uint8_t * Mrf24j::get_rxbuf(void) { 281 | return rx_buf; 282 | } 283 | 284 | int Mrf24j::rx_datalength(void) { 285 | return rx_info.frame_length - bytes_nodata; 286 | } 287 | 288 | void Mrf24j::set_ignoreBytes(int ib) { 289 | // some modules behaviour 290 | ignoreBytes = ib; 291 | } 292 | 293 | /** 294 | * Set bufPHY flag to buffer all bytes in PHY Payload, or not 295 | */ 296 | void Mrf24j::set_bufferPHY(boolean bp) { 297 | bufPHY = bp; 298 | } 299 | 300 | boolean Mrf24j::get_bufferPHY(void) { 301 | return bufPHY; 302 | } 303 | 304 | /** 305 | * Set PA/LNA external control 306 | */ 307 | void Mrf24j::set_palna(boolean enabled) { 308 | if (enabled) { 309 | write_long(MRF_TESTMODE, 0x07); // Enable PA/LNA on MRF24J40MB module. 310 | }else{ 311 | write_long(MRF_TESTMODE, 0x00); // Disable PA/LNA on MRF24J40MB module. 312 | } 313 | } 314 | 315 | void Mrf24j::rx_flush(void) { 316 | write_short(MRF_RXFLUSH, 0x01); 317 | } 318 | 319 | void Mrf24j::rx_disable(void) { 320 | write_short(MRF_BBREG1, 0x04); // RXDECINV - disable receiver 321 | } 322 | 323 | void Mrf24j::rx_enable(void) { 324 | write_short(MRF_BBREG1, 0x00); // RXDECINV - enable receiver 325 | } 326 | -------------------------------------------------------------------------------- /mrf24j.h: -------------------------------------------------------------------------------- 1 | /* 2 | * File: mrf24j.h 3 | * copyright Karl Palsson, karlp@tweak.net.au, 2011 4 | * modified BSD License / apache license 5 | */ 6 | 7 | #ifndef LIB_MRF24J_H 8 | #define LIB_MRF24J_H 9 | 10 | #if defined(ARDUINO) && ARDUINO >= 100 // Arduino IDE version >= 1.0 11 | #include "Arduino.h" 12 | #else // older Arduino IDE versions 13 | #include "WProgram.h" 14 | #endif 15 | #include "SPI.h" 16 | 17 | 18 | #define MRF_RXMCR 0x00 19 | #define MRF_PANIDL 0x01 20 | #define MRF_PANIDH 0x02 21 | #define MRF_SADRL 0x03 22 | #define MRF_SADRH 0x04 23 | #define MRF_EADR0 0x05 24 | #define MRF_EADR1 0x06 25 | #define MRF_EADR2 0x07 26 | #define MRF_EADR3 0x08 27 | #define MRF_EADR4 0x09 28 | #define MRF_EADR5 0x0A 29 | #define MRF_EADR6 0x0B 30 | #define MRF_EADR7 0x0C 31 | #define MRF_RXFLUSH 0x0D 32 | //#define MRF_Reserved 0x0E 33 | //#define MRF_Reserved 0x0F 34 | #define MRF_ORDER 0x10 35 | #define MRF_TXMCR 0x11 36 | #define MRF_ACKTMOUT 0x12 37 | #define MRF_ESLOTG1 0x13 38 | #define MRF_SYMTICKL 0x14 39 | #define MRF_SYMTICKH 0x15 40 | #define MRF_PACON0 0x16 41 | #define MRF_PACON1 0x17 42 | #define MRF_PACON2 0x18 43 | //#define MRF_Reserved 0x19 44 | #define MRF_TXBCON0 0x1A 45 | 46 | // TXNCON: TRANSMIT NORMAL FIFO CONTROL REGISTER (ADDRESS: 0x1B) 47 | #define MRF_TXNCON 0x1B 48 | #define MRF_TXNTRIG 0 49 | #define MRF_TXNSECEN 1 50 | #define MRF_TXNACKREQ 2 51 | #define MRF_INDIRECT 3 52 | #define MRF_FPSTAT 4 53 | 54 | #define MRF_TXG1CON 0x1C 55 | #define MRF_TXG2CON 0x1D 56 | #define MRF_ESLOTG23 0x1E 57 | #define MRF_ESLOTG45 0x1F 58 | #define MRF_ESLOTG67 0x20 59 | #define MRF_TXPEND 0x21 60 | #define MRF_WAKECON 0x22 61 | #define MRF_FRMOFFSET 0x23 62 | // TXSTAT: TX MAC STATUS REGISTER (ADDRESS: 0x24) 63 | #define MRF_TXSTAT 0x24 64 | #define TXNRETRY1 7 65 | #define TXNRETRY0 6 66 | #define CCAFAIL 5 67 | #define TXG2FNT 4 68 | #define TXG1FNT 3 69 | #define TXG2STAT 2 70 | #define TXG1STAT 1 71 | #define TXNSTAT 0 72 | 73 | #define MRF_TXBCON1 0x25 74 | #define MRF_GATECLK 0x26 75 | #define MRF_TXTIME 0x27 76 | #define MRF_HSYMTMRL 0x28 77 | #define MRF_HSYMTMRH 0x29 78 | #define MRF_SOFTRST 0x2A 79 | //#define MRF_Reserved 0x2B 80 | #define MRF_SECCON0 0x2C 81 | #define MRF_SECCON1 0x2D 82 | #define MRF_TXSTBL 0x2E 83 | //#define MRF_Reserved 0x2F 84 | #define MRF_RXSR 0x30 85 | #define MRF_INTSTAT 0x31 86 | #define MRF_INTCON 0x32 87 | #define MRF_GPIO 0x33 88 | #define MRF_TRISGPIO 0x34 89 | #define MRF_SLPACK 0x35 90 | #define MRF_RFCTL 0x36 91 | #define MRF_SECCR2 0x37 92 | #define MRF_BBREG0 0x38 93 | #define MRF_BBREG1 0x39 94 | #define MRF_BBREG2 0x3A 95 | #define MRF_BBREG3 0x3B 96 | #define MRF_BBREG4 0x3C 97 | //#define MRF_Reserved 0x3D 98 | #define MRF_BBREG6 0x3E 99 | #define MRF_CCAEDTH 0x3F 100 | 101 | #define MRF_RFCON0 0x200 102 | #define MRF_RFCON1 0x201 103 | #define MRF_RFCON2 0x202 104 | #define MRF_RFCON3 0x203 105 | #define MRF_RFCON5 0x205 106 | #define MRF_RFCON6 0x206 107 | #define MRF_RFCON7 0x207 108 | #define MRF_RFCON8 0x208 109 | #define MRF_SLPCAL0 0x209 110 | #define MRF_SLPCAL1 0x20A 111 | #define MRF_SLPCAL2 0x20B 112 | #define MRF_RSSI 0x210 113 | #define MRF_SLPCON0 0x211 114 | #define MRF_SLPCON1 0x220 115 | #define MRF_WAKETIMEL 0x222 116 | #define MRF_WAKETIMEH 0x223 117 | #define MRF_REMCNTL 0x224 118 | #define MRF_REMCNTH 0x225 119 | #define MRF_MAINCNT0 0x226 120 | #define MRF_MAINCNT1 0x227 121 | #define MRF_MAINCNT2 0x228 122 | #define MRF_MAINCNT3 0x229 123 | #define MRF_TESTMODE 0x22F 124 | #define MRF_ASSOEADR1 0x231 125 | #define MRF_ASSOEADR2 0x232 126 | #define MRF_ASSOEADR3 0x233 127 | #define MRF_ASSOEADR4 0x234 128 | #define MRF_ASSOEADR5 0x235 129 | #define MRF_ASSOEADR6 0x236 130 | #define MRF_ASSOEADR7 0x237 131 | #define MRF_ASSOSADR0 0x238 132 | #define MRF_ASSOSADR1 0x239 133 | #define MRF_UPNONCE0 0x240 134 | #define MRF_UPNONCE1 0x241 135 | #define MRF_UPNONCE2 0x242 136 | #define MRF_UPNONCE3 0x243 137 | #define MRF_UPNONCE4 0x244 138 | #define MRF_UPNONCE5 0x245 139 | #define MRF_UPNONCE6 0x246 140 | #define MRF_UPNONCE7 0x247 141 | #define MRF_UPNONCE8 0x248 142 | #define MRF_UPNONCE9 0x249 143 | #define MRF_UPNONCE10 0x24A 144 | #define MRF_UPNONCE11 0x24B 145 | #define MRF_UPNONCE12 0x24C 146 | 147 | #define MRF_I_RXIF 0b00001000 148 | #define MRF_I_TXNIF 0b00000001 149 | 150 | typedef struct _rx_info_t{ 151 | uint8_t frame_length; 152 | uint8_t rx_data[116]; //max data length = (127 aMaxPHYPacketSize - 2 Frame control - 1 sequence number - 2 panid - 2 shortAddr Destination - 2 shortAddr Source - 2 FCS) 153 | uint8_t lqi; 154 | uint8_t rssi; 155 | } rx_info_t; 156 | 157 | /** 158 | * Based on the TXSTAT register, but "better" 159 | */ 160 | typedef struct _tx_info_t{ 161 | uint8_t tx_ok:1; 162 | uint8_t retries:2; 163 | uint8_t channel_busy:1; 164 | } tx_info_t; 165 | 166 | class Mrf24j 167 | { 168 | public: 169 | Mrf24j(int pin_reset, int pin_chip_select, int pin_interrupt); 170 | void reset(void); 171 | void init(void); 172 | 173 | byte read_short(byte address); 174 | byte read_long(word address); 175 | 176 | void write_short(byte address, byte data); 177 | void write_long(word address, byte data); 178 | 179 | word get_pan(void); 180 | void set_pan(word panid); 181 | 182 | void address16_write(word address16); 183 | word address16_read(void); 184 | 185 | void set_interrupts(void); 186 | 187 | void set_promiscuous(boolean enabled); 188 | 189 | /** 190 | * Set the channel, using 802.15.4 channel numbers (11..26) 191 | */ 192 | void set_channel(byte channel); 193 | 194 | void rx_enable(void); 195 | void rx_disable(void); 196 | 197 | /** If you want to throw away rx data */ 198 | void rx_flush(void); 199 | 200 | rx_info_t * get_rxinfo(void); 201 | 202 | tx_info_t * get_txinfo(void); 203 | 204 | uint8_t * get_rxbuf(void); 205 | 206 | int rx_datalength(void); 207 | 208 | void set_ignoreBytes(int ib); 209 | 210 | /** 211 | * Set bufPHY flag to buffer all bytes in PHY Payload, or not 212 | */ 213 | void set_bufferPHY(boolean bp); 214 | 215 | boolean get_bufferPHY(void); 216 | 217 | /** 218 | * Set PA/LNA external control 219 | */ 220 | void set_palna(boolean enabled); 221 | 222 | void send16(word dest16, char * data); 223 | 224 | void interrupt_handler(void); 225 | 226 | void check_flags(void (*rx_handler)(void), void (*tx_handler)(void)); 227 | 228 | private: 229 | int _pin_reset; 230 | int _pin_cs; 231 | int _pin_int; 232 | }; 233 | 234 | #endif /* LIB_MRF24J_H */ 235 | --------------------------------------------------------------------------------