From 15a3f39dc99fa28cc6b6a01fd7bca0948fefde9c Mon Sep 17 00:00:00 2001 From: Pat Pannuto Date: Wed, 6 Nov 2024 14:22:41 -0800 Subject: [PATCH 1/2] tock: use native time getter, remove globals Tock has direct support for querying time. The prior `millis()` method here replicated the same functionality, but missed some corner case concerns around overflow/wrapping. Instead, just use the native Tock time getter method. This also removes unneeded global variables and methods. --- src/hal/Tock/libtockHal.h | 30 +++++++----------------------- 1 file changed, 7 insertions(+), 23 deletions(-) diff --git a/src/hal/Tock/libtockHal.h b/src/hal/Tock/libtockHal.h index 9d597fd16..1b9467d90 100644 --- a/src/hal/Tock/libtockHal.h +++ b/src/hal/Tock/libtockHal.h @@ -56,20 +56,6 @@ typedef void (*gpioIrqFn)(void); gpioIrqFn gpio_funcs[4] = { NULL, NULL, NULL, NULL}; -uint32_t frequency = 0; - -/* - * Get the the timer frequency in Hz. - */ -int alarm_internal_frequency(uint32_t* frequency) { - syscall_return_t rval = command(0x0, 1, 0, 0); - return tock_command_return_u32_to_returncode(rval, frequency); -} - -int alarm_internal_read(uint32_t* time) { - syscall_return_t rval = command(0x0, 2, 0, 0); - return tock_command_return_u32_to_returncode(rval, time); -} static void lora_phy_gpio_Callback (int gpioPin, __attribute__ ((unused)) int arg2, @@ -174,16 +160,11 @@ class TockHal : public RadioLibHal { } unsigned long millis() override { - uint32_t now; + struct timeval tv; unsigned long ms; - if (frequency == 0) { - alarm_internal_frequency(&frequency); - } - - alarm_internal_read(&now); - - ms = now / (frequency / 1000); + libtock_alarm_gettimeasticks(&tv); + ms = tv.tv_sec * 1000 + tv.tv_usec / 1000; #if !defined(RADIOLIB_CLOCK_DRIFT_MS) return ms; @@ -193,7 +174,10 @@ class TockHal : public RadioLibHal { } unsigned long micros() override { - return millis() / 1000; + struct timeval tv; + + libtock_alarm_gettimeasticks(&tv); + return tv.tv_sec * 1000000 + tv.tv_usec; } long pulseIn(uint32_t pin, uint32_t state, unsigned long timeout) override { From ff12e943ebeb2bd2f7c8d21f7b375b05c764c73c Mon Sep 17 00:00:00 2001 From: Alistair Francis Date: Wed, 13 Nov 2024 21:19:41 +1000 Subject: [PATCH 2/2] NonArduino/Tock: Update to latest libtock-c Update to the latest libtock-c commit. libtock-c now includes a libtockHal.h, so we can use that instead of the version here. Signed-off-by: Alistair Francis --- .github/workflows/main.yml | 2 +- examples/NonArduino/Tock/CMakeLists.txt | 28 +++- examples/NonArduino/Tock/README.md | 2 +- examples/NonArduino/Tock/build.sh | 4 +- examples/NonArduino/Tock/main.cpp | 6 +- src/hal/Tock/libtockHal.h | 210 ------------------------ 6 files changed, 33 insertions(+), 219 deletions(-) delete mode 100644 src/hal/Tock/libtockHal.h diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 06c8d6f82..c28278a3c 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -247,7 +247,7 @@ jobs: run: | cd $PWD/examples/NonArduino/Tock git clone https://github.com/tock/libtock-c.git - cd libtock-c; git checkout dbee65a56d74b4bad166317f199e80b959f7c82c; cd ../ + cd libtock-c; git checkout c0202f9ab78da4a6e95f136cf5250701e3778f63; cd ../ LIBTOCK_C_DIRECTORY="$(pwd)/libtock-c" ./build.sh rpi-build: diff --git a/examples/NonArduino/Tock/CMakeLists.txt b/examples/NonArduino/Tock/CMakeLists.txt index 42d6d6744..661968f84 100644 --- a/examples/NonArduino/Tock/CMakeLists.txt +++ b/examples/NonArduino/Tock/CMakeLists.txt @@ -50,7 +50,21 @@ add_executable(${PROJECT_NAME} main.cpp) # The build system for libtock-c is a bit odd and the version of libraries # built changes based on compiler version. if (RISCV_BUILD) - if(EXISTS "$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-libc++-13.2.0") + if(EXISTS "$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-libc++-14.1.0") + target_link_libraries(${PROJECT_NAME} PUBLIC + RadioLib + $ENV{LIBTOCK_C_DIRECTORY}/libtock/build/rv32imc/libtock.a + $ENV{LIBTOCK_C_DIRECTORY}/libtock-sync/build/rv32imc/libtocksync.a + $ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-libc++-14.1.0/riscv/lib/gcc/riscv64-unknown-elf/14.1.0/rv32i/ilp32/libgcc.a + $ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-libc++-14.1.0/riscv/riscv64-unknown-elf/lib/rv32i/ilp32/libstdc++.a + $ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-newlib-4.4.0.20231231/riscv/riscv64-unknown-elf/lib/rv32i/ilp32/libc.a + $ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-newlib-4.4.0.20231231/riscv/riscv64-unknown-elf/lib/rv32i/ilp32/libm.a + ) + + target_include_directories(RadioLib AFTER PUBLIC + $ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-newlib-4.3.0.20230120/riscv/riscv64-unknown-elf/include/ + ) + elseif(EXISTS "$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-libc++-13.2.0") target_link_libraries(${PROJECT_NAME} PUBLIC RadioLib $ENV{LIBTOCK_C_DIRECTORY}/libtock/build/rv32imc/libtock.a @@ -80,7 +94,17 @@ if (RISCV_BUILD) ) endif() else() - if(EXISTS "$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-libc++-13.2.0") + if (EXISTS "$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-libc++-14.1.0") + target_link_libraries(${PROJECT_NAME} PUBLIC + RadioLib + $ENV{LIBTOCK_C_DIRECTORY}/libtock/build/cortex-m4/libtock.a + $ENV{LIBTOCK_C_DIRECTORY}/libtock-sync/build/cortex-m4/libtocksync.a + $ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-libc++-14.1.0/arm/lib/gcc/arm-none-eabi/14.1.0/libgcc.a + $ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-libc++-14.1.0/arm/arm-none-eabi/lib/libstdc++.a + $ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-newlib-4.4.0.20231231/arm/arm-none-eabi/lib/libc.a + $ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-newlib-4.4.0.20231231/arm/arm-none-eabi/lib/libm.a + ) + elseif(EXISTS "$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-libc++-13.2.0") target_link_libraries(${PROJECT_NAME} PUBLIC RadioLib $ENV{LIBTOCK_C_DIRECTORY}/libtock/build/cortex-m4/libtock.a diff --git a/examples/NonArduino/Tock/README.md b/examples/NonArduino/Tock/README.md index cae7f3809..8022a303b 100644 --- a/examples/NonArduino/Tock/README.md +++ b/examples/NonArduino/Tock/README.md @@ -23,7 +23,7 @@ The RadioLib example can be built with: $ git clone https://github.com/jgromes/RadioLib.git $ cd RadioLib/examples/NonArduino/Tock/ $ git clone https://github.com/tock/libtock-c.git -$ cd libtock-c; git checkout dbee65a56d74b4bad166317f199e80b959f7c82c; cd ../ +$ cd libtock-c; git checkout c0202f9ab78da4a6e95f136cf5250701e3778f63; cd ../ $ LIBTOCK_C_DIRECTORY="$(pwd)/libtock-c" ./build.sh ``` diff --git a/examples/NonArduino/Tock/build.sh b/examples/NonArduino/Tock/build.sh index cb91a4aed..2ac538e49 100755 --- a/examples/NonArduino/Tock/build.sh +++ b/examples/NonArduino/Tock/build.sh @@ -3,9 +3,9 @@ set -e rm -rf ./build-* -cd libtock-c/examples/cxx_hello +pushd ${LIBTOCK_C_DIRECTORY}/examples/cxx_hello make -j4 -cd ../../../ +popd mkdir -p build-arm cd build-arm diff --git a/examples/NonArduino/Tock/main.cpp b/examples/NonArduino/Tock/main.cpp index e716d5097..e0db2196e 100644 --- a/examples/NonArduino/Tock/main.cpp +++ b/examples/NonArduino/Tock/main.cpp @@ -28,14 +28,14 @@ #include // include the hardware abstraction layer -#include "hal/Tock/libtockHal.h" +#include "RadioLib/libtockHal.h" // the entry point for the program int main(void) { printf("[SX1261] Initialising Radio ... \r\n"); // create a new instance of the HAL class - TockHal* hal = new TockHal(); + TockRadioLibHal* hal = new TockRadioLibHal(); // now we can create the radio module // pinout corresponds to the SparkFun LoRa Thing Plus - expLoRaBLE @@ -43,7 +43,7 @@ int main(void) { // DIO1 pin: 2 // NRST pin: 4 // BUSY pin: 1 - Module* tock_module = new Module(hal, RADIO_NSS, RADIO_DIO_1, RADIO_RESET, RADIO_BUSY); + Module* tock_module = new Module(hal, RADIOLIB_RADIO_NSS, RADIOLIB_RADIO_DIO_1, RADIOLIB_RADIO_RESET, RADIOLIB_RADIO_BUSY); SX1262* radio = new SX1262(tock_module); // Setup the radio diff --git a/src/hal/Tock/libtockHal.h b/src/hal/Tock/libtockHal.h deleted file mode 100644 index 1b9467d90..000000000 --- a/src/hal/Tock/libtockHal.h +++ /dev/null @@ -1,210 +0,0 @@ -/* - RadioLib Non-Arduino Tock Library helper functions - - Licensed under the MIT License - - Copyright (c) 2023 Alistair Francis - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. -*/ - -#ifndef TOCK_HAL_H -#define TOCK_HAL_H - -// include RadioLib -#include - -// include all the dependencies -#include "libtock/net/lora_phy.h" -#include "libtock/net/syscalls/lora_phy_syscalls.h" -#include "libtock-sync/net/lora_phy.h" -#include "libtock/peripherals/gpio.h" -#include "libtock-sync/services/alarm.h" -#include "libtock/kernel/read_only_state.h" - -#define RADIO_BUSY 1 -#define RADIO_DIO_1 2 -#define RADIO_DIO_3 3 -#define RADIO_RESET 4 -// Skip the chips select as Tock handles this for us -#define RADIO_NSS RADIOLIB_NC - -// define Arduino-style macros -#define PIN_LOW (0x0) -#define PIN_HIGH (0x1) -#define PIN_INPUT (0x01) -#define PIN_OUTPUT (0x03) -#define PIN_RISING (0x01) -#define PIN_FALLING (0x02) - -typedef void (*gpioIrqFn)(void); - -gpioIrqFn gpio_funcs[4] = { NULL, NULL, NULL, NULL}; - -static void lora_phy_gpio_Callback (int gpioPin, - __attribute__ ((unused)) int arg2, - __attribute__ ((unused)) int arg3, - void* userdata) -{ - gpioIrqFn fn = gpio_funcs[gpioPin - 1]; - - if (fn != NULL ) { - fn(); - } -} - -class TockHal : public RadioLibHal { - public: - // default constructor - initializes the base HAL and any needed private members - TockHal() - : RadioLibHal(PIN_INPUT, PIN_OUTPUT, PIN_LOW, PIN_HIGH, PIN_RISING, PIN_FALLING) { - } - - void init() override { - } - - void term() override { - } - - // GPIO-related methods (pinMode, digitalWrite etc.) should check - // RADIOLIB_NC as an alias for non-connected pins - void pinMode(uint32_t pin, uint32_t mode) override { - if(pin == RADIOLIB_NC) { - return; - } - - if (mode == PIN_OUTPUT) { - libtock_lora_phy_gpio_enable_output(pin); - } else if (mode == PIN_INPUT) { - libtock_lora_phy_gpio_enable_input(pin, libtock_pull_down); - } - } - - void digitalWrite(uint32_t pin, uint32_t value) override { - if(pin == RADIOLIB_NC) { - return; - } - - if (value) { - libtock_lora_phy_gpio_set(pin); - } else { - libtock_lora_phy_gpio_clear(pin); - } - } - - uint32_t digitalRead(uint32_t pin) override { - int value; - - if(pin == RADIOLIB_NC) { - return 0; - } - - libtock_lora_phy_gpio_read(pin, &value); - - return value; - } - - void attachInterrupt(uint32_t interruptNum, gpioIrqFn interruptCb, uint32_t mode) override { - if(interruptNum == RADIOLIB_NC) { - return; - } - - gpio_funcs[interruptNum - 1] = interruptCb; - libtock_lora_phy_gpio_command_interrupt_callback(lora_phy_gpio_Callback, NULL); - - // set GPIO as input and enable interrupts on it - libtock_lora_phy_gpio_enable_input(interruptNum, libtock_pull_down); - libtock_lora_phy_gpio_enable_interrupt(interruptNum, libtock_change); - } - - void detachInterrupt(uint32_t interruptNum) override { - if(interruptNum == RADIOLIB_NC) { - return; - } - - gpio_funcs[interruptNum - 1] = NULL; - libtock_lora_phy_gpio_disable_interrupt(interruptNum); - libtock_lora_phy_gpio_enable_input(interruptNum, libtock_pull_down); - } - - void delay(unsigned long ms) override { -#if !defined(RADIOLIB_CLOCK_DRIFT_MS) - libtocksync_alarm_delay_ms(ms); -#else - libtocksync_alarm_delay_ms(ms * 1000 / (1000 + RADIOLIB_CLOCK_DRIFT_MS)); -#endif - } - - void delayMicroseconds(unsigned long us) override { -#if !defined(RADIOLIB_CLOCK_DRIFT_MS) - libtocksync_alarm_delay_ms(us / 1000); -#else - libtocksync_alarm_delay_ms((us * 1000 / (1000 + RADIOLIB_CLOCK_DRIFT_MS)) / 1000); -#endif - } - - unsigned long millis() override { - struct timeval tv; - unsigned long ms; - - libtock_alarm_gettimeasticks(&tv); - ms = tv.tv_sec * 1000 + tv.tv_usec / 1000; - -#if !defined(RADIOLIB_CLOCK_DRIFT_MS) - return ms; -#else - return ms * 1000 / (1000 + RADIOLIB_CLOCK_DRIFT_MS); -#endif - } - - unsigned long micros() override { - struct timeval tv; - - libtock_alarm_gettimeasticks(&tv); - return tv.tv_sec * 1000000 + tv.tv_usec; - } - - long pulseIn(uint32_t pin, uint32_t state, unsigned long timeout) override { - return 0; - } - - void spiBegin() { - } - - void spiBeginTransaction() { - } - - void spiTransfer(uint8_t* out, size_t len, uint8_t* in) { - libtocksync_lora_phy_read_write(out, in, len); - } - - void spiEndTransaction() { - } - - void spiEnd() { - } - - void yield() { - ::yield_no_wait(); - } - - private: -}; - -#endif