From 19edd271b94d853d39aee70ab67d6e5c464433ec Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Sun, 13 Mar 2011 17:33:58 +0000 Subject: [PATCH] Initial basic version of my arduino mrf24j40 library --- mrf24j.cpp | 171 +++++++++++++++++++++++++++++++++++++++++++++++++ mrf24j.h | 184 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 355 insertions(+) create mode 100644 mrf24j.cpp create mode 100644 mrf24j.h diff --git a/mrf24j.cpp b/mrf24j.cpp new file mode 100644 index 0000000..27964be --- /dev/null +++ b/mrf24j.cpp @@ -0,0 +1,171 @@ +/** + * 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... + mrf_reset(); + mrf_init(); +} + +void Mrf24j::mrf_reset(void) { + digitalWrite(_pin_reset, LOW); + delay(10); // just my gut + digitalWrite(_pin_reset, HIGH); + delay(20); // from manual +} + +byte Mrf24j::mrf_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::mrf_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::mrf_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::mrf_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::mrf_pan_read(void) { + byte panh = mrf_read_short(MRF_PANIDH); + return panh << 8 | mrf_read_short(MRF_PANIDL); +} + +void Mrf24j::mrf_pan_write(word panid) { + mrf_write_short(MRF_PANIDH, panid >> 8); + mrf_write_short(MRF_PANIDL, panid & 0xff); +} + +void Mrf24j::mrf_address16_write(word address16) { + mrf_write_short(MRF_SADRH, address16 >> 8); + mrf_write_short(MRF_SADRL, address16 & 0xff); +} + +word Mrf24j::mrf_address16_read(void) { + byte a16h = mrf_read_short(MRF_SADRH); + return a16h << 8 | mrf_read_short(MRF_SADRL); +} + +/** + * Simple send 16, with acks, not much of anything.. assumes src16 and local pan only. + * @param data + */ +void Mrf24j::mrf_send16(word dest16, byte len, char * data) { + + int i = 0; + mrf_write_long(i++, 9); // header length + mrf_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] + mrf_write_long(i++, 0b01100001); // first byte of Frame Control +// 16 bit source, 802.15.4 (2003), 16 bit dest, + mrf_write_long(i++, 0b10001000); // second byte of frame control + mrf_write_long(i++, 1); // sequence number 1 + + word panid = mrf_pan_read(); + + mrf_write_long(i++, panid & 0xff); // dest panid + mrf_write_long(i++, panid >> 8); + mrf_write_long(i++, dest16 & 0xff); // dest16 low + mrf_write_long(i++, dest16 >> 8); // dest16 high + + word src16 = mrf_address16_read(); + mrf_write_long(i++, src16 & 0xff); // src16 low + mrf_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++) { + mrf_write_long(i++, data[q]); + } + // ack on, and go! + mrf_write_short(MRF_TXNCON, (1<