commit 19edd271b94d853d39aee70ab67d6e5c464433ec
Author: Karl Palsson <github@tweak.net.au>
Date:   Sun Mar 13 17:33:58 2011 +0000

    Initial basic version of my arduino mrf24j40 library

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<<MRF_TXNACKREQ | 1<<MRF_TXNTRIG));
+}
+
+void Mrf24j::mrf_set_interrupts(void) {
+    // interrupts for rx and tx normal complete
+    mrf_write_short(MRF_INTCON, 0b11110110);
+}
+
+// Set the channel to 12, 2.41Ghz, xbee channel 0xC
+void Mrf24j::mrf_set_channel(void) {
+    mrf_write_long(MRF_RFCON0, 0x13);
+}
+
+void Mrf24j::mrf_init(void) {
+/*
+ // Seems a bit ridiculous when I use reset pin anyway
+    mrf_write_short(MRF_SOFTRST, 0x7); // from manual
+    while (mrf_read_short(MRF_SOFTRST) & 0x7 != 0) {
+        ; // wait for soft reset to finish
+    }
+*/
+    mrf_write_short(MRF_PACON2, 0x98); // – Initialize FIFOEN = 1 and TXONTS = 0x6.
+    mrf_write_short(MRF_TXSTBL, 0x95); // – Initialize RFSTBL = 0x9.
+
+    mrf_write_long(MRF_RFCON0, 0x03); // – Initialize RFOPT = 0x03.
+    mrf_write_long(MRF_RFCON1, 0x01); // – Initialize VCOOPT = 0x02.
+    mrf_write_long(MRF_RFCON2, 0x80); // – Enable PLL (PLLEN = 1).
+    mrf_write_long(MRF_RFCON6, 0x90); // – Initialize TXFIL = 1 and 20MRECVR = 1.
+    mrf_write_long(MRF_RFCON7, 0x80); // – Initialize SLPCLKSEL = 0x2 (100 kHz Internal oscillator).
+    mrf_write_long(MRF_RFCON8, 0x10); // – Initialize RFVCO = 1.
+    mrf_write_long(MRF_SLPCON1, 0x21); // – Initialize CLKOUTEN = 1 and SLPCLKDIV = 0x01.
+
+    //  Configuration for nonbeacon-enabled devices (see Section 3.8 “Beacon-Enabled and
+    //  Nonbeacon-Enabled Networks”):
+    mrf_write_short(MRF_BBREG2, 0x80); // Set CCA mode to ED
+    mrf_write_short(MRF_CCAEDTH, 0x60); // – Set CCA ED threshold.
+    mrf_write_short(MRF_BBREG6, 0x40); // – Set appended RSSI value to RXFIFO.
+    mrf_set_interrupts();
+    mrf_set_channel();
+    // max power is by default.. just leave it...
+    //Set transmitter power - See “REGISTER 2-62: RF CONTROL 3 REGISTER (ADDRESS: 0x203)”.
+    mrf_write_short(MRF_RFCTL, 0x04); //  – Reset RF state machine.
+    mrf_write_short(MRF_RFCTL, 0x00); // part 2
+    delay(1); // delay at least 192usec
+}
+
+
+
diff --git a/mrf24j.h b/mrf24j.h
new file mode 100644
index 0000000..6a5799f
--- /dev/null
+++ b/mrf24j.h
@@ -0,0 +1,184 @@
+/* 
+ * File:   mrf24j.h
+ * copyright Karl Palsson, karlp@tweak.net.au, 2011
+ * modified BSD License / apache license
+ */
+
+#ifndef LIB_MRF24J_H
+#define LIB_MRF24J_H
+
+#include "WProgram.h"
+#include "SPI.h"
+
+
+#define MRF_RXMCR 0x00
+#define MRF_PANIDL 0x01
+#define MRF_PANIDH 0x02
+#define MRF_SADRL 0x03
+#define MRF_SADRH 0x04
+#define MRF_EADR0 0x05
+#define MRF_EADR1 0x06
+#define MRF_EADR2 0x07
+#define MRF_EADR3 0x08
+#define MRF_EADR4 0x09
+#define MRF_EADR5 0x0A
+#define MRF_EADR6 0x0B
+#define MRF_EADR7 0x0C
+#define MRF_RXFLUSH 0x0D
+//#define MRF_Reserved 0x0E
+//#define MRF_Reserved 0x0F
+#define MRF_ORDER 0x10
+#define MRF_TXMCR 0x11
+#define MRF_ACKTMOUT 0x12
+#define MRF_ESLOTG1 0x13
+#define MRF_SYMTICKL 0x14
+#define MRF_SYMTICKH 0x15
+#define MRF_PACON0 0x16
+#define MRF_PACON1 0x17
+#define MRF_PACON2 0x18
+//#define MRF_Reserved 0x19
+#define MRF_TXBCON0 0x1A
+
+// TXNCON: TRANSMIT NORMAL FIFO CONTROL REGISTER (ADDRESS: 0x1B)
+#define MRF_TXNCON      0x1B
+#define MRF_TXNTRIG     0
+#define MRF_TXNSECEN    1
+#define MRF_TXNACKREQ   2
+#define MRF_INDIRECT    3
+#define MRF_FPSTAT      4
+
+#define MRF_TXG1CON 0x1C
+#define MRF_TXG2CON 0x1D
+#define MRF_ESLOTG23 0x1E
+#define MRF_ESLOTG45 0x1F
+#define MRF_ESLOTG67 0x20
+#define MRF_TXPEND 0x21
+#define MRF_WAKECON 0x22
+#define MRF_FRMOFFSET 0x23
+// TXSTAT: TX MAC STATUS REGISTER (ADDRESS: 0x24)
+#define MRF_TXSTAT 0x24
+#define TXNRETRY1       7
+#define TXNRETRY0       6
+#define CCAFAIL         5
+#define TXG2FNT         4
+#define TXG1FNT         3
+#define TXG2STAT        2
+#define TXG1STAT        1
+#define TXNSTAT         0
+
+#define MRF_TXBCON1 0x25
+#define MRF_GATECLK 0x26
+#define MRF_TXTIME 0x27
+#define MRF_HSYMTMRL 0x28
+#define MRF_HSYMTMRH 0x29
+#define MRF_SOFTRST 0x2A
+//#define MRF_Reserved 0x2B
+#define MRF_SECCON0 0x2C
+#define MRF_SECCON1 0x2D
+#define MRF_TXSTBL 0x2E
+//#define MRF_Reserved 0x2F
+#define MRF_RXSR 0x30
+#define MRF_INTSTAT 0x31
+#define MRF_INTCON 0x32
+#define MRF_GPIO 0x33
+#define MRF_TRISGPIO 0x34
+#define MRF_SLPACK 0x35
+#define MRF_RFCTL 0x36
+#define MRF_SECCR2 0x37
+#define MRF_BBREG0 0x38
+#define MRF_BBREG1 0x39
+#define MRF_BBREG2 0x3A
+#define MRF_BBREG3 0x3B
+#define MRF_BBREG4 0x3C
+//#define MRF_Reserved 0x3D
+#define MRF_BBREG6 0x3E
+#define MRF_CCAEDTH 0x3F
+
+#define MRF_RFCON0 0x200
+#define MRF_RFCON1 0x201
+#define MRF_RFCON2 0x202
+#define MRF_RFCON3 0x203
+#define MRF_RFCON5 0x205
+#define MRF_RFCON6 0x206
+#define MRF_RFCON7 0x207
+#define MRF_RFCON8 0x208
+#define MRF_SLPCAL0 0x209
+#define MRF_SLPCAL1 0x20A
+#define MRF_SLPCAL2 0x20B
+#define MRF_RSSI 0x210
+#define MRF_SLPCON0 0x211
+#define MRF_SLPCON1 0x220
+#define MRF_WAKETIMEL 0x222
+#define MRF_WAKETIMEH 0x223
+#define MRF_REMCNTL 0x224
+#define MRF_REMCNTH 0x225
+#define MRF_MAINCNT0 0x226
+#define MRF_MAINCNT1 0x227
+#define MRF_MAINCNT2 0x228
+#define MRF_MAINCNT3 0x229
+#define MRF_TESTMODE 0x22F
+#define MRF_ASSOEADR1 0x231
+#define MRF_ASSOEADR2 0x232
+#define MRF_ASSOEADR3 0x233
+#define MRF_ASSOEADR4 0x234
+#define MRF_ASSOEADR5 0x235
+#define MRF_ASSOEADR6 0x236
+#define MRF_ASSOEADR7 0x237
+#define MRF_ASSOSADR0 0x238
+#define MRF_ASSOSADR1 0x239
+#define MRF_UPNONCE0 0x240
+#define MRF_UPNONCE1 0x241
+#define MRF_UPNONCE2 0x242
+#define MRF_UPNONCE3 0x243
+#define MRF_UPNONCE4 0x244
+#define MRF_UPNONCE5 0x245
+#define MRF_UPNONCE6 0x246
+#define MRF_UPNONCE7 0x247
+#define MRF_UPNONCE8 0x248
+#define MRF_UPNONCE9 0x249
+#define MRF_UPNONCE10 0x24A
+#define MRF_UPNONCE11 0x24B
+#define MRF_UPNONCE12 0x24C
+
+#define MRF_I_RXIF  0b00001000
+#define MRF_I_TXNIF 0b00000001
+
+
+class Mrf24j
+{
+
+public:
+Mrf24j(int pin_reset, int pin_chip_select, int pin_interrupt);
+void mrf_reset(void);
+void mrf_init(void);
+
+byte mrf_read_short(byte address);
+byte mrf_read_long(word address);
+
+void mrf_write_short(byte address, byte data);
+void mrf_write_long(word address, byte data);
+
+word mrf_pan_read(void);
+void mrf_pan_write(word panid);
+
+void mrf_address16_write(word address16);
+word mrf_address16_read(void);
+
+void mrf_set_interrupts(void);
+
+// Set the channel to 12, 2.41Ghz, xbee channel 0xC
+void mrf_set_channel(void);
+
+void mrf_send16(word dest16, byte len, char * data);
+
+private:
+    int _pin_reset;
+    int _pin_cs;
+    int _pin_int;
+
+
+};
+
+#endif  /* LIB_MRF24J_H */
+
+