From 3ccfb5b3dbaa68d05e13049ee26503f6febecb10 Mon Sep 17 00:00:00 2001 From: Matthijs Kooijman Date: Thu, 23 May 2019 13:22:59 +0200 Subject: [PATCH] Arduino: Adapt Arduino code to basicmac Examples are untouched, those will be updated separately. --- lmic/debug.c | 4 +- lmic/region.h | 2 + target/arduino/board.h | 1 + target/arduino/export.sh | 2 + target/arduino/hal/hal.cpp | 142 ++++++++++++++++++++++++++--- target/arduino/hal/target-config.h | 65 +++++-------- target/arduino/hw.h | 45 +++++++++ target/arduino/library.properties | 8 +- 8 files changed, 206 insertions(+), 63 deletions(-) create mode 100644 target/arduino/board.h create mode 100644 target/arduino/hw.h diff --git a/lmic/debug.c b/lmic/debug.c index df0af38..a9f8550 100644 --- a/lmic/debug.c +++ b/lmic/debug.c @@ -4,12 +4,12 @@ // This file is subject to the terms and conditions defined in file 'LICENSE', // which is part of this source code package. +#include "lmic.h" + #ifdef CFG_DEBUG #include -#include "lmic.h" - void debug_led (int val) { hal_debug_led(val); } diff --git a/lmic/region.h b/lmic/region.h index 11495ab..27a7917 100644 --- a/lmic/region.h +++ b/lmic/region.h @@ -6,6 +6,8 @@ #ifndef _region_h_ #define _region_h_ +#include "board.h" + // public region codes - DO NOT CHANGE! enum { REGCODE_UNDEF = 0, diff --git a/target/arduino/board.h b/target/arduino/board.h new file mode 100644 index 0000000..426077a --- /dev/null +++ b/target/arduino/board.h @@ -0,0 +1 @@ +#include "../hal/target-config.h" diff --git a/target/arduino/export.sh b/target/arduino/export.sh index 6b09210..6eb16a3 100755 --- a/target/arduino/export.sh +++ b/target/arduino/export.sh @@ -66,3 +66,5 @@ $CMD "$SRC"/../../lmic "$TARGET"/src $CMD "$SRC"/hal "$TARGET"/src $CMD "$SRC"/../../aes "$TARGET"/src $CMD "$SRC"/examples "$TARGET" +$CMD "$SRC"/board.h "$TARGET"/src/lmic +$CMD "$SRC"/hw.h "$TARGET"/src/lmic diff --git a/target/arduino/hal/hal.cpp b/target/arduino/hal/hal.cpp index 53bf359..fb65405 100644 --- a/target/arduino/hal/hal.cpp +++ b/target/arduino/hal/hal.cpp @@ -37,7 +37,7 @@ static void hal_io_init () { } // val == 1 => tx 1 -void hal_pin_rxtx (u1_t val) { +void hal_pin_rxtx (s1_t val) { if (lmic_pins.rxtx != LMIC_UNUSED_PIN) digitalWrite(lmic_pins.rxtx, val); } @@ -55,6 +55,10 @@ void hal_pin_rst (u1_t val) { } } +void hal_irqmask_set (int mask) { + // Not implemented +} + static bool dio_states[NUM_DIO] = {0}; static void hal_io_check() { @@ -66,11 +70,20 @@ static void hal_io_check() { if (dio_states[i] != digitalRead(lmic_pins.dio[i])) { dio_states[i] = !dio_states[i]; if (dio_states[i]) - radio_irq_handler(i); + radio_irq_handler(i, hal_ticks()); } } } +bool hal_pin_tcxo (u1_t val) { + // Not implemented + return false; +} + +void hal_pin_busy_wait (void) { + // Not implemented +} + // ----------------------------------------------------------------------------- // SPI @@ -80,14 +93,14 @@ static void hal_spi_init () { SPI.begin(); } -void hal_pin_nss (u1_t val) { - if (!val) +void hal_spi_select (int on) { + if (on) SPI.beginTransaction(settings); else SPI.endTransaction(); //Serial.println(val?">>":"<<"); - digitalWrite(lmic_pins.nss, val); + digitalWrite(lmic_pins.nss, !on); } // perform SPI transaction with radio @@ -154,6 +167,17 @@ u4_t hal_ticks () { static_assert(US_PER_OSTICK_EXPONENT > 0 && US_PER_OSTICK_EXPONENT < 8, "Invalid US_PER_OSTICK_EXPONENT value"); } +u8_t hal_xticks (void) { + // TODO + return hal_ticks(); +} +/* Not actually used now +s2_t hal_subticks (void) { + // TODO + return 0; +} +*/ + // Returns the number of ticks until time. Negative values indicate that // time has already passed. static s4_t delta_time(u4_t time) { @@ -201,10 +225,47 @@ void hal_enableIRQs () { } } -void hal_sleep () { +u1_t hal_sleep (u1_t type, u4_t targettime) { + // Actual sleeping not implemented, but jobs are only run when this + // function returns 0, so make sure we only do that when the + // targettime is close. When asked to sleep forever (until woken up + // by an interrupt), just return immediately to keep polling. + if (type == HAL_SLEEP_FOREVER) + return 0; + + // TODO: What value should we use for "close"? + return delta_time(targettime) < 10 ? 0 : 1; +} + +void hal_watchcount (int cnt) { // Not implemented } +// ----------------------------------------------------------------------------- +// DEBUG + +#ifdef CFG_DEBUG +static void hal_debug_init() { + #ifdef LED_BUILTIN + pinMode(LED_BUILTIN, OUTPUT); + #endif +} + +#if !defined(CFG_DEBUG_STREAM) +#error "CFG_DEBUG needs CFG_DEBUG_STREAM defined in target-config.h" +#endif + +void hal_debug_str (const char* str) { + CFG_DEBUG_STREAM.print(str); +} + +void hal_debug_led (int val) { + #ifdef LED_BUILTIN + digitalWrite(LED_BUILTIN, val); + #endif +} +#endif // CFG_DEBUG + // ----------------------------------------------------------------------------- #if defined(LMIC_PRINTF_TO) @@ -227,7 +288,7 @@ void hal_printf_init() { } #endif // defined(LMIC_PRINTF_TO) -void hal_init () { +void hal_init (void *bootarg) { // configure radio I/O and interrupt handler hal_io_init(); // configure radio SPI @@ -238,16 +299,69 @@ void hal_init () { // printf support hal_printf_init(); #endif +#ifdef CFG_DEBUG + hal_debug_init(); +#endif } -void hal_failed (const char *file, u2_t line) { -#if defined(LMIC_FAILURE_TO) - LMIC_FAILURE_TO.println("FAILURE "); - LMIC_FAILURE_TO.print(file); - LMIC_FAILURE_TO.print(':'); - LMIC_FAILURE_TO.println(line); - LMIC_FAILURE_TO.flush(); +void hal_failed () { +#ifdef CFG_DEBUG + CFG_DEBUG_STREAM.flush(); #endif hal_disableIRQs(); while(1); } + +void hal_reboot (void) { + // TODO + hal_failed(); +} + +u1_t hal_getBattLevel (void) { + // Not implemented + return 0; +} + +void hal_setBattLevel (u1_t level) { + // Not implemented +} + +void hal_fwinfo (hal_fwi* fwi) { + // Not implemented +} + +u1_t* hal_joineui (void) { + return nullptr; +} + +u1_t* hal_deveui (void) { + return nullptr; +} + +u1_t* hal_nwkkey (void) { + return nullptr; +} + +u1_t* hal_appkey (void) { + return nullptr; +} + +u1_t* hal_serial (void) { + return nullptr; +} + +u4_t hal_region (void) { + return 0; +} + +u4_t hal_hwid (void) { + return 0; +} + +u4_t hal_unique (void) { + return 0; +} + +u4_t hal_dnonce_next (void) { + return 0; +} diff --git a/target/arduino/hal/target-config.h b/target/arduino/hal/target-config.h index 026a18c..d1a4f8c 100644 --- a/target/arduino/hal/target-config.h +++ b/target/arduino/hal/target-config.h @@ -4,12 +4,14 @@ #define CFG_eu868 1 //#define CFG_us915 1 +#define CFG_autojoin + // This is the SX1272/SX1273 radio, which is also used on the HopeRF // RFM92 boards. -//#define CFG_sx1272_radio 1 +//#define BRD_sx1272_radio 1 // This is the SX1276/SX1277/SX1278/SX1279 radio, which is also used on // the HopeRF RFM95 boards. -#define CFG_sx1276_radio 1 +#define BRD_sx1276_radio 1 // 16 μs per tick // LMIC requires ticks to be 15.5μs - 100 μs long @@ -17,50 +19,27 @@ #define US_PER_OSTICK (1 << US_PER_OSTICK_EXPONENT) #define OSTICKS_PER_SEC (1000000 / US_PER_OSTICK) -// Enable this to allow using printf() to print to the given serial port -// (or any other Print object). This can be easy for debugging. The -// current implementation only works on AVR, though. -//#define LMIC_PRINTF_TO Serial - -// Any runtime assertion failures are printed to this serial port (or -// any other Print object). If this is unset, any failures just silently -// halt execution. -#define LMIC_FAILURE_TO Serial - -// Set this to 1 to enable some basic debug output (using printf) about -// RF settings used during transmission and reception. Set to 2 to -// enable more verbose output. Make sure that printf is actually -// configured (e.g. on AVR it is not by default), otherwise using it can -// cause crashing. -#define LMIC_DEBUG_LEVEL 0 +// When this is defined, some debug output will be printed and +// debug_printf(...) is available (which is a slightly non-standard +// printf implementation). +// Without this, assertion failures are *not* printed! +#define CFG_DEBUG +// Debug output (and assertion failures) are printed to this Stream +#define CFG_DEBUG_STREAM Serial +// Define these to add some TX or RX specific debug output +//#define DEBUG_TX +//#define DEBUG_RX +// Uncomment to display timestamps in ticks rather than milliseconds +//#define CFG_DEBUG_RAW_TIMESTAMPS + +// When this is defined, the standard libc printf function will print to +// this Stream. You should probably use CFG_DEBUG and debug_printf() +// instead, though. +//#define LMIC_PRINTF_FO -// Uncomment this to disable all code related to joining -//#define DISABLE_JOIN -// Uncomment this to disable all code related to ping -#define DISABLE_PING // Uncomment this to disable all code related to beacon tracking. // Requires ping to be disabled too -#define DISABLE_BEACONS - -// Uncomment these to disable the corresponding MAC commands. -// Class A -//#define DISABLE_MCMD_DCAP_REQ // duty cycle cap -//#define DISABLE_MCMD_DN2P_SET // 2nd DN window param -//#define DISABLE_MCMD_SNCH_REQ // set new channel -// Class B -//#define DISABLE_MCMD_PING_SET // set ping freq, automatically disabled by DISABLE_PING -//#define DISABLE_MCMD_BCNI_ANS // next beacon start, automatical disabled by DISABLE_BEACON - -// In LoRaWAN, a gateway applies I/Q inversion on TX, and nodes do the -// same on RX. This ensures that gateways can talk to nodes and vice -// versa, but gateways will not hear other gateways and nodes will not -// hear other nodes. By uncommenting this macro, this inversion is -// disabled and this node can hear other nodes. If two nodes both have -// this macro set, they can talk to each other (but they can no longer -// hear gateways). This should probably only be used when debugging -// and/or when talking to the radio directly (e.g. like in the "raw" -// example). -//#define DISABLE_INVERT_IQ_ON_RX +#define DISABLE_CLASSB // This allows choosing between multiple included AES implementations. // Make sure exactly one of these is uncommented. diff --git a/target/arduino/hw.h b/target/arduino/hw.h new file mode 100644 index 0000000..efdffe1 --- /dev/null +++ b/target/arduino/hw.h @@ -0,0 +1,45 @@ +// __ __ ___ __ __ _________________________________ +// (_ |_ |V| | |_ / |_| (C) 2018-2018 Semtech Corporation +// __)|__| | | |__\__| | All rights reserved + +#ifndef _hw_h_ +#define _hw_h_ + +/* +#define PERIPH_EEPROM + +#define EEPROM_BASE 0x30000000 +#define EEPROM_SZ (8 * 1024) +#define EEPROM_END (EEPROM_BASE + EEPROM_SZ) + +// 0x0000-0x003f 64 B : reserved for bootloader +// 0x0040-0x005f 32 B : reserved for persistent stack data +// 0x0060-0x00ff 160 B : reserved for personalization data +// 0x0100-...... : reserved for application + +#define STACKDATA_BASE (EEPROM_BASE + 0x0040) +#define PERSODATA_BASE (EEPROM_BASE + 0x0060) +#define APPDATA_BASE (EEPROM_BASE + 0x0100) + +#define STACKDATA_SZ (PERSODATA_BASE - STACKDATA_BASE) +#define PERSODATA_SZ (APPDATA_BASE - PERSODATA_BASE) +#define APPDATA_SZ (EEPROM_END - APPDATA_BASE) + + +#define FLASH_BASE 0x20000000 +#define FLASH_SZ (128 * 1024) +#define FLASH_END (FLASH_BASE + FLASH_SZ) +#define FLASH_PAGE_SZ 128 + + +#define PERIPH_USART +#define USART_BR_9600 9600 +#define USART_BR_115200 115200 + +#define PERIPH_PIO +#define PIO_IRQ_LINE(gpio) (gpio) + +#define PERIPH_CRC +#define PERIPH_SHA256 +*/ +#endif diff --git a/target/arduino/library.properties b/target/arduino/library.properties index 0dbf7d5..9ee51d9 100644 --- a/target/arduino/library.properties +++ b/target/arduino/library.properties @@ -1,9 +1,9 @@ -name=IBM LMIC framework -version=1.5.0+arduino-1 -author=IBM +name=Basicmac LoRaWAN stack +version=2.1.0 +author=Various maintainer=Matthijs Kooijman sentence=Arduino port of the LMIC (LoraWAN-in-C, formerly LoraMAC-in-C) framework provided by IBM. paragraph=Supports SX1272/SX1276 and HopeRF RFM92/RFM95 tranceivers category=Communication -url=http://www.research.ibm.com/labs/zurich/ics/lrsc/lmic.html +url=https://github.com/lorabasics/basicmac architectures=*