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:
parent
f3a8c6dc2d
commit
9d9d480a48
6 changed files with 33 additions and 235 deletions
2
.github/workflows/main.yml
vendored
2
.github/workflows/main.yml
vendored
|
@ -247,7 +247,7 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
cd $PWD/examples/NonArduino/Tock
|
cd $PWD/examples/NonArduino/Tock
|
||||||
git clone https://github.com/tock/libtock-c.git
|
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
|
LIBTOCK_C_DIRECTORY="$(pwd)/libtock-c" ./build.sh
|
||||||
|
|
||||||
rpi-build:
|
rpi-build:
|
||||||
|
|
|
@ -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
|
# The build system for libtock-c is a bit odd and the version of libraries
|
||||||
# built changes based on compiler version.
|
# built changes based on compiler version.
|
||||||
if (RISCV_BUILD)
|
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
|
target_link_libraries(${PROJECT_NAME} PUBLIC
|
||||||
RadioLib
|
RadioLib
|
||||||
$ENV{LIBTOCK_C_DIRECTORY}/libtock/build/rv32imc/libtock.a
|
$ENV{LIBTOCK_C_DIRECTORY}/libtock/build/rv32imc/libtock.a
|
||||||
|
@ -80,7 +94,17 @@ if (RISCV_BUILD)
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
else()
|
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
|
target_link_libraries(${PROJECT_NAME} PUBLIC
|
||||||
RadioLib
|
RadioLib
|
||||||
$ENV{LIBTOCK_C_DIRECTORY}/libtock/build/cortex-m4/libtock.a
|
$ENV{LIBTOCK_C_DIRECTORY}/libtock/build/cortex-m4/libtock.a
|
||||||
|
|
|
@ -23,7 +23,7 @@ The RadioLib example can be built with:
|
||||||
$ git clone https://github.com/jgromes/RadioLib.git
|
$ git clone https://github.com/jgromes/RadioLib.git
|
||||||
$ cd RadioLib/examples/NonArduino/Tock/
|
$ cd RadioLib/examples/NonArduino/Tock/
|
||||||
$ git clone https://github.com/tock/libtock-c.git
|
$ 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
|
$ LIBTOCK_C_DIRECTORY="$(pwd)/libtock-c" ./build.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -3,9 +3,9 @@ set -e
|
||||||
|
|
||||||
rm -rf ./build-*
|
rm -rf ./build-*
|
||||||
|
|
||||||
cd libtock-c/examples/cxx_hello
|
pushd ${LIBTOCK_C_DIRECTORY}/examples/cxx_hello
|
||||||
make -j4
|
make -j4
|
||||||
cd ../../../
|
popd
|
||||||
|
|
||||||
mkdir -p build-arm
|
mkdir -p build-arm
|
||||||
cd build-arm
|
cd build-arm
|
||||||
|
|
|
@ -28,14 +28,14 @@
|
||||||
#include <RadioLib.h>
|
#include <RadioLib.h>
|
||||||
|
|
||||||
// include the hardware abstraction layer
|
// include the hardware abstraction layer
|
||||||
#include "hal/Tock/libtockHal.h"
|
#include "RadioLib/libtockHal.h"
|
||||||
|
|
||||||
// the entry point for the program
|
// the entry point for the program
|
||||||
int main(void) {
|
int main(void) {
|
||||||
printf("[SX1261] Initialising Radio ... \r\n");
|
printf("[SX1261] Initialising Radio ... \r\n");
|
||||||
|
|
||||||
// create a new instance of the HAL class
|
// create a new instance of the HAL class
|
||||||
TockHal* hal = new TockHal();
|
TockRadioLibHal* hal = new TockRadioLibHal();
|
||||||
|
|
||||||
// now we can create the radio module
|
// now we can create the radio module
|
||||||
// pinout corresponds to the SparkFun LoRa Thing Plus - expLoRaBLE
|
// pinout corresponds to the SparkFun LoRa Thing Plus - expLoRaBLE
|
||||||
|
@ -43,7 +43,7 @@ int main(void) {
|
||||||
// DIO1 pin: 2
|
// DIO1 pin: 2
|
||||||
// NRST pin: 4
|
// NRST pin: 4
|
||||||
// BUSY pin: 1
|
// 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);
|
SX1262* radio = new SX1262(tock_module);
|
||||||
|
|
||||||
// Setup the radio
|
// Setup the radio
|
||||||
|
|
|
@ -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
|
|
Loading…
Add table
Reference in a new issue