diff --git a/examples/tests/lr1110/README.md b/examples/tests/lr1110/README.md new file mode 100644 index 000000000..4811efb64 --- /dev/null +++ b/examples/tests/lr1110/README.md @@ -0,0 +1,11 @@ +LR1110 Test Apps +================ + +The [LR1110](https://www.semtech.com/products/wireless-rf/lora-edge/lr1110) is +an integrated LoRa radio with a WiFi access point scanner and a GNSS scanner +built in. + +These example apps use the `libtock-c/lr1110` library to implement the +LoRa/WiFi/GNSS functionality. While this library should work with any LR1110 +radio, this was developed and tested with the [WM1110 Dev +Kit](https://www.seeedstudio.com/Wio-WM1110-Dev-Kit-p-5677.html). diff --git a/examples/tests/lr1110/lorawan/.DS_Store b/examples/tests/lr1110/lorawan/.DS_Store new file mode 100644 index 000000000..e145b5c7f Binary files /dev/null and b/examples/tests/lr1110/lorawan/.DS_Store differ diff --git a/examples/tests/lr1110/lorawan/Makefile b/examples/tests/lr1110/lorawan/Makefile new file mode 100644 index 000000000..7b2e16139 --- /dev/null +++ b/examples/tests/lr1110/lorawan/Makefile @@ -0,0 +1,19 @@ +# Makefile for user application + +# Specify this directory relative to the current application. +TOCK_USERLAND_BASE_DIR = ../../../.. + +# External libraries used +EXTERN_LIBS += $(TOCK_USERLAND_BASE_DIR)/lr1110 + +override CFLAGS += -I$(TOCK_USERLAND_BASE_DIR)/lr1110 + +# Which files to compile. +C_SRCS += $(wildcard *.c) + +APP_HEAP_SIZE := 40000 +STACK_SIZE := 4096 + +# Include userland master makefile. Contains rules and flags for actually +# building the application. +include $(TOCK_USERLAND_BASE_DIR)/AppMakefile.mk diff --git a/examples/tests/lr1110/lorawan/main_lorawan.c b/examples/tests/lr1110/lorawan/main_lorawan.c new file mode 100644 index 000000000..0ea200966 --- /dev/null +++ b/examples/tests/lr1110/lorawan/main_lorawan.c @@ -0,0 +1,467 @@ +/*! + * @file main_lorawan.c + * + * @brief LoRa Basics Modem Class A/C device implementation + * + * @copyright + * The Clear BSD License + * Copyright Semtech Corporation 2021. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted (subject to the limitations in the disclaimer + * below) provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the Semtech corporation nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY + * THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT + * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SEMTECH CORPORATION BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + + +/* + * link to README.md of this example in seeed studio's repo: + * https://github.com/Seeed-Studio/Seeed_Wio_WM1110_Dev_Board/blob/master/apps/examples/lorawan/README.md + */ + +/* + * ----------------------------------------------------------------------------- + * --- DEPENDENCIES ------------------------------------------------------------ + */ + +// #include "main_lorawan.h" +// #include "lorawan_key_config.h" +// #include "smtc_board.h" +// #include "smtc_hal.h" +// #include "apps_modem_common.h" +// #include "apps_modem_event.h" +// #include "smtc_modem_api.h" +// #include "device_management_defs.h" +// #include "smtc_board_ralf.h" +// #include "apps_utilities.h" +// #include "smtc_modem_utilities.h" + + +#include +#include +#include + +#include +#include +#include + +#include +#include + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE MACROS----------------------------------------------------------- + */ + + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE CONSTANTS ------------------------------------------------------- + */ + +#define LORAWAN_REGION SMTC_MODEM_REGION_US_915 +#define LORAWAN_CLASS SMTC_MODEM_CLASS_A + +// wm1110dev parameters +/* These need to be updated to use values from your LoRaWAN server */ +#define LORAWAN_DEVICE_EUI "0x0000000000000000" +#define LORAWAN_JOIN_EUI "0x0000000000000000" +#define LORAWAN_APP_KEY "0x00000000000000000000000000000000" + +/*! + * @brief Defines the application data transmission duty cycle. 60s (changed to 3s), value in [s]. + */ +#define APP_TX_DUTYCYCLE 3 + +/*! + * @brief LoRaWAN application port + */ +#define LORAWAN_APP_PORT 2 + +/*! + * @brief User application data buffer size + */ +#define LORAWAN_APP_DATA_MAX_SIZE 242 + +/* + * ----------------------------------------------------------------------------- + * --- LoRaWAN Configuration --------------------------------------------------- + */ + +/*! + * @brief LoRaWAN confirmed messages + */ +#define LORAWAN_CONFIRMED_MSG_ON true + +/*! + * @brief Default datarate + * + * @remark See @ref smtc_modem_adr_profile_t + */ +#define LORAWAN_DEFAULT_DATARATE SMTC_MODEM_ADR_PROFILE_NETWORK_CONTROLLED + +/*! + * @brief ADR custom list when LORAWAN_DEFAULT_DATARATE is set to SMTC_MODEM_ADR_PROFILE_CUSTOM + */ +uint8_t adr_custom_list[16] = { 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x03, 0x03, + 0x03, 0x02, 0x02, 0x02, 0x01, 0x01, 0x00, 0x00 }; + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE TYPES ----------------------------------------------------------- + */ + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE VARIABLES ------------------------------------------------------- + */ + +/*! + * @brief Stack identifier + */ +static uint8_t stack_id = 0; + +/*! + * @brief User application data + */ +static uint8_t app_data_buffer[LORAWAN_APP_DATA_MAX_SIZE]; + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE FUNCTIONS DECLARATION ------------------------------------------- + */ + +/*! + * @brief Send an application frame on LoRaWAN port defined by LORAWAN_APP_PORT + * + * @param [in] buffer Buffer containing the LoRaWAN buffer + * @param [in] length Payload length + * @param [in] confirmed Send a confirmed or unconfirmed uplink [false : unconfirmed / true : confirmed] + */ +static void send_frame(const uint8_t* buffer, const uint8_t length, const bool confirmed); + +/*! + * @brief Reset event callback + * + * @param [in] reset_count reset counter from the modem + */ +static void on_modem_reset(uint16_t reset_count); + +/*! + * @brief Network Joined event callback + */ +static void on_modem_network_joined(void); + +/*! + * @brief Alarm event callback + */ +static void on_modem_alarm(void); + +/*! + * @brief Tx done event callback + * + * @param [in] status tx done status @ref smtc_modem_event_txdone_status_t + */ +static void on_modem_tx_done(smtc_modem_event_txdone_status_t status); + +/*! + * @brief Downlink data event callback. + * + * @param [in] rssi RSSI in signed value in dBm + 64 + * @param [in] snr SNR signed value in 0.25 dB steps + * @param [in] rx_window RX window + * @param [in] port LoRaWAN port + * @param [in] payload Received buffer pointer + * @param [in] size Received buffer size + */ +static void on_modem_down_data(int8_t rssi, int8_t snr, smtc_modem_event_downdata_window_t rx_window, uint8_t port, + const uint8_t* payload, uint8_t size); + +static void on_modem_join_fail(void); + +static void lorawan_apps_modem_common_configure_lorawan_params(void); + +/* + * ----------------------------------------------------------------------------- + * --- PUBLIC FUNCTIONS DEFINITION --------------------------------------------- + */ + +/** + * @brief Main application entry point. + */ + +lr11xx_hal_context_t radio_context = { + .nss = LR1110_SPI_NSS_PIN, + .busy = LR1110_BUSY_PIN, + .reset = LR1110_NRESER_PIN, + .spi_id = 3, +}; + +int main(void) { + lr11xx_system_clear_errors(&radio_context); + + lr11xx_system_version_t version; + lr11xx_system_get_version(&radio_context, &version); + printf("Hardware Version: %u, 0x%04X\n", version.hw, version.hw); + printf("Type: %u, 0x%04X\n", version.type, version.type); + printf("Firmware Version: %u, 0x%04X\n", version.fw, version.fw); + lr11xx_system_uid_t unique_identifier; + lr11xx_system_read_uid(&radio_context, unique_identifier); + + printf("uid %x %x %x\n", unique_identifier[0], unique_identifier[1], unique_identifier[2]); + + printf("start of lorawan app\n"); + + static apps_modem_event_callback_t smtc_event_callback = { + .adr_mobile_to_static = NULL, + .alarm = on_modem_alarm, + .almanac_update = NULL, + .down_data = on_modem_down_data, + .join_fail = on_modem_join_fail, + .joined = on_modem_network_joined, + .link_status = NULL, + .mute = NULL, + .new_link_adr = NULL, + .reset = on_modem_reset, + .set_conf = NULL, + .stream_done = NULL, + .time_updated_alc_sync = NULL, + .tx_done = on_modem_tx_done, + .upload_done = NULL, + }; + + /* Initialise the ralf_t object corresponding to the board */ + ralf_t* modem_radio = smtc_board_initialise_and_get_ralf( ); + + /* Init board and peripherals */ + hal_mcu_init( ); + smtc_board_init_periph( ); + + /* Init the Lora Basics Modem event callbacks */ + apps_modem_event_init(&smtc_event_callback); + + /* Init the modem and use apps_modem_event_process as event callback, please note that the callback will be called + * immediately after the first call to modem_run_engine because of the reset detection */ + smtc_modem_init(modem_radio, &apps_modem_event_process); // cause process fault + + printf("\n###### ===== LoRa Basics Modem LoRaWAN Class A/C demo application ==== ######\n\n"); + + /* LoRa Basics Modem Version */ + apps_modem_common_display_lbm_version( ); + + /* Configure the partial low power mode */ + // hal_mcu_partial_sleep_enable( APP_PARTIAL_SLEEP ); // smtc function implementation is empty + + lr11xx_system_clear_errors(&radio_context); + lr11xx_system_clear_irq_status(&radio_context, 0xFFFFFFFF); + + printf("inside loop\n"); + + while (1) { + lr11xx_system_clear_errors(&radio_context); + + /* Execute modem runtime, this function must be called again in sleep_time_ms milliseconds or sooner. */ + uint32_t sleep_time_ms = smtc_modem_run_engine( ); // cause process fault + + /* go in low power */ + hal_mcu_set_sleep_for_ms(sleep_time_ms); + + } +} + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE FUNCTIONS DEFINITION -------------------------------------------- + */ + +static void on_modem_reset(uint16_t reset_count) { + printf("on_modem_reset (%i)\n", reset_count); + + HAL_DBG_TRACE_INFO("Application parameters:\n"); + HAL_DBG_TRACE_INFO(" - LoRaWAN uplink Fport = %d\n", LORAWAN_APP_PORT); + HAL_DBG_TRACE_INFO(" - DM report interval = %d\n", APP_TX_DUTYCYCLE); + HAL_DBG_TRACE_INFO(" - Confirmed uplink = %s\n", (LORAWAN_CONFIRMED_MSG_ON == true) ? "Yes" : "No"); + + lorawan_apps_modem_common_configure_lorawan_params(); + + // We use TTN so only enable bank 2 channels. + region_us_915_the_things_network_init(); + + ASSERT_SMTC_MODEM_RC(smtc_modem_join_network(stack_id)); +} + +static void on_modem_network_joined(void) { + printf("on_modem_network_joined successful!\n"); + + ASSERT_SMTC_MODEM_RC(smtc_modem_alarm_start_timer(APP_TX_DUTYCYCLE)); + + ASSERT_SMTC_MODEM_RC(smtc_modem_adr_set_profile(stack_id, LORAWAN_DEFAULT_DATARATE, adr_custom_list)); +} + +static void on_modem_join_fail(void) { + printf("join failed!\n"); +} + +static void on_modem_alarm(void) { + printf("on_modem_alarm\n"); + smtc_modem_status_mask_t modem_status; + // uint32_t charge = 0; + uint8_t app_data_size = 0; + + /* Schedule next packet transmission */ + ASSERT_SMTC_MODEM_RC(smtc_modem_alarm_start_timer(APP_TX_DUTYCYCLE)); + HAL_DBG_TRACE_PRINTF("smtc_modem_alarm_start_timer: %d s\n\n", APP_TX_DUTYCYCLE); + + ASSERT_SMTC_MODEM_RC(smtc_modem_get_status(stack_id, &modem_status)); + modem_status_to_string(modem_status); + + // ASSERT_SMTC_MODEM_RC( smtc_modem_get_charge( &charge ) ); + + printf("[Sensors] Sampling Temperature and Humidity sensors once.\n"); + + bool temperature_available = driver_exists(DRIVER_NUM_TEMPERATURE); + bool humidity_available = driver_exists(DRIVER_NUM_HUMIDITY); + int temp = 0; + int humi = 0; + if (temperature_available) { + libtocksync_temperature_read(&temp); + printf("Temperature: %d.%d deg C, send %d to TTN\n", temp / 100, temp % 100, temp); + } else { + printf("Temperature sensor not available.\n"); + } + + if (humidity_available) { + libtocksync_humidity_read(&humi); + printf("Humidity: %d.%d%%, send %d to TTN\n", humi / 100, humi % 100, humi); + } else { + printf("Humidity sensor not available.\n"); + } + + app_data_buffer[app_data_size++] = (uint8_t)((temp >> 8) & 0xFF); + app_data_buffer[app_data_size++] = (uint8_t)(temp & 0xFF); + app_data_buffer[app_data_size++] = (uint8_t)((humi >> 8) & 0xFF); + app_data_buffer[app_data_size++] = (uint8_t)(humi & 0xFF); + + send_frame(app_data_buffer, app_data_size, LORAWAN_CONFIRMED_MSG_ON); +} + +static void on_modem_tx_done(smtc_modem_event_txdone_status_t status) { + printf("on_modem_tx_done (%i)\n", status); +} + +static void on_modem_down_data(int8_t rssi, int8_t snr, smtc_modem_event_downdata_window_t rx_window, uint8_t port, + const uint8_t* payload, uint8_t size) { + printf("on_modem_down_data\n"); + HAL_DBG_TRACE_INFO("Downlink received:\n"); + HAL_DBG_TRACE_INFO(" - LoRaWAN Fport = %d\n", port); + HAL_DBG_TRACE_INFO(" - Payload size = %d\n", size); + HAL_DBG_TRACE_INFO(" - RSSI = %d dBm\n", rssi - 64); + HAL_DBG_TRACE_INFO(" - SNR = %d dB\n", snr >> 2); + + if (size != 0) { + printf("Payload %p %i %i %i %i %i", payload, size, rx_window, port, rssi, snr); + } +} + +static void send_frame(const uint8_t* buffer, const uint8_t length, bool tx_confirmed) { + printf("send_frame\n"); + uint8_t tx_max_payload; + int32_t duty_cycle; + + /* Check if duty cycle is available */ + ASSERT_SMTC_MODEM_RC(smtc_modem_get_duty_cycle_status(&duty_cycle)); + if (duty_cycle < 0) { + HAL_DBG_TRACE_WARNING("Duty-cycle limitation - next possible uplink in %d ms \n\n", duty_cycle); + return; + } + + ASSERT_SMTC_MODEM_RC(smtc_modem_get_next_tx_max_payload(stack_id, &tx_max_payload)); + if (length > tx_max_payload) { + HAL_DBG_TRACE_WARNING("Not enough space in buffer - send empty uplink to flush MAC commands \n"); + ASSERT_SMTC_MODEM_RC(smtc_modem_request_empty_uplink(stack_id, true, LORAWAN_APP_PORT, tx_confirmed)); + } else { + HAL_DBG_TRACE_INFO("Request uplink\n"); + ASSERT_SMTC_MODEM_RC(smtc_modem_request_uplink(stack_id, LORAWAN_APP_PORT, tx_confirmed, buffer, length)); + } +} + +static void lorawan_apps_modem_common_configure_lorawan_params(void) { + smtc_modem_return_code_t rc = SMTC_MODEM_RC_OK; + uint8_t dev_eui[8] = { 0 }; + uint8_t join_eui[8] = { 0 }; + uint8_t app_key[16] = { 0 }; + + hal_hex_to_bin((char*) LORAWAN_DEVICE_EUI, dev_eui, 8); + hal_hex_to_bin((char*) LORAWAN_JOIN_EUI, join_eui, 8); + hal_hex_to_bin((char*) LORAWAN_APP_KEY, app_key, 16); + + rc = smtc_modem_set_deveui(stack_id, dev_eui); + if (rc != SMTC_MODEM_RC_OK) { + printf("smtc_modem_set_deveui failed: rc=%s (%d)\n", smtc_modem_return_code_to_str(rc), rc); + } + + rc = smtc_modem_set_joineui(stack_id, join_eui); + if (rc != SMTC_MODEM_RC_OK) { + printf("smtc_modem_set_joineui failed: rc=%s (%d)\n", smtc_modem_return_code_to_str(rc), rc); + } + + rc = smtc_modem_set_nwkkey(stack_id, app_key); + if (rc != SMTC_MODEM_RC_OK) { + printf("smtc_modem_set_nwkkey failed: rc=%s (%d)\n", smtc_modem_return_code_to_str(rc), rc); + } + + HAL_DBG_TRACE_INFO("LoRaWAN parameters:\n"); + + rc = smtc_modem_get_deveui(stack_id, dev_eui); + if (rc == SMTC_MODEM_RC_OK) { + HAL_DBG_TRACE_ARRAY("DevEUI", dev_eui, SMTC_MODEM_EUI_LENGTH); + } else { + printf("smtc_modem_get_deveui failed: rc=%s (%d)\n", smtc_modem_return_code_to_str(rc), rc); + } + + rc = smtc_modem_get_joineui(stack_id, join_eui); + if (rc == SMTC_MODEM_RC_OK) { + HAL_DBG_TRACE_ARRAY("JoinEUI", join_eui, SMTC_MODEM_EUI_LENGTH); + } else { + printf("smtc_modem_get_joineui failed: rc=%s (%d)\n", smtc_modem_return_code_to_str(rc), rc); + } + + rc = smtc_modem_set_class(stack_id, LORAWAN_CLASS); + if (rc != SMTC_MODEM_RC_OK) { + printf("smtc_modem_set_class failed: rc=%s (%d)\n", smtc_modem_return_code_to_str(rc), rc); + } + + modem_class_to_string(LORAWAN_CLASS); + + rc = smtc_modem_set_region(stack_id, LORAWAN_REGION); + if (rc != SMTC_MODEM_RC_OK) { + printf("smtc_modem_set_region failed: rc=%s (%d)\n", smtc_modem_return_code_to_str(rc), rc); + } + + modem_region_to_string(LORAWAN_REGION); + + /* adapt the tx power offet depending on the board */ + rc |= smtc_modem_set_tx_power_offset_db(stack_id, smtc_board_get_tx_power_offset( )); +} + +/* --- EOF ------------------------------------------------------------------ */ diff --git a/examples/tests/lr1110/wifi_scan/Makefile b/examples/tests/lr1110/wifi_scan/Makefile new file mode 100644 index 000000000..7b2e16139 --- /dev/null +++ b/examples/tests/lr1110/wifi_scan/Makefile @@ -0,0 +1,19 @@ +# Makefile for user application + +# Specify this directory relative to the current application. +TOCK_USERLAND_BASE_DIR = ../../../.. + +# External libraries used +EXTERN_LIBS += $(TOCK_USERLAND_BASE_DIR)/lr1110 + +override CFLAGS += -I$(TOCK_USERLAND_BASE_DIR)/lr1110 + +# Which files to compile. +C_SRCS += $(wildcard *.c) + +APP_HEAP_SIZE := 40000 +STACK_SIZE := 4096 + +# Include userland master makefile. Contains rules and flags for actually +# building the application. +include $(TOCK_USERLAND_BASE_DIR)/AppMakefile.mk diff --git a/examples/tests/lr1110/wifi_scan/main_geolocation_wifi.c b/examples/tests/lr1110/wifi_scan/main_geolocation_wifi.c new file mode 100644 index 000000000..f781acf6b --- /dev/null +++ b/examples/tests/lr1110/wifi_scan/main_geolocation_wifi.c @@ -0,0 +1,516 @@ +/*! + * @ingroup apps_geolocation + * @file main_geolocation_wifi.c + * + * @brief LoRa Basics Modem LR11XX Geolocation Wi-Fi example + * + * @copyright + * @parblock + * The Clear BSD License + * Copyright Semtech Corporation 2021. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted (subject to the limitations in the disclaimer + * below) provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the Semtech corporation nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY + * THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT + * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SEMTECH CORPORATION BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * @endparblock + +/* + * link to README.md of this example in seeed studio's repo: + * https://github.com/Seeed-Studio/Seeed_Wio_WM1110_Dev_Board/blob/master/apps/examples/geolocation_wifi/README.md + */ + +/*! + * @addtogroup apps_geolocation + * LoRa Basics Modem LR11XX Geolocation Wi-Fi example + * @{ + */ + +#include +#include + +#include + +#include +#include + +/* + * ----------------------------------------------------------------------------- + * --- DEPENDENCIES ------------------------------------------------------------ + */ + +// included in lr1110 library + +// #include "main_geolocation_wifi.h" +// #include "smtc_board.h" +// #include "smtc_hal.h" +// #include "apps_utilities.h" +// #include "apps_modem_common.h" +// #include "apps_modem_event.h" + +// #include "wifi_middleware.h" +// #include "lr11xx_system.h" + +// #include "smtc_modem_utilities.h" +// #include "smtc_board_ralf.h" + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE MACROS----------------------------------------------------------- + */ + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE CONSTANTS ------------------------------------------------------- + */ + + +#define LORAWAN_REGION SMTC_MODEM_REGION_US_915 +#define LORAWAN_CLASS SMTC_MODEM_CLASS_A + +// wm1110dev parameters +/* These need to be updated to use values from your LoRaWAN server */ +#define LORAWAN_DEVICE_EUI "0x0000000000000000" +#define LORAWAN_JOIN_EUI "0x0000000000000000" +#define LORAWAN_APP_KEY "0x00000000000000000000000000000000" + + + +/* + * ----------------------------------------------------------------------------- + * --- LoRaWAN Configuration --------------------------------------------------- + */ + +/*! + * @brief ADR custom list and retransmission parameters for EU868 / IN865 / RU864 / AU915 / CN470 /AS923 / KR920 regions + */ +#define CUSTOM_NB_TRANS_DR5_DR3 1 +#define ADR_CUSTOM_LIST_DR5_DR3 \ + { \ + 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 3, 3 \ + } /* 125kHz - SF7, SF8, SF9 */ + +/*! + * @brief ADR custom list and retransmission parameters for US915 region + */ +#define CUSTOM_NB_TRANS_US915 2 // 1 in code, 2 on README +#define ADR_CUSTOM_LIST_US915 \ + { \ + 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 3, 3 \ + } /* 125kHz - SF7, SF8, SF9 */ + +/*! + * @brief ADR custom list and retransmission parameters for WW2G4 region + */ +#define CUSTOM_NB_TRANS_WW2G4 1 +#define ADR_CUSTOM_LIST_WW2G4 \ + { \ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 \ + } /* SF12 */ + + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE TYPES ----------------------------------------------------------- + */ + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE VARIABLES ------------------------------------------------------- + */ + +/*! + * @brief Stack identifier + */ +static uint8_t stack_id = 0; + +/*! + * @brief Modem radio + */ +static ralf_t* modem_radio; + +/*! + * @brief Wi-Fi output results + */ +static wifi_mw_event_data_scan_done_t wifi_results; + +/*! + * @brief ADR custom list and retransmission definition for EU868 / IN865 / RU864 / AU915 / CN470 /AS923 / KR920 regions + */ +static const uint8_t adr_custom_list_dr5_dr3[16] = ADR_CUSTOM_LIST_DR5_DR3; +static const uint8_t custom_nb_trans_dr5_dr3 = CUSTOM_NB_TRANS_DR5_DR3; + +/*! + * @brief ADR custom list and retransmission definition for US915 region + */ +static const uint8_t adr_custom_list_us915[16] = ADR_CUSTOM_LIST_US915; +static const uint8_t custom_nb_trans_us915 = CUSTOM_NB_TRANS_US915; + +/*! + * @brief ADR custom list and retransmission definition for WW2G4 region + */ +static const uint8_t adr_custom_list_ww2g4[16] = ADR_CUSTOM_LIST_WW2G4; +static const uint8_t custom_nb_trans_ww2g4 = CUSTOM_NB_TRANS_WW2G4; + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE FUNCTIONS DECLARATION ------------------------------------------- + */ + +/*! + * @brief Helper function that configure the custom ADR configuration for geolocation scan & send, based on the region + * already configured in the stack. + * + * Prior using this function, the region must have been set already in the stack. + */ +static void configure_adr(void); + +/*! + * @addtogroup basics_modem_evt_callback + * LoRa Basics Modem event callbacks + * @{ + */ + +/*! + * @brief Reset event callback + * + * @param [in] reset_count reset counter from the modem + */ +static void on_modem_reset(uint16_t reset_count); + +/*! + * @brief Network Joined event callback + */ +static void on_modem_network_joined(void); + +/*! + * @brief Alarm event callback + */ +static void on_modem_alarm(void); + +/*! + * @brief Wi-Fi middleware event callback + */ +static void on_middleware_wifi_event(uint8_t pending_events); + +static void on_modem_join_fail(void); + +static void wifi_apps_modem_common_configure_lorawan_params(void); + +/*! + * @} + */ + +/* + * ----------------------------------------------------------------------------- + * --- PUBLIC FUNCTIONS DEFINITION --------------------------------------------- + */ + +lr11xx_hal_context_t radio_context = { + .nss = LR1110_SPI_NSS_PIN, + .busy = LR1110_BUSY_PIN, + .reset = LR1110_NRESER_PIN, + .spi_id = 3, +}; + +/** + * @brief Main application entry point. + */ +int main(void) { + static apps_modem_event_callback_t smtc_event_callback = { + .adr_mobile_to_static = NULL, + .alarm = on_modem_alarm, + .almanac_update = NULL, + .down_data = NULL, + .join_fail = on_modem_join_fail, + .joined = on_modem_network_joined, + .link_status = NULL, + .mute = NULL, + .new_link_adr = NULL, + .reset = on_modem_reset, + .set_conf = NULL, + .stream_done = NULL, + .time_updated_alc_sync = NULL, + .tx_done = NULL, + .upload_done = NULL, + .user_radio_access = NULL, + .middleware_1 = NULL, + .middleware_2 = on_middleware_wifi_event, + }; + + lr11xx_system_clear_errors(&radio_context); + + /* Initialise the ralf_t object corresponding to the board */ + modem_radio = smtc_board_initialise_and_get_ralf( ); + + /* Init board and peripherals */ + hal_mcu_init( ); + smtc_board_init_periph( ); + + /* Init the Lora Basics Modem event callbacks */ + apps_modem_event_init(&smtc_event_callback); + + /* Init the modem and use smtc_event_process as event callback, please note that the callback will be called + * immediately after the first call to modem_run_engine because of the reset detection */ + smtc_modem_init(modem_radio, &apps_modem_event_process); + + printf("###### ===== LoRa Basics Modem Geolocation Wi-Fi example ==== ######\n\n"); + apps_modem_common_display_lbm_version( ); + + lr11xx_system_clear_errors(&radio_context); + lr11xx_system_clear_irq_status(&radio_context, 0xFFFFFFFF); + + while (1) { + lr11xx_system_clear_errors(&radio_context); + + /* Execute modem runtime, this function must be called again in sleep_time_ms milliseconds or sooner. */ + uint32_t sleep_time_ms = smtc_modem_run_engine( ); + + /* go in low power */ + hal_mcu_set_sleep_for_ms(sleep_time_ms); + } +} + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE FUNCTIONS DEFINITION -------------------------------------------- + */ + +/*! + * @brief LoRa Basics Modem event callbacks called by smtc_event_process function + */ + +static void on_modem_reset(uint16_t reset_count) { + printf("on_modem_reset %i\n", reset_count); + + /* Basic LoRaWAN configuration */ + wifi_apps_modem_common_configure_lorawan_params( ); + + // We use TTN so only enable bank 2 channels. + region_us_915_the_things_network_init(); + + /* Start the Join process */ + ASSERT_SMTC_MODEM_RC(smtc_modem_join_network(stack_id)); + + HAL_DBG_TRACE_INFO("###### ===== JOINING ==== ######\n\n"); +} + +static void on_modem_network_joined(void) { + printf("on_modem_network_joined successful!\n"); + + mw_return_code_t wifi_rc; + mw_version_t mw_version; + + /* Set the custom ADR profile for geolocation scan & send */ + configure_adr( ); + + /* Initialize Wi-Fi middleware */ + wifi_mw_get_version(&mw_version); + // printf( "Initializing Wi-Fi middleware v%d.%d.%d\n", mw_version.major, mw_version.minor, + // mw_version.patch ); + wifi_mw_set_payload_format(WIFI_MW_PAYLOAD_MAC); + wifi_mw_init(modem_radio, stack_id); + + ASSERT_SMTC_MODEM_RC(smtc_modem_alarm_start_timer(5)); + + /* Start the Wi-Fi scan sequence */ + // smtc_modem_suspend_before_user_radio_access( ); + + wifi_rc = wifi_mw_scan_start(1); + if (wifi_rc != MW_RC_OK) { + printf("Error: Failed to start WiFi scan\n"); + } +} + +static void on_modem_alarm(void) { + // printf("on_modem_alarm\n"); + // wifi_mw_scan_rp_task_done(); + + // ASSERT_SMTC_MODEM_RC( smtc_modem_alarm_start_timer( WIFI_SCAN_PERIOD ) ); + // printf( "smtc_modem_alarm_start_timer: %d s\n\n", WIFI_SCAN_PERIOD ); + + // mw_return_code_t wifi_rc; + // wifi_rc = wifi_mw_scan_start( 5 ); + // if( wifi_rc != MW_RC_OK ) + // { + // HAL_DBG_TRACE_ERROR( "Failed to start WiFi scan\n" ); + // } +} + +static void on_modem_join_fail(void) { + printf("join failed!\n"); +} + +/*! + * @brief User private function + */ + +static void on_middleware_wifi_event(uint8_t pending_events) { + // printf("on_middleware_wifi_event\n"); + + /* Parse events */ + if (wifi_mw_has_event(pending_events, WIFI_MW_EVENT_SCAN_DONE)) { + // printf( "Wi-Fi middleware event - SCAN DONE\n" ); + wifi_mw_get_event_data_scan_done(&wifi_results); + wifi_mw_display_results(&wifi_results); + } + + if (wifi_mw_has_event(pending_events, WIFI_MW_EVENT_TERMINATED)) { + wifi_mw_event_data_terminated_t event_data; + + // printf( "Wi-Fi middleware event - TERMINATED\n" ); + wifi_mw_get_event_data_terminated(&event_data); + // HAL_DBG_TRACE_PRINTF( "TERMINATED info:\n" ); + printf("-- number of scans sent: %u\n", event_data.nb_scans_sent); + } + + if (wifi_mw_has_event(pending_events, WIFI_MW_EVENT_SCAN_CANCELLED)) { + printf("Wi-Fi middleware event - SCAN CANCELLED\n"); + } + + if (wifi_mw_has_event(pending_events, WIFI_MW_EVENT_ERROR_UNKNOWN)) { + printf("Wi-Fi middleware event - UNEXPECTED ERROR\n"); + } + + /* Program next scan */ + if (wifi_mw_has_event(pending_events, WIFI_MW_EVENT_ERROR_UNKNOWN) || + wifi_mw_has_event(pending_events, WIFI_MW_EVENT_TERMINATED)) { + /* Program the next Wi-Fi group */ + // wifi_rc = wifi_mw_scan_start( WIFI_SCAN_PERIOD ); + // printf("receive unknown error\n"); + // smtc_modem_alarm_start_timer( 1 ); + // wifi_rc = wifi_mw_scan_start( 0 ); + // if( wifi_rc != MW_RC_OK ) + // { + // printf( "Error! Failed to start WiFi scan\n" ); + // } + } + + wifi_mw_clear_pending_events( ); +} + +void configure_adr(void) { + // printf("configure_adr\n"); + + smtc_modem_region_t region; + + ASSERT_SMTC_MODEM_RC(smtc_modem_get_region(stack_id, ®ion)); + + // printf("Region number: %d\n", region); + + /* Set the ADR profile once joined */ + switch (region) { + case SMTC_MODEM_REGION_EU_868: + case SMTC_MODEM_REGION_IN_865: + case SMTC_MODEM_REGION_RU_864: + case SMTC_MODEM_REGION_AU_915: + case SMTC_MODEM_REGION_AS_923_GRP1: + case SMTC_MODEM_REGION_AS_923_GRP2: + case SMTC_MODEM_REGION_AS_923_GRP3: + case SMTC_MODEM_REGION_CN_470: + case SMTC_MODEM_REGION_CN_470_RP_1_0: + case SMTC_MODEM_REGION_KR_920: + ASSERT_SMTC_MODEM_RC(smtc_modem_adr_set_profile(stack_id, SMTC_MODEM_ADR_PROFILE_CUSTOM, + adr_custom_list_dr5_dr3)); + ASSERT_SMTC_MODEM_RC(smtc_modem_set_nb_trans(stack_id, custom_nb_trans_dr5_dr3)); + break; + case SMTC_MODEM_REGION_US_915: + ASSERT_SMTC_MODEM_RC(smtc_modem_adr_set_profile(stack_id, SMTC_MODEM_ADR_PROFILE_CUSTOM, adr_custom_list_us915)); + ASSERT_SMTC_MODEM_RC(smtc_modem_set_nb_trans(stack_id, custom_nb_trans_us915)); + break; + case SMTC_MODEM_REGION_WW2G4: + ASSERT_SMTC_MODEM_RC(smtc_modem_adr_set_profile(stack_id, SMTC_MODEM_ADR_PROFILE_CUSTOM, adr_custom_list_ww2g4)); + ASSERT_SMTC_MODEM_RC(smtc_modem_set_nb_trans(stack_id, custom_nb_trans_ww2g4)); + break; + default: + HAL_DBG_TRACE_ERROR("Region not supported in this example, could not set custom ADR profile\n"); + break; + } + /* Disable auto switch to network controlled after a certain amount of TX without RX */ + ASSERT_SMTC_MODEM_RC(smtc_modem_connection_timeout_set_thresholds(stack_id, 0, 0)); +} + +static void wifi_apps_modem_common_configure_lorawan_params(void) { + smtc_modem_return_code_t rc = SMTC_MODEM_RC_OK; + uint8_t dev_eui[8] = { 0 }; + uint8_t join_eui[8] = { 0 }; + uint8_t app_key[16] = { 0 }; + + hal_hex_to_bin((char*) LORAWAN_DEVICE_EUI, dev_eui, 8); + hal_hex_to_bin((char*) LORAWAN_JOIN_EUI, join_eui, 8); + hal_hex_to_bin((char*) LORAWAN_APP_KEY, app_key, 16); + + rc = smtc_modem_set_deveui(stack_id, dev_eui); + if (rc != SMTC_MODEM_RC_OK) { + printf("smtc_modem_set_deveui failed: rc=%s (%d)\n", smtc_modem_return_code_to_str(rc), rc); + } + + rc = smtc_modem_set_joineui(stack_id, join_eui); + if (rc != SMTC_MODEM_RC_OK) { + printf("smtc_modem_set_joineui failed: rc=%s (%d)\n", smtc_modem_return_code_to_str(rc), rc); + } + + rc = smtc_modem_set_nwkkey(stack_id, app_key); + if (rc != SMTC_MODEM_RC_OK) { + printf("smtc_modem_set_nwkkey failed: rc=%s (%d)\n", smtc_modem_return_code_to_str(rc), rc); + } + + HAL_DBG_TRACE_INFO("LoRaWAN parameters:\n"); + + rc = smtc_modem_get_deveui(stack_id, dev_eui); + if (rc == SMTC_MODEM_RC_OK) { + HAL_DBG_TRACE_ARRAY("DevEUI", dev_eui, SMTC_MODEM_EUI_LENGTH); + } else { + printf("smtc_modem_get_deveui failed: rc=%s (%d)\n", smtc_modem_return_code_to_str(rc), rc); + } + + rc = smtc_modem_get_joineui(stack_id, join_eui); + if (rc == SMTC_MODEM_RC_OK) { + HAL_DBG_TRACE_ARRAY("JoinEUI", join_eui, SMTC_MODEM_EUI_LENGTH); + } else { + printf("smtc_modem_get_joineui failed: rc=%s (%d)\n", smtc_modem_return_code_to_str(rc), rc); + } + + rc = smtc_modem_set_class(stack_id, LORAWAN_CLASS); + if (rc != SMTC_MODEM_RC_OK) { + printf("smtc_modem_set_class failed: rc=%s (%d)\n", smtc_modem_return_code_to_str(rc), rc); + } + + modem_class_to_string(LORAWAN_CLASS); + + rc = smtc_modem_set_region(stack_id, LORAWAN_REGION); + if (rc != SMTC_MODEM_RC_OK) { + printf("smtc_modem_set_region failed: rc=%s (%d)\n", smtc_modem_return_code_to_str(rc), rc); + } + + modem_region_to_string(LORAWAN_REGION); + + /* adapt the tx power offet depending on the board */ + rc |= smtc_modem_set_tx_power_offset_db(stack_id, smtc_board_get_tx_power_offset( )); +} + +/*! + * @} + */ + +/* --- EOF ------------------------------------------------------------------ */ diff --git a/libtock/services/alarm.c b/libtock/services/alarm.c index d6e5b89ab..feca19987 100644 --- a/libtock/services/alarm.c +++ b/libtock/services/alarm.c @@ -48,15 +48,15 @@ static uint32_t ticks_to_ms(uint32_t ticks) { uint32_t frequency; libtock_alarm_command_get_frequency(&frequency); - uint32_t seconds = (ticks / frequency); - uint32_t milliseconds_per_second = 1000; + uint64_t seconds = (ticks / frequency); + uint64_t milliseconds_per_second = 1000; // Calculate the conversion of full seconds to ticks. - uint32_t milliseconds = seconds * milliseconds_per_second; + uint64_t milliseconds = seconds * milliseconds_per_second; // To get conversion accuracy within 1 millisecond, the conversion // must also convert partial seconds. - uint32_t leftover_ticks = ticks % frequency; + uint64_t leftover_ticks = ticks % frequency; // This calculation is mathematically equivalent to doing: // diff --git a/lr1110/.gitignore b/lr1110/.gitignore new file mode 100644 index 000000000..3e77899d9 --- /dev/null +++ b/lr1110/.gitignore @@ -0,0 +1,2 @@ +*.zip +lr1110/seeed \ No newline at end of file diff --git a/lr1110/Makefile b/lr1110/Makefile new file mode 100644 index 000000000..3b83c109a --- /dev/null +++ b/lr1110/Makefile @@ -0,0 +1,139 @@ +TOCK_USERLAND_BASE_DIR ?= .. +LIBNAME := lr1110 +$(LIBNAME)_DIR := $(TOCK_USERLAND_BASE_DIR)/$(LIBNAME) + +LR1110_DIR = $(TOCK_USERLAND_BASE_DIR)/lr1110/lr1110 +SEEED_DIR = $(LR1110_DIR)/seeed + +ifeq ($(wildcard $(SEEED_DIR)/.*),) + $(error Error: $(SEEED_DIR) directory does not exist. Please run `make -f Makefile.setup` first) +endif + +# include our provided source files +OUR_CSRCS := $(wildcard $(LR1110_DIR)/*.c) + +# include changed source files +CHANGED_CSRCS := $(wildcard $(LR1110_DIR)/src_changed/*.c) + +# include changed headers +override CFLAGS += -I$(LR1110_DIR)/inc_changed + +# -DREGION_US_915: Defines the LoRaWAN region to US 915 MHz band +# -DRP2_103: Specifies the use of Regional Parameters version RP2-1.0.3 +# -DTASK_EXTENDED_2: The LoRa Basics Modem extended uplink ID to be used for Wi-Fi uplinks +# -DLR11XX, -DLR11XX_TRANSCEIVER: Let the code select methods for LR11XX radio board +override CFLAGS += -DREGION_US_915 -DRP2_103 -DTASK_EXTENDED_2 -DLR11XX -DLR11XX_TRANSCEIVER + +# include unchanged source files from seeed's repo +UNCHANGED_CSRCS := \ +$(SEEED_DIR)/apps/common/apps_modem_common.c \ +$(SEEED_DIR)/apps/common/apps_modem_event.c \ +$(SEEED_DIR)/apps/common/apps_utilities.c \ +$(SEEED_DIR)/apps/common/smtc_modem_api_str.c \ +$(SEEED_DIR)/geolocation_middleware/common/mw_common.c \ +$(SEEED_DIR)/geolocation_middleware/gnss/src/gnss_helpers.c \ +$(SEEED_DIR)/geolocation_middleware/gnss/src/gnss_middleware.c \ +$(SEEED_DIR)/geolocation_middleware/gnss/src/gnss_queue.c \ +$(SEEED_DIR)/geolocation_middleware/gnss/src/lr11xx_driver_extension.c \ +$(SEEED_DIR)/geolocation_middleware/wifi/src/wifi_middleware.c \ +$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/device_management/dm_downlink.c \ +$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/device_management/modem_context.c \ +$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/lorawan_api/lorawan_api.c \ +$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/lr1mac/src/lr1_stack_mac_layer.c \ +$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/lr1mac/src/lr1mac_class_b/smtc_beacon_sniff.c \ +$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/lr1mac/src/lr1mac_class_b/smtc_ping_slot.c \ +$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/lr1mac/src/lr1mac_class_c/lr1mac_class_c.c \ +$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/lr1mac/src/lr1mac_core.c \ +$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/lr1mac/src/lr1mac_utilities.c \ +$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/lr1mac/src/services/smtc_duty_cycle.c \ +$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/lr1mac/src/services/smtc_lbt.c \ +$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/lr1mac/src/services/smtc_multicast.c \ +$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/lr1mac/src/smtc_real/src/smtc_real.c \ +$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/lr1mac/src/smtc_real/src/region_us_915.c \ +$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/modem_core/smtc_modem_test.c \ +$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/modem_services/fifo_ctrl.c \ +$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/modem_services/lorawan_certification.c \ +$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/modem_services/modem_utilities.c \ +$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/modem_services/smtc_clock_sync.c \ +$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/modem_services/smtc_modem_services_hal.c \ +$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/modem_supervisor/modem_supervisor.c \ +$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/radio_drivers/lr11xx_driver/src/lr11xx_bootloader.c \ +$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/radio_drivers/lr11xx_driver/src/lr11xx_crypto_engine.c \ +$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/radio_drivers/lr11xx_driver/src/lr11xx_driver_version.c \ +$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/radio_drivers/lr11xx_driver/src/lr11xx_gnss.c \ +$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/radio_drivers/lr11xx_driver/src/lr11xx_lr_fhss.c \ +$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/radio_drivers/lr11xx_driver/src/lr11xx_radio.c \ +$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/radio_drivers/lr11xx_driver/src/lr11xx_radio_timings.c \ +$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/radio_drivers/lr11xx_driver/src/lr11xx_regmem.c \ +$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/radio_drivers/lr11xx_driver/src/lr11xx_system.c \ +$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/radio_drivers/lr11xx_driver/src/lr11xx_wifi.c \ +$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/radio_planner/src/radio_planner_hal.c \ +$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/smtc_modem_crypto/smtc_modem_crypto.c \ +$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/smtc_modem_crypto/soft_secure_element/aes.c \ +$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/smtc_modem_crypto/soft_secure_element/cmac.c \ +$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/smtc_modem_crypto/soft_secure_element/soft_se.c \ +$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/smtc_modem_services/src/alc_sync/alc_sync.c \ +$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/smtc_modem_services/src/almanac_update/almanac_update.c \ +$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/smtc_modem_services/src/file_upload/file_upload.c \ +$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/smtc_modem_services/src/stream/rose.c \ +$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/smtc_modem_services/src/stream/stream.c \ +$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/smtc_ral/src/ral_lr11xx.c \ +$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/smtc_ralf/src/ralf_lr11xx.c \ +$(SEEED_DIR)/smtc_hal/smtc_modem_hal.c \ +$(SEEED_DIR)/wm1110/LR11XX/common/src/ral_lr11xx_bsp.c \ +$(SEEED_DIR)/wm1110/LR11XX/common/src/smtc_board_lr11xx.c \ +$(SEEED_DIR)/wm1110/LR11XX/smtc_shield_lr11xx/common/src/mw_bsp.c \ +$(SEEED_DIR)/wm1110/LR11XX/smtc_shield_lr11xx/common/src/smtc_shield_lr11x0_common.c \ +$(SEEED_DIR)/wm1110/LR11XX/smtc_shield_lr11xx/common/src/smtc_shield_lr11xx_common.c \ +$(SEEED_DIR)/wm1110/LR11XX/smtc_shield_lr11xx/LR1110/LR1110MB1DxS/smtc_shield_lr1110mb1dxs.c \ +$(SEEED_DIR)/wm1110/LR11XX/smtc_shield_lr11xx/LR1110/LR1110MB1GxS/smtc_shield_lr1110mb1gxs.c \ + +# include unchanged headers from seeed's repo +override CFLAGS += \ +-I$(SEEED_DIR)/apps/common/ \ +-I$(SEEED_DIR)/geolocation_middleware/gnss/src/ \ +-I$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/device_management/ \ +-I$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/lorawan_api/ \ +-I$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/lr1mac/src/ \ +-I$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/lr1mac/src/lr1mac_class_b/ \ +-I$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/lr1mac/src/lr1mac_class_c/ \ +-I$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/lr1mac/src/services/ \ +-I$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/lr1mac/src/smtc_real/src/ \ +-I$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/modem_services/ \ +-I$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/modem_supervisor/ \ +-I$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/radio_drivers/lr11xx_driver/src/ \ +-I$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/radio_planner/src/ \ +-I$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/smtc_modem_crypto/ \ +-I$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/smtc_modem_crypto/soft_secure_element/ \ +-I$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/smtc_modem_services/src/alc_sync/ \ +-I$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/smtc_modem_services/src/almanac_update/ \ +-I$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/smtc_modem_services/src/file_upload/ \ +-I$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/smtc_modem_services/src/stream/ \ +-I$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/smtc_ral/src/ \ +-I$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/smtc_ralf/src/ \ +-I$(SEEED_DIR)/wm1110/LR11XX/common/src/ \ +-I$(SEEED_DIR)/wm1110/LR11XX/smtc_shield_lr11xx/LR1110/LR1110MB1DxS/ \ +-I$(SEEED_DIR)/wm1110/LR11XX/smtc_shield_lr11xx/LR1110/LR1110MB1GxS/ \ +-I$(SEEED_DIR)/wm1110/LR11XX/smtc_shield_lr11xx/common/src/ \ +-I$(SEEED_DIR)/lora_basics_modem \ +-I$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/smtc_modem_services \ +-I$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/smtc_modem_services/headers \ +-I$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/smtc_modem_services/src \ +-I$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/modem_config \ +-I$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/smtc_modem_crypto/smtc_secure_element \ +-I$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/lr1mac \ +-I$(SEEED_DIR)/geolocation_middleware/common \ +-I$(SEEED_DIR)/lora_basics_modem/smtc_modem_api \ +-I$(SEEED_DIR)/lora_basics_modem/smtc_modem_hal \ +-I$(SEEED_DIR)/geolocation_middleware/bsp \ +-I$(SEEED_DIR)/geolocation_middleware/wifi/src \ +-I$(SEEED_DIR)/wm1110/LR11XX/smtc_lr11xx_board \ +-I$(SEEED_DIR)/wm1110/LR11XX/smtc_shield_lr11xx/common/inc/ \ +-I$(SEEED_DIR)/wm1110/LR11XX/radio_drivers_hal \ +-I$(SEEED_DIR)/wm1110/LR11XX/common/inc \ +-I$(SEEED_DIR)/wm1110/interface \ +-I$(SEEED_DIR)/smtc_hal/inc + +$(LIBNAME)_SRCS := $(OUR_CSRCS) $(UNCHANGED_CSRCS) $(CHANGED_CSRCS) + +include $(TOCK_USERLAND_BASE_DIR)/TockLibrary.mk \ No newline at end of file diff --git a/lr1110/Makefile.app b/lr1110/Makefile.app new file mode 100644 index 000000000..abd19df2c --- /dev/null +++ b/lr1110/Makefile.app @@ -0,0 +1,52 @@ +LR1110_DIR = $(TOCK_USERLAND_BASE_DIR)/lr1110/lr1110 +SEEED_DIR = $(LR1110_DIR)/seeed + +# include changed headers and parameters +override CFLAGS += -I$(LR1110_DIR)/inc_changed -DREGION_US_915 -DRP2_103 -DTASK_EXTENDED_2 -DLR11XX -DLR11XX_TRANSCEIVER + +# include unchanged headers from seeed's repo +override CFLAGS += \ +-I$(SEEED_DIR)/apps/common/ \ +-I$(SEEED_DIR)/geolocation_middleware/gnss/src/ \ +-I$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/device_management/ \ +-I$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/lorawan_api/ \ +-I$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/lr1mac/src/ \ +-I$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/lr1mac/src/lr1mac_class_b/ \ +-I$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/lr1mac/src/lr1mac_class_c/ \ +-I$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/lr1mac/src/services/ \ +-I$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/lr1mac/src/smtc_real/src/ \ +-I$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/modem_services/ \ +-I$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/modem_supervisor/ \ +-I$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/radio_drivers/lr11xx_driver/src/ \ +-I$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/radio_planner/src/ \ +-I$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/smtc_modem_crypto/ \ +-I$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/smtc_modem_crypto/soft_secure_element/ \ +-I$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/smtc_modem_services/src/alc_sync/ \ +-I$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/smtc_modem_services/src/almanac_update/ \ +-I$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/smtc_modem_services/src/file_upload/ \ +-I$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/smtc_modem_services/src/stream/ \ +-I$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/smtc_ral/src/ \ +-I$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/smtc_ralf/src/ \ +-I$(SEEED_DIR)/smtc_hal/ \ +-I$(SEEED_DIR)/wm1110/LR11XX/common/src/ \ +-I$(SEEED_DIR)/wm1110/LR11XX/smtc_shield_lr11xx/LR1110/LR1110MB1DxS/ \ +-I$(SEEED_DIR)/wm1110/LR11XX/smtc_shield_lr11xx/LR1110/LR1110MB1GxS/ \ +-I$(SEEED_DIR)/wm1110/LR11XX/smtc_shield_lr11xx/common/src/ \ +-I$(SEEED_DIR)/lora_basics_modem \ +-I$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/smtc_modem_services \ +-I$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/smtc_modem_services/headers \ +-I$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/smtc_modem_services/src \ +-I$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/modem_config \ +-I$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/smtc_modem_crypto/smtc_secure_element \ +-I$(SEEED_DIR)/lora_basics_modem/smtc_modem_core/lr1mac \ +-I$(SEEED_DIR)/geolocation_middleware/common \ +-I$(SEEED_DIR)/lora_basics_modem/smtc_modem_api \ +-I$(SEEED_DIR)/lora_basics_modem/smtc_modem_hal \ +-I$(SEEED_DIR)/geolocation_middleware/bsp \ +-I$(SEEED_DIR)/geolocation_middleware/wifi/src \ +-I$(SEEED_DIR)/wm1110/LR11XX/smtc_lr11xx_board \ +-I$(SEEED_DIR)/wm1110/LR11XX/smtc_shield_lr11xx/common/inc/ \ +-I$(SEEED_DIR)/wm1110/LR11XX/radio_drivers_hal \ +-I$(SEEED_DIR)/wm1110/LR11XX/common/inc \ +-I$(SEEED_DIR)/wm1110/interface \ +-I$(SEEED_DIR)/smtc_hal/inc \ No newline at end of file diff --git a/lr1110/Makefile.setup b/lr1110/Makefile.setup new file mode 100644 index 000000000..be342c835 --- /dev/null +++ b/lr1110/Makefile.setup @@ -0,0 +1,36 @@ +TOCK_USERLAND_BASE_DIR ?= .. +LR1110_DIR = $(TOCK_USERLAND_BASE_DIR)/lr1110/lr1110 + +VERSION_HASH := 7c33c9ef136c841a7b44f530d2415789c86f48af + +SEEED_DIR := $(LR1110_DIR)/seeed +ZIP_FILE := $(SEEED_DIR).zip +EXTRACTED_DIR := $(SEEED_DIR)/Seeed_Wio_WM1110_Dev_Board-$(VERSION_HASH) + +all: $(LR1110_DIR)/wifi_helpers.c $(LR1110_DIR)/smtc_modem.c $(LR1110_DIR)/radio_planner.c + +# Apply patch to wifi_helpers.c and use that version instead of what is provided +# in the seeed library. +$(LR1110_DIR)/wifi_helpers.c: $(SEEED_DIR)/smtc_hal/smtc_modem_hal.c + cp $(LR1110_DIR)/seeed/geolocation_middleware/wifi/src/wifi_helpers.c $(LR1110_DIR)/wifi_helpers.c + cd $(LR1110_DIR); patch -p1 < ../wifi_helpers.patch + +# Apply patch to smtc_modem.c and use that version instead of what is provided +# in the seeed library. +$(LR1110_DIR)/smtc_modem.c: $(SEEED_DIR)/smtc_hal/smtc_modem_hal.c + cp $(LR1110_DIR)/seeed/lora_basics_modem/smtc_modem_core/modem_core/smtc_modem.c $(LR1110_DIR)/smtc_modem.c + cd $(LR1110_DIR); patch -p1 < ../smtc_modem.patch + +# Apply patch to radio_planner.c and use that version instead of what is provided +# in the seeed library. +$(LR1110_DIR)/radio_planner.c: $(SEEED_DIR)/smtc_hal/smtc_modem_hal.c + cp $(LR1110_DIR)/seeed/lora_basics_modem/smtc_modem_core/radio_planner/src/radio_planner.c $(LR1110_DIR)/radio_planner.c + cd $(LR1110_DIR); patch -p1 < ../radio_planner.patch + +$(SEEED_DIR)/smtc_hal/smtc_modem_hal.c: + curl -L --output $(ZIP_FILE) "https://codeload.github.com/Seeed-Studio/Seeed_Wio_WM1110_Dev_Board/zip/$(VERSION_HASH)" + unzip -q $(ZIP_FILE) -d $(SEEED_DIR) + rm -f $(ZIP_FILE) # Remove zip file after unzip + mv $(EXTRACTED_DIR)/* $(SEEED_DIR)/ + rmdir $(EXTRACTED_DIR) # move unzipped code to SEEED_DIR, remove original directory + touch $(SEEED_DIR) diff --git a/lr1110/README.md b/lr1110/README.md new file mode 100644 index 000000000..6d1dd52da --- /dev/null +++ b/lr1110/README.md @@ -0,0 +1,34 @@ +lr1110 - LoRaWAN and Wi-Fi Scanning for Tock +=================================== + +This library provides user space support for the LR1110 LoRa chip on [Wio-WM1110 development board](https://github.com/Seeed-Studio/Seeed_Wio_WM1110_Dev_Board) within Tock. It enables the device to join LoRaWAN (The Things Network), perform Wi-Fi scanning, and transmit data online, which could be further used for indoor geolocation. + + +Using lr1110 in libtock-c +----------------------- + +To use this library in an app, include this line in the app Makefile: + +```make +EXTERN_LIBS += $(TOCK_USERLAND_BASE_DIR)/lr1110 +``` + +To use lr1110 library in the main source file of an example app, include this line at its beginning: + +```c +#include +``` + + +Compile the library manually +---------------------------- + +When building an app that uses lr1110, this library will automatically be compiled. + +To compile manually (perhaps for testing), run the following lines. + +``` +cd libtock-c/lr1110 +make -f Makefile.setup +make +``` diff --git a/lr1110/lr1110/.gitignore b/lr1110/lr1110/.gitignore new file mode 100644 index 000000000..498dba4f2 --- /dev/null +++ b/lr1110/lr1110/.gitignore @@ -0,0 +1,4 @@ +wifi_helpers.c +smtc_modem.c +radio_planner.c + diff --git a/lr1110/lr1110/inc_changed/lis3dh.h b/lr1110/lr1110/inc_changed/lis3dh.h new file mode 100644 index 000000000..c30256642 --- /dev/null +++ b/lr1110/lr1110/inc_changed/lis3dh.h @@ -0,0 +1,3 @@ +// We need to include this empty file because the smtc_hal_mcu.h header expects +// it. Since we do not use this driver we do not need to actually include +// anything here. \ No newline at end of file diff --git a/lr1110/lr1110/inc_changed/sht41.h b/lr1110/lr1110/inc_changed/sht41.h new file mode 100644 index 000000000..c30256642 --- /dev/null +++ b/lr1110/lr1110/inc_changed/sht41.h @@ -0,0 +1,3 @@ +// We need to include this empty file because the smtc_hal_mcu.h header expects +// it. Since we do not use this driver we do not need to actually include +// anything here. \ No newline at end of file diff --git a/lr1110/lr1110/inc_changed/smtc_hal_flash.h b/lr1110/lr1110/inc_changed/smtc_hal_flash.h new file mode 100644 index 000000000..a2ce1da26 --- /dev/null +++ b/lr1110/lr1110/inc_changed/smtc_hal_flash.h @@ -0,0 +1,56 @@ + +#ifndef __SMTC_HAL_FLASH_H +#define __SMTC_HAL_FLASH_H + +// We just use the beginning of our flash region and not a specific address. +#define ADDR_FLASH_LORAWAN_CONTEXT 0 +#define ADDR_FLASH_MODEM_CONTEXT 512 +#define ADDR_FLASH_DEVNONCE_CONTEXT 1024 +#define ADDR_FLASH_SECURE_ELEMENT_CONTEXT 1536 + +// #define ADDR_FLASH_PAGE_SIZE (( uint32_t )0x00001000 ) // Size of Page = 4 KBytes +// #define ADDR_FLASH_PAGE_0 (( uint32_t )0x00000000 ) // Base @ of Page 0, 4 KBytes */ +// #define ADDR_FLASH_PAGE( page ) ( ADDR_FLASH_PAGE_0 + ( page ) *ADDR_FLASH_PAGE_SIZE ) + +// #ifdef SOFTDEVICE_PRESENT +// #define APP_FLASH_ADDR_START 0xEA000 +// #define APP_FLASH_ADDR_END 0xEDFFF +// #else +// #define APP_FLASH_ADDR_START 0xFC000 +// #define APP_FLASH_ADDR_END 0xFFFFF +// #endif + +// #define APP_FLASH_SIZE_MAX 0x4000 +// #define APP_FLASH_PAGE_MAX 0x04 + +// #ifdef SOFTDEVICE_PRESENT +// #define ADDR_FLASH_LORAWAN_CONTEXT ADDR_FLASH_PAGE(237) +// #define ADDR_FLASH_MODEM_CONTEXT ADDR_FLASH_PAGE(236) +// #define ADDR_FLASH_DEVNONCE_CONTEXT ADDR_FLASH_PAGE(235) +// #define ADDR_FLASH_SECURE_ELEMENT_CONTEXT ADDR_FLASH_PAGE(234) +// #else +// #define ADDR_FLASH_LORAWAN_CONTEXT ADDR_FLASH_PAGE(255) +// #define ADDR_FLASH_MODEM_CONTEXT ADDR_FLASH_PAGE(254) +// #define ADDR_FLASH_DEVNONCE_CONTEXT ADDR_FLASH_PAGE(253) +// #define ADDR_FLASH_SECURE_ELEMENT_CONTEXT ADDR_FLASH_PAGE(252) +// #endif + +#ifdef __cplusplus +extern "C" { +#endif + +smtc_hal_status_t hal_flash_init( void ); + +smtc_hal_status_t hal_flash_deinit( void ); + +smtc_hal_status_t hal_flash_erase_page( uint32_t addr, uint8_t nb_page ); + +smtc_hal_status_t hal_flash_write_buffer( uint32_t addr, const uint8_t* buffer, uint32_t size ); + +void hal_flash_read_buffer( uint32_t addr, uint8_t* buffer, uint32_t size ); + +#endif + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/lr1110/lr1110/lr1110.h b/lr1110/lr1110/lr1110.h new file mode 100644 index 000000000..cec8f1870 --- /dev/null +++ b/lr1110/lr1110/lr1110.h @@ -0,0 +1,126 @@ +// unchanged headers +#include "smtc_d2d.h" +#include "modem_context.h" +#include "apps_modem_common.h" +#include "smtc_modem_utilities.h" +#include "lr11xx_regmem.h" +#include "smtc_basic_modem_lr11xx_api_extension.h" +#include "smtc_modem_hal.h" +#include "radio_planner_hook_id_defs.h" +#include "gnss_middleware.h" +#include "wifi_middleware.h" +#include "mw_bsp.h" +#include "smtc_modem_services_hal.h" +#include "ral_lr11xx_bsp.h" +#include "radio_planner_stats.h" +#include "mw_assert.h" +#include "lr11xx_crypto_engine_types.h" +#include "lr1mac_core.h" +#include "lr1mac_defs.h" +#include "lr11xx_system.h" +#include "device_management_defs.h" +#include "lr1mac_config.h" +#include "lr11xx_lr_fhss_types.h" +#include "modem_utilities.h" +#include "mw_common.h" +#include "smtc_board_ralf.h" +#include "lr11xx_radio_types.h" +#include "lr11xx_gnss.h" +#include "fifo_ctrl.h" +#include "lr1mac_utilities.h" +#include "gnss_version.h" +#include "lmic_defines.h" +#include "smtc_shield_lr11xx_geoloc_if.h" +#include "smtc_clock_sync.h" +#include "smtc_modem_test_api.h" +#include "smtc_lr11xx_board.h" +#include "file_upload_defs.h" +#include "smtc_board.h" +#include "stream.h" +#include "modem_pinout.h" +#include "wifi_version.h" +#include "gnss_queue_defs.h" +#include "gnss_queue.h" +#include "gnss_helpers_defs.h" +#include "lr11xx_radio.h" +#include "smtc_modem_services_config.template.h" +#include "lorawan_api.h" +#include "apps_modem_event.h" +#include "smtc_lbt.h" +#include "ralf_lr11xx.h" +#include "lr11xx_driver_extension.h" +#include "modem_supervisor.h" +#include "lr11xx_wifi_types.h" +#include "rose_defs.h" +#include "gnss_helpers.h" +#include "aes.h" +#include "lr11xx_gnss_types.h" +#include "lora_basics_modem_version.h" +#include "ral_defs.h" +#include "smtc_modem_api.h" +#include "ralf_lr11xx_bsp.h" +#include "lr11xx_bootloader_types.h" +#include "lr11xx_system_types.h" +#include "dm_downlink.h" +#include "lr1_stack_mac_layer.h" +#include "modem_services_common.h" +#include "lr1mac_class_c.h" +#include "lr11xx_hal.h" +#include "wifi_helpers.h" +#include "smtc_modem_crypto.h" +#include "alc_sync.h" +#include "ralf_defs.h" +#include "smtc_beacon_sniff.h" +#include "lr11xx_bootloader.h" +#include "rose.h" +#include "lr11xx_hal_context.h" +#include "region_us_915.h" +#include "file_upload.h" +#include "ralf_drv.h" +#include "ral.h" +#include "smtc_duty_cycle.h" +#include "smtc_ping_slot.h" +#include "almanac_update.h" +#include "smtc_modem_hal_dbg_trace.h" +#include "lr11xx_wifi.h" +#include "radio_planner.h" +#include "smtc_modem_services_config.h" +#include "lr11xx_driver_version.h" +#include "mw_dbg_trace.h" +#include "lr_fhss_v1_base_types.h" +#include "smtc_secure_element.h" +#include "radio_planner_hal.h" +#include "smtc_real.h" +#include "lr11xx_radio_timings.h" +#include "lr11xx_types.h" +#include "lr11xx_lr_fhss.h" +#include "ral_lr11xx.h" +#include "lorawan_certification.h" +#include "wifi_helpers_defs.h" +#include "ralf.h" +#include "cmac.h" +#include "smtc_modem_middleware_advanced_api.h" +#include "ral_drv.h" +#include "smtc_multicast.h" +#include "smtc_modem_api_str.h" +#include "region_us_915_defs.h" +#include "lr11xx_crypto_engine.h" +#include "radio_planner_types.h" +#include "apps_utilities.h" +#include "smtc_real_defs_str.h" + +// changed headers +#include "smtc_hal_gpio.h" +#include "smtc_hal_spi.h" +#include "smtc_hal_lp_time.h" +#include "smtc_hal_rtc.h" +#include "smtc_hal_def.h" +#include "smtc_hal.h" +#include "smtc_hal_config.h" +#include "smtc_hal_dbg_trace.h" +#include "smtc_hal_options.h" +#include "smtc_hal_mcu.h" +#include "smtc_hal_trace.h" +#include "smtc_hal_rng.h" +#include "smtc_hal_flash.h" +#include "smtc_real_defs.h" \ No newline at end of file diff --git a/lr1110/lr1110/src_changed/lr11xx_hal.c b/lr1110/lr1110/src_changed/lr11xx_hal.c new file mode 100644 index 000000000..d143ed2bb --- /dev/null +++ b/lr1110/lr1110/src_changed/lr11xx_hal.c @@ -0,0 +1,282 @@ +/*! + * \file lr11xx_hal.c + * + * \brief Implements the lr11xx radio HAL functions + * + * The Clear BSD License + * Copyright Semtech Corporation 2021. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted (subject to the limitations in the disclaimer + * below) provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the Semtech corporation nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY + * THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT + * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SEMTECH CORPORATION BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * ----------------------------------------------------------------------------- + * --- DEPENDENCIES ------------------------------------------------------------ + */ + +#include // C99 types +#include // bool type + +#include +#include + +#include "lr11xx_hal.h" +#include "smtc_hal_gpio.h" +#include "smtc_hal_spi.h" +//#include "smtc_hal_mcu.h" + +#include "lr11xx_hal_context.h" +#include "lr11xx_system_types.h" +#include "lr11xx_system.h" + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE MACROS----------------------------------------------------------- + */ + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE CONSTANTS ------------------------------------------------------- + */ + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE TYPES ----------------------------------------------------------- + */ + +typedef enum +{ + RADIO_SLEEP, + RADIO_AWAKE +} radio_mode_t; + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE VARIABLES ------------------------------------------------------- + */ + +static volatile radio_mode_t radio_mode = RADIO_AWAKE; + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE FUNCTIONS DECLARATION ------------------------------------------- + */ + +/** + * @brief Wait until radio busy pin returns to 0 + */ +static void lr11xx_hal_wait_on_busy( const uint32_t busy_pin ); + +/** + * @brief Check if device is ready to receive spi transaction. + * @remark If the device is in sleep mode, it will awake it and wait until it is ready + */ +static void lr11xx_hal_check_device_ready( const lr11xx_hal_context_t* lr11xx_context ); + +/** + * @brief Disables interruptions used in Modem (radio_dio and timer) + */ +static void modem_disable_irq( void ); + +/** + * @brief Enables interruptions used in Modem (radio_dio and timer) + */ +static void modem_enable_irq( void ); + +/* + * ----------------------------------------------------------------------------- + * --- PUBLIC FUNCTIONS DEFINITION --------------------------------------------- + */ + +lr11xx_hal_status_t lr11xx_hal_write( const void* context, const uint8_t* command, const uint16_t command_length, + const uint8_t* data, const uint16_t data_length ) +{ +#if defined( USE_LR11XX_CRC_OVER_SPI ) + // Compute the CRC over command array first and over data array then + uint8_t cmd_crc = lr11xx_hal_compute_crc( 0xFF, command, command_length ); + cmd_crc = lr11xx_hal_compute_crc( cmd_crc, data, data_length ); +#endif + + const lr11xx_hal_context_t* lr11xx_context = ( const lr11xx_hal_context_t* ) context; + + lr11xx_hal_check_device_ready( lr11xx_context ); + + // Disable IRQ to secure LR11XX concurrent access + modem_disable_irq( ); + + // Create one wbuffer we can send to the SPI interface via the kernel. + uint8_t rbuffer[100]; + uint8_t wbuffer[100]; + + int write_length = command_length + data_length; + + // Pack the entire message in one wbuffer. + memcpy(wbuffer, command, command_length); + memcpy(wbuffer+command_length, data, data_length); + +#if defined( USE_LR11XX_CRC_OVER_SPI ) + // Send the CRC byte at the end of the transaction + wbuffer[write_length] = cmd_crc; + write_length += 1; +#endif + + // Do the SPI transfer. + libtocksync_lora_phy_read_write((const char*)wbuffer, (const char*)rbuffer, write_length); + + // LR11XX_SYSTEM_SET_SLEEP_OC=0x011B opcode. In sleep mode the radio busy line is held at 1 => do not test it + if( ( command[0] == 0x01 ) && ( command[1] == 0x1B ) ) + { + radio_mode = RADIO_SLEEP; + + // add a incompressible delay to prevent trying to wake the radio before it is full asleep + libtocksync_alarm_delay_ms( 1 ); + + // + hal_spi_deinit( ); + } + + // Re-enable IRQ + modem_enable_irq( ); + + return LR11XX_HAL_STATUS_OK; +} + +lr11xx_hal_status_t lr11xx_hal_read( const void* context, const uint8_t* command, const uint16_t command_length, + uint8_t* data, const uint16_t data_length ) +{ + const lr11xx_hal_context_t* lr11xx_context = ( const lr11xx_hal_context_t* ) context; + + lr11xx_hal_check_device_ready( lr11xx_context ); + + // Input buffer. + uint8_t rbuffer[100]; + uint8_t wbuffer[100]; + + memcpy(wbuffer, command, command_length); + + // Do the SPI transaction to request data. + libtocksync_lora_phy_read_write((const char*)wbuffer, (char*)rbuffer, command_length); + + lr11xx_hal_check_device_ready( lr11xx_context ); + + memset(wbuffer, 0, sizeof(wbuffer)); + + // Do the SPI transaction to read data. + libtocksync_lora_phy_read_write((const char*)wbuffer, (char*)rbuffer, data_length+1); + + memcpy(data, rbuffer+1, data_length); + + return LR11XX_HAL_STATUS_OK; +} + +lr11xx_hal_status_t lr11xx_hal_direct_read( const void* radio, uint8_t* data, const uint16_t data_length ) +{ + const lr11xx_hal_context_t* lr11xx_context = ( const lr11xx_hal_context_t* ) radio; + + lr11xx_hal_check_device_ready( lr11xx_context ); + + uint8_t wbuffer[100]; + + memset(wbuffer, 0, sizeof(wbuffer)); + + // Write all zeros on SPI and read in the incoming data. + libtocksync_lora_phy_read_write(wbuffer, data, data_length); + + return LR11XX_HAL_STATUS_OK; +} + +lr11xx_hal_status_t lr11xx_hal_reset( const void* context ) +{ + const lr11xx_hal_context_t* lr11xx_context = ( const lr11xx_hal_context_t* ) context; + hal_gpio_set_value( lr11xx_context->reset, 0 ); + libtocksync_alarm_delay_ms( 5 ); + hal_gpio_set_value( lr11xx_context->reset, 1 ); + libtocksync_alarm_delay_ms( 5 ); + + // Wait until internal lr11xx fw is ready + libtocksync_alarm_delay_ms( 250 ); + + radio_mode = RADIO_AWAKE; + + return LR11XX_HAL_STATUS_OK; +} + +lr11xx_hal_status_t lr11xx_hal_wakeup( const void* context ) +{ + const lr11xx_hal_context_t* lr11xx_context = ( const lr11xx_hal_context_t* ) context; + lr11xx_hal_check_device_ready( lr11xx_context ); + return LR11XX_HAL_STATUS_OK; +} + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE FUNCTIONS DEFINITION -------------------------------------------- + */ + +static void lr11xx_hal_wait_on_busy( const uint32_t busy_pin ) +{ + uint32_t cnt = 0; + while( hal_gpio_get_value( busy_pin ) == 1 ) + { + libtocksync_alarm_delay_ms( 1 ); + cnt ++; + if( cnt >= 3000 ) + { + // printf( "lr1110_hal_wait_on_busy\r\n" ); + break; + } + }; +} + +static void lr11xx_hal_check_device_ready( const lr11xx_hal_context_t* lr11xx_context ) +{ + if( radio_mode != RADIO_SLEEP ) + { + lr11xx_hal_wait_on_busy( lr11xx_context->busy ); + } + else + { + hal_spi_init( ); + + // Busy is HIGH in sleep mode, wake-up the device with a small glitch on NSS + hal_gpio_set_value( lr11xx_context->nss, 0 ); + hal_gpio_set_value( lr11xx_context->nss, 1 ); + lr11xx_hal_wait_on_busy( lr11xx_context->busy ); + radio_mode = RADIO_AWAKE; + } +} + +static void modem_disable_irq( void ) +{ + hal_gpio_irq_disable( ); +} + +static void modem_enable_irq( void ) +{ + hal_gpio_irq_enable( ); +} + +/* --- EOF ------------------------------------------------------------------ */ diff --git a/lr1110/lr1110/src_changed/smtc_hal_flash.c b/lr1110/lr1110/src_changed/smtc_hal_flash.c new file mode 100644 index 000000000..175ffe854 --- /dev/null +++ b/lr1110/lr1110/src_changed/smtc_hal_flash.c @@ -0,0 +1,40 @@ +#include + +#include "smtc_hal.h" + +smtc_hal_status_t hal_flash_init( void ) +{ + return SMTC_HAL_SUCCESS; +} + +smtc_hal_status_t hal_flash_erase_page( uint32_t addr, uint8_t nb_page ) +{ + return SMTC_HAL_SUCCESS; +} + +smtc_hal_status_t hal_flash_write_buffer( uint32_t addr, const uint8_t* buffer, uint32_t size ) +{ + returncode_t ret; + + int length_written = 0; + ret = libtocksync_nonvolatile_storage_write(addr, size, buffer, size, &length_written); + if (ret != RETURNCODE_SUCCESS) return SMTC_HAL_FAILURE; + + return SMTC_HAL_SUCCESS; +} + +void hal_flash_read_buffer( uint32_t addr, uint8_t* buffer, uint32_t size ) +{ + returncode_t ret; + + int length_read = 0; + ret = libtocksync_nonvolatile_storage_read(addr, size, buffer, size, &length_read); + if (ret != RETURNCODE_SUCCESS) return SMTC_HAL_FAILURE; + + return SMTC_HAL_SUCCESS; +} + +smtc_hal_status_t hal_flash_deinit( void ) +{ + return SMTC_HAL_SUCCESS; +} diff --git a/lr1110/lr1110/src_changed/smtc_hal_gpio.c b/lr1110/lr1110/src_changed/smtc_hal_gpio.c new file mode 100644 index 000000000..ce50ea9b0 --- /dev/null +++ b/lr1110/lr1110/src_changed/smtc_hal_gpio.c @@ -0,0 +1,194 @@ + +#include "smtc_hal_gpio.h" +#include "smtc_hal_config.h" + +#include +#include + +static hal_gpio_irq_t const* gpio_irq[GPIO_IRQ_MAX]; + +struct gpio_result { + bool fired; + hal_gpio_irq_t* irq; +}; + +static struct gpio_result result; + +static void tock_gpio_cb ( int pin_num, + __attribute__ ((unused)) int arg2, + __attribute__ ((unused)) int arg3, + __attribute__ ((unused)) void* userdata) { + hal_gpio_irq_t* irq = gpio_irq[pin_num]; + irq->callback(irq->context); +} + +void hal_gpio_init_in( uint32_t pin, const hal_gpio_pull_mode_t pull_mode, const hal_gpio_irq_mode_t irq_mode, hal_gpio_irq_t* irq ) +{ + libtock_gpio_input_mode_t pull_value; + switch( pull_mode ) + { + case HAL_GPIO_PULL_MODE_NONE: + pull_value = libtock_pull_none; + break; + + case HAL_GPIO_PULL_MODE_UP: + pull_value = libtock_pull_up; + break; + + case HAL_GPIO_PULL_MODE_DOWN: + pull_value = libtock_pull_down; + break; + + default: + break; + } + + if( irq_mode == HAL_GPIO_IRQ_MODE_OFF ) + { + libtock_lora_phy_gpio_command_enable_input(pin, pull_value); + } + else + { + libtock_gpio_interrupt_mode_t tock_irq_mode = libtock_change; + switch( irq_mode ) + { + case HAL_GPIO_IRQ_MODE_RISING: + tock_irq_mode = libtock_rising_edge; + break; + + case HAL_GPIO_IRQ_MODE_FALLING: + tock_irq_mode = libtock_falling_edge; + break; + + case HAL_GPIO_IRQ_MODE_RISING_FALLING: + tock_irq_mode = libtock_change; + break; + + default: + break; + } + + libtock_lora_phy_gpio_command_enable_input(pin, pull_value); + libtock_lora_phy_gpio_command_enable_interrupt(pin, tock_irq_mode); + + if(( irq != NULL ) && ( irq->callback != NULL )) + { + gpio_irq[(irq->pin) & ( GPIO_IRQ_MAX - 1 )] = irq; + result.fired = false; + } + + libtock_lora_phy_gpio_command_interrupt_callback(tock_gpio_cb, irq); + } +} + +void hal_gpio_irq_attach( const hal_gpio_irq_t* irq ) +{ + if(( irq != NULL ) && ( irq->callback != NULL )) + { + gpio_irq[(irq->pin) & ( GPIO_IRQ_MAX - 1 )] = irq; + } +} + +void hal_gpio_irq_deatach( const hal_gpio_irq_t* irq ) +{ + if( irq != NULL ) + { + gpio_irq[(irq->pin) & GPIO_IRQ_MAX] = NULL; + } +} + +void hal_gpio_init_out( uint32_t pin, hal_gpio_state_t value ) +{ + libtock_lora_phy_gpio_command_enable_output(pin); + if (value == HAL_GPIO_RESET) { + libtock_lora_phy_gpio_command_clear(pin); + } else { + libtock_lora_phy_gpio_command_set(pin); + } +} + +void hal_gpio_init( void ) +{ + // re-power up LR1110 + hal_gpio_init_out( LR1110_IRQ_PIN, HAL_GPIO_RESET ); + hal_gpio_init_out( LR1110_BUSY_PIN, HAL_GPIO_RESET ); + hal_gpio_init_out( LR1110_SPI_NSS_PIN, HAL_GPIO_RESET ); + hal_gpio_init_out( LR1110_SPI_SCK_PIN, HAL_GPIO_RESET ); + hal_gpio_init_out( LR1110_SPI_MOSI_PIN, HAL_GPIO_RESET ); + hal_gpio_init_out( LR1110_SPI_MISO_PIN, HAL_GPIO_RESET ); + hal_gpio_init_out( LR1110_NRESER_PIN, HAL_GPIO_RESET ); + + hal_mcu_wait_ms( 500 ); // re-power up LR1110 and wait for CCL sensor ready + + hal_gpio_init_out( LR1110_SPI_NSS_PIN, HAL_GPIO_SET ); + hal_gpio_init_in( LR1110_BUSY_PIN, HAL_GPIO_PULL_MODE_NONE, HAL_GPIO_IRQ_MODE_OFF, NULL ); + hal_gpio_init_in( LR1110_IRQ_PIN, HAL_GPIO_PULL_MODE_DOWN, HAL_GPIO_IRQ_MODE_RISING, NULL ); + hal_gpio_set_value( LR1110_NRESER_PIN, HAL_GPIO_SET ); +} + +void hal_gpio_set_value( uint32_t pin, const hal_gpio_state_t value ) +{ + switch( value ) + { + case HAL_GPIO_RESET: + libtock_lora_phy_gpio_command_clear(pin); + break; + case HAL_GPIO_SET: + libtock_lora_phy_gpio_command_set(pin); + break; + default: + break; + } +} + +void hal_gpio_toggle( uint32_t pin ) +{ + libtock_lora_phy_gpio_command_toggle(pin); +} + +uint32_t hal_gpio_get_value( uint32_t pin ) +{ + int value; + libtock_lora_phy_gpio_read(pin, &value); + if(value != 0) { + return HAL_GPIO_SET; + } else { + return HAL_GPIO_RESET; + } +} + +void hal_gpio_wait_for_state( uint32_t pin, uint8_t state ) +{ + int value; + if( state == HAL_GPIO_RESET ) + { + while(libtock_lora_phy_gpio_read(pin, &value)) {} + } + else + { + while(!libtock_lora_phy_gpio_read(pin, &value)) {} + } +} + +// pending_irq functions has no equivalent in Tock +bool hal_gpio_is_pending_irq( uint32_t pin ) +{ + bool pending = false; + uint32_t irq_pending = 0; + + if( irq_pending ) pending = true; + + return pending; +} + +void hal_gpio_clear_pending_irq( uint32_t pin ) +{ +} + +void hal_gpio_irq_enable( void ) +{ +} + +void hal_gpio_irq_disable( void ) +{ +} diff --git a/lr1110/lr1110/src_changed/smtc_hal_lp_time.c b/lr1110/lr1110/src_changed/smtc_hal_lp_time.c new file mode 100644 index 000000000..14956cd66 --- /dev/null +++ b/lr1110/lr1110/src_changed/smtc_hal_lp_time.c @@ -0,0 +1,47 @@ +#include "smtc_hal_dbg_trace.h" +#include "smtc_hal_lp_time.h" + +#include +#include + +static hal_lp_timer_irq_t lptim_tmr_irq = { .context = NULL, .callback = NULL }; + + +static void timer_tock_upcall(__attribute__ ((unused)) int unused0, + __attribute__ ((unused)) int unused1, + __attribute__ ((unused)) int unused2, + __attribute__ ((unused)) void* ud) { + if( lptim_tmr_irq.callback != NULL ) + { + lptim_tmr_irq.callback( lptim_tmr_irq.context ); + } + +} + +void hal_lp_timer_start( const uint32_t milliseconds, const hal_lp_timer_irq_t* tmr_irq ) +{ + if( milliseconds > 1 ) + { + libtocksync_alarm_delay_ms(milliseconds); + tmr_irq->callback(tmr_irq->context); + } + else // execute immediately + { + tmr_irq->callback(tmr_irq->context); + } +} + +void hal_lp_timer_stop( void ) +{ + libtock_alarm_command_stop(); +} + +void hal_lp_timer_irq_enable( void ) +{ + +} + +void hal_lp_timer_irq_disable( void ) +{ + +} diff --git a/lr1110/lr1110/src_changed/smtc_hal_mcu.c b/lr1110/lr1110/src_changed/smtc_hal_mcu.c new file mode 100644 index 000000000..03f0585fb --- /dev/null +++ b/lr1110/lr1110/src_changed/smtc_hal_mcu.c @@ -0,0 +1,68 @@ + +#include "smtc_hal.h" +#include "smtc_hal_rtc.h" + +#include +#include +#include + + +void hal_clock_init(void) +{ +} + +void hal_pwr_init(void) +{ +} + +void hal_mcu_init( void ) +{ + hal_clock_init( ); + hal_pwr_init( ); + hal_flash_init( ); + hal_gpio_init( ); + hal_spi_init( ); +} + +void hal_mcu_reset( void ) +{ +} + +void __attribute__( ( optimize( "O0" ) ) ) hal_mcu_wait_us( const int32_t microseconds ) +{ + // Work @64MHz + uint32_t dummy = 0; + const uint32_t nb_nop = microseconds * 1000 / 171; + for( uint32_t i = 0; i < nb_nop; i++ ) + { + //__NOP( ); + } +} +void hal_mcu_wait_ms( const int32_t ms ) +{ + libtocksync_alarm_delay_ms(ms); +} + +void hal_mcu_set_sleep_for_ms( const int32_t milliseconds ) +{ + bool last_sleep_loop = false; + int32_t time_counter = milliseconds; + + if( milliseconds <= 0 ) return; + + hal_rtc_wakeup_timer_set_ms( milliseconds ); +} + +void hal_hex_to_bin( char *input, uint8_t *dst, int len ) +{ + char tmp[3]; + uint16_t length = strlen( input ); + tmp[2] = NULL; + for( int i = 0; i < length; i+=2 ) + { + tmp[0] = input[i]; + tmp[1] = input[i+1]; + dst[i/2] = ( uint8_t )strtol(( const char * )tmp, NULL, 16 ); + if (i >= (2 * len )) break; + } +} diff --git a/lr1110/lr1110/src_changed/smtc_hal_rng.c b/lr1110/lr1110/src_changed/smtc_hal_rng.c new file mode 100644 index 000000000..790e5c4fd --- /dev/null +++ b/lr1110/lr1110/src_changed/smtc_hal_rng.c @@ -0,0 +1,39 @@ + +#include +//#include "nrf_drv_rng.h" +#include "smtc_hal_rng.h" + +#include + +#define RANDOM_BUFF_SIZE 4 +static uint8_t rng_buff[RANDOM_BUFF_SIZE]; + +void hal_rng_init( void ) +{ +} + +uint32_t hal_rng_get_random( void ) +{ + int num_received = 0; + libtocksync_rng_get_random_bytes(rng_buff, RANDOM_BUFF_SIZE, RANDOM_BUFF_SIZE, &num_received); + return rng_buff[0] << 24 | rng_buff[1] << 16 | rng_buff[2] << 8 | rng_buff[3]; +} + +uint32_t hal_rng_get_random_in_range( const uint32_t val_1, const uint32_t val_2 ) +{ + uint32_t max, min, rng = 0; + + if( val_1 < val_2 ) + { + min = val_1; max = val_2; + } + else + { + min = val_2; max = val_1; + } + + rng = hal_rng_get_random( ); + rng = rng %( max - min + 1 ) + min; + + return rng; +} diff --git a/lr1110/lr1110/src_changed/smtc_hal_rtc.c b/lr1110/lr1110/src_changed/smtc_hal_rtc.c new file mode 100644 index 000000000..73f128988 --- /dev/null +++ b/lr1110/lr1110/src_changed/smtc_hal_rtc.c @@ -0,0 +1,61 @@ + +#include "smtc_hal_rtc.h" + +#include + + +uint32_t hal_rtc_get_time_s( void ) +{ + uint32_t timeInSeconds = hal_rtc_get_time_ms(); + return timeInSeconds / 1000; +} + +uint32_t hal_rtc_get_time_ms( void ) +{ + uint32_t timeInms = hal_rtc_get_time_100us(); + return timeInms / 10; +} + +static uint32_t ticks_to_100us(uint32_t ticks) { + // `ticks_to_ms`'s conversion will be accurate to within the range + // 0 to 1 milliseconds less than the exact conversion + // (true millisecond conversion - [0,1) milliseconds). + + uint32_t frequency; + libtock_alarm_command_get_frequency(&frequency); + + uint64_t seconds = (ticks / frequency); + uint64_t hundredus_per_second = 10000; + + // Calculate the conversion of full seconds to ticks. + uint64_t hundredus = seconds * hundredus_per_second; + + // To get conversion accuracy within 1 millisecond, the conversion + // must also convert partial seconds. + uint64_t leftover_ticks = ticks % frequency; + + // This calculation is mathematically equivalent to doing: + // + // `leftover_ticks` / (`frequency` / `hundredus_per_second`) + // + // This is taking the remaining unconverted ticks (leftover_ticks) + // and dividing by the number of ticks per millisecond + // (`frequency` (ticks per second) / `1000` hundredus per second) + // The division is done this way because of the same argument in + // `ms_to_ticks`. + hundredus += (leftover_ticks * hundredus_per_second) / frequency; + + return hundredus; +} + +uint32_t hal_rtc_get_time_100us( void ) +{ + uint32_t time = 0; + libtock_alarm_command_read(&time); + return ticks_to_100us(time); +} + +void hal_rtc_wakeup_timer_set_ms( const int32_t milliseconds ) +{ + libtocksync_alarm_delay_ms(milliseconds); +} diff --git a/lr1110/lr1110/src_changed/smtc_hal_spi.c b/lr1110/lr1110/src_changed/smtc_hal_spi.c new file mode 100644 index 000000000..f6b6e235a --- /dev/null +++ b/lr1110/lr1110/src_changed/smtc_hal_spi.c @@ -0,0 +1,88 @@ + +#include +#include + +#include "smtc_hal_spi.h" +#include "smtc_hal_config.h" + +#include +#include + + +static uint8_t m_tx_buf[256] = { 0 }; +static uint8_t m_rx_buf[256] = { 0 }; + +static bool spi_initialized = false; + +void hal_spi_init( void ) +{ + if( spi_initialized == false ) + { + spi_initialized = true; + // Set the SPI clock rate to 4MHz (NRF_SPIM_FREQ_4M) + libtock_spi_controller_set_rate(4000000); // 4MHz as an integer + // Set the SPI phase to sample on a leading (low to high) clock edge + libtock_spi_controller_set_phase(false); + // Set the SPI polarity so that the idle clock is low + libtock_spi_controller_set_polarity(false); + } +} + +void hal_spi_deinit( void ) +{ + if( spi_initialized == true ) + { + spi_initialized = false; + } +} + +void hal_spi_write( const uint8_t* buffer, uint16_t length ) +{ + if( spi_initialized == true ) + { + libtocksync_lora_phy_write((const char*)buffer, (size_t)length); + } +} + +// we don't have read only function implemented in Tock +void hal_spi_read( uint8_t* buffer, uint16_t length ) +{ + if( spi_initialized == true ) + { + } +} + +void hal_spi_write_read( const uint8_t* cbuffer, uint8_t* rbuffer, uint16_t length ) +{ + if( spi_initialized == true ) + { + libtocksync_lora_phy_read_write((const char*)cbuffer, (char*)rbuffer, (size_t)length); + } +} + +void hal_spi_read_with_dummy_byte( uint8_t* buffer, uint16_t length, uint8_t dummy_byte ) +{ + if( spi_initialized == true ) + { + if( length <= sizeof( m_tx_buf )) + { + memset( m_tx_buf, dummy_byte, length ); + libtocksync_lora_phy_read_write((const char*)m_tx_buf, (char*)buffer, (size_t)length); + } + else + { + printf( "error: spi m_tx_buf is emty\r\n" ); + } + } +} + +uint16_t hal_spi_in_out( const uint32_t id, const uint16_t out_data ) +{ + uint8_t tv = 0, rv = 0; + if( spi_initialized == true ) + { + tv = ( uint8_t )( out_data & 0xFF ); + libtocksync_lora_phy_read_write((const char*)&tv, (char*)&rv, 1); + } + return rv; +} diff --git a/lr1110/lr1110/src_changed/smtc_hal_trace.c b/lr1110/lr1110/src_changed/smtc_hal_trace.c new file mode 100644 index 000000000..d46ae2127 --- /dev/null +++ b/lr1110/lr1110/src_changed/smtc_hal_trace.c @@ -0,0 +1,22 @@ + +#include // C99 types +#include // bool type +#include + +#include "smtc_hal_trace.h" + +#define PRINT_BUFFER_SIZE 256 + +void hal_trace_print_var( const char* fmt, ... ) +{ + va_list args; + va_start( args, fmt ); + hal_trace_print( fmt, args ); + va_end( args ); +} + +char string[PRINT_BUFFER_SIZE]; +void hal_trace_print( const char* fmt, va_list argp ) +{ + vprintf(fmt, argp); // directly prints formatted string +} \ No newline at end of file diff --git a/lr1110/lr1110/us_915_ttn.c b/lr1110/lr1110/us_915_ttn.c new file mode 100644 index 000000000..867314fda --- /dev/null +++ b/lr1110/lr1110/us_915_ttn.c @@ -0,0 +1,32 @@ +#include "lr1_stack_mac_layer.h" +#include "lr1mac_utilities.h" +#include "lorawan_api.h" + +#include "us_915_ttn.h" + +void region_us_915_the_things_network_init(void) +{ + // Get a pointer to the mac layer data structure. + lr1_stack_mac_t* lr1_mac = lorawan_api_stack_mac_get(); + + uint8_t* channel_index_enabled = lr1_mac->real->region.us915.channel_index_enabled; + + + // TTN only supports bank 2. Disable all first. + // Tx 125 kHz channels. + for( uint8_t i = 0; i < NUMBER_OF_TX_CHANNEL_US_915 - 8; i++ ) + { + SMTC_PUT_BIT8( channel_index_enabled, i, CHANNEL_DISABLED ); + } + // Tx 500 kHz channels + for( uint8_t i = NUMBER_OF_TX_CHANNEL_US_915 - 8; i < NUMBER_OF_TX_CHANNEL_US_915; i++ ) + { + SMTC_PUT_BIT8( channel_index_enabled, i, CHANNEL_DISABLED ); + } + + // Now enable bank 2 + for( uint8_t i = 8; i < 15; i++ ) + { + SMTC_PUT_BIT8( channel_index_enabled, i, CHANNEL_ENABLED ); + } +} \ No newline at end of file diff --git a/lr1110/lr1110/us_915_ttn.h b/lr1110/lr1110/us_915_ttn.h new file mode 100644 index 000000000..59695efbb --- /dev/null +++ b/lr1110/lr1110/us_915_ttn.h @@ -0,0 +1,4 @@ +#pragma once + + +void region_us_915_the_things_network_init(void); diff --git a/lr1110/radio_planner.patch b/lr1110/radio_planner.patch new file mode 100644 index 000000000..c6326db02 --- /dev/null +++ b/lr1110/radio_planner.patch @@ -0,0 +1,41 @@ +--- radio_planner.c 2024-08-01 15:26:03 ++++ radio_planner.c 2024-08-01 13:17:59 +@@ -42,6 +42,8 @@ + // + // Private planner utilities declaration + // ++ ++rp_task_types_t rp_task_type = RP_TASK_TYPE_NONE; + + /** + * @brief rp_task_free to free a task +@@ -263,6 +265,12 @@ + rp_hook_status_t rp_task_enqueue( radio_planner_t* rp, const rp_task_t* task, uint8_t* payload, uint16_t payload_size, + const rp_radio_params_t* radio_params ) + { ++ if(task->type == RP_TASK_TYPE_WIFI_RSSI) { ++ rp_task_type = RP_TASK_TYPE_WIFI_RSSI; ++ } else { ++ rp_task_type = RP_TASK_TYPE_NONE; ++ } ++ + uint8_t hook_id = task->hook_id; + if( hook_id >= RP_NB_HOOKS ) + { +@@ -394,6 +402,16 @@ + SMTC_MODEM_HAL_RP_TRACE_PRINTF( " RP: INFO - Radio IRQ received for hook #%u\n", rp->radio_task_id ); + + rp_irq_get_status( rp, rp->radio_task_id ); ++ // For some reason we get a spurious RX_TIMEOUT interrupt sometimes. ++ // Handling it causes the stack to break, but clearing it causes the ++ // stack to work. ++ // re-get the irq status if RX_TIMEOUT happens (current workaround) ++ if( rp_task_type == RP_TASK_TYPE_WIFI_RSSI) { ++ if(rp->status[rp->radio_task_id] == RP_STATUS_RX_TIMEOUT) { ++ rp_irq_get_status( rp, rp->radio_task_id ); ++ // return; ++ } ++ } + if( rp->status[rp->radio_task_id] == RP_STATUS_LR_FHSS_HOP ) + { + return; diff --git a/lr1110/smtc_modem.patch b/lr1110/smtc_modem.patch new file mode 100644 index 000000000..09b7bdf4f --- /dev/null +++ b/lr1110/smtc_modem.patch @@ -0,0 +1,22 @@ +--- smtc_modem.c 2024-08-01 15:19:56 ++++ smtc_modem.c 2024-08-01 13:17:59 +@@ -2220,6 +2220,18 @@ + : RP_TASK_STATE_ASAP, + .schedule_task_low_priority = false, + .start_time_ms = rp_task->start_time_ms }; ++ ++ // HACK! ++ // ++ // For some reason this extra state is generated. We can't track this down, ++ // but if we set and pass the RP_TASK_TYPE_WIFI_RSSI task type if the ++ // current task id is SMTC_MODEM_RP_TASK_ID2 (a WIFI task), then the stack ++ // operates as expected. ++ if (rp_task->id == SMTC_MODEM_RP_TASK_ID2) { ++ rp_task_tmp.type = RP_TASK_TYPE_WIFI_RSSI; ++ } else { ++ rp_task_tmp.type = RP_TASK_TYPE_NONE; ++ } + + rp_hook_status_t status = rp_task_enqueue( &modem_radio_planner, &rp_task_tmp, NULL, 0, &fake_radio_params ); + +\ No newline at end of file diff --git a/lr1110/wifi_helpers.patch b/lr1110/wifi_helpers.patch new file mode 100644 index 000000000..558793980 --- /dev/null +++ b/lr1110/wifi_helpers.patch @@ -0,0 +1,13 @@ +--- wifi_helpers.c 2024-08-01 15:07:38 ++++ wifi_helpers.c 2024-08-01 15:08:24 +@@ -158,8 +158,8 @@ + max_nb_results = sizeof( wifi_results_mac_addr ) / sizeof( wifi_results_mac_addr[0] ); + if( nb_results > max_nb_results ) + { +- MW_DBG_TRACE_ERROR( "Wi-Fi scan result size exceeds %u (%u)\n", max_nb_results, nb_results ); +- return false; ++ // Just use the number we received that can fit in our results array. ++ nb_results = max_nb_results; + } + + status = lr11xx_wifi_read_basic_complete_results( radio_context, 0, nb_results, wifi_results_mac_addr );