commit 0a48d7b3c7de1231afae0ccb306f74b04292839c
Author: Jimmy <me@jimmy.nz>
Date:   Fri Aug 21 10:27:08 2020 +1200

    It works

diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json
new file mode 100644
index 0000000..b57f039
--- /dev/null
+++ b/.vscode/c_cpp_properties.json
@@ -0,0 +1,20 @@
+{
+    "configurations": [
+        {
+            "name": "linux",
+            "includePath": [
+                "${workspaceFolder}/**",
+                "/usr/lib/avr/include/"
+            ],
+            "defines": [
+                "__AVR_ATmega32__",
+                "F_CPU 8000000"
+            ],
+            "compilerPath": "/usr/bin/avr-g++",
+            "cStandard": "gnu11",
+            "cppStandard": "gnu++14",
+            "intelliSenseMode": "clang-x64"
+        }
+    ],
+    "version": 4
+}
\ No newline at end of file
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..3b66410
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,3 @@
+{
+    "git.ignoreLimitWarning": true
+}
\ No newline at end of file
diff --git a/lib/mrf24j.cpp b/lib/mrf24j.cpp
new file mode 100644
index 0000000..c3bf419
--- /dev/null
+++ b/lib/mrf24j.cpp
@@ -0,0 +1,318 @@
+/**
+ * mrf24j.cpp, Karl Palsson, 2011, karlp@tweak.net.au
+ * modified bsd license / apache license
+ */
+
+#include "mrf24j.h"
+#include <avr/io.h>
+#include <util/delay.h>
+#include <string.h>
+#include <avr/interrupt.h>
+#include "spi.h"
+
+
+// aMaxPHYPacketSize = 127, from the 802.15.4-2006 standard.
+static uint8_t rx_buf[127];
+
+// essential for obtaining the data frame only
+// bytes_MHR = 2 Frame control + 1 sequence number + 2 panid + 2 shortAddr Destination + 2 shortAddr Source
+static int bytes_MHR = 9;
+static int bytes_FCS = 2; // FCS length = 2
+static int bytes_nodata = bytes_MHR + bytes_FCS; // no_data bytes in PHY payload,  header length + FCS
+
+static int ignoreBytes = 0; // bytes to ignore, some modules behaviour.
+
+static bool bufPHY = false; // flag to buffer all bytes in PHY Payload, or not
+
+volatile uint8_t flag_got_rx;
+volatile uint8_t flag_got_tx;
+
+static rx_info_t rx_info;
+static tx_info_t tx_info;
+
+
+void Mrf24j::reset(void) {
+    RESET_PORT &= ~(1<<RESET_PIN);
+    _delay_ms(10);  // just my gut
+    RESET_PORT |= (1<<RESET_PIN);
+    _delay_ms(20);  // from manual
+}
+
+byte Mrf24j::read_short(byte address) {
+    spi::cs_low();
+    //spi::cs_low();
+    // 0 top for short addressing, 0 bottom for read
+    //spi::transfer(address<<1 & 0b01111110);
+    spi::transfer(address<<1 & 0b01111110);
+    byte ret = spi::transfer(0x00);
+    spi::cs_high();
+    spi::cs_high();
+    return ret;
+}
+
+byte Mrf24j::read_long(word address) {
+    spi::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);
+    spi::cs_high();
+    return ret;
+}
+
+
+void Mrf24j::write_short(byte address, byte data) {
+    spi::cs_low();
+    // 0 for top short address, 1 bottom for write
+    spi::transfer((address<<1 & 0b01111110) | 0x01);
+    spi::transfer(data);
+    spi::cs_high();
+}
+
+void Mrf24j::write_long(word address, byte data) {
+    spi::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);
+    spi::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, char * data) {
+    byte len = strlen(data); // get the length of the char* array
+    int i = 0;
+    write_long(i++, bytes_MHR); // header length
+    // +ignoreBytes is because some module seems to ignore 2 bytes after the header?!.
+    // default: ignoreBytes = 0;
+    write_long(i++, bytes_MHR+ignoreBytes+len);
+
+    // 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
+
+    // All testing seems to indicate that the next two bytes are ignored.
+    //2 bytes on FCS appended by TXMAC
+    i+=ignoreBytes;
+    for (int q = 0; q < len; q++) {
+        write_long(i++, data[q]);
+    }
+    // ack on, and go!
+    write_short(MRF_TXNCON, (1<<MRF_TXNACKREQ | 1<<MRF_TXNTRIG));
+}
+
+void Mrf24j::set_interrupts(void) {
+    // interrupts for rx and tx normal complete
+    write_short(MRF_INTCON, 0b11110110);
+}
+
+/** use the 802.15.4 channel numbers..
+ */
+void Mrf24j::set_channel(byte channel) {
+    write_long(MRF_RFCON0, (((channel - 11) << 4) | 0x03));
+}
+
+void Mrf24j::init(void) {
+    RESET_DDR |= (1<<RESET_PIN);
+    /*
+    // Seems a bit ridiculous when I use reset pin anyway
+    write_short(MRF_SOFTRST, 0x7); // from manual
+    while (read_short(MRF_SOFTRST) & 0x7 != 0) {
+        ; // wait for soft reset to finish
+    }
+    */
+    write_short(MRF_PACON2, 0x98); // – Initialize FIFOEN = 1 and TXONTS = 0x6.
+    write_short(MRF_TXSTBL, 0x95); // – Initialize RFSTBL = 0x9.
+
+    write_long(MRF_RFCON0, 0x03); // – Initialize RFOPT = 0x03.
+    write_long(MRF_RFCON1, 0x01); // – Initialize VCOOPT = 0x02.
+    write_long(MRF_RFCON2, 0x80); // – Enable PLL (PLLEN = 1).
+    write_long(MRF_RFCON6, 0x90); // – Initialize TXFIL = 1 and 20MRECVR = 1.
+    write_long(MRF_RFCON7, 0x80); // – Initialize SLPCLKSEL = 0x2 (100 kHz Internal oscillator).
+    write_long(MRF_RFCON8, 0x10); // – Initialize RFVCO = 1.
+    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”):
+    write_short(MRF_BBREG2, 0x80); // Set CCA mode to ED
+    write_short(MRF_CCAEDTH, 0x60); // – Set CCA ED threshold.
+    write_short(MRF_BBREG6, 0x40); // – Set appended RSSI value to RXFIFO.
+    set_interrupts();
+    set_channel(12);
+    // max power is by default.. just leave it...
+    // Set transmitter power - See “REGISTER 2-62: RF CONTROL 3 REGISTER (ADDRESS: 0x203)”.
+    write_short(MRF_RFCTL, 0x04); //  – Reset RF state machine.
+    write_short(MRF_RFCTL, 0x00); // part 2
+    _delay_ms(1); // delay at least 192usec
+}
+
+/**
+ * Call this from within an interrupt handler connected to the MRFs output
+ * interrupt pin.  It handles reading in any data from the module, and letting it
+ * continue working.
+ * Only the most recent data is ever kept.
+ */
+void Mrf24j::interrupt_handler(void) {
+    uint8_t last_interrupt = read_short(MRF_INTSTAT);
+    if (last_interrupt & MRF_I_RXIF) {
+        flag_got_rx++;
+        // read out the packet data...
+        cli();
+        rx_disable();
+        // read start of rxfifo for, has 2 bytes more added by FCS. frame_length = m + n + 2
+        uint8_t frame_length = read_long(0x300);
+
+        // buffer all bytes in PHY Payload
+        if(bufPHY){
+            int rb_ptr = 0;
+            for (int i = 0; i < frame_length; i++) { // from 0x301 to (0x301 + frame_length -1)
+                rx_buf[rb_ptr++] = read_long(0x301 + i);
+            }
+        }
+
+        // buffer data bytes
+        int rd_ptr = 0;
+        // from (0x301 + bytes_MHR) to (0x301 + frame_length - bytes_nodata - 1)
+        for (int i = 0; i < rx_datalength(); i++) {
+            rx_info.rx_data[rd_ptr++] = read_long(0x301 + bytes_MHR + i);
+        }
+
+        rx_info.frame_length = frame_length;
+        // same as datasheet 0x301 + (m + n + 2) <-- frame_length
+        rx_info.lqi = read_long(0x301 + frame_length);
+        // same as datasheet 0x301 + (m + n + 3) <-- frame_length + 1
+        rx_info.rssi = read_long(0x301 + frame_length + 1);
+
+        rx_enable();
+        sei();
+    }
+    if (last_interrupt & MRF_I_TXNIF) {
+        flag_got_tx++;
+        uint8_t tmp = read_short(MRF_TXSTAT);
+        // 1 means it failed, we want 1 to mean it worked.
+        tx_info.tx_ok = !(tmp & ~(1 << TXNSTAT));
+        tx_info.retries = tmp >> 6;
+        tx_info.channel_busy = (tmp & (1 << CCAFAIL));
+    }
+}
+
+
+/**
+ * Call this function periodically, it will invoke your nominated handlers
+ */
+void Mrf24j::check_flags(void (*rx_handler)(void), void (*tx_handler)(void)){
+    // TODO - we could check whether the flags are > 1 here, indicating data was lost?
+    if (flag_got_rx) {
+        flag_got_rx = 0;
+        rx_handler();
+    }
+    if (flag_got_tx) {
+        flag_got_tx = 0;
+        tx_handler();
+    }
+}
+
+/**
+ * Set RX mode to promiscuous, or normal
+ */
+void Mrf24j::set_promiscuous(boolean enabled) {
+    if (enabled) {
+        write_short(MRF_RXMCR, 0x01);
+    } else {
+        write_short(MRF_RXMCR, 0x00);
+    }
+}
+
+rx_info_t * Mrf24j::get_rxinfo(void) {
+    return &rx_info;
+}
+
+tx_info_t * Mrf24j::get_txinfo(void) {
+    return &tx_info;
+}
+
+uint8_t * Mrf24j::get_rxbuf(void) {
+    return rx_buf;
+}
+
+int Mrf24j::rx_datalength(void) {
+    return rx_info.frame_length - bytes_nodata;
+}
+
+void Mrf24j::set_ignoreBytes(int ib) {
+    // some modules behaviour
+    ignoreBytes = ib;
+}
+
+/**
+ * Set bufPHY flag to buffer all bytes in PHY Payload, or not
+ */
+void Mrf24j::set_bufferPHY(boolean bp) {
+    bufPHY = bp;
+}
+
+boolean Mrf24j::get_bufferPHY(void) {
+    return bufPHY;
+}
+
+/**
+ * Set PA/LNA external control
+ */
+void Mrf24j::set_palna(boolean enabled) {
+    if (enabled) {
+        write_long(MRF_TESTMODE, 0x07); // Enable PA/LNA on MRF24J40MB module.
+    }else{
+        write_long(MRF_TESTMODE, 0x00); // Disable PA/LNA on MRF24J40MB module.
+    }
+}
+
+void Mrf24j::rx_flush(void) {
+    write_short(MRF_RXFLUSH, 0x01);
+}
+
+void Mrf24j::rx_disable(void) {
+    write_short(MRF_BBREG1, 0x04);  // RXDECINV - disable receiver
+}
+
+void Mrf24j::rx_enable(void) {
+    write_short(MRF_BBREG1, 0x00);  // RXDECINV - enable receiver
+}
+
diff --git a/lib/mrf24j.h b/lib/mrf24j.h
new file mode 100644
index 0000000..d6ba63f
--- /dev/null
+++ b/lib/mrf24j.h
@@ -0,0 +1,238 @@
+/*
+ * File:   mrf24j.h
+ * copyright Karl Palsson, karlp@tweak.net.au, 2011
+ * modified BSD License / apache license
+ */
+
+#pragma once
+
+#include <avr/io.h>
+
+#define byte uint8_t
+#define boolean bool
+#define word uint16_t
+
+
+
+#define RESET_DDR DDRB
+#define RESET_PORT PORTB
+#define RESET_PIN PB0
+
+#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
+
+typedef struct _rx_info_t{
+    uint8_t frame_length;
+    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)
+    uint8_t lqi;
+    uint8_t rssi;
+} rx_info_t;
+
+/**
+ * Based on the TXSTAT register, but "better"
+ */
+typedef struct _tx_info_t{
+    uint8_t tx_ok:1;
+    uint8_t retries:2;
+    uint8_t channel_busy:1;
+} tx_info_t;
+
+class Mrf24j
+{
+    public:
+        void reset(void);
+        void init(void);
+
+        byte read_short(byte address);
+        byte read_long(word address);
+
+        void write_short(byte address, byte data);
+        void write_long(word address, byte data);
+
+        word get_pan(void);
+        void set_pan(word panid);
+
+        void address16_write(word address16);
+        word address16_read(void);
+
+        void set_interrupts(void);
+
+        void set_promiscuous(boolean enabled);
+
+        /**
+         * Set the channel, using 802.15.4 channel numbers (11..26)
+         */
+        void set_channel(byte channel);
+
+        void rx_enable(void);
+        void rx_disable(void);
+
+        /** If you want to throw away rx data */
+        void rx_flush(void);
+
+        rx_info_t * get_rxinfo(void);
+
+        tx_info_t * get_txinfo(void);
+
+        uint8_t * get_rxbuf(void);
+
+        int rx_datalength(void);
+
+        void set_ignoreBytes(int ib);
+
+        /**
+         * Set bufPHY flag to buffer all bytes in PHY Payload, or not
+         */
+        void set_bufferPHY(boolean bp);
+
+        boolean get_bufferPHY(void);
+
+        /**
+         * Set PA/LNA external control
+         */
+        void set_palna(boolean enabled);
+
+        void send16(word dest16, char * data);
+
+        void interrupt_handler(void);
+
+        void check_flags(void (*rx_handler)(void), void (*tx_handler)(void));
+
+    private:
+        int _pin_reset;
+        int _pin_cs;
+        int _pin_int;
+};
+
+
+
+
diff --git a/lib/spi.cpp b/lib/spi.cpp
new file mode 100644
index 0000000..01d7872
--- /dev/null
+++ b/lib/spi.cpp
@@ -0,0 +1,35 @@
+#include "spi.h"
+
+
+namespace spi
+{
+    void init() {
+        SPI_PORT |= (1<<SPI_CS); //set chip select pin high
+        SPI_DDR |= (1<<SPI_SCK)|(1<<SPI_MOSI)|(1<<SPI_CS); // spi sck mosi and chip select outputs
+
+        SPCR |= (1<<SPE)|(1<<MSTR)|(1<<SPR0); //enable SPI , Master, fck/16
+    }
+
+    uint8_t transfer(uint8_t data) {
+        SPDR = data;
+        while(!(SPSR & (1<<SPIF))); //wait for transmition to complete
+        return SPDR;
+    }
+}
+    
+
+
+// } // namespace spi
+
+void SPI::init() {
+    SPI_PORT |= (1<<SPI_CS); //set chip select pin high
+    SPI_DDR |= (1<<SPI_SCK)|(1<<SPI_MOSI)|(1<<SPI_CS); // spi sck mosi and chip select outputs
+
+    SPCR |= (1<<SPE)|(1<<MSTR)|(1<<SPR0); //enable SPI , Master, fck/16
+}
+
+uint8_t SPI::transfer(uint8_t data) {
+    SPDR = data;
+    while(!(SPSR & (1<<SPIF))); //wait for transmition to complete
+    return SPDR;
+}
\ No newline at end of file
diff --git a/lib/spi.h b/lib/spi.h
new file mode 100644
index 0000000..82d1398
--- /dev/null
+++ b/lib/spi.h
@@ -0,0 +1,33 @@
+#pragma once
+
+#include <avr/io.h>
+
+
+
+#define SPI_PORT PORTB
+#define SPI_DDR DDRB
+#define SPI_SCK PB7
+#define SPI_MOSI PB5
+#define SPI_CS PB4
+
+namespace spi
+{
+    void init();
+    uint8_t transfer(uint8_t data);
+  
+    inline void cs_low() {SPI_PORT &= ~(1<<SPI_CS);}
+
+    inline void cs_high() {SPI_PORT |= (1<<SPI_CS);}
+} // namespace spi
+
+
+class SPI {
+    public:
+    void init();
+    uint8_t transfer(uint8_t data);
+    inline void cs_low() {SPI_PORT &= ~(1<<SPI_CS);}
+
+    inline void cs_high() {SPI_PORT |= (1<<SPI_CS);}
+};
+
+extern SPI s;
\ No newline at end of file
diff --git a/lib/usart.cpp b/lib/usart.cpp
new file mode 100644
index 0000000..1b46c9c
--- /dev/null
+++ b/lib/usart.cpp
@@ -0,0 +1,50 @@
+#include <avr/io.h>
+#include <avr/interrupt.h>
+#include "usart.h"
+
+namespace usart
+{
+    namespace {
+        static FILE mystdout;
+    }
+    
+    void init( unsigned long baud) {
+        fdev_setup_stream(&mystdout, put_printf, NULL, _FDEV_SETUP_WRITE);
+        stdout = &mystdout;
+        const unsigned int ubrr =  F_CPU/16/baud-1;
+
+        /*Set baud rate */
+        UBRRH = (unsigned char)(ubrr>>8);
+        UBRRL = (unsigned char)ubrr;
+        //Enable receiver and transmitter 
+        UCSRB = (1<<RXEN)|(1<<TXEN);
+        //UCSRB |= (1<< RXCIE)|(1<<TXCIE);
+        /* Set frame format: 8data, 2stop bit */
+        UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);
+        sei();
+
+    }
+
+    void put(char data) {
+        /* Wait for empty transmit buffer */
+        while ( !( UCSRA & (1<<UDRE)) )
+        ;
+        /* Put data into buffer, sends the data */
+        UDR = data;
+    }
+
+    char get( void ) {
+        /* Wait for data to be received */
+        while ( !(UCSRA & (1<<RXC)) )
+        ;
+        /* Get and return received data from buffer */
+        return UDR;
+    }       
+   
+    int put_printf(char var, FILE *stream) {
+        put(var);
+        return 0;
+    }
+} // namespace usart
+
+
diff --git a/lib/usart.h b/lib/usart.h
new file mode 100644
index 0000000..ffad848
--- /dev/null
+++ b/lib/usart.h
@@ -0,0 +1,14 @@
+#pragma once
+
+#include <stdio.h>
+
+namespace usart
+{
+    void init(unsigned long baud);
+    void put(char data );
+    char get();
+    int put_printf(char var, FILE *stream);
+} // namespace usart
+
+
+
diff --git a/rx/bin/main.bin b/rx/bin/main.bin
new file mode 100644
index 0000000..b14578b
Binary files /dev/null and b/rx/bin/main.bin differ
diff --git a/rx/bin/main.elf b/rx/bin/main.elf
new file mode 100644
index 0000000..b14578b
Binary files /dev/null and b/rx/bin/main.elf differ
diff --git a/rx/bin/main.hex b/rx/bin/main.hex
new file mode 100644
index 0000000..cff4be5
--- /dev/null
+++ b/rx/bin/main.hex
@@ -0,0 +1,234 @@
+:100000000C942B000C948D000C9453000C94530012
+:100010000C9453000C9453000C9453000C94530014
+:100020000C9453000C9453000C9453000C94530004
+:100030000C9453000C9453000C9453000C945300F4
+:100040000C9453000C9453000C9453000C945300E4
+:100050000C945300E00311241FBECFE5D8E0DEBFAF
+:10006000CDBF10E0A0E6B0E0ECE4FEE002C00590F9
+:100070000D92A03AB107D9F721E0A0EAB0E001C0A3
+:100080001D92A83BB207E1F710E0CBE2D0E004C03C
+:100090002197FE010E940904CA32D107C9F70E94C4
+:1000A000AF030C9424070C9400000895CF93DF93C2
+:1000B000D89A80EA90E00E949202FC0180811F920F
+:1000C0008F9380E690E09F938F930E940F0482E8C5
+:1000D00090E00E942C040F900F900F900F90C0E0C2
+:1000E000D0E080EA90E00E949B02C817D9076CF428
+:1000F00080EA90E00E9492028C0F9D1FFC0181819A
+:1001000090E00E9425042196ECCF80E890E00E94C8
+:100110002C04D898DF91CF9108951F920F920FB6BB
+:100120000F9211242F933F934F935F936F937F937D
+:100130008F939F93AF93BF93EF93FF9380EA90E0E9
+:100140000E94C502FF91EF91BF91AF919F918F9156
+:100150007F916F915F914F913F912F910F900FBEC3
+:100160000F901F901895C0988FE19EE40197F1F7CA
+:1001700000C00000C09A8FE39CE90197F1F700C02E
+:1001800000000895CF93C62F0E94DC038C2F880FA8
+:100190008E770E946E0380E00E946E03C82F0E943B
+:1001A000DE030E94DE038C2FCF910895CF93DF935F
+:1001B000EB010E94DC03CE0123E0969587952A95FA
+:1001C000E1F780680E946E038C2F8295880F807EF5
+:1001D0000E946E0380E00E946E03C82F0E94DE031F
+:1001E0008C2FDF91CF910895CF93DF93C62FD42F1B
+:1001F0000E94DC038C2F880F8E7781600E946E0333
+:100200008D2F0E946E03DF91CF910C94DE031F931C
+:10021000CF93DF93EB01142F0E94DC03CE0123E088
+:10022000969587952A95E1F780680E946E038C2F3A
+:100230008295880F807E80610E946E03812F0E94CC
+:100240006E03DF91CF911F910C94DE030F931F93E8
+:10025000CF938C0162E00E94C200C82F61E0C80108
+:100260000E94C2002C2F30E0322F2227A901482BF8
+:10027000CA01CF911F910F9108951F93CF93DF93E0
+:10028000EC01162F472F62E00E94F400412F61E03D
+:10029000CE01DF91CF911F910C94F4001F93CF9367
+:1002A000DF93EC01162F472F64E00E94F400412FEA
+:1002B00063E0CE01DF91CF911F910C94F4000F9376
+:1002C0001F93CF938C0164E00E94C200C82F63E0AB
+:1002D000C8010E94C2002C2F30E0322F2227A90132
+:1002E000482BCA01CF911F910F910895AF92BF92F1
+:1002F000CF92DF92EF92FF920F931F93CF93DF93F2
+:10030000EC017B016A01FA0101900020E9F73197C5
+:100310008F01041B150B49E060E070E00E940701AB
+:1003200040912101475F400F61E070E0CE010E94E3
+:10033000070141E662E070E0CE010E94070148E853
+:1003400063E070E0CE010E94070141E064E070E0EC
+:10035000CE010E940701CE010E942601B92E482F2E
+:1003600065E070E0CE010E9407014B2D66E070E071
+:10037000CE010E9407014E2D67E070E0CE010E9481
+:1003800007014F2D68E070E0CE010E940701CE0109
+:100390000E945F01F92E482F69E070E0CE010E94B3
+:1003A00007014F2D6AE070E0CE010E940701E09046
+:1003B0002101F09022018BE0E80EF11C560111277B
+:1003C000C5018C199D09801791075CF4F5014191D5
+:1003D0005F01B701CE010E940701FFEFEF1AFF0A8C
+:1003E000EFCF45E06BE1CE01DF91CF911F910F91EF
+:1003F000FF90EF90DF90CF90BF90AF900C94F400FF
+:1004000046EF62E30C94F400462F50E04B50510944
+:1004100024E0440F551F2A95E1F7436060E072E045
+:100420000C940701CF93DF93EC01B89A48E968E197
+:100430000E94F40045E96EE2CE010E94F40043E020
+:1004400060E072E0CE010E94070141E061E072E0ED
+:10045000CE010E94070140E862E072E0CE010E94F6
+:10046000070140E966E072E0CE010E94070140E822
+:1004700067E072E0CE010E94070140E168E072E0AF
+:10048000CE010E94070141E260E272E0CE010E94CB
+:10049000070140E86AE3CE010E94F40040E66FE302
+:1004A000CE010E94F40040E46EE3CE010E94F4000D
+:1004B000CE010E9400026CE0CE010E94040244E0E2
+:1004C00066E3CE010E94F40040E066E3CE010E94A4
+:1004D000F4008FEC97E00197F1F700C00000DF9186
+:1004E000CF910895CF93DF93EA018091A7008823ED
+:1004F00021F01092A700FB0109958091A6008823A6
+:1005000031F01092A600FE01DF91CF910994DF91A6
+:10051000CF910895662311F041E001C040E060E012
+:100520000C94F40089EA90E0089588EA90E0089538
+:1005300085E291E008958091A90090E02091230147
+:1005400030912401821B930B0895709322016093D4
+:10055000210108956093200108958091200108955C
+:10056000662311F047E001C040E06FE272E00C94B6
+:10057000070141E06DE00C94F40044E069E30C9461
+:10058000F40040E069E30C94F4008F929F92BF92D4
+:10059000CF92DF92EF92FF920F931F93CF93DF934F
+:1005A000EC0161E30E94C200B82E83FF61C080911C
+:1005B000A7008F5F8093A700F894CE010E94BD0230
+:1005C00060E073E0CE010E94D600082F80912001E8
+:1005D000811107C05AEAE52E50E0F52EC12CD12C2E
+:1005E00017C045E2C42E41E0D42EE12CF12C802E20
+:1005F000912CE814F90474F78FEFE81AF80AB701A0
+:100600007D5FCE010E94D600F60181936F01F1CF8C
+:100610008091A90090E02091230130912401821B58
+:10062000930BC816D9066CF4FFEFCF1ADF0AB60198
+:10063000675F7C4FCE010E94D600F70181937F0156
+:10064000E7CF0093A90010E0B8016F5F7C4FCE01A7
+:100650000E94D60080931E01B8016E5F7C4FCE01D0
+:100660000E94D60080931F01CE010E94C10278949F
+:10067000B0FE20C08091A6008F5F8093A60064E248
+:10068000CE010E94C20090E0AC014E7F31E0452BCC
+:1006900009F030E02091A80030FB20F936E0959574
+:1006A00087953A95E1F78370880F297F822B877FA2
+:1006B0008093A800DF91CF911F910F91FF90EF9051
+:1006C000DF90CF90BF909F908F900895C49A87B38A
+:1006D000806B87BB8DB181658DB908958FB9779B8C
+:1006E000FECF8FB10895C49A87B3806B87BB8DB15D
+:1006F00081658DB908956FB9779BFECF8FB108954D
+:100700009B01AC01E4EAF1E086EA93E091878087FF
+:100710001386128682E0838315861486F093B501D2
+:10072000E093B40160E271EA87E090E00E94E703A1
+:100730002150310930BD29B988E18AB98EE880BDE0
+:10074000789408955D9BFECF8CB908950E94A20312
+:1007500080E090E008955F9BFECF8CB1089560E546
+:1007600073EC80E090E00E9480030E94660380EAC0
+:1007700090E00E94B30080EA90E00E9412026EEFC7
+:100780007AEC80EA90E00E943D0162E072E480EA47
+:1007900090E00E944E0184B7816084BF8BB7806473
+:1007A0008BBF7894D09A45E550E066E570E080EA2A
+:1007B00090E00E947202F7CFC4980895C49A0895F9
+:1007C0008BE090E090932401809323010895A1E2AF
+:1007D0001A2EAA1BBB1BFD010DC0AA1FBB1FEE1FBB
+:1007E000FF1FA217B307E407F50720F0A21BB30B06
+:1007F000E40BF50B661F771F881F991F1A9469F782
+:1008000060957095809590959B01AC01BD01CF01DD
+:100810000895EE0FFF1F0590F491E02D0994A0E0DC
+:10082000B0E0E5E1F4E00C94FD06AE014B5F5F4FF4
+:10083000FA0161917191AF018091B4019091B5017C
+:100840000E945C04E2E00C9419076091B40170917D
+:10085000B5010E94530608950F931F93CF93DF9322
+:10086000E091B401F091B501238121FF1BC08C01FF
+:10087000D0E0C0E0F80181918F016091B4017091E6
+:10088000B501DB011896ED91FC911997882331F0A1
+:100890000995892B79F3DFEFCFEFECCF8AE009954B
+:1008A000892B19F08FEF9FEF02C08D2F9C2FDF91C6
+:1008B000CF911F910F910895ABE0B0E0E2E6F4E034
+:1008C0000C94ED066C017B018A01FC0117821682F3
+:1008D000838181FFCCC1CE0101963C01F601938159
+:1008E000F70193FD859193FF81917F01882309F49E
+:1008F000BAC1853239F493FD859193FF81917F01CF
+:10090000853229F4B60190E00E945306E7CF912C7E
+:10091000212C312CFFE1F315D8F08B3279F038F42B
+:10092000803279F08332A1F4232D20611DC08D32F5
+:1009300061F0803369F4232D216016C0832D82601D
+:10094000382EE32DE4603E2E2AC0F32DF8601DC042
+:1009500037FC2DC020ED280F2A3040F08E32B9F43C
+:1009600036FC81C1232D2064322E19C036FE06C00C
+:100970008AE0989E200D1124922E11C0EAE02E9E4E
+:10098000200D1124222EF32DF0623F2E08C08C364C
+:1009900021F4832D8068382E02C0883641F4F70197
+:1009A00093FD859193FF81917F018111B3CF982FA2
+:1009B0009F7D9554933028F40C5F1F4F9FE39983DC
+:1009C0000DC0833631F0833771F0833509F059C09B
+:1009D00021C0F801808189830E5F1F4F8824839492
+:1009E000912C530113C02801F2E04F0E511CF80165
+:1009F000A080B18036FE03C0692D70E002C06FEFA9
+:100A00007FEFC5010E9448064C018201F32DFF775C
+:100A10003F2E16C0280122E0420E511CF801A08092
+:100A2000B18036FE03C0692D70E002C06FEF7FEF2A
+:100A3000C5010E943D064C01F32DF0683F2E820156
+:100A400033FC1BC0822D90E088169906B0F4B601E5
+:100A500080E290E00E9453062A94F4CFF50137FC1F
+:100A6000859137FE81915F01B60190E00E945306A7
+:100A700021102A9421E0821A91088114910471F7BF
+:100A8000E8C0843611F0893641F5F80137FE07C019
+:100A900060817181828193810C5F1F4F08C06081EA
+:100AA0007181072E000C880B990B0E5F1F4FF32DE1
+:100AB000FF763F2E97FF09C09095809570956195C0
+:100AC0007F4F8F4F9F4FF0683F2E2AE030E0A30109
+:100AD0000E948F06882E861845C0853731F4232D55
+:100AE0002F7EB22E2AE030E025C0932D997FB92EBB
+:100AF0008F36C1F018F4883579F0B5C0803719F019
+:100B0000883721F0B0C0E92FE061BE2EB4FE0DC0E1
+:100B1000FB2DF460BF2E09C034FE0AC0292F2660C9
+:100B2000B22E06C028E030E005C020E130E002C06F
+:100B300020E132E0F801B7FE07C060817181828157
+:100B400093810C5F1F4F06C06081718180E090E04F
+:100B50000E5F1F4FA3010E948F06882E8618FB2D63
+:100B6000FF773F2E36FE0DC0232D2E7FA22E891437
+:100B700058F434FE0BC032FC09C0832D8E7EA82EA3
+:100B800005C0B82CA32C03C0B82C01C0B92CA4FEFE
+:100B90000FC0FE01E80DF11D8081803321F49A2DF4
+:100BA000997EA92E09C0A2FE06C0B394B39404C0D6
+:100BB0008A2D867809F0B394A3FC11C0A0FE06C06C
+:100BC000B21488F4280C922C9B180EC0B21460F456
+:100BD000B60180E290E00E945306B394F7CFB214BE
+:100BE00018F42B1802C0982C212CA4FE10C0B601BA
+:100BF00080E390E00E945306A2FE17C0A1FC03C050
+:100C000088E790E002C088E590E0B6010CC08A2D2C
+:100C1000867859F0A1FE02C08BE201C080E2A7FCF9
+:100C20008DE2B60190E00E945306891438F4B601B3
+:100C300080E390E00E9453069A94F7CF8A94F301E0
+:100C4000E80DF11D8081B60190E00E9453068110ED
+:100C5000F5CF222009F442CEB60180E290E00E9456
+:100C600053062A94F6CFF6018681978102C08FEF52
+:100C70009FEF2B96E2E10C940907FC01059061506F
+:100C800070400110D8F7809590958E0F9F1F0895A2
+:100C9000FC016150704001900110D8F7809590954B
+:100CA0008E0F9F1F08950F931F93CF93DF93FB0128
+:100CB000238121FD03C08FEF9FEF2CC022FF16C0C0
+:100CC00046815781248135814217530744F4A0811E
+:100CD000B1819D012F5F3F4F318320838C9326810B
+:100CE00037812F5F3F4F3783268314C08B01EC0180
+:100CF000FB010084F185E02D0995892BE1F6D801EF
+:100D000016968D919C911797019617969C938E93AA
+:100D10001697CE01DF91CF911F910F910895FA019F
+:100D2000AA27283051F1203181F1E8946F936E7F2A
+:100D30006E5F7F4F8F4F9F4FAF4FB1E03ED0B4E01B
+:100D40003CD0670F781F891F9A1FA11D680F791F5C
+:100D50008A1F911DA11D6A0F711D811D911DA11D6D
+:100D600020D009F468943F912AE0269F112430197D
+:100D7000305D3193DEF6CF010895462F4770405D18
+:100D80004193B3E00FD0C9F7F6CF462F4F70405DC7
+:100D90004A3318F0495D31FD4052419302D0A9F722
+:100DA000EACFB4E0A6959795879577956795BA951C
+:100DB000C9F700976105710508959B01AC010A2EE2
+:100DC00006945795479537952795BA95C9F7620FB9
+:100DD000731F841F951FA01D08952F923F924F925D
+:100DE0005F926F927F928F929F92AF92BF92CF92BB
+:100DF000DF92EF92FF920F931F93CF93DF93CDB7C4
+:100E0000DEB7CA1BDB0B0FB6F894DEBF0FBECDBF3B
+:100E100009942A88398848885F846E847D848C840C
+:100E20009B84AA84B984C884DF80EE80FD800C8115
+:100E30001B81AA81B981CE0FD11D0FB6F894DEBFF8
+:0C0E40000FBECDBFED010895F894FFCF68
+:100E4C0052656365697665642061207061636B65CA
+:100E5C0074202569206279746573206C6F6E670A43
+:100E6C000A000D0A415343494920646174612028EA
+:100E7C0072656C6576616E742064617461293A00E8
+:00000001FF
diff --git a/rx/makefile b/rx/makefile
new file mode 100644
index 0000000..8b9adbf
--- /dev/null
+++ b/rx/makefile
@@ -0,0 +1,25 @@
+MCU=atmega32
+F_CPU?=8000000
+PROG=dragon_jtag
+CC=avr-g++
+OBJCOPY=avr-objcopy
+CFLAGS=-Wall -g -Os -mmcu=${MCU} -DF_CPU=${F_CPU} -I.
+TARGET=main
+SRCS=src/*.cpp ../lib/*.cpp
+
+all: build flash
+
+build:
+	${CC} ${CFLAGS} -o bin/${TARGET}.bin  ${SRCS}
+	${CC} ${CFLAGS} -o bin/${TARGET}.elf  ${SRCS}
+	${OBJCOPY} -j .text -j .data -O ihex bin/${TARGET}.bin bin/${TARGET}.hex
+
+flash:
+	avrdude -p ${MCU} -c ${PROG} -U flash:w:bin/main.hex
+
+clean:
+	rm -f bin/* 
+
+term: 
+	python3 term.py
+
diff --git a/rx/src/main.cpp b/rx/src/main.cpp
new file mode 100644
index 0000000..596ba78
--- /dev/null
+++ b/rx/src/main.cpp
@@ -0,0 +1,83 @@
+/**
+ * Example code for using a microchip mrf24j40 module to send and receive
+ * packets using plain 802.15.4
+ * Requirements: 3 pins for spi, 3 pins for reset, chip select and interrupt
+ * notifications
+ * This example file is considered to be in the public domain
+ * Originally written by Karl Palsson, karlp@tweak.net.au, March 2011
+ */
+
+
+#include <avr/io.h>
+#include <avr/interrupt.h>
+#include "../../lib/mrf24j.h"
+#include "../../lib/usart.h"
+#include "../../lib/spi.h"
+
+const int pin_reset = 5;
+const int pin_cs = 10; // default CS pin on ATmega8/168/328
+const int pin_interrupt = 2; // default interrupt pin on ATmega8/168/328
+
+Mrf24j mrf;
+
+void handle_rx();
+void handle_tx();
+
+
+int main() {
+  usart::init(50000);
+  spi::init();
+  //s.init();
+  mrf.reset();
+  mrf.init();
+  
+  mrf.set_pan(0xcafe);
+  // This is _our_ address
+  mrf.address16_write(0x4202); 
+
+  // uncomment if you want to receive any packet on this channel
+  //mrf.set_promiscuous(true);
+  
+  // uncomment if you want to enable PA/LNA external control
+  //mrf.set_palna(true);
+  
+  // uncomment if you want to buffer all PHY Payload
+  //mrf.set_bufferPHY(true);
+
+  MCUCSR |= (1<<ISC00); // INT2 falling edge
+  GICR |= (1<<INT0);
+
+  sei();
+  DDRA |= (1<<PA0);
+
+  while(1) {
+      mrf.check_flags(&handle_rx, &handle_tx);
+  }
+  return 0;
+}
+
+
+ISR(INT0_vect) {
+    mrf.interrupt_handler(); // mrf24 object interrupt routine
+}
+
+
+void handle_rx() {
+    PORTA |= (1<<PA0);
+    printf("Received a packet %i bytes long\n\n", mrf.get_rxinfo()->frame_length);
+    
+    printf("\r\nASCII data (relevant data):\n");
+    for (int i = 0; i < mrf.rx_datalength(); i++) {
+        printf("%c", mrf.get_rxinfo()->rx_data[i]);
+    }
+    printf("\n\n");
+    // Serial.print("\r\nLQI/RSSI=");
+    // Serial.print(mrf.get_rxinfo()->lqi, DEC);
+    // Serial.print("/");
+    // Serial.println(mrf.get_rxinfo()->rssi, DEC);
+    PORTA &= ~(1<<PA0);
+}
+
+void handle_tx() {
+    
+}
\ No newline at end of file
diff --git a/rx/term.py b/rx/term.py
new file mode 100644
index 0000000..2e7d8ad
--- /dev/null
+++ b/rx/term.py
@@ -0,0 +1,11 @@
+import serial
+from time import sleep
+
+with serial.Serial('/dev/ttyUSB0', 50000, timeout=1) as ser:
+    while True:
+        x = ser.read()          # read one byte
+        if x != b'':
+            pass
+        print(x.decode('utf'), end ="")
+        
+        #print(ser.read())
\ No newline at end of file
diff --git a/tx/bin/main.bin b/tx/bin/main.bin
new file mode 100644
index 0000000..1000056
Binary files /dev/null and b/tx/bin/main.bin differ
diff --git a/tx/bin/main.elf b/tx/bin/main.elf
new file mode 100644
index 0000000..1000056
Binary files /dev/null and b/tx/bin/main.elf differ
diff --git a/tx/bin/main.hex b/tx/bin/main.hex
new file mode 100644
index 0000000..f8d890f
--- /dev/null
+++ b/tx/bin/main.hex
@@ -0,0 +1,228 @@
+:100000000C942B000C947C000C9453000C94530023
+:100010000C9453000C9453000C9453000C94530014
+:100020000C9453000C9453000C9453000C94530004
+:100030000C9453000C9453000C9453000C945300F4
+:100040000C9453000C9453000C9453000C945300E4
+:100050000C945300E20311241FBECFE5D8E0DEBFAD
+:10006000CDBF10E0A0E6B0E0E2EEFDE002C00590FA
+:100070000D92A639B107D9F721E0A6E9B0E001C099
+:100080001D92AE3AB207E1F710E0CBE2D0E004C037
+:100090002197FE010E940B04CA32D107C9F70E94C2
+:1000A0009E030C94EF060C940000089586E990E0FE
+:1000B0000E948402FC01808180FF09C080E690E0FC
+:1000C0009F938F930E9411040F900F90089586E9DB
+:1000D00090E00E948402FC018081869583701F92CB
+:1000E0008F9384E790E09F938F930E9411040F9069
+:1000F0000F900F900F9008951F920F920FB60F92CE
+:1001000011242F933F934F935F936F937F938F931C
+:100110009F93AF93BF93EF93FF9386E990E00E9484
+:10012000B402FF91EF91BF91AF919F918F917F9119
+:100130006F915F914F913F912F910F900FBE0F9054
+:100140001F901895C0988FE19EE40197F1F700C0C9
+:100150000000C09A8FE39CE90197F1F700C000000E
+:100160000895CF93C62F0E94DE038C2F880F8E77C1
+:100170000E945D0380E00E945D03C82F0E94E0039F
+:100180000E94E0038C2FCF910895CF93DF93EB0172
+:100190000E94DE03CE0123E0969587952A95E1F72C
+:1001A00080680E945D038C2F8295880F807E0E945C
+:1001B0005D0380E00E945D03C82F0E94E0038C2F46
+:1001C000DF91CF910895CF93DF93C62FD42F0E9454
+:1001D000DE038C2F880F8E7781600E945D038D2F48
+:1001E0000E945D03DF91CF910C94E0031F93CF93A6
+:1001F000DF93EB01142F0E94DE03CE0123E09695DE
+:1002000087952A95E1F780680E945D038C2F82957F
+:10021000880F807E80610E945D03812F0E945D03B4
+:10022000DF91CF911F910C94E0030F931F93CF9315
+:100230008C0162E00E94B100C82F61E0C8010E94F9
+:10024000B1002C2F30E0322F2227A901482BCA0100
+:10025000CF911F910F9108951F93CF93DF93EC01DE
+:10026000162F472F62E00E94E300412F61E0CE018C
+:10027000DF91CF911F910C94E3001F93CF93DF93F5
+:10028000EC01162F472F64E00E94E300412F63E04A
+:10029000CE01DF91CF911F910C94E3000F931F9338
+:1002A000CF938C0164E00E94B100C82F63E0C801C5
+:1002B0000E94B1002C2F30E0322F2227A901482BB9
+:1002C000CA01CF911F910F910895AF92BF92CF9223
+:1002D000DF92EF92FF920F931F93CF93DF93EC0186
+:1002E0007B016A01FA0101900020E9F731978F0143
+:1002F000041B150B49E060E070E00E94F60040919D
+:100300001701475F400F61E070E0CE010E94F600E8
+:1003100041E662E070E0CE010E94F60048E863E04A
+:1003200070E0CE010E94F60041E064E070E0CE0192
+:100330000E94F600CE010E941501B92E482F65E0FB
+:1003400070E0CE010E94F6004B2D66E070E0CE0119
+:100350000E94F6004E2D67E070E0CE010E94F6008C
+:100360004F2D68E070E0CE010E94F600CE010E94A1
+:100370004E01F92E482F69E070E0CE010E94F60090
+:100380004F2D6AE070E0CE010E94F600E090170168
+:10039000F09018018BE0E80EF11C56011127C50101
+:1003A0008C199D09801791075CF4F50141915F015B
+:1003B000B701CE010E94F600FFEFEF1AFF0AEFCF60
+:1003C00045E06BE1CE01DF91CF911F910F91FF903E
+:1003D000EF90DF90CF90BF90AF900C94E30046EF8A
+:1003E00062E30C94E300462F50E04B50510924E0A7
+:1003F000440F551F2A95E1F7436060E072E00C94CA
+:10040000F600CF93DF93EC01B89A48E968E10E94C7
+:10041000E30045E96EE2CE010E94E30043E060E0C4
+:1004200072E0CE010E94F60041E061E072E0CE0190
+:100430000E94F60040E862E072E0CE010E94F60001
+:1004400040E966E072E0CE010E94F60040E867E015
+:1004500072E0CE010E94F60040E168E072E0CE0159
+:100460000E94F60041E260E272E0CE010E94F600D6
+:1004700040E86AE3CE010E94E30040E66FE3CE016C
+:100480000E94E30040E46EE3CE010E94E300CE014F
+:100490000E94EF016CE0CE010E94F30144E066E3AC
+:1004A000CE010E94E30040E066E3CE010E94E3003B
+:1004B0008FEC97E00197F1F700C00000DF91CF913A
+:1004C0000895CF93DF93EA0180919D00882321F066
+:1004D00010929D00FB01099580919C00882331F0CA
+:1004E00010929C00FE01DF91CF910994DF91CF9192
+:1004F0000895662311F041E001C040E060E00C94F3
+:10050000E3008FE990E008958EE990E008958BE193
+:1005100091E0089580919F0090E020911901309121
+:100520001A01821B930B08957093180160931701B1
+:100530000895609316010895809116010895662329
+:1005400011F047E001C040E06FE272E00C94F60069
+:1005500041E06DE00C94E30044E069E30C94E300B7
+:1005600040E069E30C94E3008F929F92BF92CF9298
+:10057000DF92EF92FF920F931F93CF93DF93EC01E3
+:1005800061E30E94B100B82E83FF61C080919D009D
+:100590008F5F80939D00F894CE010E94AC0260E0D2
+:1005A00073E0CE010E94C500082F809116018111D1
+:1005B00007C050EAE52E50E0F52EC12CD12C17C013
+:1005C0004BE1C42E41E0D42EE12CF12C802E912C55
+:1005D000E814F90474F78FEFE81AF80AB7017D5FA1
+:1005E000CE010E94C500F60181936F01F1CF809189
+:1005F0009F0090E02091190130911A01821B930B0A
+:10060000C816D9066CF4FFEFCF1ADF0AB601675F90
+:100610007C4FCE010E94C500F70181937F01E7CF97
+:1006200000939F0010E0B8016F5F7C4FCE010E94E5
+:10063000C50080931401B8016E5F7C4FCE010E940B
+:10064000C50080931501CE010E94B0027894B0FEDF
+:1006500020C080919C008F5F80939C0064E2CE015B
+:100660000E94B10090E0AC014E7F31E0452B09F0D3
+:1006700030E020919E0030FB20F936E0959587957B
+:100680003A95E1F78370880F297F822B877F8093CB
+:100690009E00DF91CF911F910F91FF90EF90DF901F
+:1006A000CF90BF909F908F900895C49A87B3806B2E
+:1006B00087BB8DB181658DB908958FB9779BFECFCA
+:1006C0008FB10895C49A87B3806B87BB8DB1816564
+:1006D0008DB908956FB9779BFECF8FB108959B01B7
+:1006E000AC01EAE9F1E085E993E091878087138620
+:1006F000128682E0838315861486F093AB01E09323
+:10070000AA0160E271EA87E090E00E94E9032150CB
+:10071000310930BD29B988E18AB98EE880BD789465
+:1007200008955D9BFECF8CB908950E94910380E0EF
+:1007300090E008955F9BFECF8CB1089560E573EC67
+:1007400080E090E00E946F030E94550386E990E0EC
+:100750000E94A20086E990E00E9401026EEF7AEC0E
+:1007600086E990E00E942C0162E072E486E990E064
+:100770000E943D0184B7816084BF8BB780648BBFCA
+:100780007894D09AD89A46E550E065E570E086E91D
+:1007900090E00E94610240E950E062E072E486E984
+:1007A00090E00E946501D8982FEF89E698E12150EA
+:1007B00080409040E1F700C00000E4CFC498089565
+:1007C000C49A08958BE090E090931A0180931901E8
+:1007D0000895A1E21A2EAA1BBB1BFD010DC0AA1F82
+:1007E000BB1FEE1FFF1FA217B307E407F50720F09A
+:1007F000A21BB30BE40BF50B661F771F881F991F15
+:100800001A9469F760957095809590959B01AC015D
+:10081000BD01CF010895EE0FFF1F0590F491E02D6B
+:100820000994A0E0B0E0E7E1F4E00C94C806AE0162
+:100830004B5F5F4FFA0161917191AF018091AA0105
+:100840009091AB010E942704E2E00C94E406ABE037
+:10085000B0E0EDE2F4E00C94B8066C017B018A0193
+:10086000FC0117821682838181FFCCC1CE010196E3
+:100870003C01F6019381F70193FD859193FF8191EE
+:100880007F01882309F4BAC1853239F493FD85913B
+:1008900093FF81917F01853229F4B60190E00E9497
+:1008A0001E06E7CF912C212C312CFFE1F315D8F057
+:1008B0008B3279F038F4803279F08332A1F4232D31
+:1008C00020611DC08D3261F0803369F4232D2160D9
+:1008D00016C0832D8260382EE32DE4603E2E2AC0A0
+:1008E000F32DF8601DC037FC2DC020ED280F2A30F5
+:1008F00040F08E32B9F436FC81C1232D2064322EB3
+:1009000019C036FE06C08AE0989E200D1124922E52
+:1009100011C0EAE02E9E200D1124222EF32DF0624C
+:100920003F2E08C08C3621F4832D8068382E02C0FB
+:10093000883641F4F70193FD859193FF81917F0102
+:100940008111B3CF982F9F7D9554933028F40C5F7D
+:100950001F4F9FE399830DC0833631F0833771F0C9
+:10096000833509F059C021C0F801808189830E5F69
+:100970001F4F88248394912C530113C02801F2E067
+:100980004F0E511CF801A080B18036FE03C0692DC6
+:1009900070E002C06FEF7FEFC5010E9413064C01AB
+:1009A0008201F32DFF773F2E16C0280122E0420E70
+:1009B000511CF801A080B18036FE03C0692D70E0A3
+:1009C00002C06FEF7FEFC5010E9408064C01F32DB6
+:1009D000F0683F2E820133FC1BC0822D90E0881608
+:1009E0009906B0F4B60180E290E00E941E062A94B7
+:1009F000F4CFF50137FC859137FE81915F01B60197
+:100A000090E00E941E0621102A9421E0821A91088B
+:100A10008114910471F7E8C0843611F0893641F5EC
+:100A2000F80137FE07C060817181828193810C5F7C
+:100A30001F4F08C060817181072E000C880B990B35
+:100A40000E5F1F4FF32DFF763F2E97FF09C0909545
+:100A50008095709561957F4F8F4F9F4FF0683F2E27
+:100A60002AE030E0A3010E945A06882E861845C06D
+:100A7000853731F4232D2F7EB22E2AE030E025C0B9
+:100A8000932D997FB92E8F36C1F018F4883579F0FF
+:100A9000B5C0803719F0883721F0B0C0E92FE06188
+:100AA000BE2EB4FE0DC0FB2DF460BF2E09C034FE77
+:100AB0000AC0292F2660B22E06C028E030E005C00B
+:100AC00020E130E002C020E132E0F801B7FE07C0CB
+:100AD00060817181828193810C5F1F4F06C06081AC
+:100AE000718180E090E00E5F1F4FA3010E945A06C3
+:100AF000882E8618FB2DFF773F2E36FE0DC0232D46
+:100B00002E7FA22E891458F434FE0BC032FC09C08B
+:100B1000832D8E7EA82E05C0B82CA32C03C0B82C24
+:100B200001C0B92CA4FE0FC0FE01E80DF11D8081AB
+:100B3000803321F49A2D997EA92E09C0A2FE06C009
+:100B4000B394B39404C08A2D867809F0B394A3FCBF
+:100B500011C0A0FE06C0B21488F4280C922C9B1879
+:100B60000EC0B21460F4B60180E290E00E941E064E
+:100B7000B394F7CFB21418F42B1802C0982C212C80
+:100B8000A4FE10C0B60180E390E00E941E06A2FE03
+:100B900017C0A1FC03C088E790E002C088E590E0A0
+:100BA000B6010CC08A2D867859F0A1FE02C08BE2F6
+:100BB00001C080E2A7FC8DE2B60190E00E941E0613
+:100BC000891438F4B60180E390E00E941E069A94DE
+:100BD000F7CF8A94F301E80DF11D8081B60190E012
+:100BE0000E941E068110F5CF222009F442CEB601E4
+:100BF00080E290E00E941E062A94F6CFF6018681DC
+:100C0000978102C08FEF9FEF2B96E2E10C94D40600
+:100C1000FC010590615070400110D8F780959095C7
+:100C20008E0F9F1F0895FC016150704001900110CC
+:100C3000D8F7809590958E0F9F1F08950F931F935F
+:100C4000CF93DF93FB01238121FD03C08FEF9FEF43
+:100C50002CC022FF16C0468157812481358142175E
+:100C6000530744F4A081B1819D012F5F3F4F318331
+:100C700020838C93268137812F5F3F4F37832683D4
+:100C800014C08B01EC01FB010084F185E02D099576
+:100C9000892BE1F6D80116968D919C9117970196B4
+:100CA00017969C938E931697CE01DF91CF911F914B
+:100CB0000F910895FA01AA27283051F1203181F1CE
+:100CC000E8946F936E7F6E5F7F4F8F4F9F4FAF4F54
+:100CD000B1E03ED0B4E03CD0670F781F891F9A1F67
+:100CE000A11D680F791F8A1F911DA11D6A0F711D1B
+:100CF000811D911DA11D20D009F468943F912AE027
+:100D0000269F11243019305D3193DEF6CF0108950E
+:100D1000462F4770405D4193B3E00FD0C9F7F6CF3F
+:100D2000462F4F70405D4A3318F0495D31FD405207
+:100D3000419302D0A9F7EACFB4E0A695979587959D
+:100D400077956795BA95C9F700976105710508957C
+:100D50009B01AC010A2E0694579547953795279528
+:100D6000BA95C9F7620F731F841F951FA01D0895C0
+:100D70002F923F924F925F926F927F928F929F92AB
+:100D8000AF92BF92CF92DF92EF92FF920F931F9399
+:100D9000CF93DF93CDB7DEB7CA1BDB0B0FB6F8944A
+:100DA000DEBF0FBECDBF09942A88398848885F848A
+:100DB0006E847D848C849B84AA84B984C884DF80FB
+:100DC000EE80FD800C811B81AA81B981CE0FD11DDF
+:100DD0000FB6F894DEBF0FBECDBFED010895F894B5
+:020DE000FFCF43
+:100DE20054582077656E74206F6B2C20676F7420C7
+:100DF20061636B005458206661696C6564206166AA
+:100E020074657220256920726574726965730A00BF
+:060E12006163646500004D
+:00000001FF
diff --git a/tx/makefile b/tx/makefile
new file mode 100644
index 0000000..8b9adbf
--- /dev/null
+++ b/tx/makefile
@@ -0,0 +1,25 @@
+MCU=atmega32
+F_CPU?=8000000
+PROG=dragon_jtag
+CC=avr-g++
+OBJCOPY=avr-objcopy
+CFLAGS=-Wall -g -Os -mmcu=${MCU} -DF_CPU=${F_CPU} -I.
+TARGET=main
+SRCS=src/*.cpp ../lib/*.cpp
+
+all: build flash
+
+build:
+	${CC} ${CFLAGS} -o bin/${TARGET}.bin  ${SRCS}
+	${CC} ${CFLAGS} -o bin/${TARGET}.elf  ${SRCS}
+	${OBJCOPY} -j .text -j .data -O ihex bin/${TARGET}.bin bin/${TARGET}.hex
+
+flash:
+	avrdude -p ${MCU} -c ${PROG} -U flash:w:bin/main.hex
+
+clean:
+	rm -f bin/* 
+
+term: 
+	python3 term.py
+
diff --git a/tx/src/main.cpp b/tx/src/main.cpp
new file mode 100644
index 0000000..0ec017e
--- /dev/null
+++ b/tx/src/main.cpp
@@ -0,0 +1,80 @@
+/**
+ * Example code for using a microchip mrf24j40 module to send and receive
+ * packets using plain 802.15.4
+ * Requirements: 3 pins for spi, 3 pins for reset, chip select and interrupt
+ * notifications
+ * This example file is considered to be in the public domain
+ * Originally written by Karl Palsson, karlp@tweak.net.au, March 2011
+ */
+
+
+#include <avr/io.h>
+#include <avr/interrupt.h>
+#include <util/delay.h>
+#include "../../lib/mrf24j.h"
+#include "../../lib/usart.h"
+#include "../../lib/spi.h"
+
+const int pin_reset = 5;
+const int pin_cs = 10; // default CS pin on ATmega8/168/328
+const int pin_interrupt = 2; // default interrupt pin on ATmega8/168/328
+
+Mrf24j mrf;
+
+void handle_rx();
+void handle_tx();
+
+
+int main() {
+	usart::init(50000);
+	spi::init();
+	mrf.reset();
+	mrf.init();
+	
+	mrf.set_pan(0xcafe);
+	// This is _our_ address
+	mrf.address16_write(0x4202); 
+
+	// uncomment if you want to receive any packet on this channel
+	//mrf.set_promiscuous(true);
+	
+	// uncomment if you want to enable PA/LNA external control
+	//mrf.set_palna(true);
+	
+	// uncomment if you want to buffer all PHY Payload
+	//mrf.set_bufferPHY(true);
+
+	MCUCSR |= (1<<ISC00); // INT2 falling edge
+	GICR |= (1<<INT0);
+
+	sei();
+	DDRA |= (1<<PA0);
+
+	while(1) {
+		PORTA |= (1<<PA0);
+		mrf.check_flags(&handle_rx, &handle_tx);
+		mrf.send16(0x4202, "acde");
+		PORTA &= ~(1<<PA0);
+		_delay_ms(1000);
+	}
+	return 0;
+}
+
+
+ISR(INT0_vect) {
+    mrf.interrupt_handler(); // mrf24 object interrupt routine
+}
+
+
+void handle_rx() {
+
+    
+}
+
+void handle_tx() {
+    if (mrf.get_txinfo()->tx_ok) {
+        printf("TX went ok, got ack");
+    } else {
+        printf("TX failed after %i retries\n", mrf.get_txinfo()->retries);
+    }
+}
\ No newline at end of file
diff --git a/tx/term.py b/tx/term.py
new file mode 100644
index 0000000..2e7d8ad
--- /dev/null
+++ b/tx/term.py
@@ -0,0 +1,11 @@
+import serial
+from time import sleep
+
+with serial.Serial('/dev/ttyUSB0', 50000, timeout=1) as ser:
+    while True:
+        x = ser.read()          # read one byte
+        if x != b'':
+            pass
+        print(x.decode('utf'), end ="")
+        
+        #print(ser.read())
\ No newline at end of file