hal: Tock: Namespace HAL, update timer implementation and update libtock-c (#1313)

* 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.

* 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 <alistair@alistair23.me>

---------

Signed-off-by: Alistair Francis <alistair@alistair23.me>
Co-authored-by: Pat Pannuto <pat.pannuto@gmail.com>
This commit is contained in:
Alistair Francis 2024-11-15 03:51:00 +10:00 committed by GitHub
parent f3a8c6dc2d
commit 9d9d480a48
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 33 additions and 235 deletions

View file

@ -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:

View file

@ -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

View file

@ -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
```

View file

@ -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

View file

@ -28,14 +28,14 @@
#include <RadioLib.h>
// 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

View file

@ -1,226 +0,0 @@
/*
RadioLib Non-Arduino Tock Library helper functions
Licensed under the MIT License
Copyright (c) 2023 Alistair Francis <alistair@alistair23.me>
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 <RadioLib.h>
// 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};
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,
__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 {
uint32_t now;
unsigned long ms;
if (frequency == 0) {
alarm_internal_frequency(&frequency);
}
alarm_internal_read(&now);
ms = now / (frequency / 1000);
#if !defined(RADIOLIB_CLOCK_DRIFT_MS)
return ms;
#else
return ms * 1000 / (1000 + RADIOLIB_CLOCK_DRIFT_MS);
#endif
}
unsigned long micros() override {
return millis() / 1000;
}
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