/** * mrf24j.cpp, Karl Palsson, 2011, karlp@tweak.net.au * modifed bsd license / apache license */ #include "WProgram.h" #include "mrf24j.h" Mrf24j::Mrf24j(int pin_reset, int pin_chip_select, int pin_interrupt) { _pin_reset = pin_reset; _pin_cs = pin_chip_select; _pin_int = pin_interrupt; pinMode(_pin_reset, OUTPUT); pinMode(_pin_cs, OUTPUT); pinMode(_pin_int, INPUT); SPI.begin(); // arguably should not be here... reset(); init(); } void Mrf24j::reset(void) { digitalWrite(_pin_reset, LOW); delay(10); // just my gut digitalWrite(_pin_reset, HIGH); delay(20); // from manual } byte Mrf24j::read_short(byte address) { digitalWrite(_pin_cs, LOW); // 0 top for short addressing, 0 bottom for read SPI.transfer(address<<1 & 0b01111110); byte ret = SPI.transfer(0x0); digitalWrite(_pin_cs, HIGH); return ret; } byte Mrf24j::read_long(word address) { digitalWrite(_pin_cs, LOW); byte ahigh = address >> 3; byte alow = address << 5; SPI.transfer(0x80 | ahigh); // high bit for long SPI.transfer(alow); byte ret = SPI.transfer(0); digitalWrite(_pin_cs, HIGH); return ret; } void Mrf24j::write_short(byte address, byte data) { digitalWrite(_pin_cs, LOW); // 0 for top address, 1 bottom for write SPI.transfer((address<<1 & 0b01111110) | 0x01); SPI.transfer(data); digitalWrite(_pin_cs, HIGH); } void Mrf24j::write_long(word address, byte data) { digitalWrite(_pin_cs, LOW); byte ahigh = address >> 3; byte alow = address << 5; SPI.transfer(0x80 | ahigh); // high bit for long SPI.transfer(alow | 0x10); // last bit for write SPI.transfer(data); digitalWrite(_pin_cs, HIGH); } word Mrf24j::get_pan(void) { byte panh = read_short(MRF_PANIDH); return panh << 8 | read_short(MRF_PANIDL); } void Mrf24j::set_pan(word panid) { write_short(MRF_PANIDH, panid >> 8); write_short(MRF_PANIDL, panid & 0xff); } void Mrf24j::address16_write(word address16) { write_short(MRF_SADRH, address16 >> 8); write_short(MRF_SADRL, address16 & 0xff); } word Mrf24j::address16_read(void) { byte a16h = read_short(MRF_SADRH); return a16h << 8 | read_short(MRF_SADRL); } /** * Simple send 16, with acks, not much of anything.. assumes src16 and local pan only. * @param data */ void Mrf24j::send16(word dest16, byte len, char * data) { int i = 0; write_long(i++, 9); // header length write_long(i++, 9+2+len); //+2 is because module seems to ignore 2 bytes after the header?! // 0 | pan compression | ack | no security | no data pending | data frame[3 bits] write_long(i++, 0b01100001); // first byte of Frame Control // 16 bit source, 802.15.4 (2003), 16 bit dest, write_long(i++, 0b10001000); // second byte of frame control write_long(i++, 1); // sequence number 1 word panid = get_pan(); write_long(i++, panid & 0xff); // dest panid write_long(i++, panid >> 8); write_long(i++, dest16 & 0xff); // dest16 low write_long(i++, dest16 >> 8); // dest16 high word src16 = address16_read(); write_long(i++, src16 & 0xff); // src16 low write_long(i++, src16 >> 8); // src16 high i+=2; // All testing seems to indicate that the next two bytes are ignored. for (int q = 0; q < len; q++) { write_long(i++, data[q]); } // ack on, and go! write_short(MRF_TXNCON, (1<