From 0a48d7b3c7de1231afae0ccb306f74b04292839c Mon Sep 17 00:00:00 2001 From: Jimmy Date: Fri, 21 Aug 2020 10:27:08 +1200 Subject: [PATCH] It works --- .vscode/c_cpp_properties.json | 20 +++ .vscode/settings.json | 3 + lib/mrf24j.cpp | 318 ++++++++++++++++++++++++++++++++++ lib/mrf24j.h | 238 +++++++++++++++++++++++++ lib/spi.cpp | 35 ++++ lib/spi.h | 33 ++++ lib/usart.cpp | 50 ++++++ lib/usart.h | 14 ++ rx/bin/main.bin | Bin 0 -> 33348 bytes rx/bin/main.elf | Bin 0 -> 33348 bytes rx/bin/main.hex | 234 +++++++++++++++++++++++++ rx/makefile | 25 +++ rx/src/main.cpp | 83 +++++++++ rx/term.py | 11 ++ tx/bin/main.bin | Bin 0 -> 32908 bytes tx/bin/main.elf | Bin 0 -> 32908 bytes tx/bin/main.hex | 228 ++++++++++++++++++++++++ tx/makefile | 25 +++ tx/src/main.cpp | 80 +++++++++ tx/term.py | 11 ++ 20 files changed, 1408 insertions(+) create mode 100644 .vscode/c_cpp_properties.json create mode 100644 .vscode/settings.json create mode 100644 lib/mrf24j.cpp create mode 100644 lib/mrf24j.h create mode 100644 lib/spi.cpp create mode 100644 lib/spi.h create mode 100644 lib/usart.cpp create mode 100644 lib/usart.h create mode 100644 rx/bin/main.bin create mode 100644 rx/bin/main.elf create mode 100644 rx/bin/main.hex create mode 100644 rx/makefile create mode 100644 rx/src/main.cpp create mode 100644 rx/term.py create mode 100644 tx/bin/main.bin create mode 100644 tx/bin/main.elf create mode 100644 tx/bin/main.hex create mode 100644 tx/makefile create mode 100644 tx/src/main.cpp create mode 100644 tx/term.py 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 +#include +#include +#include +#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<> 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<> 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 + +#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< + + + +#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< +#include +#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< + +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 0000000000000000000000000000000000000000..b14578be2c06eebdae110b2cf39a7fb75c70bab5 GIT binary patch literal 33348 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 literal 0 HcmV?d00001 diff --git a/rx/bin/main.elf b/rx/bin/main.elf new file mode 100644 index 0000000000000000000000000000000000000000..b14578be2c06eebdae110b2cf39a7fb75c70bab5 GIT binary patch literal 33348 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 literal 0 HcmV?d00001 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 +#include +#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<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 &= 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 +#include +#include +#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<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