From a982df85fe3fccd7c628a0035ab27ac0925bce3f Mon Sep 17 00:00:00 2001 From: Francisco Molina Date: Fri, 14 Aug 2020 15:36:51 +0200 Subject: [PATCH 1/4] boards/dwm10001: fix dw1000 config --- boards/dwm1001/include/board.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/boards/dwm1001/include/board.h b/boards/dwm1001/include/board.h index 47f585a6b8..03ae755338 100644 --- a/boards/dwm1001/include/board.h +++ b/boards/dwm1001/include/board.h @@ -77,9 +77,9 @@ extern "C" { * @name DW1000 UWB transceiver * @{ */ -#define DW1000_PARAM_SPI_DEV SPI_DEV(1) -#define DW1000_PARAM_CS_PIN GPIO_DEV(0, 17) -#define DW1000_PARAM_INT_PIN GPIO_DEV(0, 19) +#define DW1000_PARAM_SPI SPI_DEV(1) +#define DW1000_PARAM_CS_PIN GPIO_PIN(0, 17) +#define DW1000_PARAM_INT_PIN GPIO_PIN(0, 19) /** @} */ #ifdef __cplusplus From cc0d8a83f14cc3ec5f4f16e1c8d83c43dc75c564 Mon Sep 17 00:00:00 2001 From: Francisco Molina Date: Fri, 14 Aug 2020 15:44:30 +0200 Subject: [PATCH 2/4] pkg/uwb-dw1000: initial import --- pkg/uwb-dw1000/Makefile | 26 ++ pkg/uwb-dw1000/Makefile.dep | 13 + pkg/uwb-dw1000/Makefile.include | 5 + pkg/uwb-dw1000/README.md | 0 pkg/uwb-dw1000/doc.txt | 41 +++ pkg/uwb-dw1000/hal/Makefile | 3 + pkg/uwb-dw1000/hal/uwb_dw1000.c | 170 +++++++++++ pkg/uwb-dw1000/hal/uwb_dw1000_spi.c | 92 ++++++ pkg/uwb-dw1000/include/hal/hal_gpio.h | 197 +++++++++++++ pkg/uwb-dw1000/include/hal/hal_spi.h | 169 +++++++++++ pkg/uwb-dw1000/include/hal/hal_timer.h | 45 +++ pkg/uwb-dw1000/include/syscfg_uwb_dw1000.h | 120 ++++++++ pkg/uwb-dw1000/include/uwb_dw1000.h | 87 ++++++ pkg/uwb-dw1000/include/uwb_dw1000_config.h | 263 ++++++++++++++++++ pkg/uwb-dw1000/include/uwb_dw1000_params.h | 96 +++++++ ...de-dw1000-dw1000_dev-add-linked-list.patch | Bin 0 -> 894 bytes ...0_hal-send-spi-cmd-and-data-separetl.patch | Bin 0 -> 2402 bytes ...0_hal-define-even-if-DW1000_DEVICE_0.patch | Bin 0 -> 1004 bytes ...0_hal-replace-OS_-_CRTICAL-with-DPL_.patch | Bin 0 -> 1101 bytes ...w1000-dw1000_hal-os_sr_t-by-dpl_sr_t.patch | Bin 0 -> 810 bytes ...000_dev-use-gpio_t-types-for-dev_cfg.patch | Bin 0 -> 1310 bytes ...000_mac-avoid-conflict-with-msp430-N.patch | Bin 0 -> 1810 bytes pkg/uwb-dw1000/uwb-dw1000.mk | 13 + 23 files changed, 1340 insertions(+) create mode 100644 pkg/uwb-dw1000/Makefile create mode 100644 pkg/uwb-dw1000/Makefile.dep create mode 100644 pkg/uwb-dw1000/Makefile.include create mode 100644 pkg/uwb-dw1000/README.md create mode 100644 pkg/uwb-dw1000/doc.txt create mode 100644 pkg/uwb-dw1000/hal/Makefile create mode 100644 pkg/uwb-dw1000/hal/uwb_dw1000.c create mode 100644 pkg/uwb-dw1000/hal/uwb_dw1000_spi.c create mode 100644 pkg/uwb-dw1000/include/hal/hal_gpio.h create mode 100644 pkg/uwb-dw1000/include/hal/hal_spi.h create mode 100644 pkg/uwb-dw1000/include/hal/hal_timer.h create mode 100644 pkg/uwb-dw1000/include/syscfg_uwb_dw1000.h create mode 100644 pkg/uwb-dw1000/include/uwb_dw1000.h create mode 100644 pkg/uwb-dw1000/include/uwb_dw1000_config.h create mode 100644 pkg/uwb-dw1000/include/uwb_dw1000_params.h create mode 100644 pkg/uwb-dw1000/patches/0001-uwb_dw1000-include-dw1000-dw1000_dev-add-linked-list.patch create mode 100644 pkg/uwb-dw1000/patches/0002-uwb_dw1000-dw1000_hal-send-spi-cmd-and-data-separetl.patch create mode 100644 pkg/uwb-dw1000/patches/0003-uwb_dw1000-dw1000_hal-define-even-if-DW1000_DEVICE_0.patch create mode 100644 pkg/uwb-dw1000/patches/0004-uwb_dw1000-dw1000_hal-replace-OS_-_CRTICAL-with-DPL_.patch create mode 100644 pkg/uwb-dw1000/patches/0005-uwb_dw1000-dw1000_hal-os_sr_t-by-dpl_sr_t.patch create mode 100644 pkg/uwb-dw1000/patches/0006-dw1000-dw1000_dev-use-gpio_t-types-for-dev_cfg.patch create mode 100644 pkg/uwb-dw1000/patches/0007-uwb_dw1000-dw1000_mac-avoid-conflict-with-msp430-N.patch create mode 100644 pkg/uwb-dw1000/uwb-dw1000.mk diff --git a/pkg/uwb-dw1000/Makefile b/pkg/uwb-dw1000/Makefile new file mode 100644 index 0000000000..1635ceaec4 --- /dev/null +++ b/pkg/uwb-dw1000/Makefile @@ -0,0 +1,26 @@ +PKG_NAME=uwb-dw1000 +PKG_URL=https://github.com/Decawave/uwb-dw1000/ +PKG_VERSION=6eaa85e6d429450d19a6ddeb2de05303016c0dd2 +PKG_LICENSE=Apache-2.0 + +include $(RIOTBASE)/pkg/pkg.mk + +CFLAGS += -Wno-address-of-packed-member +CFLAGS += -Wno-enum-conversion +CFLAGS += -Wno-maybe-uninitialized +CFLAGS += -Wno-missing-braces +CFLAGS += -Wno-missing-declarations +CFLAGS += -Wno-sign-compare +CFLAGS += -Wno-return-type +CFLAGS += -Wno-unused-but-set-variable +CFLAGS += -Wno-unused-function +CFLAGS += -Wno-unused-parameter +CFLAGS += -Wno-unused-variable +CFLAGS += -fms-extensions + +ifneq (,$(filter llvm,$(TOOLCHAIN))) + CFLAGS += -Wno-microsoft-anon-tag +endif + +all: + "$(MAKE)" -C $(PKG_SOURCE_DIR)/hw/drivers/uwb/uwb_dw1000/src -f $(RIOTPKG)/uwb-dw1000/uwb-dw1000.mk MODULE=uwb-dw1000 diff --git a/pkg/uwb-dw1000/Makefile.dep b/pkg/uwb-dw1000/Makefile.dep new file mode 100644 index 0000000000..b64241bd0b --- /dev/null +++ b/pkg/uwb-dw1000/Makefile.dep @@ -0,0 +1,13 @@ +USEMODULE += uwb-dw1000_hal +DEFAULT_MODULE += auto_init_uwb-dw1000 + +USEMODULE += xtimer + +FEATURES_REQUIRED += periph_gpio_irq +FEATURES_REQUIRED += periph_spi + +# Some of the pkg operation would overflow on 16bit +FEATURES_REQUIRED += arch_32bit + +# LLVM ARM shows issues with missing definitions for stdatomic +TOOLCHAINS_BLACKLIST += llvm diff --git a/pkg/uwb-dw1000/Makefile.include b/pkg/uwb-dw1000/Makefile.include new file mode 100644 index 0000000000..f34b7a9ab3 --- /dev/null +++ b/pkg/uwb-dw1000/Makefile.include @@ -0,0 +1,5 @@ +INCLUDES += -I$(PKGDIRBASE)/uwb-dw1000/hw/drivers/uwb/uwb_dw1000/include \ + -I$(RIOTPKG)/uwb-dw1000/include \ + # + +DIRS += $(RIOTPKG)/uwb-dw1000/hal diff --git a/pkg/uwb-dw1000/README.md b/pkg/uwb-dw1000/README.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/pkg/uwb-dw1000/doc.txt b/pkg/uwb-dw1000/doc.txt new file mode 100644 index 0000000000..d54f7da58b --- /dev/null +++ b/pkg/uwb-dw1000/doc.txt @@ -0,0 +1,41 @@ +/** + * @defgroup pkg_uwb_dw1000 Driver implementation for the uwb-core driver for Decawave DW1000 transceiver + * @ingroup pkg + * @brief uwb-core driver for Decawave DW1000 transceiver + * @see https://github.com/Decawave/uwb-dw1000 + */ + +# Decawave uwb-dw1000 RIOT Port + +The distribution https://github.com/decawave/uwb-core contains the +device driver implementation for the Decawave Impulse Radio-Ultra +Wideband (IR-UWB) transceiver(s). The driver includes hardware abstraction +layers (HAL), media access control (MAC) layer, Ranging Services (RNG). + +## Abstraction details + +uwb-dw1000 is meant as a hardware and architecture agnostic driver. It +was developed with MyNewt as its default OS, but its abstractions are +well defined which makes it easy to use with another OS. + +A porting layer DPL (Decawave Porting Layer) has been implemented that +wraps around OS functionalities and modules: mutex, semaphores, threads, +etc.. In most cases the mapping is direct although some specific +functionalities might not be supported. This layer is found in the uwb-core +pkg. + +A hardware abstraction layer is defined under `hal` which wraps around +modules such as: periph_gpio, periph_spi, etc. + +Since the library was used on top of mynewt most configuration values +are prefixed with `MYNEWT_VAL_%`, all configurations can be found under +`pkg/uwb-dw1000/include/syscfg`. + +## Todos + +The uwb-dw1000 can be used to provide a netdev driver for the dw1000 +module. + +uwb-dw1000 repository uses fixed length arrays to keep track of the +devices that are present. This port uses linked list but some of the +upstream code is not compatible with this. diff --git a/pkg/uwb-dw1000/hal/Makefile b/pkg/uwb-dw1000/hal/Makefile new file mode 100644 index 0000000000..0cf360bd67 --- /dev/null +++ b/pkg/uwb-dw1000/hal/Makefile @@ -0,0 +1,3 @@ +MODULE = uwb-dw1000_hal + +include $(RIOTBASE)/Makefile.base diff --git a/pkg/uwb-dw1000/hal/uwb_dw1000.c b/pkg/uwb-dw1000/hal/uwb_dw1000.c new file mode 100644 index 0000000000..db6e5e64d2 --- /dev/null +++ b/pkg/uwb-dw1000/hal/uwb_dw1000.c @@ -0,0 +1,170 @@ +/* + * Copyright (C) 2020 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup pkg_uwb_dw1000 + * @{ + * + * @file + * @brief Glue code for running uwb-core for RIOT + * + * @author Francisco Molina + * @} + */ + +#include "dpl/dpl.h" +#include "dw1000/dw1000_phy.h" +#include "dw1000/dw1000_hal.h" +#include "uwb_dw1000.h" +#include "uwb_dw1000_config.h" + +#include "uwb/uwb.h" +#include "uwb/uwb_mac.h" + +#include "utlist.h" +#include "thread.h" + +#ifndef LOG_LEVEL +#define LOG_LEVEL LOG_NONE +#endif +#include "log.h" + + +#ifndef DW1000_THREAD_PRIORITY +#define DW1000_THREAD_PRIORITY MYNEWT_VAL_UWB_DEV_TASK_PRIO +#endif + +/* Link list head */ +static struct _dw1000_dev_instance_t * dw1000_instance_head; + +/* Default instance configuration */ +static const dw1000_dev_instance_t dw1000_instance_config_default = { + .uwb_dev = { + .idx = 0, + .role = DW1000_ROLE_DEFAULT, + .task_prio = DW1000_THREAD_PRIORITY, + .status = {0}, + .rx_ant_separation = DW1000_RX_ANTSEP_DEFAULT, + .attrib = { + .nsfd = DW1000_NSFD_DEFAULT, + .nsync = DW1000_NSYNC_DEFAULT, + .nphr = DW1000_NPHR_DEFAULT , + }, + .config = { + .channel = DW1000_CHANNEL_DEFAULT, + .prf = DW1000_PRF_DEFAULT, + .dataRate = DW1000_DATARATE_DEFAULT, + .rx = { + .pacLength = DW1000_PACLEN_DEFAULT, + .preambleCodeIndex = DW1000_RX_PREAM_CIDX_DEFAULT, + .sfdType = DW1000_RX_SFD_TYPE_DEFAULT, + .phrMode = DW1000_RX_PHR_MODE_DEFAULT, + .sfdTimeout = DW1000_RX_SFD_TO_DEFAULT, + .timeToRxStable = DW1000_RX_STABLE_TIME_US , + .frameFilter = DW1000_FRAME_FILTER_DEFAULT, + .xtalTrim = DW1000_XTAL_TRIM_DEFAULT, + }, + .tx ={ + .preambleCodeIndex = DW1000_TX_PREAM_CIDX_DEAULT, + .preambleLength = DW1000_TX_PREAM_LEN_DEFAULT, + }, + .txrf={ + .PGdly = DW1000_CHANNEL_DEFAULT, + .BOOSTNORM = dw1000_power_value(DW1000_txrf_config_9db, 2.5), + .BOOSTP500 = dw1000_power_value(DW1000_txrf_config_9db, 2.5), + .BOOSTP250 = dw1000_power_value(DW1000_txrf_config_9db, 2.5), + .BOOSTP125 = dw1000_power_value(DW1000_txrf_config_9db, 2.5) + }, + .trxoff_enable = DW1000_TRXOFF_ENABLE, + .rxdiag_enable = DW1000_RX_DIAGNOSTIC, + .dblbuffon_enabled = DW1000_DOUBLE_BUFFER_ENABLE, + .LDE_enable = DW1000_LDE_ENABLE, + .LDO_enable = DW1000_LDO_ENABLE, + .sleep_enable = DW1000_SLEEP_ENABLE, + .wakeup_rx_enable = DW1000_WAKEUP_RX_ENABLE, + .rxauto_enable = DW1000_RX_AUTO_ENABLE, + .cir_enable = 0, /**< Default behavior for CIR interface */ + .cir_pdoa_slave = 0, /**< First instance should not act as pdoa slave */ + .blocking_spi_transfers = 1, /**< Nonblocking spi transfers are not supported */ + }, + } +}; + +void _uwb_dw1000_set_idx(dw1000_dev_instance_t* dev) +{ + int count = 0; + dw1000_dev_instance_t *elt = NULL; + LL_COUNT(dw1000_instance_head, elt, count); + dev->uwb_dev.idx = count++; + /* prepend to list */ + LL_PREPEND(dw1000_instance_head, dev); +} + +void uwb_dw1000_setup(dw1000_dev_instance_t* dev, dw1000_params_t* params) +{ + /* set semaphore */ + dpl_sem_init(params->spi_sem, 0x1); + /* set default uwb config */ + memcpy(dev, &dw1000_instance_config_default, + sizeof(dw1000_dev_instance_t)); + /* set uwb_dev idx */ + _uwb_dw1000_set_idx(dev); + /* this will set the configuration and init uwb_dev which ATM only + allocates an RX and TX buffer if none is yet available */ + dw1000_dev_init((struct os_dev *) dev, (void *) params); +} + +void uwb_dw1000_config_and_start(dw1000_dev_instance_t* dev) +{ + dw1000_dev_config(dev); +} + +void uwb_dw1000_set_buffs(dw1000_dev_instance_t* dev, uint8_t* tx_buf, + uint8_t* rx_buf) +{ + dev->uwb_dev.rxbuf = rx_buf; + dev->uwb_dev.txbuf = tx_buf; +} + +void uwb_dw1000_init(void) +{ + dw1000_instance_head = NULL; +} + +struct uwb_dev* uwb_dev_idx_lookup(int idx) +{ + dw1000_dev_instance_t *current = dw1000_instance_head; + + while (current) { + if (current->uwb_dev.idx == idx) { + LOG_DEBUG("uwb_dev: found dev of idx %d\n", idx); + break; + } + current = current->next; + } + + return (struct uwb_dev*) ¤t->uwb_dev; +} + +/** + * API to choose DW1000 instances based on parameters. + * + * @param idx Indicates number of instances for the chosen bsp. + * @return dw1000_dev_instance_t + */ + +struct _dw1000_dev_instance_t * hal_dw1000_inst(uint8_t idx) +{ + dw1000_dev_instance_t *current = dw1000_instance_head; + + for (uint8_t i = 0; i < idx; i++) { + current = current->next; + } + + return current; +} diff --git a/pkg/uwb-dw1000/hal/uwb_dw1000_spi.c b/pkg/uwb-dw1000/hal/uwb_dw1000_spi.c new file mode 100644 index 0000000000..be8bc8833d --- /dev/null +++ b/pkg/uwb-dw1000/hal/uwb_dw1000_spi.c @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2020 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup pkg_uwb_dw1000 + * @{ + * + * @file + * @brief SPI abstraction layer implementation + * + * @author Francisco Molina + * @} + */ + +#include "hal/hal_spi.h" +#include "periph/spi.h" + +static uint32_t spi_clk[SPI_NUMOF] = { SPI_CLK_1MHZ }; +static uint32_t spi_mode[SPI_NUMOF] = { SPI_MODE_0 }; + +int hal_spi_set_txrx_cb(int spi_num, hal_spi_txrx_cb txrx_cb, void *arg) +{ + (void) txrx_cb; + (void) spi_num; + (void) arg; + return 0; +} + +int hal_spi_init(int spi_num, void *cfg, uint8_t spi_type) +{ + (void) cfg; + (void) spi_type; + spi_init(spi_num); + return 0; +} + +int hal_spi_config(int spi_num, struct hal_spi_settings *settings) +{ + spi_clk[spi_num] = settings->baudrate; + spi_mode[spi_num] = settings->data_mode; + return 0; +} + +int hal_spi_enable(int spi_num) +{ + (void) spi_num; + return 0; +} + +int hal_spi_disable(int spi_num) +{ + (void) spi_num; + return 0; +} + +int hal_spi_txrx(int spi_num, void *txbuf, void *rxbuf, int cnt) +{ + spi_acquire(spi_num, + SPI_CS_UNDEF, + spi_mode[spi_num], + spi_clk[spi_num]); + + spi_transfer_bytes(spi_num, + SPI_CS_UNDEF, + false, + txbuf, + rxbuf, + cnt); + + spi_release(spi_num); + return 0; +} + +int hal_spi_txrx_noblock(int spi_num, void *txbuf, void *rxbuf, int cnt) +{ + (void) spi_num; + (void) txbuf; + (void) rxbuf; + (void) cnt; + return 0; +} + +int hal_spi_deinit(int spi_num) +{ + (void) spi_num; + return 0; +} diff --git a/pkg/uwb-dw1000/include/hal/hal_gpio.h b/pkg/uwb-dw1000/include/hal/hal_gpio.h new file mode 100644 index 0000000000..b09ba8beea --- /dev/null +++ b/pkg/uwb-dw1000/include/hal/hal_gpio.h @@ -0,0 +1,197 @@ +/* + * Copyright (C) 2020 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup pkg_uwb_dw1000 + * @{ + * + * @file + * @brief GPIO abstraction layer RIOT adaption + * + * @author Francisco Molina + * @} + */ + +#ifndef HAL_HAL_GPIO_H +#define HAL_HAL_GPIO_H + +#include "periph/gpio.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Map hal_gpio_pull_t enum types to gpio_mode_t enum types + */ +enum { + /** Pull-up/down not enabled */ + HAL_GPIO_PULL_NONE = GPIO_IN, + /** Pull-up enabled */ + HAL_GPIO_PULL_UP = GPIO_IN_PU, + /** Pull-down enabled */ + HAL_GPIO_PULL_DOWN = GPIO_IN_PD +}; +/** + * @brief hal_gpio_pull type + */ +typedef gpio_mode_t hal_gpio_pull_t; + +/** + * @brief Map hal_gpio_irq_trig_t enum types to gpio_flank_t enum types + */ +enum { +#ifdef GPIO_NONE + HAL_GPIO_TRIG_NONE = GPIO_NONE, +#endif + /** IRQ occurs on rising edge */ + HAL_GPIO_TRIG_RISING = GPIO_RISING, + /** IRQ occurs on falling edge */ + HAL_GPIO_TRIG_FALLING = GPIO_FALLING, + /** IRQ occurs on either edge */ + HAL_GPIO_TRIG_BOTH = GPIO_BOTH, + /** IRQ occurs when line is low */ +#ifdef GPIO_LOW + HAL_GPIO_TRIG_LOW = GPIO_LOW, +#endif + /** IRQ occurs when line is high */ +#ifdef GPIO_HIGH + HAL_GPIO_TRIG_HIGH = GPIO_HIGH +#endif +}; +/** + * @brief hal_gpio_irq_trig type + */ +typedef gpio_flank_t hal_gpio_irq_trig_t; + +/** + * @brief Function proto for GPIO irq handler functions + */ +typedef gpio_cb_t hal_gpio_irq_handler_t; + +/** + * Initializes the specified pin as an input + * + * @param pin Pin number to set as input + * @param pull pull type + * + * @return int 0: no error; -1 otherwise. + */ +static inline int hal_gpio_init_in(gpio_t pin, hal_gpio_pull_t pull) +{ + return gpio_init(pin, pull); +} + +/** + * Initialize the specified pin as an output, setting the pin to the specified + * value. + * + * @param pin Pin number to set as output + * @param val Value to set pin + * + * @return int 0: no error; -1 otherwise. + */ +static inline int hal_gpio_init_out(gpio_t pin, int val) +{ + int res = gpio_init(pin, GPIO_OUT); + gpio_write(pin, val); + return res; +} + +/** + * Write a value (either high or low) to the specified pin. + * + * @param pin Pin to set + * @param val Value to set pin (0:low 1:high) + */ +static inline void hal_gpio_write(gpio_t pin, int val) +{ + gpio_write(pin, val); +} + +/** + * Reads the specified pin. + * + * @param pin Pin number to read + * + * @return int 0: low, 1: high + */ +static inline int hal_gpio_read(gpio_t pin) +{ + return gpio_read(pin); +} + +/** + * Toggles the specified pin + * + * @param pin Pin number to toggle + * + * @return current gpio state int 0: low, 1: high + */ +static inline int hal_gpio_toggle(gpio_t pin) +{ + gpio_toggle(pin); + return gpio_read(pin); +} + +/** + * Initialize a given pin to trigger a GPIO IRQ callback. + * + * @param pin The pin to trigger GPIO interrupt on + * @param handler The handler function to call + * @param arg The argument to provide to the IRQ handler + * @param trig The trigger mode (e.g. rising, falling) + * @param pull The mode of the pin (e.g. pullup, pulldown) + * + * @return 0 on success, non-zero error code on failure. + */ +static inline int hal_gpio_irq_init(gpio_t pin, + hal_gpio_irq_handler_t handler, + void *arg, + hal_gpio_irq_trig_t trig, + hal_gpio_pull_t pull) +{ + return gpio_init_int(pin, pull, trig, handler, arg); +} + +/** + * Release a pin from being configured to trigger IRQ on state change. + * + * @param pin The pin to release + */ +static inline void hal_gpio_irq_release(gpio_t pin) +{ + /* can't release the interrupt so ar least disable it */ + gpio_irq_disable(pin); +} + +/** + * Enable IRQs on the passed pin + * + * @param pin The pin to enable IRQs on + */ +static inline void hal_gpio_irq_enable(gpio_t pin) +{ + gpio_irq_enable(pin); +} + +/** + * Disable IRQs on the passed pin + * + * @param pin The pin to disable IRQs on + */ +static inline void hal_gpio_irq_disable(gpio_t pin) +{ + gpio_irq_disable(pin); +} + +#ifdef __cplusplus +} +#endif + +#endif /* HAL_HAL_GPIO_H */ diff --git a/pkg/uwb-dw1000/include/hal/hal_spi.h b/pkg/uwb-dw1000/include/hal/hal_spi.h new file mode 100644 index 0000000000..da13747bb1 --- /dev/null +++ b/pkg/uwb-dw1000/include/hal/hal_spi.h @@ -0,0 +1,169 @@ +/* + * Copyright (C) 2020 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup pkg_uwb_dw1000 + * @{ + * + * @file + * @brief SPI abstraction layer RIOT adaption + * + * @author Francisco Molina + * @} + */ + +#ifndef HAL_HAL_SPI_H +#define HAL_HAL_SPI_H + +#include "periph/spi.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** SPI mode 0 */ +#define HAL_SPI_MODE0 (SPI_MODE_0) +/** SPI mode 1 */ +#define HAL_SPI_MODE1 (SPI_MODE_1) +/** SPI mode 2 */ +#define HAL_SPI_MODE2 (SPI_MODE_2) +/** SPI mode 3 */ +#define HAL_SPI_MODE3 (SPI_MODE_3) + +/** + * @brief Prototype for tx/rx callback + */ +typedef void (*hal_spi_txrx_cb)(void *arg, int len); + +/** + * @brief since one spi device can control multiple devices, some configuration + * can be changed on the fly from the hal + */ +struct hal_spi_settings { + /** Data mode of SPI driver, defined by HAL_SPI_MODEn */ + spi_mode_t data_mode; + /** Baudrate in kHz */ + spi_clk_t baudrate; +}; + +/** + * @brief Configure the spi. Must be called after the spi is initialized (after + * hal_spi_init is called) and when the spi is disabled (user must call + * hal_spi_disable if the spi has been enabled through hal_spi_enable prior + * to calling this function). Can also be used to reconfigure an initialized + * SPI (assuming it is disabled as described previously). + * + * @param spi_num The number of the SPI to configure. + * @param psettings The settings to configure this SPI with + * + * @return int 0 on success, non-zero error code on failure. + */ +int hal_spi_config(int spi_num, struct hal_spi_settings *psettings); + +/** + * @brief Sets the txrx callback (executed at interrupt context) when the + * buffer is transferred by the master or the slave using the non-blocking API. + * Cannot be called when the spi is enabled. This callback will also be called + * when chip select is de-asserted on the slave. + * + * NOTE: This callback is only used for the non-blocking interface and must + * be called prior to using the non-blocking API. + * + * @param spi_num SPI interface on which to set callback + * @param txrx_cb Callback function + * @param arg Argument to be passed to callback function + * + * @return int 0 on success, non-zero error code on failure. + */ +int hal_spi_set_txrx_cb(int spi_num, hal_spi_txrx_cb txrx_cb, void *arg); + +/** + * @brief Enables the SPI. This does not start a transmit or receive operation; + * it is used for power mgmt. Cannot be called when a SPI transfer is in + * progress. + * + * @param spi_num + * + * @return int 0 on success, non-zero error code on failure. + */ +int hal_spi_enable(int spi_num); + +/** + * @brief Disables the SPI. Used for power mgmt. It will halt any current SPI transfers + * in progress. + * + * @param spi_num + * + * @return int 0 on success, non-zero error code on failure. + */ +int hal_spi_disable(int spi_num); + +/** + * @brief Blocking interface to send a buffer and store the received values from the + * slave. The transmit and receive buffers are either arrays of 8-bit (uint8_t) + * values or 16-bit values depending on whether the spi is configured for 8 bit + * data or more than 8 bits per value. The 'cnt' parameter is the number of + * 8-bit or 16-bit values. Thus, if 'cnt' is 10, txbuf/rxbuf would point to an + * array of size 10 (in bytes) if the SPI is using 8-bit data; otherwise + * txbuf/rxbuf would point to an array of size 20 bytes (ten, uint16_t values). + * + * NOTE: these buffers are in the native endian-ness of the platform. + * + * MASTER: master sends all the values in the buffer and stores the + * stores the values in the receive buffer if rxbuf is not NULL. + * The txbuf parameter cannot be NULL. + * SLAVE: cannot be called for a slave; returns -1 + * + * @param spi_num SPI interface to use + * @param txbuf Pointer to buffer where values to transmit are stored. + * @param rxbuf Pointer to buffer to store values received from peer. + * @param cnt Number of 8-bit or 16-bit values to be transferred. + * + * @return int 0 on success, non-zero error code on failure. + */ +int hal_spi_txrx(int spi_num, void *txbuf, void *rxbuf, int cnt); + +/** + * @brief Non-blocking interface to send a buffer and store received values. Can be + * used for both master and slave SPI types. The user must configure the + * callback (using hal_spi_set_txrx_cb); the txrx callback is executed at + * interrupt context when the buffer is sent. + * + * The transmit and receive buffers are either arrays of 8-bit (uint8_t) + * values or 16-bit values depending on whether the spi is configured for 8 bit + * data or more than 8 bits per value. The 'cnt' parameter is the number of + * 8-bit or 16-bit values. Thus, if 'cnt' is 10, txbuf/rxbuf would point to an + * array of size 10 (in bytes) if the SPI is using 8-bit data; otherwise + * txbuf/rxbuf would point to an array of size 20 bytes (ten, uint16_t values). + * + * NOTE: these buffers are in the native endian-ness of the platform. + * + * MASTER: master sends all the values in the buffer and stores the + * stores the values in the receive buffer if rxbuf is not NULL. + * The txbuf parameter cannot be NULL + * SLAVE: Slave "preloads" the data to be sent to the master (values + * stored in txbuf) and places received data from master in rxbuf + * (if not NULL). The txrx callback occurs when len values are + * transferred or master de-asserts chip select. If txbuf is NULL, + * the slave transfers its default byte. Both rxbuf and txbuf cannot + * be NULL. + * + * @param spi_num SPI interface to use + * @param txbuf Pointer to buffer where values to transmit are stored. + * @param rxbuf Pointer to buffer to store values received from peer. + * @param cnt Number of 8-bit or 16-bit values to be transferred. + * + * @return int 0 on success, non-zero error code on failure. + */ +int hal_spi_txrx_noblock(int spi_num, void *txbuf, void *rxbuf, int cnt); + +#ifdef __cplusplus +} +#endif + +#endif /* HAL_HAL_SPI_H */ diff --git a/pkg/uwb-dw1000/include/hal/hal_timer.h b/pkg/uwb-dw1000/include/hal/hal_timer.h new file mode 100644 index 0000000000..a3b72c3bb5 --- /dev/null +++ b/pkg/uwb-dw1000/include/hal/hal_timer.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2020 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup pkg_uwb_dw1000 + * @{ + * + * @file + * @brief Timer abstraction layer RIOT adaption + * + * @author Francisco Molina + * @} + */ + +#ifndef HAL_HAL_TIMER_H +#define HAL_HAL_TIMER_H + +#include "xtimer.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief HAL timer callback + */ +typedef xtimer_callback_t hal_timer_cb; + +/** + * @brief The HAL timer structure. + */ +struct hal_timer { + xtimer_t timer; /**< the timer */ +}; + +#ifdef __cplusplus +} +#endif + +#endif /* HAL_HAL_TIMER_H */ diff --git a/pkg/uwb-dw1000/include/syscfg_uwb_dw1000.h b/pkg/uwb-dw1000/include/syscfg_uwb_dw1000.h new file mode 100644 index 0000000000..7e62e91bf1 --- /dev/null +++ b/pkg/uwb-dw1000/include/syscfg_uwb_dw1000.h @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2020 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup pkg_uwb_core + * @{ + * + * @file + * @brief uwb-dw1000 module configurations + * taken from decawave-uwb-dw1000/hw/drivers/uwb/uwb_dw1000 + * + * @author Francisco Molina + * @} + */ + +#ifndef SYSCFG_UWB_DW1000_H +#define SYSCFG_UWB_DW1000_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Used to check that the UWB_DEV has been setup correctly + * at compile time. + * @note (UWB_DEV_RXDIAG_MAXLEN > 19) + */ +#ifndef MYNEWT_VAL_UWB_DW1000_API_CHECKS +#define MYNEWT_VAL_UWB_DW1000_API_CHECKS (1) +#endif + +/** + * @brief Size of spi read/write buffer, sets the + * maximum allowed nonblocking read operation + */ +#ifndef MYNEWT_VAL_DW1000_HAL_SPI_BUFFER_SIZE +#define MYNEWT_VAL_DW1000_HAL_SPI_BUFFER_SIZE (256) +#endif + +/** + * @brief The maximum number of bytes in a single transfer that the + * SPI hardware supports. + * + * @note RIOT spi implementation will take care of splitting if this max + * value is exceeded. If asynchronous (non-blocking) spi is ever + * added to RIOT this value will need to be adapted to the platform + * specific value. + */ +#ifndef MYNEWT_VAL_DW1000_HAL_SPI_MAX_CNT +#define MYNEWT_VAL_DW1000_HAL_SPI_MAX_CNT (1024) +#endif + +/** + * @brief Max size spi read in bytes that is always done with blocking io. + * Reads longer than this value will be done with non-blocking io. + * @note Ignore in RIOT since non-blocking SPI is not yet enabled + */ +#ifndef MYNEWT_VAL_DW1000_DEVICE_SPI_RD_MAX_NOBLOCK +#define MYNEWT_VAL_DW1000_DEVICE_SPI_RD_MAX_NOBLOCK (9) +#endif + +/** + * @brief Enable range bias correction polynomial + */ +#ifndef MYNEWT_VAL_DW1000_BIAS_CORRECTION_ENABLED +#define MYNEWT_VAL_DW1000_BIAS_CORRECTION_ENABLED (0) +#endif + +/** + * @brief Tx Power dBm + */ +#ifndef MYNEWT_VAL_DW1000_DEVICE_TX_PWR +#define MYNEWT_VAL_DW1000_DEVICE_TX_PWR (((float)-14.3f)) +#endif + +/** + * @brief Antenna Gain dB + */ +#ifndef MYNEWT_VAL_DW1000_DEVICE_ANT_GAIN +#define MYNEWT_VAL_DW1000_DEVICE_ANT_GAIN (((float)1.0f)) +#endif + +/** + * @brief Enable showing rx and tx activity on leds + */ +#ifndef MYNEWT_VAL_DW1000_RXTX_LEDS +#define MYNEWT_VAL_DW1000_RXTX_LEDS (1) +#endif + +/** + * @brief Enable showing rx and tx activity on gpios + */ +#ifndef MYNEWT_VAL_DW1000_RXTX_GPIO +#define MYNEWT_VAL_DW1000_RXTX_GPIO (0) +#endif + +/** + * @brief Toggle LED_1 for every range packet received + */ +#ifndef MYNEWT_VAL_DW1000_RNG_INDICATE_LED +#define MYNEWT_VAL_DW1000_RNG_INDICATE_LED (0) +#endif + +/** + * @brief Expose event counter cli api + */ +#ifndef MYNEWT_VAL_DW1000_CLI_EVENT_COUNTERS +#define MYNEWT_VAL_DW1000_CLI_EVENT_COUNTERS (0) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* SYSCFG_UWB_DW1000_H */ diff --git a/pkg/uwb-dw1000/include/uwb_dw1000.h b/pkg/uwb-dw1000/include/uwb_dw1000.h new file mode 100644 index 0000000000..e63d26b9b6 --- /dev/null +++ b/pkg/uwb-dw1000/include/uwb_dw1000.h @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2020 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup pkg_uwb_dw1000 + * + * @{ + * + * @file + * @brief Abstraction layer for RIOT adaption + * + * @author Francisco Molina + * @} + */ +#ifndef UWB_DW1000_H +#define UWB_DW1000_H + +#include + +#include "dw1000/dw1000_dev.h" +#include "dw1000/dw1000_hal.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Device initialization parameters + */ +typedef struct dw1000_dev_cfg dw1000_params_t; + +/** + * @brief Device descriptor for the driver + */ +typedef struct { + dw1000_dev_instance_t dev; /**< dwDevice parent struct */ +} uwb_dw1000_t; + +/** + * @brief Sets device linked list to 0, not really needed... + */ +void uwb_dw1000_init(void); + +/** + * @brief Sets the tx and rx buffer for the uwb_dev in the dw1000 instance + * + * @note If this is not set before uwb_dw1000_setup() is called then + * the buffers will be dynamically allocated. + * + * @param[in] dev dw1000 device instance pointer + * @param[in] tx_buf transmit buffer + * @param[in] rx_buf receive buffer + */ +void uwb_dw1000_set_buffs(dw1000_dev_instance_t* dev, uint8_t* tx_buf, + uint8_t* rx_buf); + +/** + * @brief Setup a dw1000 device + * + * This will setup the dw1000 dev instance and the uwb_dev instance within. + * + * @param[out] dev dw1000 device descriptor + * @param[in] params receive buffer + */ +void uwb_dw1000_setup(dw1000_dev_instance_t* dev, dw1000_params_t* params); + +/** + * @brief Configure and start the dw1000 + * + * This will wakeup and setup the dw1000 device, configure the mac and + * phy. Setting up the mac will also call dw1000_tasks_init() that will + * handle the device interrupts. + * + * @param[out] dev dw1000 device descriptor + */ +void uwb_dw1000_config_and_start(dw1000_dev_instance_t* dev); + +#ifdef __cplusplus +} +#endif + +#endif /* UWB_DW1000_H */ diff --git a/pkg/uwb-dw1000/include/uwb_dw1000_config.h b/pkg/uwb-dw1000/include/uwb_dw1000_config.h new file mode 100644 index 0000000000..40b1f01d9b --- /dev/null +++ b/pkg/uwb-dw1000/include/uwb_dw1000_config.h @@ -0,0 +1,263 @@ +/* + * Copyright (C) 2020 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup pkg_uwb_core + * @{ + * + * @file + * @brief uwb-dw1000 radio configurations + * + * @author Francisco Molina + * @} + */ + +#ifndef UWB_DW1000_CONFIG_H +#define UWB_DW1000_CONFIG_H + +#include "dw1000/dw1000_regs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Default UWB Role + * + * - Tag "0x00" + * - Node "0x01" + * - Pan master "0x02" + * - Anchor "0x04" + * - Panmaster "0x07" + */ +#ifndef DW1000_ROLE_DEFAULT +#define DW1000_ROLE_DEFAULT 0x0 +#endif + +/** + * @brief Default Number of symbols in start of frame delimiter + */ +#ifndef DW1000_NSFD_DEFAULT +#define DW1000_NSFD_DEFAULT 8 +#endif + +/** + * @brief Default Number of symbols in preamble sequence + */ +#ifndef DW1000_NSYNC_DEFAULT +#define DW1000_NSYNC_DEFAULT 128 +#endif + +/** + * @brief Default Number of symbols in phy header + */ +#ifndef DW1000_NPHR_DEFAULT +#define DW1000_NPHR_DEFAULT 21 +#endif + + +/** + * @brief Default channel + */ +#ifndef DW1000_CHANNEL_DEFAULT +#define DW1000_CHANNEL_DEFAULT 5 +#if DW1000_CHANNEL_DEFAULT > 7 || DW1000_CHANNEL_DEFAULT < 1 +#error "DW1000_CHANNEL_DEFAULT must be 1..7" +#endif +#endif + +/** + * @brief Default Pulse generator delay + */ +#ifndef DW1000_TX_PGDELAY_DEFAULT +#if DW1000_CHANNEL_DEFAULT == 1 +#define DW1000_TX_PGDELAY_DEFAULT TC_PGDELAY_CH1 +#elif DW1000_CHANNEL_DEFAULT == 2 +#define DW1000_TX_PGDELAY_DEFAULT TC_PGDELAY_CH2 +#elif DW1000_CHANNEL_DEFAULT == 3 +#define DW1000_TX_PGDELAY_DEFAULT TC_PGDELAY_CH3 +#elif DW1000_CHANNEL_DEFAULT == 4 +#define DW1000_TX_PGDELAY_DEFAULT TC_PGDELAY_CH4 +#elif DW1000_CHANNEL_DEFAULT == 5 +#define DW1000_TX_PGDELAY_DEFAULT TC_PGDELAY_CH5 +#elif DW1000_CHANNEL_DEFAULT == 6 +#define DW1000_TX_PGDELAY_DEFAULT TC_PGDELAY_CH7 +#elif DW1000_CHANNEL_DEFAULT == 7 +#define DW1000_TX_PGDELAY_DEFAULT TC_PGDELAY_CH7 +#endif +#endif + +/** + * @brief Default UWB Pulse Repetition Frequency (MHz) + * + * - DWT_PRF_16M + * - DWT_PRF_64M + */ +#ifndef DW1000_PRF_DEFAULT +#define DW1000_PRF_DEFAULT DWT_PRF_64M +#endif + +/** + * @brief Default UWB Datarate (110k, 850k, 6m8) + * + * - DWT_BR_110K + * - DWT_BR_850K + * - DWT_BR_6M8 + */ +#ifndef DW1000_DATARATE_DEFAULT +#define DW1000_DATARATE_DEFAULT DWT_BR_6M8 +#endif + +/** + * @brief Default UWB Acquisition Chunk Size (Relates to RX preamble length) + * + * - 8 + * - 16 + * - 32 + * - 64 + */ +#ifndef DW1000_PACLEN_DEFAULT +#define DW1000_PACLEN_DEFAULT DWT_PAC8 +#endif + +/** + * @brief Default UWB RX Preamble Code Index + */ +#ifndef DW1000_RX_PREAM_CIDX_DEFAULT +#define DW1000_RX_PREAM_CIDX_DEFAULT 9 +#endif + +/** + * @brief Default UWB SFD Type + * + * - true: use non standard SFD for better performance + * - false: use standard SFD + */ +#ifndef DW1000_RX_SFD_TYPE_DEFAULT +#define DW1000_RX_SFD_TYPE_DEFAULT true +#endif + +/** + * @brief Default UWB SFD Timeout (-1=auto, timeout in symbols) + * + */ +#ifndef DW1000_RX_SFD_TO_DEFAULT +#define DW1000_RX_SFD_TO_DEFAULT (128 + 1 + 8 - 8) /* (preamble length + 1 + SFD length - PAC size) */ +#endif + +/** + * @brief Default UWB PHR Mode + * + * - 0x0 - standard DWT_PHRMODE_STD + * - 0x3 - extended frames DWT_PHRMODE_EXT + */ +#ifndef DW1000_RX_PHR_MODE_DEFAULT +#define DW1000_RX_PHR_MODE_DEFAULT DWT_PHRMODE_EXT +#endif + +/** + * @brief Enable RX Frame Quality diagnositics (rssi, fppl, etc.) + */ +#ifndef DW1000_RX_DIAGNOSTIC +#define DW1000_RX_DIAGNOSTIC 0 +#endif + + +/** + * @brief Default UWB RX Antenna separation distance in m + */ +#ifndef DW1000_TX_PREAM_CIDX_DEAULT +#define DW1000_TX_PREAM_CIDX_DEAULT 9 +#endif + +/** + * @brief Default UWB Preamble Length + * + * - DWT_PLEN_4096 : Standard preamble length 4096 symbols + * - DWT_PLEN_2048 : Non-standard preamble length 2048 symbols + * - DWT_PLEN_1536 : Non-standard preamble length 1536 symbols + * - DWT_PLEN_1024 : Standard preamble length 1024 symbols + * - DWT_PLEN_512 : Non-standard preamble length 512 symbols + * - DWT_PLEN_256 : Non-standard preamble length 256 symbols + * - DWT_PLEN_128 : Non-standard preamble length 128 symbols + * - DWT_PLEN_64 : Standard preamble length 64 symbols + * - DWT_PLEN_32 : When setting length 32 symbols this is 0x0, which is programmed to byte 2 of the TX_FCTRL register + * - DWT_PLEN_72 : Non-standard length 72 + */ +#ifndef DW1000_TX_PREAM_LEN_DEFAULT +#define DW1000_TX_PREAM_LEN_DEFAULT DWT_PLEN_128 +#endif + +/** + * @brief Default UWB RX Antenna separation distance in m + */ +#ifndef DW1000_RX_ANTSEP_DEFAULT +#define DW1000_RX_ANTSEP_DEFAULT 0.0205 +#endif + +/** + * @brief Default MAC FrameFilter (0x0000 = no filter) + */ +#ifndef DW1000_FRAME_FILTER_DEFAULT +#define DW1000_FRAME_FILTER_DEFAULT 0x0000 +#endif + +/** + * @brief Default MAC FrameFilter Crystal Trim value, 0xff == not set + */ +#ifndef DW1000_XTAL_TRIM_DEFAULT +#define DW1000_XTAL_TRIM_DEFAULT 0x10 +#endif + +/** + * @brief Time until the Receiver is stable, (in us) + */ +#ifndef DW1000_RX_STABLE_TIME_US +#define DW1000_RX_STABLE_TIME_US 6 +#endif + +/** + * @brief Enables forced TRXOFF in start_tx and start_tx interface + */ +#define DW1000_TRXOFF_ENABLE 1 + +/** + * @brief Enables double buffer + */ +#define DW1000_DOUBLE_BUFFER_ENABLE false + +/** + * @brief Load LDE microcode on wake up + */ +#define DW1000_LDE_ENABLE true + +/** + * @brief Load the LDO tune value on wake up + */ +#define DW1000_LDO_ENABLE false + +/** + * @brief Enable sleep + */ +#define DW1000_SLEEP_ENABLE true + +/** + * @brief Wakeup to Rx state + */ +#define DW1000_WAKEUP_RX_ENABLE true + +/** + * @brief On error re-enable + */ +#define DW1000_RX_AUTO_ENABLE true + +#ifdef __cplusplus +} +#endif + +#endif /* UWB_DW1000_CONFIG_H */ diff --git a/pkg/uwb-dw1000/include/uwb_dw1000_params.h b/pkg/uwb-dw1000/include/uwb_dw1000_params.h new file mode 100644 index 0000000000..11fc23ce67 --- /dev/null +++ b/pkg/uwb-dw1000/include/uwb_dw1000_params.h @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2020 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup pkg_uwb_dw1000 + * + * @{ + * @file + * @brief Default configuration + * + * @author Francisco Molina + */ + +#ifndef UWB_DW1000_PARAMS_H +#define UWB_DW1000_PARAMS_H + +#include "board.h" +#include "uwb_dw1000.h" +#include "dpl/dpl_sem.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @name Set default configuration parameters + * @{ + */ +#ifndef DW1000_SPI_SEM +static struct dpl_sem sem_spi; +#define DW1000_SPI_SEM &sem_spi +#endif +#ifndef DW1000_PARAM_SPI +#define DW1000_PARAM_SPI (SPI_DEV(1)) +#endif +#ifndef DW1000_PARAM_SPI_CLK_LOW +#define DW1000_PARAM_SPI_CLK_LOW (SPI_CLK_1MHZ) +#endif +#ifndef DW1000_PARAM_SPI_CLK_HIGH +#define DW1000_PARAM_SPI_CLK_HIGH (SPI_CLK_10MHZ) +#endif +#ifndef DW1000_SPI_MODE +#define DW1000_SPI_MODE (SPI_MODE_0) +#endif +#ifndef DW1000_PARAM_CS_PIN +#define DW1000_PARAM_CS_PIN (GPIO_PIN(0, 17)) +#endif +#ifndef DW1000_PARAM_IRQ_PIN +#define DW1000_PARAM_IRQ_PIN (GPIO_PIN(0, 19)) +#endif +#ifndef DW1000_PARAM_RESET_PIN +#define DW1000_PARAM_RESET_PIN (GPIO_PIN(0, 24)) +#endif +#ifndef DW1000_RX_ANTENNA_DELAY +#define DW1000_RX_ANTENNA_DELAY (0x4042) +#endif +#ifndef DW1000_TX_ANTENNA_DELAY +#define DW1000_TX_ANTENNA_DELAY (0x4042) +#endif +#ifndef DW1000_EXT_CLOCK_DELAY +#define DW1000_EXT_CLOCK_DELAY (0) +#endif + +#ifndef DW1000_PARAMS +#define DW1000_PARAMS { .spi_sem = DW1000_SPI_SEM, \ + .spi_baudrate = DW1000_PARAM_SPI_CLK_HIGH, \ + .spi_baudrate_low = DW1000_PARAM_SPI_CLK_LOW, \ + .spi_num = DW1000_PARAM_SPI, \ + .rst_pin = DW1000_PARAM_RESET_PIN, \ + .irq_pin = DW1000_PARAM_IRQ_PIN, \ + .ss_pin = DW1000_PARAM_CS_PIN, \ + .rx_antenna_delay = DW1000_RX_ANTENNA_DELAY, \ + .tx_antenna_delay = DW1000_TX_ANTENNA_DELAY, \ + .ext_clock_delay = DW1000_EXT_CLOCK_DELAY } +#endif +/**@}*/ + +/** + * @brief Configuration struct + */ +static const dw1000_params_t dw1000_params[] = +{ + DW1000_PARAMS +}; + +#ifdef __cplusplus +} +#endif + +#endif /* UWB_DW1000_PARAMS_H */ +/** @} */ diff --git a/pkg/uwb-dw1000/patches/0001-uwb_dw1000-include-dw1000-dw1000_dev-add-linked-list.patch b/pkg/uwb-dw1000/patches/0001-uwb_dw1000-include-dw1000-dw1000_dev-add-linked-list.patch new file mode 100644 index 0000000000000000000000000000000000000000..9b39d60598ea771e9e7177e3de3a496afb420bf1 GIT binary patch literal 894 zcmbVKO^?$s5WV|XJj4Z>P2!|!lLmyk0#$H8TB&LiRY{VhTB&xSSDBQn`Kr`XXGK-yyj-pbpL>ffosgB_yuNhg zoM&v~-PG6&!YVVW-aqV&6?ogy@v>S^DpB1#_CYub@5~Ld0=Lu7!*h;oUeBwVFA(`1 zXWL1BBjsv*xx2l8{}EZb_=@Q)8-30==c%!(n>3}*+b7d#dZ;0^h7Wz9U`EGa>Cxfj z2FBtzX4s!oJ(vd?#?(6u-saC7uVQ{kZiO;wa%!+2-jm8NsYb~ z*l7tp4aV*ug*teIqFMUnYBJW%^Tt8C=7P)v>75yc|wq5Jz%ecD@#1d6HKNXY4ndE)_EX literal 0 HcmV?d00001 diff --git a/pkg/uwb-dw1000/patches/0002-uwb_dw1000-dw1000_hal-send-spi-cmd-and-data-separetl.patch b/pkg/uwb-dw1000/patches/0002-uwb_dw1000-dw1000_hal-send-spi-cmd-and-data-separetl.patch new file mode 100644 index 0000000000000000000000000000000000000000..38356d4e375870e0819b8fd907dcb578b6a0125d GIT binary patch literal 2402 zcmeHIZEw>s5dQ98acB~xYtklZ(>K^y#h94rUc}0q5QyaZ2Gk~K!l2jBlL&HSK2p+{eHNOr@+MvlkIgAw7cESd)4a0JZ z?!F6NYY+qj&x1P7TyjxPK5(iA@a}v#e)0_bX7C=$#Ux}4&vo5qHH5P$89>1$gJLd# zrVJwd%_0@y>O9K1O0EdRSq?9b&&Gr}jzeI!XtG>f^1NtbMEzYyEpqxzk;%fU*YpD839sf(jSwc{7#wFR6hzG}cAjiuOoU{7 z3AFFI-8gDACcS{S{0PtPcG_(XdaJz&!iBB&KR5uV<+*kj>eYY?n3@%>Va_9F6)G>O zg7q5XmmyN8P%b=Fu&a4gHUR?q(azJk$ihV~6u0z$&VEsZb0KYTYY)-R*%2|^V>}j; zGwbB->C@Na8mZs53it2dSZX2Es$H79FcPv{LYgrSc*-QXvW;36GcI9)d5+`*h1yCm zeQJjDEKRk-u2r_%tU^VFR)K{I3=8p*Lmd(>r)ma|3@~TksEl7W)N)eB#zv#i&o5jn zRN<@P$U1zjbss((j>3!cEzV93I&G6^soAdnes@UHEVCz~lDC!l? zHJFsAbbe(a#+c{!ZP<~TwXeM*NjvZGq~OHSo97hvi~_KxL$%D8>-^(XmZ=TaWhU5e z4a1-qZjORs>RbDtz8sAzmYn4 zTnRw$c(*wWZe!DIS7`uSw$?y3Y-*sYqTi}OlsFa}lnAqD>e8^Rr~hknqpa`F7%E2B zX3*~2`W9J@e0kAY>kx+fFS?CMyz%w*hQ literal 0 HcmV?d00001 diff --git a/pkg/uwb-dw1000/patches/0003-uwb_dw1000-dw1000_hal-define-even-if-DW1000_DEVICE_0.patch b/pkg/uwb-dw1000/patches/0003-uwb_dw1000-dw1000_hal-define-even-if-DW1000_DEVICE_0.patch new file mode 100644 index 0000000000000000000000000000000000000000..c103f8d71b374abd69a848e35c259e27447a68f5 GIT binary patch literal 1004 zcmb7D%Wm5+5WMp%2I$4MELjgrmfa#qkO%5R(Vz+1Ls2L)xw6^Hk|9!YinjmWrQ-l? zZWbg^B!@dQyUUxd-GWq1$SJ47>t z;o|Tj4#P;?aF_*dy0Vel$d-Y%Zc4nXXnXiO?`0tCGjUZ~ayUIkG{r@~=HqdQC|RW0 zB2MA)EEISB>N`ohz}MT0`^)!8Ch0fy`&FU#Q5c4k=b_k?^#Y12-4N)J8t4jFUmT*i zy8gVpye>j$BhWX7tPslvpOzo*vF&TCcQqZc9N|$*GT7_7#)@Ee98zjhu$#8)*Bg{z zH$OzJjfH9Pz{E!>g>H;};E=q-M>{`(A9DPX1#(kob)$JkK49P-%7~H)XRXHAV~;MxE7dV+P*P zEhwt#dF~H|P`aw%`)h4cPEMd)od6cPQS^jWo>CH*K`;-cRG9=!rm@J8>@_T8i%x tv8a(Nqh(#c{*&fBIJ%;vQVkr$KjUBpvkwodec>NfbB;wE#CZ@3@fUqaF^K>G literal 0 HcmV?d00001 diff --git a/pkg/uwb-dw1000/patches/0004-uwb_dw1000-dw1000_hal-replace-OS_-_CRTICAL-with-DPL_.patch b/pkg/uwb-dw1000/patches/0004-uwb_dw1000-dw1000_hal-replace-OS_-_CRTICAL-with-DPL_.patch new file mode 100644 index 0000000000000000000000000000000000000000..26c64f4c2753b8de3fe62c2c569463991d30a059 GIT binary patch literal 1101 zcmbtT-*1~R5PtVxaW9j|2*D5tAziyx{h>w6)-27#q-nB@xg=f*AZ(ge+Wz<1r0FJY zdx(ZWhrc_2=lkw_(^OlCq8KTrVLncxJmsr6i*S^r!*Gl=K`{(5Ni&*o_)wK_hcyHV zP&(;e2q_K7jiH&qO~Xqem8eW$AxjQ#R=Dl{&Ra1M#TmKc8f~2HLlD75yEfZH3PC&x z(n&Z1*Q_YHYqM`C^aQ@lFP4|@AoAm{(C#vp?*dAxzc*~diwQJX7hE9R-mzEga1>WxUSt4z)BVfV#CWd z=6wi3mI@m!t5P{`&jL9XxL4F@#G2WG_6W>S!8 zcx{!`JpzYkUFiytH^mdfN2yQto*x8=XG2VzuRkuY7pB$wwmPcmoeHS)^>YhQm^H=U>;dV!KA_ml(xrS@waNsIKVYxGTCd|68>0gCjO5 z?qNQgL1rdKmM~p>diyL&UKdQ%t(IG4X2|#xYZVIR#O5a0Q~%QC^K|)7S^o4rtI`NK r1)D?RmNjOGxq2zvNMq20G+fz{ckG7KPV3wE#$~3AgoAKApoIJcfwe>E literal 0 HcmV?d00001 diff --git a/pkg/uwb-dw1000/patches/0005-uwb_dw1000-dw1000_hal-os_sr_t-by-dpl_sr_t.patch b/pkg/uwb-dw1000/patches/0005-uwb_dw1000-dw1000_hal-os_sr_t-by-dpl_sr_t.patch new file mode 100644 index 0000000000000000000000000000000000000000..0c48acdbd152da79e7b2961f54bafeeaa94a25e0 GIT binary patch literal 810 zcmb7CU2mH(6n*!vxO)pDfH7YQ-KtD$qE1`aYR&dCO~{x_f;S^L# zKBCfr;o5KJYbE~C@CEz<2CkumP|F5E9C-VHmFW>=t5FTIYZtC#;|d#`LeC+jl64K9 z_aF!0!5QVsGm?pHEBpx&O`25^$B2Lu@EWe}J`}g_ zFNkN+d7fHb5Z40pRKX$^0Iuy!7FNx>)V(Y;9-Zg2NpPazvFNd_{!d#@#rE%Rwzr@6 e#mDWJ?WdV3Ygicei@6`i^l8i`%x5c~67m+(OTcMNCuL5H8FJ)&giMU^j3*_sf+sUpBw~_GrwQED3hr?QYyy;~ z?G7=ej9fUG6fShGxHP%h_GN_z%36bqWV~Du z5{4mx$4w-(T%$Hovnl+MZH1)bRU>dKxTiaOgkLa*AP8Co2BoYJ_+zdX-u4+tWl&pL zD{~SI{D8m;yXSB~h>&FoVYrYM^60qvi{m&VmB43+1s9WYIvgTPW^|N*OWZg~d_svVan;{d)7K1s67ZW;7R*X!McxSQ7R=jr^z{@)Z{~1+ zdj%i1VK|w`^yc!%pr6jFdb3k#>Fav)pTbU{aq~~zn(`J@v)r+*gFn-|P=T6+e)JX5 z#%3$2`j9&`Xu$>lCZv8kL|iG0S~n{T8lM_8J+v`BFmx8He2rk-(sX(D(+1w?wq5#t zcHqwFKGE;9Bl?Z*)BQdV7=^BmKBsK#>Y$&q+@(UP+_im`zqHwHzwyrfu3U4&HtZWQ efBA>D2k8g*w=zrLrk(m0cU?l_VLTmDLVg3CYcCON`^xvIUmhfAOks!WcY?BIvS<)U>F7JAP6-Zg>X^i@Ku$- zBA|5Ket=WT$P{VDFs+hYnpzeJ%uJrZTdfxD-N{n=GCL-xNu$Q_O{IN^;InKnn^Rz; zF$>3>Ll2)Q`MR9_RI(Yv_shxE`;QO}q93rlnThm%q_5v_5d8&Sa4An3Rl<(7Y$m#42 z_D)A(XgB?$+61=?FRFiX0vmQA?fWz zxcOwT`0u28ag5-26F36L%HkcjbE{Uq9dfMS6Env0OJm(Egbw&4Q82L; zH2)u}-Si4k$RUz6bvEl$?oQ7AhuXTkMq;hwa|C>gfxEjnp34oka?!TKPK?b4QnPaG zMB!c*%gn*~iY=y<;u#E1SZ*C~)TemD=uxpin`EE zn`KQIh0e;ws}B>)zo)WV-FxS>Z=?GU-=0O>dA5z% Date: Fri, 14 Aug 2020 15:50:26 +0200 Subject: [PATCH 3/4] pkg/uwb-core: initial import --- pkg/uwb-core/Makefile | 53 ++++ pkg/uwb-core/Makefile.dep | 36 +++ pkg/uwb-core/Makefile.include | 22 ++ pkg/uwb-core/contrib/Makefile | 9 + pkg/uwb-core/contrib/uwb_core.c | 61 +++++ pkg/uwb-core/contrib/uwb_core_init.c | 79 ++++++ pkg/uwb-core/doc.txt | 121 +++++++++ pkg/uwb-core/dpl/Makefile | 3 + pkg/uwb-core/dpl/dpl_callout.c | 58 +++++ pkg/uwb-core/dpl/dpl_mutex.c | 58 +++++ pkg/uwb-core/dpl/dpl_sem.c | 60 +++++ pkg/uwb-core/dpl/dpl_task.c | 68 +++++ pkg/uwb-core/include/dpl/dpl.h | 40 +++ pkg/uwb-core/include/dpl/dpl_callout.h | 83 ++++++ pkg/uwb-core/include/dpl/dpl_cputime.h | 162 ++++++++++++ pkg/uwb-core/include/dpl/dpl_error.h | 55 ++++ pkg/uwb-core/include/dpl/dpl_eventq.h | 241 ++++++++++++++++++ pkg/uwb-core/include/dpl/dpl_mutex.h | 74 ++++++ pkg/uwb-core/include/dpl/dpl_os.h | 97 +++++++ pkg/uwb-core/include/dpl/dpl_sem.h | 89 +++++++ pkg/uwb-core/include/dpl/dpl_tasks.h | 90 +++++++ pkg/uwb-core/include/dpl/dpl_time.h | 113 ++++++++ pkg/uwb-core/include/dpl/dpl_types.h | 118 +++++++++ pkg/uwb-core/include/log/dpl_log.h | 48 ++++ pkg/uwb-core/include/mcu/mcu.h | 33 +++ pkg/uwb-core/include/os/os.h | 30 +++ pkg/uwb-core/include/os/os_dev.h | 52 ++++ pkg/uwb-core/include/stats/stats.h | 33 +++ pkg/uwb-core/include/syscfg/syscfg.h | 75 ++++++ pkg/uwb-core/include/syscfg/syscfg_twr_ds.h | 53 ++++ .../include/syscfg/syscfg_twr_ds_ext.h | 53 ++++ pkg/uwb-core/include/syscfg/syscfg_twr_ss.h | 53 ++++ .../include/syscfg/syscfg_twr_ss_ack.h | 53 ++++ .../include/syscfg/syscfg_twr_ss_ext.h | 53 ++++ pkg/uwb-core/include/syscfg/syscfg_uwb.h | 144 +++++++++++ pkg/uwb-core/include/syscfg/syscfg_uwb_rng.h | 67 +++++ pkg/uwb-core/include/syscfg/syscfg_uwbcfg.h | 241 ++++++++++++++++++ pkg/uwb-core/include/sysinit/sysinit.h | 38 +++ pkg/uwb-core/include/uwb_core.h | 63 +++++ ...use-RIOT-specific-uwb_dev_idx_lookup.patch | Bin 0 -> 787 bytes ...002-lib-twr_-enable-stats-optionally.patch | Bin 0 -> 28840 bytes ...-use-DPL_ENOENT-instead-of-OS_ENOENT.patch | Bin 0 -> 640 bytes ...-use-DPL_ENOENT-instead-of-OS_ENOENT.patch | Bin 0 -> 685 bytes ..._log.h-instaed-of-log.h-to-avoid-con.patch | Bin 0 -> 2711 bytes ...on-src-use-fmt-to-avoid-newlib-issue.patch | Bin 0 -> 1461 bytes ...b-uwb_rng-always-set-rssi-to-vrssi-0.patch | Bin 0 -> 1346 bytes .../0008-porting-dpl-add-riot-files.patch | Bin 0 -> 37259 bytes sys/auto_init/auto_init.c | 5 + 48 files changed, 2884 insertions(+) create mode 100644 pkg/uwb-core/Makefile create mode 100644 pkg/uwb-core/Makefile.dep create mode 100644 pkg/uwb-core/Makefile.include create mode 100644 pkg/uwb-core/contrib/Makefile create mode 100644 pkg/uwb-core/contrib/uwb_core.c create mode 100644 pkg/uwb-core/contrib/uwb_core_init.c create mode 100644 pkg/uwb-core/doc.txt create mode 100644 pkg/uwb-core/dpl/Makefile create mode 100644 pkg/uwb-core/dpl/dpl_callout.c create mode 100644 pkg/uwb-core/dpl/dpl_mutex.c create mode 100644 pkg/uwb-core/dpl/dpl_sem.c create mode 100644 pkg/uwb-core/dpl/dpl_task.c create mode 100644 pkg/uwb-core/include/dpl/dpl.h create mode 100644 pkg/uwb-core/include/dpl/dpl_callout.h create mode 100644 pkg/uwb-core/include/dpl/dpl_cputime.h create mode 100644 pkg/uwb-core/include/dpl/dpl_error.h create mode 100644 pkg/uwb-core/include/dpl/dpl_eventq.h create mode 100644 pkg/uwb-core/include/dpl/dpl_mutex.h create mode 100644 pkg/uwb-core/include/dpl/dpl_os.h create mode 100644 pkg/uwb-core/include/dpl/dpl_sem.h create mode 100644 pkg/uwb-core/include/dpl/dpl_tasks.h create mode 100644 pkg/uwb-core/include/dpl/dpl_time.h create mode 100644 pkg/uwb-core/include/dpl/dpl_types.h create mode 100644 pkg/uwb-core/include/log/dpl_log.h create mode 100644 pkg/uwb-core/include/mcu/mcu.h create mode 100644 pkg/uwb-core/include/os/os.h create mode 100644 pkg/uwb-core/include/os/os_dev.h create mode 100644 pkg/uwb-core/include/stats/stats.h create mode 100644 pkg/uwb-core/include/syscfg/syscfg.h create mode 100644 pkg/uwb-core/include/syscfg/syscfg_twr_ds.h create mode 100644 pkg/uwb-core/include/syscfg/syscfg_twr_ds_ext.h create mode 100644 pkg/uwb-core/include/syscfg/syscfg_twr_ss.h create mode 100644 pkg/uwb-core/include/syscfg/syscfg_twr_ss_ack.h create mode 100644 pkg/uwb-core/include/syscfg/syscfg_twr_ss_ext.h create mode 100644 pkg/uwb-core/include/syscfg/syscfg_uwb.h create mode 100644 pkg/uwb-core/include/syscfg/syscfg_uwb_rng.h create mode 100644 pkg/uwb-core/include/syscfg/syscfg_uwbcfg.h create mode 100644 pkg/uwb-core/include/sysinit/sysinit.h create mode 100644 pkg/uwb-core/include/uwb_core.h create mode 100644 pkg/uwb-core/patches/0001-uwb-uwb.c-use-RIOT-specific-uwb_dev_idx_lookup.patch create mode 100644 pkg/uwb-core/patches/0002-lib-twr_-enable-stats-optionally.patch create mode 100644 pkg/uwb-core/patches/0003-lib-tofdb-use-DPL_ENOENT-instead-of-OS_ENOENT.patch create mode 100644 pkg/uwb-core/patches/0004-sys-uwbcfg-use-DPL_ENOENT-instead-of-OS_ENOENT.patch create mode 100644 pkg/uwb-core/patches/0005-treewide-use-dpl_log.h-instaed-of-log.h-to-avoid-con.patch create mode 100644 pkg/uwb-core/patches/0006-lib-json-src-use-fmt-to-avoid-newlib-issue.patch create mode 100644 pkg/uwb-core/patches/0007-lib-uwb_rng-always-set-rssi-to-vrssi-0.patch create mode 100644 pkg/uwb-core/patches/0008-porting-dpl-add-riot-files.patch diff --git a/pkg/uwb-core/Makefile b/pkg/uwb-core/Makefile new file mode 100644 index 0000000000..f4c3a19cc9 --- /dev/null +++ b/pkg/uwb-core/Makefile @@ -0,0 +1,53 @@ +PKG_NAME=uwb-core +PKG_URL=https://github.com/Decawave/uwb-core +PKG_VERSION=8ffba63755a932a89d841872ce5bdf35b9c78777 +PKG_LICENSE=Apache-2.0 + +include $(RIOTBASE)/pkg/pkg.mk + +CFLAGS += -Wno-implicit-int +CFLAGS += -Wno-int-conversion +CFLAGS += -Wno-strict-prototypes +CFLAGS += -Wno-maybe-uninitialized +CFLAGS += -Wno-missing-braces +CFLAGS += -Wno-missing-declarations +CFLAGS += -Wno-missing-field-initializers +CFLAGS += -Wno-old-style-definition +CFLAGS += -Wno-return-type +CFLAGS += -Wno-sign-compare +CFLAGS += -Wno-unused-but-set-variable +CFLAGS += -Wno-unused-parameter +CFLAGS += -Wno-unused-variable +CFLAGS += -fms-extensions + +ifneq (,$(filter llvm,$(TOOLCHAIN))) + CFLAGS += -Wno-microsoft-anon-tag +endif + +IGNORE_MODULES := uwb-core_dpl \ + uwb-core_config \ + uwb-core_contrib \ + # + +UWB_CORE_MODULES := $(filter-out $(IGNORE_MODULES),$(filter uwb-core%,$(USEMODULE))) + +UWB_CORE_PATH_dsp = lib/dsp/src +UWB_CORE_PATH_uwb_json = lib/json/src +UWB_CORE_PATH_uwbcfg = sys/uwbcfg/src/ +UWB_CORE_PATH_rng = lib/uwb_rng/src +UWB_CORE_PATH_rng_math = lib/rng_math/src +UWB_CORE_PATH_twr_ss = lib/twr_ss/src +UWB_CORE_PATH_twr_ss_ack = lib/twr_ss_ack/src +UWB_CORE_PATH_twr_ss_ext = lib/twr_ss_ext/src +UWB_CORE_PATH_twr_ds = lib/twr_ds/src +UWB_CORE_PATH_twr_ds_ext = lib/twr_ds_ext/src + +all: $(UWB_CORE_MODULES) + "$(MAKE)" -C $(PKG_SOURCE_DIR)/hw/drivers/uwb/src -f $(RIOTBASE)/Makefile.base MODULE=$(PKG_NAME) + +uwb-core_config: + "$(MAKE)" -C $(PKG_SOURCE_DIR)/porting/dpl/riot/src -f $(RIOTBASE)/Makefile.base MODULE=$@ + +uwb-core_uwbcfg: uwb-core_config +uwb-core_%: + "$(MAKE)" -C $(PKG_SOURCE_DIR)/$(UWB_CORE_PATH_$*) -f $(RIOTBASE)/Makefile.base MODULE=$@ diff --git a/pkg/uwb-core/Makefile.dep b/pkg/uwb-core/Makefile.dep new file mode 100644 index 0000000000..d23cc1dcab --- /dev/null +++ b/pkg/uwb-core/Makefile.dep @@ -0,0 +1,36 @@ +USEMODULE += uwb-core_dpl +USEMODULE += uwb-core_contrib + +DEFAULT_MODULE += auto_init_uwb-core + +USEMODULE += sema +USEMODULE += event_callback +USEMODULE += xtimer +USEMODULE += fmt + +FEATURES_REQUIRED += periph_gpio_irq +FEATURES_REQUIRED += periph_spi + +ifneq (,$(filter uwb-core_twr_%,$(USEMODULE))) + USEMODULE += uwb-core_rng +endif + +ifneq (,$(filter uwb-core_rng,$(USEMODULE))) + USEMODULE += uwb-core_rng_math + USEMODULE += uwb-core_dsp + USEMODULE += uwb-core_uwb_json +endif + +ifneq (,$(filter uwb-core_uwbcfg,$(USEMODULE))) + USEMODULE += uwb-core_config +endif + +# Some stdlib functions used by the pkg are not in avr-gcc +FEATURES_BLACKLIST += arch_avr8 +# uwb-core has specific compilation sources when compiling kernel +# libraries these introduce additional compilation issues that have not +# been addressed in this port +FEATURES_BLACKLIST += arch_native + +# LLVM ARM shows issues with missing definitions for stdatomic +TOOLCHAINS_BLACKLIST += llvm diff --git a/pkg/uwb-core/Makefile.include b/pkg/uwb-core/Makefile.include new file mode 100644 index 0000000000..6eb2f5f9ca --- /dev/null +++ b/pkg/uwb-core/Makefile.include @@ -0,0 +1,22 @@ +INCLUDES += -I$(PKGDIRBASE)/uwb-core/hw/drivers/uwb/include/ \ + -I$(PKGDIRBASE)/uwb-core/lib/euclid/include \ + -I$(PKGDIRBASE)/uwb-core/lib/dsp/include \ + -I$(PKGDIRBASE)/uwb-core/lib/json/include \ + -I$(PKGDIRBASE)/uwb-core/lib/rng_math/include \ + -I$(PKGDIRBASE)/uwb-core/lib/twr_ss/include \ + -I$(PKGDIRBASE)/uwb-core/lib/twr_ss_ext/include \ + -I$(PKGDIRBASE)/uwb-core/lib/twr_ss_ack/include \ + -I$(PKGDIRBASE)/uwb-core/lib/twr_ds/include \ + -I$(PKGDIRBASE)/uwb-core/lib/twr_ds_ext/include \ + -I$(PKGDIRBASE)/uwb-core/lib/uwb_rng/include \ + -I$(PKGDIRBASE)/uwb-core/porting/dpl/riot/include/ \ + -I$(PKGDIRBASE)/uwb-core/sys/uwbcfg/include \ + -I$(RIOTPKG)/uwb-core/include \ + # + +DIRS += $(RIOTPKG)/uwb-core/dpl \ + $(RIOTPKG)/uwb-core/contrib \ + # + +# A cflag to indicate in pkg code that we are building for RIOT +CFLAGS += -DRIOT diff --git a/pkg/uwb-core/contrib/Makefile b/pkg/uwb-core/contrib/Makefile new file mode 100644 index 0000000000..4b0943bf88 --- /dev/null +++ b/pkg/uwb-core/contrib/Makefile @@ -0,0 +1,9 @@ +MODULE = uwb-core_contrib + +SRC = uwb_core.c + +ifneq (,$(filter auto_init_uwb-core,$(USEMODULE))) + SRC += uwb_core_init.c +endif + +include $(RIOTBASE)/Makefile.base diff --git a/pkg/uwb-core/contrib/uwb_core.c b/pkg/uwb-core/contrib/uwb_core.c new file mode 100644 index 0000000000..bc275d325c --- /dev/null +++ b/pkg/uwb-core/contrib/uwb_core.c @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2020 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup pkg_uwb_core + * @{ + * + * @file + * @brief uwb-core bootstrapping functions + * + * @author Francisco Molina + * @} + */ + +#include + +#include "thread.h" +#include "event.h" +#include "event/callback.h" +#include "uwb_core.h" + +#ifndef UWB_CORE_STACKSIZE +#define UWB_CORE_STACKSIZE (THREAD_STACKSIZE_LARGE) +#endif +#ifndef UWB_CORE_PRIO +#define UWB_CORE_PRIO (THREAD_PRIORITY_MAIN - 5) +#endif + +static char _stack_uwb_core[UWB_CORE_STACKSIZE]; + +static event_queue_t _queue; + +atomic_uint dpl_in_critical = 0; + +static void *_uwb_core_thread(void *arg) +{ + (void)arg; + event_queue_init(&_queue); + event_loop(&_queue); + /* never reached */ + return NULL; +} + +event_queue_t *uwb_core_get_eventq(void) +{ + return &_queue; +} + +void uwb_core_riot_init(void) +{ + thread_create(_stack_uwb_core, sizeof(_stack_uwb_core), + UWB_CORE_PRIO, + THREAD_CREATE_STACKTEST, + _uwb_core_thread, NULL, + "uwb_core"); +} diff --git a/pkg/uwb-core/contrib/uwb_core_init.c b/pkg/uwb-core/contrib/uwb_core_init.c new file mode 100644 index 0000000000..62a84093de --- /dev/null +++ b/pkg/uwb-core/contrib/uwb_core_init.c @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2020 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup pkg_uwb_core + * @{ + * + * @file + * @brief uwb-core bootstrapping core + * + * @author Francisco Molina + * @} + */ + +#include "thread.h" + +#include "dpl/dpl.h" +#include "uwb_core.h" + +#include "uwb_dw1000.h" +#include "uwb_dw1000_params.h" + +#include "twr_ss/twr_ss.h" +#include "twr_ss_ext/twr_ss_ext.h" +#include "twr_ss_ack/twr_ss_ack.h" +#include "twr_ds/twr_ds.h" +#include "twr_ds_ext/twr_ds_ext.h" + +static dw1000_dev_instance_t dev; +static uint8_t _dw1000_rx_buffer[MYNEWT_VAL(UWB_RX_BUFFER_SIZE)]; +static uint8_t _dw1000_tx_buffer[MYNEWT_VAL(DW1000_HAL_SPI_BUFFER_SIZE)]; + +void uwb_core_init(void) +{ + /* this will start the thread handling the event queue for uwb-core */ + uwb_core_riot_init(); + /* inits the dw1000 devices linked list */ + uwb_dw1000_init(); + /* set preallocated buffers to avoid malloc/calloc */ + uwb_dw1000_set_buffs(&dev, _dw1000_tx_buffer, _dw1000_rx_buffer); + /* setup dw1000 device */ + uwb_dw1000_setup(&dev, (void *) &dw1000_params[0]); + /* this will start a thread handling dw1000 device*/ + uwb_dw1000_config_and_start(&dev); + + /* init uwb pkg's */ + if (IS_USED(MODULE_UWB_CORE_RNG)) { + extern void uwb_rng_pkg_init(void); + uwb_rng_pkg_init(); + } + + /* uwb configuration module */ + if (IS_USED(MODULE_UWB_CORE_UWBCFG)) { + extern int uwbcfg_pkg_init(void); + uwbcfg_pkg_init(); + } + + /* ranging algorithms */ + if (IS_USED(MODULE_UWB_CORE_RNG)) { + twr_ss_pkg_init(); + } + if (IS_USED(MODULE_UWB_CORE_RNG)) { + twr_ss_ack_pkg_init(); + } + if (IS_USED(MODULE_UWB_CORE_RNG)) { + twr_ss_ext_pkg_init(); + } + if (IS_USED(MODULE_UWB_CORE_RNG)) { + twr_ds_pkg_init(); + } + if (IS_USED(MODULE_UWB_CORE_RNG)) { + twr_ds_ext_pkg_init(); + } +} diff --git a/pkg/uwb-core/doc.txt b/pkg/uwb-core/doc.txt new file mode 100644 index 0000000000..1b6b839e2c --- /dev/null +++ b/pkg/uwb-core/doc.txt @@ -0,0 +1,121 @@ +/** + * @defgroup pkg_uwb_core Device driver model for the Decawave Impulse Radio-Ultra Wideband (IR-UWB) transceiver(s) + * @ingroup pkg + * @brief Hardware and architecture agnostic platform for IoT + * Location Based Services (LBS) + * @see https://github.com/Decawave/uwb-core + */ + +# Decawave uwb-core RIOT Port + +The distribution https://github.com/decawave/uwb-core contains the +device driver model for the Decawave Impulse Radio-Ultra Wideband +(IR-UWB) transceiver(s). The driver includes hardware abstraction +layers (HAL), media access control (MAC) layer, Ranging Services (RNG). +The uwb-core driver and RIOT combine to create a hardware and +architecture agnostic platform for IoT Location Based Services (LBS). + +## Abstraction details + +uwb-core is meant as a hardware and architecture agnostic library. It +was developed with MyNewt as its default OS, but its abstractions are +well defined which makes it easy to use with another OS. + +A porting layer DPL (Decawave Porting Layer) has been implemented that +wraps around OS functionalities and modules: mutex, semaphores, threads, +etc.. In most cases the mapping is direct although some specific +functionalities might not be supported. + +Since the library was used on top of mynewt most configuration values +are prefixed with `MYNEWT_VAL_%`, all configurations can be found under +`pkg/uwb-core/include/syscfg`. + +In MyNewt there is always a default event thread, since we don't have +this in RIOT when using this pkg an event thread is started which will +run as this default event thread. + +To work this library needs to be built on top of an UWB device +implementing the `uwb` api (see [uwb](https://github.com/Decawave/uwb-core/tree/master/hw/drivers/uwb). +This port uses [uwb-dw1000](https://github.com/Decawave/uwb-dw1000) as +device driver for dw1000 modules. + +The library can be used by directly including the different module headers. + +## Current support + +uwb-core comes with many utility libraries, only ranging related libraries +are described here. For more info refer to [uwb-core](https://github.com/Decawave/uwb-core). + +- uwb-core_uwb: The uwb-core driver implements the MAC layers and + exports a MAC extension interface for additional services. + In the case of this port the api implementation is provided mainly by + the uwb-dw1000 pkg. + +- uwb-core_rng: ranging base class, provides the api to perform ranging. + It can use any of the twr_% ranging algorithms mentioned below, + for details on each algorithm refer to the pertinent literature. + +- uwb-core_twr_ss: single side two way ranging + +- uwb-core_twr_ss_ack: : single side two way ranging using hardware + generated ACK as the response. + +- uwb-core_twr_ss_ext: single side two way ranging with extended frames. + +- uwb-core_twr_ds: double side two-way ranging + +- uwb-core_twr_ds_ext: double side wo way ranging with extended frames. + +## Usage example + +The most simple examples would be a tdoa blinking tag, here the device +is considered awake. + +```c + // IEEE 802.15.4e standard blink + ieee_blink_frame_t tdoa_blink_frame = { + .fctrl = 0xC5, /* frame type (0xC5 for a blink) using 64-bit addressing */ + .seq_num = 0, /* sequence number, incremented for each new frame. */ + .long_address = 0, /* device ID */ + }; + // Set device address + tdoa_blink_frame.long_address = udev->my_long_address; + // Write tx data and start transmission + uwb_write_tx(udev, tdoa_blink_frame.array, 0, sizeof(ieee_blink_frame_t)); + uwb_start_tx(udev); + // Increase sequence number + tdoa_blink_frame.seq_num++; +``` + +The following can be wrapped into a timer callback to setup a blinking tag. + +For more examples check the [uwb-apps](https://github.com/Decawave/uwb-apps) +repository as well as [examples/twr_aloha](https://github.com/RIOT-OS/RIOT/tree/master/examples/twr-aloha) + +## Watchout! + +uwb-core uses anonymous structures, therefore any application using this +pkg must also set at application level: + + CFLAGS += -fms-extensions + +If building with llvm then also `CFLAGS += -Wno-microsoft-anon-tag` must +be added, although it is currently blacklisted because of missing stdatomic +definitions. + +## Todos + +The uwb-core pkg comes with a wide range of feature that are currently +untested and not supported in this port, these will be incrementally +included: + +- [ ] `uwb_cpp`: Clock Calibration Packet (CCP) Service +- [ ] `tdma`: uwb-core offers TDMA support +- [ ] `uwb_wcs`: Wireless Clock Synchronization (WCS) Service +- [ ] `rtdoa`: Reverse Time Difference of Arrival profiles +- [ ] `cir`: Circular impulse response +- [ ] `nrng`: N-ranges support +- [ ] other modules in `lib` + +uwb-core uses dynamic allocation for some of its internal modules. It +would be nice to make this optional when possible. diff --git a/pkg/uwb-core/dpl/Makefile b/pkg/uwb-core/dpl/Makefile new file mode 100644 index 0000000000..6f5935a4a6 --- /dev/null +++ b/pkg/uwb-core/dpl/Makefile @@ -0,0 +1,3 @@ +MODULE = uwb-core_dpl + +include $(RIOTBASE)/Makefile.base diff --git a/pkg/uwb-core/dpl/dpl_callout.c b/pkg/uwb-core/dpl/dpl_callout.c new file mode 100644 index 0000000000..232eaead62 --- /dev/null +++ b/pkg/uwb-core/dpl/dpl_callout.c @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2020 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup pkg_uwb_core + * @{ + * + * @file + * @brief uwb-core DPL (Decawave Porting Layer) callout + * + * @author Francisco Molina + * @} + */ + +#include + +#include "xtimer.h" +#include "dpl/dpl_callout.h" + +static void _dpl_callout_timer_cb(void* arg) +{ + struct dpl_callout *c = (struct dpl_callout *) arg; + assert(c); + + /* post the event if there is a queue, otherwise call the callback + here */ + if (c->c_q) { + dpl_eventq_put(c->c_q, &c->c_e); + } else { + c->c_e.e.callback(&c->c_e); + } +} + +void dpl_callout_init(struct dpl_callout *c, struct dpl_eventq *q, + dpl_event_fn *e_cb, void *e_arg) +{ + dpl_event_init(&c->c_e, e_cb, e_arg); + c->c_q = q; + c->timer.callback = _dpl_callout_timer_cb; + c->timer.arg = (void*) c; +} + +dpl_error_t dpl_callout_reset(struct dpl_callout *c, dpl_time_t ticks) +{ + xtimer_ticks32_t val = {.ticks32 = ticks}; + xtimer_set(&(c->timer), xtimer_usec_from_ticks(val)); + return DPL_OK; +} + +void dpl_callout_stop(struct dpl_callout *c) +{ + xtimer_remove(&(c->timer)); +} diff --git a/pkg/uwb-core/dpl/dpl_mutex.c b/pkg/uwb-core/dpl/dpl_mutex.c new file mode 100644 index 0000000000..40a4ec9542 --- /dev/null +++ b/pkg/uwb-core/dpl/dpl_mutex.c @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2020 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup pkg_uwb_core + * @{ + * + * @file + * @brief Decawave Porting Layer mutex RIOT wrapper + * + * @author Francisco Molina + * @} + */ + +#include "mutex.h" +#include "dpl/dpl_mutex.h" + +dpl_error_t dpl_mutex_init(struct dpl_mutex *mu) +{ + if (!mu) { + return DPL_INVALID_PARAM; + } + mutex_init(&mu->mutex); + return DPL_OK; +} + +dpl_error_t dpl_mutex_release(struct dpl_mutex *mu) +{ + if (!mu) { + return DPL_INVALID_PARAM; + } + + mutex_unlock(&mu->mutex); + return DPL_OK; +} + +dpl_error_t dpl_mutex_pend(struct dpl_mutex *mu, uint32_t timeout) +{ + int rc = DPL_OK; + + if (!mu) { + return DPL_INVALID_PARAM; + } + + if (!timeout) { + rc = mutex_trylock(&mu->mutex); + } + else { + /* TODO: no timeout equivalent */ + mutex_lock(&mu->mutex); + } + return rc; +} diff --git a/pkg/uwb-core/dpl/dpl_sem.c b/pkg/uwb-core/dpl/dpl_sem.c new file mode 100644 index 0000000000..a6e2c39437 --- /dev/null +++ b/pkg/uwb-core/dpl/dpl_sem.c @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2020 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup pkg_uwb_core + * @{ + * + * @file + * @brief Decawave Porting Layer semaphore RIOT wrapper + * + * @author Francisco Molina + * @} + */ + +#include + +#include "irq.h" +#include "dpl/dpl_sem.h" + +dpl_error_t dpl_sem_init(struct dpl_sem *sem, uint16_t tokens) +{ + if (!sem) { + return DPL_INVALID_PARAM; + } + + sema_create(&sem->sema, tokens); + return DPL_OK; +} + +dpl_error_t dpl_sem_release(struct dpl_sem *sem) +{ + int ret; + + if (!sem) { + return DPL_INVALID_PARAM; + } + + ret = sema_post(&sem->sema); + + return (ret) ? DPL_ERROR : DPL_OK; +} + +uint16_t dpl_sem_get_count(struct dpl_sem *sem) +{ + unsigned state = irq_disable(); + unsigned int value = sem->sema.value; + irq_restore(state); + return value; +} + +dpl_error_t dpl_sem_pend(struct dpl_sem *sem, dpl_time_t timeout) +{ + int ret = sema_wait_timed(&sem->sema, timeout); + return (ret) ? DPL_ERROR : DPL_OK; +} diff --git a/pkg/uwb-core/dpl/dpl_task.c b/pkg/uwb-core/dpl/dpl_task.c new file mode 100644 index 0000000000..eba30fc540 --- /dev/null +++ b/pkg/uwb-core/dpl/dpl_task.c @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2020 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup pkg_uwb_core + * @{ + * + * @file + * @brief Decawave Porting Layer tasks RIOT wrapper + * + * @author Francisco Molina + * @} + */ + +#include "dpl/dpl_error.h" +#include "dpl/dpl_tasks.h" +#include "thread.h" + +#ifndef LOG_LEVEL +#define LOG_LEVEL LOG_INFO +#endif +#include "log.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int dpl_task_init(struct dpl_task *t, const char *name, dpl_task_func_t func, + void *arg, uint8_t prio, dpl_time_t sanity_itvl, + dpl_stack_t *stack_bottom, uint16_t stack_size) +{ + (void) sanity_itvl; + + LOG_INFO("dpl: starting thread %s\n", name); + + kernel_pid_t pid = thread_create(stack_bottom, (int) stack_size, + prio, THREAD_CREATE_STACKTEST, + func, arg, name); + + t->pid = pid; + + return (pid) ? DPL_ERROR : DPL_OK;; +} + +int dpl_task_remove(struct dpl_task *t) +{ + thread_zombify(); + return thread_kill_zombie(t->pid); +} + +uint8_t dpl_task_count(void) +{ + return sched_num_threads; +} + +void dpl_task_yield(void) +{ + thread_yield(); +} + +#ifdef __cplusplus +} +#endif diff --git a/pkg/uwb-core/include/dpl/dpl.h b/pkg/uwb-core/include/dpl/dpl.h new file mode 100644 index 0000000000..79612a6140 --- /dev/null +++ b/pkg/uwb-core/include/dpl/dpl.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2020 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup pkg_uwb_core + * @{ + * + * @file + * @brief Abstraction layer for RIOT adaption + * + * @author Francisco Molina + * @} + */ + +#ifndef DPL_DPL_H +#define DPL_DPL_H + +#include "syscfg/syscfg.h" +#include "dpl/dpl_types.h" +#include "dpl/dpl_error.h" +#include "dpl/dpl_eventq.h" +#include "dpl/dpl_callout.h" +#include "dpl/dpl_cputime.h" +#include "dpl/dpl_mutex.h" +#include "dpl/dpl_os.h" +#include "dpl/dpl_sem.h" +#include "dpl/dpl_tasks.h" +#include "dpl/dpl_time.h" +#include "kernel_defines.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#endif /* DPL_DPL_H */ diff --git a/pkg/uwb-core/include/dpl/dpl_callout.h b/pkg/uwb-core/include/dpl/dpl_callout.h new file mode 100644 index 0000000000..5759522fc7 --- /dev/null +++ b/pkg/uwb-core/include/dpl/dpl_callout.h @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2020 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup pkg_uwb_core + * @{ + * + * @file + * @brief uwb-core DPL (Decawave Porting Layer) callout abstraction + * + * Callout sets a timer that on expiration will post an event to an + * event queue. This mimics the same as MyNewt callout api. + * + * @author Francisco Molina + * @} + */ + +#ifndef DPL_DPL_CALLOUT_H +#define DPL_DPL_CALLOUT_H + +#include "xtimer.h" + +#include "dpl/dpl_types.h" +#include "dpl/dpl_eventq.h" +#include "dpl/dpl_error.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief callout structure + */ +struct dpl_callout { + xtimer_t timer; /**< timer */ + struct dpl_event c_e; /**< callout event */ + struct dpl_eventq *c_q; /**< callout event queue */ +}; + +/** + * @brief Initialize a callout. + * + * Callouts are used to schedule events in the future onto an event + * queue. Callout timers are scheduled using the dpl_callout_reset() + * function. When the timer expires, an event is posted to the event + * queue specified in dpl_callout_init(). The event argument given here + * is posted in the ev_arg field of that event. + * + * @param[out] c callout to initialize + * @param[in] q event queue to queue event in + * @param[in] e_cb callback function + * @param[in] e_arg callback function argument + */ +void dpl_callout_init(struct dpl_callout *c, struct dpl_eventq *q, + dpl_event_fn *e_cb, void *e_arg); + +/** + * @brief Reset the callout to fire off in 'ticks' ticks. + * + * @param[in] c callout to reset + * @param[in] ticks number of ticks to wait before posting an event + * + * @return 0 on success, non-zero on failure + */ +dpl_error_t dpl_callout_reset(struct dpl_callout *c, dpl_time_t ticks); + +/** + * @brief Stops the callout from firing. + * + * @param[in] c the callout to stop + */ +void dpl_callout_stop(struct dpl_callout *c); + +#ifdef __cplusplus +} +#endif + +#endif /* DPL_DPL_CALLOUT_H */ diff --git a/pkg/uwb-core/include/dpl/dpl_cputime.h b/pkg/uwb-core/include/dpl/dpl_cputime.h new file mode 100644 index 0000000000..e5ee6b27f1 --- /dev/null +++ b/pkg/uwb-core/include/dpl/dpl_cputime.h @@ -0,0 +1,162 @@ +/* + * Copyright (C) 2020 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup pkg_uwb_core + * @{ + * + * @file + * @brief uwb-core DPL (Decawave Porting Layer) cputime abstraction + * + * @author Francisco Molina + * @} + */ + +#ifndef DPL_DPL_CPUTIME_H +#define DPL_DPL_CPUTIME_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include "xtimer.h" +#include "hal/hal_timer.h" + +/** + * Returns the low 32 bits of cputime. + * + * @return uint32_t The lower 32 bits of cputime + */ +static inline uint32_t dpl_cputime_get32(void) +{ + return xtimer_now().ticks32; +} + +/** + * Converts the given number of microseconds into cputime ticks. + * + * @param usecs The number of microseconds to convert to ticks + * + * @return uint32_t The number of ticks corresponding to 'usecs' + */ +static inline uint32_t dpl_cputime_usecs_to_ticks(uint32_t usecs) +{ + return xtimer_ticks_from_usec(usecs).ticks32; +} + +/** + * Convert the given number of ticks into microseconds. + * + * @param ticks The number of ticks to convert to microseconds. + * + * @return uint32_t The number of microseconds corresponding to 'ticks' + */ +static inline uint32_t dpl_cputime_ticks_to_usecs(uint32_t ticks) +{ + xtimer_ticks32_t val = {.ticks32 = ticks}; + return xtimer_usec_from_ticks(val); +} + +/** + * Wait until the number of ticks has elapsed. This is a blocking delay. + * + * @param ticks The number of ticks to wait. + */ +static inline void dpl_cputime_delay_ticks(uint32_t ticks) +{ + xtimer_ticks32_t val = {.ticks32 = ticks}; + xtimer_tsleep32((xtimer_ticks32_t) val); +} + +/** + * Wait until 'usecs' microseconds has elapsed. This is a blocking delay. + * + * @param usecs The number of usecs to wait. + */ +static inline void dpl_cputime_delay_usecs(uint32_t usecs) +{ + xtimer_usleep(usecs); +} + +/** + * Initialize a CPU timer, using the given HAL timer. + * + * @param timer The timer to initialize. Cannot be NULL. + * @param fp The timer callback function. Cannot be NULL. + * @param arg Pointer to data object to pass to timer. + */ +static inline void dpl_cputime_timer_init(struct hal_timer *timer, hal_timer_cb fp, + void *arg) +{ + timer->timer.callback = fp; + timer->timer.arg = arg; +} + +/** + * Start a cputimer that will expire at 'cputime'. If cputime has already + * passed, the timer callback will still be called (at interrupt context). + * + * NOTE: This must be called when the timer is stopped. + * + * @param timer Pointer to timer to start. Cannot be NULL. + * @param cputime The cputime at which the timer should expire. + * + * @return int 0 on success; EINVAL if timer already started or timer struct + * invalid + * + */ +static inline int dpl_cputime_timer_start(struct hal_timer *timer, uint32_t cputime) +{ + xtimer_set(&timer->timer, xtimer_now_usec() + cputime); + return 0; +} + +/** + * Sets a cpu timer that will expire 'usecs' microseconds from the current + * cputime. + * + * NOTE: This must be called when the timer is stopped. + * + * @param timer Pointer to timer. Cannot be NULL. + * @param usecs The number of usecs from now at which the timer will expire. + * + * @return int 0 on success; EINVAL if timer already started or timer struct + * invalid + */ +static inline int dpl_cputime_timer_relative(struct hal_timer *timer, uint32_t usecs) +{ + uint32_t now = xtimer_now_usec(); + if (now > usecs) { + xtimer_set(&timer->timer, now); + } else { + xtimer_set(&timer->timer, 0); + } + return 0; +} + +/** + * @brief Stops a cputimer from running. + * + * The timer is removed from the timer queue and interrupts are disabled + * if no timers are left on the queue. Can be called even if timer is + * not running. + * + * @param timer Pointer to cputimer to stop. Cannot be NULL. + */ +static inline void dpl_cputime_timer_stop(struct hal_timer *timer) +{ + xtimer_remove(&timer->timer); +} + +#ifdef __cplusplus +} +#endif + +#endif /* DPL_DPL_CPUTIME_H */ diff --git a/pkg/uwb-core/include/dpl/dpl_error.h b/pkg/uwb-core/include/dpl/dpl_error.h new file mode 100644 index 0000000000..212a32efed --- /dev/null +++ b/pkg/uwb-core/include/dpl/dpl_error.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2020 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup pkg_uwb_core + * @{ + * + * @file + * @brief uwb-core DPL (Decawave Porting Layer) error types + * + * @author Francisco Molina + * @} + */ + +#ifndef DPL_DPL_ERROR_H +#define DPL_DPL_ERROR_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief DPL error types + */ +enum dpl_error { + DPL_OK = 0, + DPL_ENOMEM = 1, + DPL_EINVAL = 2, + DPL_INVALID_PARAM = 3, + DPL_MEM_NOT_ALIGNED = 4, + DPL_BAD_MUTEX = 5, + DPL_TIMEOUT = 6, + DPL_ERR_IN_ISR = 7, + DPL_ERR_PRIV = 8, + DPL_OS_NOT_STARTED = 9, + DPL_ENOENT = 10, + DPL_EBUSY = 11, + DPL_ERROR = 12, +}; + +/** + * @brief dep error type + */ +typedef enum dpl_error dpl_error_t; + +#ifdef __cplusplus +} +#endif + +#endif /* DPL_DPL_ERROR_H */ diff --git a/pkg/uwb-core/include/dpl/dpl_eventq.h b/pkg/uwb-core/include/dpl/dpl_eventq.h new file mode 100644 index 0000000000..5244879339 --- /dev/null +++ b/pkg/uwb-core/include/dpl/dpl_eventq.h @@ -0,0 +1,241 @@ +/* + * Copyright (C) 2020 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup pkg_uwb_core + * @{ + * + * @file + * @brief uwb-core DPL (Decawave Porting Layer) event queue wrappers + * + * @author Francisco Molina + * @} + */ + +#ifndef DPL_DPL_EVENTQ_H +#define DPL_DPL_EVENTQ_H + +#include + +#include "uwb_core.h" +#include "event/callback.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief dpl event wrapper + */ +struct dpl_event +{ + event_callback_t e; /**< the event callback */ + void *arg; /**< the event argument */ +}; + +/** + * @brief dpl event queue wrapper + */ +struct dpl_eventq +{ + event_queue_t q; /**< the event queue */ +}; + +/** + * @brief dpl event callback function + */ +typedef void dpl_event_fn(struct dpl_event *ev); + +/** + * @brief Init a event + * + * @param[in] ev pointer to event to set + * @param[in] fn event callback function + * @param[in] arg event argument + */ +static inline void dpl_event_init(struct dpl_event *ev, dpl_event_fn * fn, + void *arg) +{ + /* + * Need to clear list_node manually since init function below does not do + * this. + */ + ev->e.super.list_node.next = NULL; + event_callback_init(&ev->e, (void(*)(void *))fn, ev); + ev->arg = arg; +} + +/** + * @brief Check if event is in queue + * + * @param[in] ev event to check + * + * @return true if event is queues, false otherwise + */ +static inline bool dpl_event_is_queued(struct dpl_event *ev) +{ + return (ev->e.super.list_node.next != NULL); +} + +/** + * @brief Runs an event + * + * @param[in] ev event to run + */ +static inline void *dpl_event_get_arg(struct dpl_event *ev) +{ + return ev->arg; +} + +/** + * @brief Set the vent arg + * + * @param[in] ev event + * @param[in] arg arg to set event + */ +static inline void dpl_event_set_arg(struct dpl_event *ev, void *arg) +{ + ev->arg = arg; +} + +/** + * @brief Runs an event + * + * @param[in] ev event to run + */ +static inline void dpl_event_run(struct dpl_event *ev) +{ + ev->e.super.handler(&ev->e.super); +} + +/** + * @brief Initialize the event queue + * + * @param[in] evq The event queue to initialize + */ +static inline void dpl_eventq_init(struct dpl_eventq *evq) +{ + event_queue_init_detached(&evq->q); +} + +/** + * @brief Check whether the event queue is initialized. + * + * @param[in] evq the event queue to check + */ +static inline int dpl_eventq_inited(struct dpl_eventq *evq) +{ + return evq->q.waiter != NULL; +} + +/** + * @brief Deinitialize an event queue + * + * @note Not supported in RIOT + * + * @param[in] evq the event queue to deinit + */ +static inline void dpl_eventq_deinit(struct dpl_eventq *evq) +{ + (void) evq; + /* Can't deinit an eventq in RIOT */ +} + +/** + * @brief Get next event from event queue, blocking. + * + * @param[in] evq the event queue to pull an event from + * + * @return the event from the queue + */ +static inline struct dpl_event * dpl_eventq_get(struct dpl_eventq *evq) +{ + if (evq->q.waiter == NULL) { + event_queue_claim(&evq->q); + } + + return (struct dpl_event *) event_wait(&evq->q); +} + +/** + * @brief Get next event from event queue, non-blocking + * + * @return event from the queue, or NULL if none available. + */ +static inline struct dpl_event * dpl_eventq_get_no_wait(struct dpl_eventq *evq) +{ + if (evq->q.waiter == NULL) { + event_queue_claim(&evq->q); + } + + return (struct dpl_event *) event_get(&evq->q); +} + +/** + * @brief Put an event on the event queue. + * + * @param[in] evq event queue + * @param[in] ev event to put in queue + */ +static inline void dpl_eventq_put(struct dpl_eventq *evq, struct dpl_event *ev) +{ + event_post(&evq->q, &ev->e.super); +} + +/** + * @brief Remove an event from the queue. + * + * @param[in] evq event queue to remove the event from + * @param[in] ev event to remove from the queue + */ +static inline void dpl_eventq_remove(struct dpl_eventq *evq, struct dpl_event *ev) +{ + event_cancel(&evq->q, &ev->e.super); +} + +/** + * @brief Gets and runs an event from the queue callback. + * + * @param[in] evq The event queue to pull the item off. + */ +static inline void dpl_eventq_run(struct dpl_eventq *evq) +{ + struct dpl_event *ev = dpl_eventq_get(evq); + dpl_event_run(ev); +} + +/** + * @brief Check if queue is empty + * + * @param[in] evq the event queue to check + * + * @return true if empty, false otherwise + */ +static inline bool dpl_eventq_is_empty(struct dpl_eventq *evq) +{ + return clist_count(&(evq->q.event_list)) == 0; +} + +/** + * @brief Retrieves the default event queue. + * + * As there is no default event queue in RIOT, uwb-core will start and + * handle a default event queue. + * + * @return the default event queue. + */ +static inline struct dpl_eventq * dpl_eventq_dflt_get(void) +{ + return (struct dpl_eventq*) uwb_core_get_eventq(); +} + +#ifdef __cplusplus +} +#endif + +#endif /* DPL_DPL_EVENTQ_H */ diff --git a/pkg/uwb-core/include/dpl/dpl_mutex.h b/pkg/uwb-core/include/dpl/dpl_mutex.h new file mode 100644 index 0000000000..667a5201d7 --- /dev/null +++ b/pkg/uwb-core/include/dpl/dpl_mutex.h @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2020 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup pkg_uwb_core + * @{ + * + * @file + * @brief uwb-core DPL (Decawave Porting Layer) mutex wrappers + * + * @author Francisco Molina + * @} + */ + +#ifndef DPL_DPL_MUTEX_H +#define DPL_DPL_MUTEX_H + +#include "dpl_types.h" +#include "dpl_error.h" + +#include "mutex.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief dpl mutex wrapper + */ +struct dpl_mutex { + mutex_t mutex; /**< the mutex */ +}; + +/** + * @brief Initializes a mutex object. + * + * @param[out] mu pre-allocated mutex structure, must not be NULL. + */ +dpl_error_t dpl_mutex_init(struct dpl_mutex *mu); + +/** + * @brief Pend (wait) for a mutex. + * + * @param[in] mu Pointer to mutex. + * @param[in] timeout Timeout, in os ticks. + * A timeout of 0 means do not wait if not available. + * A timeout of OS_TIMEOUT_NEVER means wait forever. + * + * @return dpl_error_t + * DPL_INVALID_PARM mutex passed in was NULL + * DPL_OK no error + */ +dpl_error_t dpl_mutex_pend(struct dpl_mutex *mu, dpl_time_t timeout); + +/** + * + * @brief Release a mutex. + * + * @return dpl_error_t + * DPL_INVALID_PARM mutex was NULL + * DPL_OK no error + */ +dpl_error_t dpl_mutex_release(struct dpl_mutex *mu); + +#ifdef __cplusplus +} +#endif + +#endif /* DPL_DPL_MUTEX_H */ diff --git a/pkg/uwb-core/include/dpl/dpl_os.h b/pkg/uwb-core/include/dpl/dpl_os.h new file mode 100644 index 0000000000..62d703a18a --- /dev/null +++ b/pkg/uwb-core/include/dpl/dpl_os.h @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2020 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup pkg_uwb_core + * @{ + * + * @file + * @brief uwb-core DPL (Decawave Porting Layer) error types + * + * @author Francisco Molina + * @} + */ + +#ifndef DPL_DPL_OS_H +#define DPL_DPL_OS_H + +#include +#include +#include + +#include "irq.h" +#include "dpl/dpl_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @name Entering and exiting critical section defines + * @{ + */ +#define DPL_ENTER_CRITICAL(_sr) (_sr = dpl_hw_enter_critical()) +#define DPL_EXIT_CRITICAL(_sr) (dpl_hw_exit_critical(_sr)) +#define DPL_ASSERT_CRITICAL() assert(dpl_hw_is_in_critical()) +/** @} */ + +/** + * @brief variable to check if ISR are disabled + */ +extern atomic_uint dpl_in_critical; + +/** + * @brief CPU status register + */ +typedef uint32_t dpl_sr_t; + +/** + * @brief Disable ISRs + * + * @return current isr context + */ +static inline uint32_t dpl_hw_enter_critical(void) +{ + uint32_t ctx = irq_disable(); + unsigned int count = atomic_load(&dpl_in_critical); + atomic_store(&dpl_in_critical, count + 1); + return ctx; +} + +/** + * @brief Restores ISR context + * + * @param[in] ctx ISR context to restore. + */ +static inline void dpl_hw_exit_critical(uint32_t ctx) +{ + unsigned int count = atomic_load(&dpl_in_critical); + atomic_store(&dpl_in_critical, count - 1); + irq_restore((unsigned)ctx); +} + +/** + * @brief Check if is in critical section + * + * @return true, if in critical section, false otherwise + */ +static inline bool dpl_hw_is_in_critical(void) +{ + /* + * XXX Currently RIOT does not support an API for finding out if interrupts + * are currently disabled, hence in a critical section in this context. + * So for now, we use this global variable to keep this state for us. + */ + return (atomic_load(&dpl_in_critical) > 0); +} + +#ifdef __cplusplus +} +#endif + +#endif /* DPL_DPL_OS_H */ diff --git a/pkg/uwb-core/include/dpl/dpl_sem.h b/pkg/uwb-core/include/dpl/dpl_sem.h new file mode 100644 index 0000000000..4184199556 --- /dev/null +++ b/pkg/uwb-core/include/dpl/dpl_sem.h @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2020 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup pkg_uwb_core + * @{ + * + * @file + * @brief uwb-core DPL (Decawave Porting Layer) semapahore wrappers + * + * @author Francisco Molina + * @} + */ + +#ifndef DPL_DPL_SEM_H +#define DPL_DPL_SEM_H + +#include + +#include "dpl_types.h" +#include "dpl_error.h" + +#include "sema.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief dpl semaphore wrapper + */ +struct dpl_sem { + sema_t sema; /**< the semaphore */ +}; + +/** + * @brief Initialize a semaphore + * + * @param[in] sem pointer to semaphore + * @param[in] tokens # of tokens the semaphore should contain initially. + * + * @return dpl_error_t + * DPL_INVALID_PARM Semaphore passed in was NULL. + * DPL_OK no error. + */ +dpl_error_t dpl_sem_init(struct dpl_sem *sem, uint16_t tokens); + +/** + * @brief Pend (wait) for a semaphore. + * + * @param[in] sem pointer to semaphore. + * @param[in] timeout timeout, in os ticks. + * A timeout of 0 means do not wait if not available. + * A timeout of DPL_TIMEOUT_NEVER means wait forever. + * + * + * @return dpl_error_t + * DPL_INVALID_PARM semaphore passed in was NULL. + * DPL_TIMEOUT semaphore was owned by another task and timeout=0 + * DPL_OK no error + */ +dpl_error_t dpl_sem_pend(struct dpl_sem *sem, dpl_time_t timeout); + +/** + * @brief Release a semaphore. + * + * @param[in] sem pointer to the semaphore to be released + * + * @return dpl_error_t + * DPL_INVALID_PARM semaphore passed in was NULL. + * DPL_OK no error + */ +dpl_error_t dpl_sem_release(struct dpl_sem *sem); + +/** + * @brief Get current semaphore's count + */ +uint16_t dpl_sem_get_count(struct dpl_sem *sem); + +#ifdef __cplusplus +} +#endif + +#endif /* DPL_DPL_SEM_H */ diff --git a/pkg/uwb-core/include/dpl/dpl_tasks.h b/pkg/uwb-core/include/dpl/dpl_tasks.h new file mode 100644 index 0000000000..29591396b2 --- /dev/null +++ b/pkg/uwb-core/include/dpl/dpl_tasks.h @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2020 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup pkg_uwb_core + * @{ + * + * @file + * @brief uwb-core DPL (Decawave Porting Layer) thread/task wrappers + * + * @author Francisco Molina + * @} + */ + +#ifndef DPL_DPL_TASKS_H +#define DPL_DPL_TASKS_H + +#include "dpl_types.h" + +#include "kernel_types.h" +#include "thread.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief dpl task wrapper + */ +struct dpl_task { + kernel_pid_t pid; /**< the process id */ +}; + +/** + * @brief dpl task function + */ +typedef thread_task_func_t dpl_task_func_t; + +/** + * @brief Initialize a task. + * + * This function initializes the task structure pointed to by t, + * clearing and setting it's stack pointer, provides sane defaults + * and sets the task as ready to run, and inserts it into the operating + * system scheduler. + * + * @param[in] t the task to initialize + * @param[in] name task name + * @param[in] func task function to call + * @param[in] arg argument to pass in task init function + * @param[in] prio task priority + * @param[in] sanity_itvl UNUSED + * @param[in] stack_bottom pointer to bottom of the stack + * @param[in] stack_size task stack size + * + * @return 0 on success, non-zero on failure. + */ +int dpl_task_init(struct dpl_task *t, const char *name, dpl_task_func_t func, + void *arg, uint8_t prio, dpl_time_t sanity_itvl, + dpl_stack_t *stack_bottom, uint16_t stack_size); + +/** + * @brief removes specified task + * + * NOTE: This interface is currently experimental and not ready for common use + */ +int dpl_task_remove(struct dpl_task *t); + +/** + * @brief Return the number of tasks initialized. + * + * @return number of tasks initialized + */ +uint8_t dpl_task_count(void); + +/** + * @brief Lets current thread yield. + */ +void dpl_task_yield(void); + +#ifdef __cplusplus +} +#endif + +#endif /* DPL_DPL_TASKS_H */ diff --git a/pkg/uwb-core/include/dpl/dpl_time.h b/pkg/uwb-core/include/dpl/dpl_time.h new file mode 100644 index 0000000000..192ccc5dd9 --- /dev/null +++ b/pkg/uwb-core/include/dpl/dpl_time.h @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2020 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup pkg_uwb_core + * @{ + * + * @file + * @brief uwb-core DPL (Decawave Porting Layer) time abstraction + * + * @author Francisco Molina + * @} + */ + +#ifndef DPL_DPL_TIME_H +#define DPL_DPL_TIME_H + +#include "xtimer.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief DPL ticks per seconds + */ +#define DPL_TICKS_PER_SEC (XTIMER_HZ) + +/** + * @brief Returns the low 32 bits of cputime. + * + * @return uint32_t The lower 32 bits of cputime + */ +static inline dpl_time_t dpl_time_get(void) +{ + return xtimer_now().ticks32; +} + +/** + * @brief Converts the given number of milliseconds into cputime ticks. + * + * @param[in] ms The number of milliseconds to convert to ticks + * @param[out] out_ticks The number of ticks corresponding to 'ms' + * + * @return dpl_error_t DPL_OK - no error + */ +static inline dpl_error_t dpl_time_ms_to_ticks(uint32_t ms, dpl_time_t *out_ticks) +{ + *out_ticks = xtimer_ticks_from_usec(ms * US_PER_MS).ticks32; + return DPL_OK; +} + +/** + * @brief Convert the given number of ticks into milliseconds. + * + * @param[in] ticks The number of ticks to convert to milliseconds. + * @param[out] out_ms The converted milliseconds from 'ticks' + * + * @return dpl_error_t DPL_OK - no error + */ +static inline dpl_error_t dpl_time_ticks_to_ms(dpl_time_t ticks, uint32_t *out_ms) +{ + xtimer_ticks32_t val = {.ticks32 = ticks}; + *out_ms = xtimer_usec_from_ticks(val) * US_PER_MS; + return DPL_OK; +} + +/** + * @brief Converts the given number of milliseconds into cputime ticks. + * + * @param[in] ms The number of milliseconds to convert to ticks + * + * @return uint32_t The number of ticks corresponding to 'ms' + */ +static inline dpl_time_t dpl_time_ms_to_ticks32(uint32_t ms) +{ + return xtimer_ticks_from_usec(ms * US_PER_MS).ticks32; +} + +/** + * @brief Convert the given number of ticks into milliseconds. + * + * @param[in] ticks The number of ticks to convert to milliseconds. + * + * @return uint32_t The number of milliseconds corresponding to 'ticks' + */ +static inline dpl_time_t dpl_time_ticks_to_ms32(dpl_time_t ticks) +{ + xtimer_ticks32_t val = {.ticks32 = ticks}; + return xtimer_usec_from_ticks(val) * US_PER_MS; +} + +/** + * @brief Wait until the number of ticks has elapsed, BLOICKING. + * + * @param[in] ticks The number of ticks to wait. + */ +static inline void dpl_time_delay(dpl_time_t ticks) +{ + xtimer_ticks32_t val = {.ticks32 = ticks}; + xtimer_tsleep32((xtimer_ticks32_t) val); +} + +#ifdef __cplusplus +} +#endif + +#endif /* DPL_DPL_TIME_H */ diff --git a/pkg/uwb-core/include/dpl/dpl_types.h b/pkg/uwb-core/include/dpl/dpl_types.h new file mode 100644 index 0000000000..a8d9eeb767 --- /dev/null +++ b/pkg/uwb-core/include/dpl/dpl_types.h @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2020 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup pkg_uwb_core + * @{ + * + * @file + * @brief uwb-core DPL (Decawave Porting Layer) types + * + * @author Francisco Molina + * @} + */ + +#ifndef DPL_DPL_TYPES_H +#define DPL_DPL_TYPES_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief PI approximated value macro definition + */ +#ifndef M_PI +#define M_PI 3.1415926535 +#endif + +/** + * @name Macro to wait forever on events and mutexes + * @{ + */ +#define DPL_TIMEOUT_NEVER (UINT32_MAX) +#define DPL_WAIT_FOREVER (DPL_TIMEOUT_NEVER) +/** @} */ + +/** + * @name Decawave porting layer (DPL) stack alignment requirement + * @{ + */ +#define DPL_STACK_ALIGNMENT (4) +/** @} */ + +/** + * @brief dpl time type + */ +typedef uint32_t dpl_time_t; + +/** + * @brief dpl stack buffer type + */ +typedef char dpl_stack_t; + +/** + * @brief dpl float 32 type + */ +typedef float dpl_float32_t; +/** + * @brief dpl float 64 type + */ +typedef double dpl_float64_t; + +/** + * @name Decawave porting layer (DPL) float type macros + * @{ + */ +#define DPL_FLOAT32_INIT(__X) ((float)__X) +#define DPL_FLOAT64_INIT(__X) ((double)__X) +#define DPL_FLOAT64TO32(__X) (float)(__X) +#define DPL_FLOAT32_I32_TO_F32(__X) (float)(__X) +#define DPL_FLOAT64_I32_TO_F64(__X) ((double)(__X)) +#define DPL_FLOAT64_I64_TO_F64(__X) ((double)(__X)) +#define DPL_FLOAT64_U64_TO_F64(__X) ((double)(__X)) +#define DPL_FLOAT64_F64_TO_U64(__X) ((uint64_t)(__X)) +#define DPL_FLOAT32_INT(__X) ((int32_t)__X) +#define DPL_FLOAT64_INT(__X) ((int64_t)__X) +#define DPL_FLOAT64_FROM_F32(__X) (double)(__X) +#define DPL_FLOAT32_FROM_F64(__X) (float)(__X) +#define DPL_FLOAT32_CEIL(__X) (ceilf(__X)) +#define DPL_FLOAT64_CEIL(__X) (ceil(__X)) +#define DPL_FLOAT32_FABS(__X) fabsf(__X) +#define DPL_FLOAT32_FMOD(__X, __Y) fmodf(__X, __Y) +#define DPL_FLOAT64_FMOD(__X, __Y) fmod(__X, __Y) +#define DPL_FLOAT32_NAN() nanf("") +#define DPL_FLOAT64_NAN() nan("") +#define DPL_FLOAT32_ISNAN(__X) isnan(__X) +#define DPL_FLOAT64_ISNAN(__X) DPL_FLOAT32_ISNAN(__X) +#define DPL_FLOAT32_LOG10(__X) (log10f(__X)) +#define DPL_FLOAT64_LOG10(__X) (log10(__X)) +#define DPL_FLOAT64_ASIN(__X) asin(__X) +#define DPL_FLOAT64_ATAN(__X) atan(__X) +#define DPL_FLOAT32_SUB(__X, __Y) ((__X)-(__Y)) +#define DPL_FLOAT64_SUB(__X, __Y) ((__X)-(__Y)) +#define DPL_FLOAT32_ADD(__X, __Y) ((__X)+(__Y)) +#define DPL_FLOAT64_ADD(__X, __Y) ((__X)+(__Y)) +#define DPL_FLOAT32_MUL(__X, __Y) ((__X)*(__Y)) +#define DPL_FLOAT64_MUL(__X, __Y) ((__X)*(__Y)) +#define DPL_FLOAT32_DIV(__X, __Y) ((__X)/(__Y)) +#define DPL_FLOAT64_DIV(__X, __Y) ((__X)/(__Y)) +#define DPL_FLOAT32_PRINTF_PRIM "%s%d.%03d" +#define DPL_FLOAT32_PRINTF_VALS(__X) (__X)<0?"-":"", (int)(fabsf(__X)), (int)(fabsf((__X)-(int)(__X))*1000) +#define DPL_FLOAT64_PRINTF_PRIM "%s%d.%06d" +#define DPL_FLOAT64_PRINTF_VALS(__X) (__X)<0?"-":"", (int)(fabs(__X)), (int)(fabs((__X)-(int)(__X))*1000000) +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* DPL_DPL_TYPES_H */ diff --git a/pkg/uwb-core/include/log/dpl_log.h b/pkg/uwb-core/include/log/dpl_log.h new file mode 100644 index 0000000000..34ab483832 --- /dev/null +++ b/pkg/uwb-core/include/log/dpl_log.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2020 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup pkg_uwb_core + * @{ + * + * @file + * @brief System logging header for uwb-core + * + * @author Francisco Molina + * @} + */ + +#ifndef LOG_DPL_LOG_H +#define LOG_DPL_LOG_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "log.h" + +/** + * @name Logging convenience defines wrappers + * @{ + */ +#define LOG_WARN(...) LOG(LOG_WARNING, __VA_ARGS__) +#define LOG_CRITICAL(...) LOG(LOG_ERROR, __VA_ARGS__) +#define log_register(__X, __Y, __Z, __A, __B) {} +/** @} */ + +/** + * @brief Empty log structure + */ +struct log { +}; + +#ifdef __cplusplus +} +#endif + +#endif /* LOG_DPL_LOG_H */ diff --git a/pkg/uwb-core/include/mcu/mcu.h b/pkg/uwb-core/include/mcu/mcu.h new file mode 100644 index 0000000000..e58aa6c3ed --- /dev/null +++ b/pkg/uwb-core/include/mcu/mcu.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2020 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup pkg_uwb_core + * @{ + * + * @file + * @brief Abstraction layer for RIOT adaption + * + * @author Francisco Molina + * @} + */ + +#ifndef MCU_MCU_H +#define MCU_MCU_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* empty header */ + +#ifdef __cplusplus +} +#endif + +#endif /* MCU_MCU_H */ diff --git a/pkg/uwb-core/include/os/os.h b/pkg/uwb-core/include/os/os.h new file mode 100644 index 0000000000..c9cff4a40e --- /dev/null +++ b/pkg/uwb-core/include/os/os.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2020 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup pkg_uwb_core + * @{ + * + * @file + * @brief Abstraction layer for RIOT adaption + * + * @author Francisco Molina + * @} + */ +#ifndef OS_OS_H +#define OS_OS_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* OS_OS_H */ diff --git a/pkg/uwb-core/include/os/os_dev.h b/pkg/uwb-core/include/os/os_dev.h new file mode 100644 index 0000000000..f1068749fb --- /dev/null +++ b/pkg/uwb-core/include/os/os_dev.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2020 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup pkg_uwb_core + * @{ + * + * @file + * @brief Abstraction layer for RIOT adaption + * + * @author Francisco Molina + * @} + */ +#ifndef OS_OS_DEV_H +#define OS_OS_DEV_H + +#include "dpl/dpl.h" +#include "dpl/queue.h" + +#include "net/ieee802154.h" +#include "net/netdev.h" +#include "net/netdev/ieee802154.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Device structure. + */ +struct os_dev { + netdev_ieee802154_t netdev; /**< Netdev parent struct */ +}; + +/** + * @brief Unused define, void cast + */ +#define OS_DEV_SETHANDLERS(__dev, __open, __close) \ + (void) __dev; \ + (void) __open; \ + (void) __close; + +#ifdef __cplusplus +} +#endif + +#endif /* OS_OS_DEV_H */ diff --git a/pkg/uwb-core/include/stats/stats.h b/pkg/uwb-core/include/stats/stats.h new file mode 100644 index 0000000000..1be9452c1c --- /dev/null +++ b/pkg/uwb-core/include/stats/stats.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2020 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup pkg_uwb_core + * @{ + * + * @file + * @brief Abstraction layer for RIOT adaption + * + * @author Francisco Molina + * @} + */ + +#ifndef STATS_STATS_H +#define STATS_STATS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* empty header */ + +#ifdef __cplusplus +} +#endif + +#endif /* STATS_STATS_H */ diff --git a/pkg/uwb-core/include/syscfg/syscfg.h b/pkg/uwb-core/include/syscfg/syscfg.h new file mode 100644 index 0000000000..7d412928b7 --- /dev/null +++ b/pkg/uwb-core/include/syscfg/syscfg.h @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2020 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup pkg_uwb_core + * @{ + * + * @file + * @brief uwb-core system configurations + * + * @author Francisco Molina + * @} + */ + +#ifndef SYSCFG_SYSCFG_H +#define SYSCFG_SYSCFG_H + +#include "kernel_defines.h" + +/** + * @name MyNewt header inclusion macro definitions + * @{ + * + * This macro exists to ensure code includes this header when needed. If code + * checks the existence of a setting directly via ifdef without including this + * header, the setting macro will silently evaluate to 0. In contrast, an + * attempt to use these macros without including this header will result in a + * compiler error. + */ +#define MYNEWT_VAL(_name) MYNEWT_VAL_ ## _name +#define MYNEWT_VAL_CHOICE(_name, _val) MYNEWT_VAL_ ## _name ## __ ## _val +/** @} */ + + +/*** @decawave-uwb-core/hw/drivers/uwb */ +#include "syscfg_uwb.h" + +/*** @decawave-uwb-core/lib/twr_ds */ +#include "syscfg_twr_ds.h" + +/*** @decawave-uwb-core/lib/twr_ds_ext */ +#include "syscfg_twr_ds_ext.h" + +/*** @decawave-uwb-core/lib/twr_ss */ +#include "syscfg_twr_ss.h" + +/*** @decawave-uwb-core/lib/twr_ss_ack */ +#include "syscfg_twr_ss_ack.h" + +/*** @decawave-uwb-core/lib/twr_ss_ext */ +#include "syscfg_twr_ss_ext.h" + +/*** @decawave-uwb-core/lib/uwb_rng */ +#include "syscfg_uwb_rng.h" + +/*** @decawave-uwb-core/sys/uwbcfg */ +#include "syscfg_uwbcfg.h" + +/*** @decawave-uwb-dw1000/hw/drivers/uwb/uwb_dw1000 */ +#include "syscfg_uwb_dw1000.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* SYSCFG_SYSCFG_H */ diff --git a/pkg/uwb-core/include/syscfg/syscfg_twr_ds.h b/pkg/uwb-core/include/syscfg/syscfg_twr_ds.h new file mode 100644 index 0000000000..54345c88ac --- /dev/null +++ b/pkg/uwb-core/include/syscfg/syscfg_twr_ds.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2020 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup pkg_uwb_core + * @{ + * + * @file + * @brief uwb-dw100 double side two-way ranging module configurations + * taken from decawave-uwb-core/lib/twr_ds/syscfg.yml + * + * @author Francisco Molina + * @} + */ + +#ifndef SYSCFG_SYSCFG_TWR_DS_H +#define SYSCFG_SYSCFG_TWR_DS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Enable toplevel ranging services + */ +#ifndef MYNEWT_VAL_TWR_DS_ENABLED +#define MYNEWT_VAL_TWR_DS_ENABLED (IS_ACTIVE(MODULE_UWB_CORE_TWR_DS)) +#endif + +/** + * @brief TOA timeout delay for DS TWR (usec) + */ +#ifndef MYNEWT_VAL_TWR_DS_RX_TIMEOUT +#define MYNEWT_VAL_TWR_DS_RX_TIMEOUT (((uint16_t)0x30)) +#endif + +/** + * @brief tx holdoff delay for DS TWR (usec) + */ +#ifndef MYNEWT_VAL_TWR_DS_TX_HOLDOFF +#define MYNEWT_VAL_TWR_DS_TX_HOLDOFF (((uint32_t)0x0300)) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* SYSCFG_SYSCFG_TWR_DS_H */ diff --git a/pkg/uwb-core/include/syscfg/syscfg_twr_ds_ext.h b/pkg/uwb-core/include/syscfg/syscfg_twr_ds_ext.h new file mode 100644 index 0000000000..9163686515 --- /dev/null +++ b/pkg/uwb-core/include/syscfg/syscfg_twr_ds_ext.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2020 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup pkg_uwb_core + * @{ + * + * @file + * @brief uwb-core double side extended two-way ranging module configurations + * taken from decawave-uwb-core/lib/twr_ds_ext/syscfg.yml + * + * @author Francisco Molina + * @} + */ + +#ifndef SYSCFG_SYSCFG_TWR_DS_EXT_H +#define SYSCFG_SYSCFG_TWR_DS_EXT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Enable double sided extended two way ranging + */ +#ifndef MYNEWT_VAL_TWR_DS_EXT_ENABLED +#define MYNEWT_VAL_TWR_DS_EXT_ENABLED IS_ACTIVE(MODULE_UWB_CORE_TWR_DS_EXT) +#endif + +/** + * @brief Enable double sided extended two way ranging + */ +#ifndef MYNEWT_VAL_TWR_DS_EXT_RX_TIMEOUT +#define MYNEWT_VAL_TWR_DS_EXT_RX_TIMEOUT (((uint16_t)0x40)) +#endif + +/** + * @brief tx holdoff delay for DS TWR extended frame (usec) + */ +#ifndef MYNEWT_VAL_TWR_DS_EXT_TX_HOLDOFF +#define MYNEWT_VAL_TWR_DS_EXT_TX_HOLDOFF (((uint32_t)0x0400)) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* SYSCFG_SYSCFG_TWR_DS_EXT_H */ diff --git a/pkg/uwb-core/include/syscfg/syscfg_twr_ss.h b/pkg/uwb-core/include/syscfg/syscfg_twr_ss.h new file mode 100644 index 0000000000..e730ecba8d --- /dev/null +++ b/pkg/uwb-core/include/syscfg/syscfg_twr_ss.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2020 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup pkg_uwb_core + * @{ + * + * @file + * @brief uwb-core single-sided two-way ranging module configurations + * taken from decawave-uwb-core/lib/twr_ss/syscfg.yml + * + * @author Francisco Molina + * @} + */ + +#ifndef SYSCFG_SYSCFG_TWR_SS_H +#define SYSCFG_SYSCFG_TWR_SS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Enable ranging services + */ +#ifndef MYNEWT_VAL_TWR_SS_ENABLED +#define MYNEWT_VAL_TWR_SS_ENABLED (IS_ACTIVE(MODULE_UWB_CORE_TWR_SS)) +#endif + +/** + * @brief TOA timeout delay for SS TWR (usec) + */ +#ifndef MYNEWT_VAL_TWR_SS_RX_TIMEOUT +#define MYNEWT_VAL_TWR_SS_RX_TIMEOUT (((uint16_t)0x30)) +#endif + +/** + * @brief tx holdoff delay for SS TWR (usec) + */ +#ifndef MYNEWT_VAL_TWR_SS_TX_HOLDOFF +#define MYNEWT_VAL_TWR_SS_TX_HOLDOFF (((uint32_t)0x0300)) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* SYSCFG_SYSCFG_TWR_SS_H */ diff --git a/pkg/uwb-core/include/syscfg/syscfg_twr_ss_ack.h b/pkg/uwb-core/include/syscfg/syscfg_twr_ss_ack.h new file mode 100644 index 0000000000..5371159033 --- /dev/null +++ b/pkg/uwb-core/include/syscfg/syscfg_twr_ss_ack.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2020 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup pkg_uwb_core + * @{ + * + * @file + * @brief Single sided ranging using a hw generated ack module configurations + * taken from decawave-uwb-core/lib/twr_ss_ack/syscfg.yml + * + * @author Francisco Molina + * @} + */ + +#ifndef SYSCFG_SYSCFG_TWR_SS_ACK_H +#define SYSCFG_SYSCFG_TWR_SS_ACK_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Enable toplevel ranging services + */ +#ifndef MYNEWT_VAL_TWR_SS_ACK_ENABLED +#define MYNEWT_VAL_TWR_SS_ACK_ENABLED (IS_ACTIVE(MODULE_UWB_CORE_TWR_SS_ACK)) +#endif + +/** + * @brief tx holdoff delay used to know how long to wait for SS TWR ACK message (usec) + */ +#ifndef MYNEWT_VAL_TWR_SS_ACK_RX_TIMEOUT +#define MYNEWT_VAL_TWR_SS_ACK_RX_TIMEOUT (((uint16_t)0x100)) +#endif + +/** + * @brief TOA timeout delay for SS TWR (usec) + */ +#ifndef MYNEWT_VAL_TWR_SS_ACK_TX_HOLDOFF +#define MYNEWT_VAL_TWR_SS_ACK_TX_HOLDOFF (((uint32_t)0x800)) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* SYSCFG_SYSCFG_TWR_SS_ACK_H */ diff --git a/pkg/uwb-core/include/syscfg/syscfg_twr_ss_ext.h b/pkg/uwb-core/include/syscfg/syscfg_twr_ss_ext.h new file mode 100644 index 0000000000..3fe15820e8 --- /dev/null +++ b/pkg/uwb-core/include/syscfg/syscfg_twr_ss_ext.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2020 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup pkg_uwb_core + * @{ + * + * @file + * @brief uwb-core single-sided two-way ranging module configurations + * taken from decawave-uwb-core/lib/twr_ss_ext/syscfg.yml + * + * @author Francisco Molina + * @} + */ + +#ifndef SYSCFG_SYSCFG_TWR_SS_EXT_H +#define SYSCFG_SYSCFG_TWR_SS_EXT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Enable Single Sided extended ranging services + */ +#ifndef MYNEWT_VAL_TWR_SS_EXT_ENABLED +#define MYNEWT_VAL_TWR_SS_EXT_ENABLED (IS_ACTIVE(MODULE_UWB_CORE_TWR_SS_EXT)) +#endif + +/** + * @brief TOA timeout delay for SS EXT TWR (usec) + */ +#ifndef MYNEWT_VAL_TWR_SS_EXT_RX_TIMEOUT +#define MYNEWT_VAL_TWR_SS_EXT_RX_TIMEOUT (((uint16_t)0x40)) +#endif + +/** + * @brief tx holdoff delay for SS EXT TWR (usec) + */ +#ifndef MYNEWT_VAL_TWR_SS_EXT_TX_HOLDOFF +#define MYNEWT_VAL_TWR_SS_EXT_TX_HOLDOFF (((uint32_t)0x0400)) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* SYSCFG_SYSCFG_TWR_SS_EXT_H */ diff --git a/pkg/uwb-core/include/syscfg/syscfg_uwb.h b/pkg/uwb-core/include/syscfg/syscfg_uwb.h new file mode 100644 index 0000000000..48ac7b849d --- /dev/null +++ b/pkg/uwb-core/include/syscfg/syscfg_uwb.h @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2020 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup pkg_uwb_core + * @{ + * + * @file + * @brief uwb-core uwb module configurations + * taken from decawave-uwb-core/hw/drivers/uwb/syscfg.yml + * + * @author Francisco Molina + * @} + */ + +#ifndef SYSCFG_SYSCFG_UWB_H +#define SYSCFG_SYSCFG_UWB_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Interrupt task priority for instance 0 + */ +#ifndef MYNEWT_VAL_UWB_DEV_TASK_PRIO +#define MYNEWT_VAL_UWB_DEV_TASK_PRIO (THREAD_PRIORITY_MAIN - 5) +#endif + +/** + * @brief Size of interrupt task stack + */ +#ifndef MYNEWT_VAL_UWB_DEV_TASK_STACK_SZ +#define MYNEWT_VAL_UWB_DEV_TASK_STACK_SZ (1024) +#endif + +/** + * @brief Size of the rx buffer in the uwb_dev + */ +#ifndef MYNEWT_VAL_UWB_RX_BUFFER_SIZE +#define MYNEWT_VAL_UWB_RX_BUFFER_SIZE (1024) +#endif + +/** + * @brief Enable init messages showing each package has been initialised + */ +#ifndef MYNEWT_VAL_UWB_PKG_INIT_LOG +#define MYNEWT_VAL_UWB_PKG_INIT_LOG (1) +#endif + +/** + * @brief Maximum size of rxdiag structure + */ +#ifndef MYNEWT_VAL_UWB_DEV_RXDIAG_MAXLEN +#define MYNEWT_VAL_UWB_DEV_RXDIAG_MAXLEN (20) +#endif + +/** + * @brief UWB_0 Device Enable. BSP uses this to enable the specific uwb device + * + * @note in uwb-core you need to tell exactly how many uwb-device there + * are, ideally thus would be done different + */ +#ifndef MYNEWT_VAL_UWB_DEVICE_0 +#define MYNEWT_VAL_UWB_DEVICE_0 (1) +#endif + +/** + * @brief Max number of UWB_DEVICES allowed in system + * + * @note uwb-core uses arrays to keep track of devices, currently se use + * linked list, this is temporary... + */ +#ifndef MYNEWT_VAL_UWB_DEVICE_MAX +#define MYNEWT_VAL_UWB_DEVICE_MAX (3) +#endif + +/** + * @brief If ipatov and sts timestamps differ by more than this value + * they are considered invalid + */ +#ifndef MYNEWT_VAL_UWB_STS_TS_MATCH_THRESHOLD +#define MYNEWT_VAL_UWB_STS_TS_MATCH_THRESHOLD (30) +#endif + +/** + * @brief Default Anchor X Coordinate + */ +#ifndef MYNEWT_VAL_LOCAL_COORDINATE_X +#define MYNEWT_VAL_LOCAL_COORDINATE_X (((float)0.0f)) +#endif + +/** + * @brief Default Anchor Y Coordinate + */ +#ifndef MYNEWT_VAL_LOCAL_COORDINATE_Y +#define MYNEWT_VAL_LOCAL_COORDINATE_Y (((float)0.0f)) +#endif + +/** + * @brief Default Anchor Z Coordinate + */ +#ifndef MYNEWT_VAL_LOCAL_COORDINATE_Z +#define MYNEWT_VAL_LOCAL_COORDINATE_Z (((float)0.0f)) +#endif + +/** + * @brief Range Measurement Variance + */ +#ifndef MYNEWT_VAL_RANGE_VARIANCE +#define MYNEWT_VAL_RANGE_VARIANCE (((float)5.4444e-04)) +#endif + +/** + * @brief Azimuth Measurement Variance + */ +#ifndef MYNEWT_VAL_AZIMUTH_VARIANCE +#define MYNEWT_VAL_AZIMUTH_VARIANCE (((float)2.91e-2)) +#endif + +/** + * @brief OS Latency Guardband (usec) + */ +#ifndef MYNEWT_VAL_OS_LATENCY +#define MYNEWT_VAL_OS_LATENCY (((uint32_t)800)) +#endif + +/** + * @brief Default Pan ID + */ +#ifndef MYNEWT_VAL_PANID +#define MYNEWT_VAL_PANID (((const uint16_t)0xdeca)) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* SYSCFG_SYSCFG_UWB_H */ diff --git a/pkg/uwb-core/include/syscfg/syscfg_uwb_rng.h b/pkg/uwb-core/include/syscfg/syscfg_uwb_rng.h new file mode 100644 index 0000000000..572ceccad6 --- /dev/null +++ b/pkg/uwb-core/include/syscfg/syscfg_uwb_rng.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2020 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup pkg_uwb_core + * @{ + * + * @file + * @brief uwb-core uwb_rng module configurations + * taken from decawave-uwb-core/lib/uwb_rng/syscfg.yml + * + * @author Francisco Molina + * @} + */ + +#ifndef SYSCFG_SYSCFG_UWB_RNG_H +#define SYSCFG_SYSCFG_UWB_RNG_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief uwb-core uwb_rng module is enabled + */ +#ifndef MYNEWT_VAL_UWB_RNG_ENABLED +#define MYNEWT_VAL_UWB_RNG_ENABLED ((IS_ACTIVE(MODULE_UWB_CORE_RNG))) +#endif + +/** + * @brief TOA timeout delay for TWR (usec) + */ +#ifndef MYNEWT_VAL_RNG_RX_TIMEOUT +#define MYNEWT_VAL_RNG_RX_TIMEOUT (((uint16_t)0x20)) +#endif + +/** + * @brief worstcase tx holdoff delay for all TWR modes (usec) + */ +#ifndef MYNEWT_VAL_RNG_TX_HOLDOFF +#define MYNEWT_VAL_RNG_TX_HOLDOFF (((uint32_t)0x0320)) +#endif + +/** + * @brief Show debug output from postprocess + */ +#ifndef MYNEWT_VAL_RNG_VERBOSE +#define MYNEWT_VAL_RNG_VERBOSE (0) +#endif + +/** + * @brief JSON buffer size + */ +#ifndef MYNEWT_VAL_UWB_RNG_JSON_BUFSIZE +#define MYNEWT_VAL_UWB_RNG_JSON_BUFSIZE (256) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* SYSCFG_SYSCFG_UWB_RNG_H */ diff --git a/pkg/uwb-core/include/syscfg/syscfg_uwbcfg.h b/pkg/uwb-core/include/syscfg/syscfg_uwbcfg.h new file mode 100644 index 0000000000..543a746784 --- /dev/null +++ b/pkg/uwb-core/include/syscfg/syscfg_uwbcfg.h @@ -0,0 +1,241 @@ +/* + * Copyright (C) 2020 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup pkg_uwb_core + * @{ + * + * @file + * @brief uwb-core uwbcfg module configurations + * taken from decawave-uwb-core/sys/uwbcfg/syscfg.yml + * + * @author Francisco Molina + * @} + */ + +#ifndef SYSCFG_SYSCFG_UWBCFG_H +#define SYSCFG_SYSCFG_UWBCFG_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Enable uwbcfg module + */ +#ifndef MYNEWT_VAL_UWBCFG_ENABLED +#define MYNEWT_VAL_UWBCFG_ENABLED (IS_ACTIVE(MODULE_UWB_CORE_UWBCFG)) +#endif + +/** + * @brief Apply configuration on uwbcfg module setup + */ +#ifndef MYNEWT_VAL_UWBCFG_APPLY_AT_INIT +#define MYNEWT_VAL_UWBCFG_APPLY_AT_INIT (1) +#endif + +/** + * @brief Default channel + */ +#ifndef MYNEWT_VAL_UWBCFG_DEF_CH +#define MYNEWT_VAL_UWBCFG_DEF_CH ("5") +#endif + +/** + * @brief Default UWB PRF (MHz) + */ +#ifndef MYNEWT_VAL_UWBCFG_DEF_PRF +#define MYNEWT_VAL_UWBCFG_DEF_PRF ("64") +#endif + +/** + * @brief Default UWB Datarate (110k, 850k, 6m8) + */ +#ifndef MYNEWT_VAL_UWBCFG_DEF_DATARATE +#define MYNEWT_VAL_UWBCFG_DEF_DATARATE ("6m8") +#endif + +/** + * @brief Default UWB PAC Length (8, 16, 32, 64) + */ +#ifndef MYNEWT_VAL_UWBCFG_DEF_PACLEN +#define MYNEWT_VAL_UWBCFG_DEF_PACLEN ("8") +#endif + +/** + * @brief Default UWB External clock delay + */ +#ifndef MYNEWT_VAL_UWBCFG_DEF_EXT_CLKDLY +#define MYNEWT_VAL_UWBCFG_DEF_EXT_CLKDLY ("0") +#endif + +/** + * @brief Default MAC FrameFilter (0x0000 = no filter) + */ +#ifndef MYNEWT_VAL_UWBCFG_DEF_FRAME_FILTER +#define MYNEWT_VAL_UWBCFG_DEF_FRAME_FILTER ("0x0000") +#endif + +/** + * @brief Default UWB Role + * + * - Tag "0x00" + * - Node "0x01" + * - Pan master "0x02" + * - Anchor "0x04" + * - Panmaster "0x07" + */ +#ifndef MYNEWT_VAL_UWBCFG_DEF_ROLE +#define MYNEWT_VAL_UWBCFG_DEF_ROLE ("0x0") +#endif + +/** + * @brief Default UWB RX Antenna delay + */ +#ifndef MYNEWT_VAL_UWBCFG_DEF_RX_ANTDLY +#define MYNEWT_VAL_UWBCFG_DEF_RX_ANTDLY ("0x4050") +#endif + +/** + * @brief Default UWB RX Antenna separation distance in m + */ +#ifndef MYNEWT_VAL_UWBCFG_DEF_RX_ANTSEP +#define MYNEWT_VAL_UWBCFG_DEF_RX_ANTSEP ("0.0205") +#endif + +/** + * @brief UWBCFG_DEF_RX_DIAG_EN + */ +#ifndef MYNEWT_VAL_UWBCFG_DEF_RX_DIAG_EN +#define MYNEWT_VAL_UWBCFG_DEF_RX_DIAG_EN ("0x1") +#endif + +/** + * @brief Default UWB PDOA Mode (0, 1, 2, 3) + */ +#ifndef MYNEWT_VAL_UWBCFG_DEF_RX_PDOA_MODE +#define MYNEWT_VAL_UWBCFG_DEF_RX_PDOA_MODE ("0") +#endif + +/** + * @brief Default UWB PHR Mode (s, e) + */ +#ifndef MYNEWT_VAL_UWBCFG_DEF_RX_PHR_MODE +#define MYNEWT_VAL_UWBCFG_DEF_RX_PHR_MODE ("e") +#endif + +/** + * @brief Default UWB PHR Rate (0 = std, 1 = data) + */ +#ifndef MYNEWT_VAL_UWBCFG_DEF_RX_PHR_RATE +#define MYNEWT_VAL_UWBCFG_DEF_RX_PHR_RATE ("0") +#endif + +/** + * @brief Default UWB RX Preamble Code Index + */ +#ifndef MYNEWT_VAL_UWBCFG_DEF_RX_PREAM_CIDX +#define MYNEWT_VAL_UWBCFG_DEF_RX_PREAM_CIDX ("9") +#endif + +/** + * @brief Default UWB SFD Timeout (-1=auto, timeout in symbols) + */ +#ifndef MYNEWT_VAL_UWBCFG_DEF_RX_SFD_TO +#define MYNEWT_VAL_UWBCFG_DEF_RX_SFD_TO ("-1") +#endif + +/** + * @brief Default UWB SFD Type (0, 1) + */ +#ifndef MYNEWT_VAL_UWBCFG_DEF_RX_SFD_TYPE +#define MYNEWT_VAL_UWBCFG_DEF_RX_SFD_TYPE ("1") +#endif + +/** + * @brief Default UWB Sts Length (32-2040 in steps of 8) + */ +#ifndef MYNEWT_VAL_UWBCFG_DEF_RX_STS_LEN +#define MYNEWT_VAL_UWBCFG_DEF_RX_STS_LEN ("64") +#endif + +/** + * @brief Default UWB Sts Mode (0, 1, 2, sdc, 4z) + */ +#ifndef MYNEWT_VAL_UWBCFG_DEF_RX_STS_MODE +#define MYNEWT_VAL_UWBCFG_DEF_RX_STS_MODE ("0") +#endif + +/** + * @brief Default UWB Coarse TX Power (0,3,6,..,18) + */ +#ifndef MYNEWT_VAL_UWBCFG_DEF_TXRF_POWER_COARSE +#define MYNEWT_VAL_UWBCFG_DEF_TXRF_POWER_COARSE ("15") +#endif + +/** + * @brief Default UWB FINE TX Power (0,1,2,..,31) + */ +#ifndef MYNEWT_VAL_UWBCFG_DEF_TXRF_POWER_FINE +#define MYNEWT_VAL_UWBCFG_DEF_TXRF_POWER_FINE ("22") +#endif + +/** + * @brief Default UWB FINE TX Power (0,1,2,..,31) + */ +#ifndef MYNEWT_VAL_UWBCFG_DEF_TXRF_VCM_LO +#define MYNEWT_VAL_UWBCFG_DEF_TXRF_VCM_LO ("15") +#endif + +/** + * @brief Default UWB TX Antenna delay + */ +#ifndef MYNEWT_VAL_UWBCFG_DEF_TX_ANTDLY +#define MYNEWT_VAL_UWBCFG_DEF_TX_ANTDLY ("0x4050") +#endif + +/** + * @brief Default UWB RX Antenna separation distance in m + */ +#ifndef MYNEWT_VAL_UWBCFG_DEF_TX_PREAM_CIDX +#define MYNEWT_VAL_UWBCFG_DEF_TX_PREAM_CIDX ("9") +#endif + +/** + * @brief Default UWB Preamble Length + */ +#ifndef MYNEWT_VAL_UWBCFG_DEF_TX_PREAM_LEN +#define MYNEWT_VAL_UWBCFG_DEF_TX_PREAM_LEN ("128") +#endif + +/** + * @brief Default XTAL Trim value (0xff = no trim, or use OTP value) + */ +#ifndef MYNEWT_VAL_UWBCFG_DEF_XTAL_TRIM +#define MYNEWT_VAL_UWBCFG_DEF_XTAL_TRIM ("0xff") +#endif + +/** + * @brief Offset relative leading edge to start extracting CIR from + */ +#ifndef MYNEWT_VAL_UWBCFG_DEF_CIR_OFFSET +#define MYNEWT_VAL_UWBCFG_DEF_CIR_OFFSET ("0") +#endif + +/** + * @brief Number of bins to extract from CIR + */ +#ifndef MYNEWT_VAL_UWBCFG_DEF_CIR_SIZE +#define MYNEWT_VAL_UWBCFG_DEF_CIR_SIZE ("0") +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* SYSCFG_SYSCFG_UWBCFG_H */ diff --git a/pkg/uwb-core/include/sysinit/sysinit.h b/pkg/uwb-core/include/sysinit/sysinit.h new file mode 100644 index 0000000000..c340c1c2fc --- /dev/null +++ b/pkg/uwb-core/include/sysinit/sysinit.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2020 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup pkg_uwb_core + * @{ + * + * @file + * @brief sysinit abstraction layer for RIOT adaption + * + * @author Francisco Molina + * @} + */ + +#ifndef SYSINIT_SYSINIT_H +#define SYSINIT_SYSINIT_H + +#include "assert.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief DPL assert macro + */ +#define SYSINIT_PANIC_ASSERT(rc) assert(rc); + +#ifdef __cplusplus +} +#endif + +#endif /* SYSINIT_SYSINIT_H */ diff --git a/pkg/uwb-core/include/uwb_core.h b/pkg/uwb-core/include/uwb_core.h new file mode 100644 index 0000000000..19550aab9e --- /dev/null +++ b/pkg/uwb-core/include/uwb_core.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2020 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup pkg_uwb_core + * + * @{ + * + * @file + * + * @author Francisco Molina + */ + +#ifndef UWB_CORE_H +#define UWB_CORE_H + +#include +#include "event.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Priority used for + */ +#ifndef UWB_CORE__PRIO +#define UWB_CORE__PRIO (THREAD_PRIORITY_MAIN - 2) +#endif + +/** + * @brief Stacksize used for + */ +#ifndef UWB_CORE__STACKSIZE +#define UWB_CORE__STACKSIZE (THREAD_STACKSIZE_DEFAULT) +#endif + +/** + * @brief Setup and run uwb-core thread + */ +void uwb_core_riot_init(void); + +/** + * @brief Retrieves the default event queue. + * + * As there is no default event queue in RIOT, uwb-core will start and + * handle a default event queue. + * + * @return the default event queue. + */ +event_queue_t *uwb_core_get_eventq(void); + +#ifdef __cplusplus +} +#endif + +#endif /* UWB_CORE_H */ +/** @} */ diff --git a/pkg/uwb-core/patches/0001-uwb-uwb.c-use-RIOT-specific-uwb_dev_idx_lookup.patch b/pkg/uwb-core/patches/0001-uwb-uwb.c-use-RIOT-specific-uwb_dev_idx_lookup.patch new file mode 100644 index 0000000000000000000000000000000000000000..0af7be3d937e4b7a6b56c8eabce6e475ada933d3 GIT binary patch literal 787 zcmaJ;U2obz5PZL1F;!jwgE<=)V-iKs57bDFK!Jx=RfX)kHC*GIkf3;o#M8%SknPP3@N8i zhEU2tEEr~rMU`4*oGLl7FgC?iP7hDstWmxyuEmG6rZ&&?5k#0bJ1!3;`%|`X1dqR@ zSU1@ZQuP$yR`bpKPY8zbcQlXLkgu<%XdL10X1ReokTSVZZE&mUxHbB;Ez0t~Idr;0 z3O)+OBG~s;QQl*#xc(yNI8z8w#_rRf_uan?AZ*1QP3a5 zJO%`YJ#G^{%vU$4ONQSWS5pN#)npxO2&l9uvQ*tWL= literal 0 HcmV?d00001 diff --git a/pkg/uwb-core/patches/0002-lib-twr_-enable-stats-optionally.patch b/pkg/uwb-core/patches/0002-lib-twr_-enable-stats-optionally.patch new file mode 100644 index 0000000000000000000000000000000000000000..9877337b9f34b37f05aedaeb5655ed6061546d53 GIT binary patch literal 28840 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 literal 0 HcmV?d00001 diff --git a/pkg/uwb-core/patches/0003-lib-tofdb-use-DPL_ENOENT-instead-of-OS_ENOENT.patch b/pkg/uwb-core/patches/0003-lib-tofdb-use-DPL_ENOENT-instead-of-OS_ENOENT.patch new file mode 100644 index 0000000000000000000000000000000000000000..774f3d5191ac916a1bddf8dd267a80d32bdd37c7 GIT binary patch literal 640 zcmZ`$(Q4Z;6n)oMoX4h)97(a`#4ROdZ5V883hCPz!IorK!*kI<6u}NUH-}7c-`8YU0y51-l2Z{8670~I zKdlZqzCYi;eEN*#BKv{Hm5b0;rd;IcPZkf)UyqMZ`^TpjIDZPZFla065C2HUIOpub zb?WrlA8Y)9LPTAO$~6}HweYnyG}91eyWm=X70m{0Y-2~rXN(zFRp7jK0mWjP=Q6qc zKhK;u_BZTGuZ2wGI5SzgNfe|IwCrKjj}loFMffOny9HP4d4_0w2|6DzZs}OtaHQ(0 zCrYl4G_o<>90Ob`g4fiXFPki!SKtM<{@#`Pn;} R_Ft$$Q5;OgY8?y4{sN4bw_*SQ literal 0 HcmV?d00001 diff --git a/pkg/uwb-core/patches/0004-sys-uwbcfg-use-DPL_ENOENT-instead-of-OS_ENOENT.patch b/pkg/uwb-core/patches/0004-sys-uwbcfg-use-DPL_ENOENT-instead-of-OS_ENOENT.patch new file mode 100644 index 0000000000000000000000000000000000000000..a2d71e5d6165e8a0cc5d882da5567943d45ad62f GIT binary patch literal 685 zcmZ{hU2oGc6o&8pE6!!xeAG^yw#g7`wY3asv=b@ZOjG1I$H6FbP(B7o?7!o*g$|@z zmVDmha~{98H%uP{u)9KobobjLwtneVcF(HLk3OujW9f;}K z(ZB5c(hkw4z#kCBkz{f1`&{zbe1X6yopC-GzDy;K1NO7V Ab^rhX literal 0 HcmV?d00001 diff --git a/pkg/uwb-core/patches/0005-treewide-use-dpl_log.h-instaed-of-log.h-to-avoid-con.patch b/pkg/uwb-core/patches/0005-treewide-use-dpl_log.h-instaed-of-log.h-to-avoid-con.patch new file mode 100644 index 0000000000000000000000000000000000000000..a9388932ad4098fbd8f3ab1a9195f342211229dc GIT binary patch literal 2711 zcmbtW?{C^V6#eeM;%ZNt+6N?Y2n5(x!P?SJT7L-I?ZeZPl{hx_lqMBPx;?%9@$cGc zfjsJVWl@X6^|{Bn$JZxJm-#IW`biuHJnRm;gJjT;x-pl%0ga?j!(ce1T*!Xcmjcf6 z4CdkvXb7G+GJoKE9wk$x8NqZJWn2|JM_{V52;NI^YwpGscX)b0j-pa%oN5CNU{WnG z-S>d@MwE`cKD6+gN9I-hP4IFAe_c+l4o{)yhJQo36ym!|Fuf`SBzGxG^M!K*Dl5uJ zB#=v}17!};eXbG$JkMmRcu7d7(;<+m*u9Ig+o&kT(k+&J{mtR<6Q~C*eIZ!Gi+>8Y z`i@d847R>SV14}r@S$acvAdZNFq{E z2Ri$NBuYx?bQY?F$bG(w`1yIFvPArVi2B_i?mLe3lc5w6OZWOgpk;b#1%d*>ORJ2> z(DBQ*o>mqMrSi@q6E@JekXFF>?+;i9L`vGY+ zqpKEatfYHFE!=uAD{VZ-n{|7v?wp%9#MIMm>jv@7fC22fQgNtMR?X+U4K4imy>gLHkn@? z&tPvz_p#y!%;g#TbUwY!u+W_z!oYrU*oLz_*!O&e>1rFtvgR$n9Gv5|^$ zS@BZ49O$h!t>gaLbO)Ph#rpU>WoHkL5b&TM4us?IkPkx*N=zO6LvZK^o5|n6l7FI8Z_T_IF z&h??)zUnvZmW$OqHU~pO+bMm^c4f32-d18G j0bh0^t8U?6V%}ZYj`OP-J3Rg1weiOX5a00!jz`FUruQmK literal 0 HcmV?d00001 diff --git a/pkg/uwb-core/patches/0006-lib-json-src-use-fmt-to-avoid-newlib-issue.patch b/pkg/uwb-core/patches/0006-lib-json-src-use-fmt-to-avoid-newlib-issue.patch new file mode 100644 index 0000000000000000000000000000000000000000..a6c242b808a4b04c9bb8f77d1d582d511e9e0c5d GIT binary patch literal 1461 zcmdT?Yirvu6#cGWamg4o^&_&I`H^)cWlLDMt}Sgk7-I-qx=NHfam$YUYGga{YQuf@ee3eK3JMk4@|{J&=>@{s-Z3+TbD|J#yg7uWlV#F zc%DagGB&9UH7^DF9DYFpjvW?ffdNQWAn-+|=O|nlg3<=7T9w-DIsG;uu)yu!>k}fB zl;C-DRYNxD3VTu}f98-VE$|+O0@E---#>_BDS`w7N~7Vhy}`5G#Hxp9`Nw1M!oZEd zvHt|dV*;;~=0zhA4ozJtJ@*$!-JsHS{qq*hCQO_^=$>`jU-XF6f~7zSjD4P5o=r{} z>*m{@H}``ZtTYx|YAg(rR!B_U-~gOBbc4W3fwq$m?O^MyXmHOeYIxl}s9=BFu*!w* z=>`w`%XObXcRYZ-qb0JtO4Yd6jbzo_g>GQGW_crBC{Xv`?y}_-W;dM}&+L=?baj5l zz8;@mPuT3+#e`j-oXw))hyKT<8%_9pAr z9lx>SoX2=OZ%f#=Fq_W=^1qgO!qO$#apNBu_F})(3;ijXGUu zI18icGWjOBjo{{bG<*92dad3qWGZPbACg$-^9We>z+>&a$v-^l3%pOdfl? zwkGrMV5nEAV)Oc|7h+{uX0Q|M?LD!`&BZSzp+W>h&PtZ3Oj#vNXsoHj&o#uuo=KD$ zo15^Cnb^TxzO^o1@pLwgFRsS#;;YGIqxt~lJX48bv zU*5!@zK%bR-uvqRqJ{o1FLlHXU*Hpn%m_EH%KFEW55-g^kFU?;$@$f2)~500=(4uW zx+hOn&I>Uf4o?WyhpKf9*M+gAF1RqpjS}pgn_lWJmAfM=3&$;YYXQ-a_Ct)&FL=nK AT>t<8 literal 0 HcmV?d00001 diff --git a/pkg/uwb-core/patches/0008-porting-dpl-add-riot-files.patch b/pkg/uwb-core/patches/0008-porting-dpl-add-riot-files.patch new file mode 100644 index 0000000000000000000000000000000000000000..300f04078bffe122d88a021c589dc95da90c8f09 GIT binary patch literal 37259 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 Date: Fri, 14 Aug 2020 15:52:39 +0200 Subject: [PATCH 4/4] examples/twr_aloha: RIOT adaptation of twr_aloha --- examples/twr_aloha/Makefile | 57 ++++++++ examples/twr_aloha/Makefile.ci | 12 ++ examples/twr_aloha/README.md | 68 +++++++++ examples/twr_aloha/control.c | 260 +++++++++++++++++++++++++++++++++ examples/twr_aloha/control.h | 53 +++++++ examples/twr_aloha/main.c | 31 ++++ 6 files changed, 481 insertions(+) create mode 100644 examples/twr_aloha/Makefile create mode 100644 examples/twr_aloha/Makefile.ci create mode 100644 examples/twr_aloha/README.md create mode 100644 examples/twr_aloha/control.c create mode 100644 examples/twr_aloha/control.h create mode 100644 examples/twr_aloha/main.c diff --git a/examples/twr_aloha/Makefile b/examples/twr_aloha/Makefile new file mode 100644 index 0000000000..9a03b53c5f --- /dev/null +++ b/examples/twr_aloha/Makefile @@ -0,0 +1,57 @@ +APPLICATION = twr-aloha + +# If no BOARD is found in the environment, use this default: +BOARD ?= dwm1001 + +# This has to be the absolute path to the RIOT base directory: +RIOTBASE ?= $(CURDIR)/../.. + +# Change this to 0 show compiler invocation lines by default: +QUIET ?= 1 + +# Comment this out to disable code in RIOT that does safety checking +# which is not needed in a production environment but helps in the +# development process: +DEVELHELP ?= 1 + +# Include uwb-core, uwb-dw1000 +USEPKG += uwb-core +USEPKG += uwb-dw1000 + +# Include all ranging algorithms +USEMODULE += uwb-core_twr_ss +USEMODULE += uwb-core_twr_ss_ack +USEMODULE += uwb-core_twr_ss_ext +USEMODULE += uwb-core_twr_ds +USEMODULE += uwb-core_twr_ds_ext + +USEMODULE += shell +USEMODULE += shell_commands +USEMODULE += ps + +# Set the device role: 0x0 for tag, 0x4 for an anchor +DW1000_ROLE ?= 0x00 +CFLAGS += -DDW1000_ROLE_DEFAULT=$(DW1000_ROLE) + +# All uwb-core applications need to enable `-fms-extensions` +CFLAGS += -fms-extensions +ifneq (,$(filter llvm,$(TOOLCHAIN))) + CFLAGS += -Wno-microsoft-anon-tag +endif + +# Enable verbose mode to get all logs +CFLAGS += -DMYNEWT_VAL_RNG_VERBOSE=2 +# Enable RX diagnostics +CFLAGS += -DDW1000_RX_DIAGNOSTIC=1 + +# Fix the TWR algorithm: +# - UWB_DATA_CODE_SS_TWR +# - UWB_DATA_CODE_SS_TWR_EXT +# - UWB_DATA_CODE_SS_TWR_ACK +# - UWB_DATA_CODE_DS_TWR +# - UWB_DATA_CODE_DS_TWR_EXT +UWB_TWR_ALGORITHM_ONLY_ONE ?= UWB_DATA_CODE_SS_TWR +# Uncomment to fix the TWR algoritm +# CFLAGS += -DUWB_TWR_ALGORITHM_ONLY_ONE=$(UWB_TWR_ALGORITHM_ONLY_ONE) + +include $(RIOTBASE)/Makefile.include diff --git a/examples/twr_aloha/Makefile.ci b/examples/twr_aloha/Makefile.ci new file mode 100644 index 0000000000..8cc220c328 --- /dev/null +++ b/examples/twr_aloha/Makefile.ci @@ -0,0 +1,12 @@ +BOARD_INSUFFICIENT_MEMORY := \ + i-nucleo-lrwan1 \ + nucleo-f031k6 \ + nucleo-f042k6 \ + nucleo-l011k4 \ + nucleo-l031k6 \ + nucleo-l053r8 \ + stk3200 \ + stm32f030f4-demo \ + stm32f0discovery \ + stm32l0538-disco \ + # diff --git a/examples/twr_aloha/README.md b/examples/twr_aloha/README.md new file mode 100644 index 0000000000..bae09b34b6 --- /dev/null +++ b/examples/twr_aloha/README.md @@ -0,0 +1,68 @@ +## Decawave TWR_ALOHA Example + +This example allows testing different two-way ranging algorithms between +two boards supporting a dw1000 device. This makes use of the uwb-core +pkg. This example is based on the twr-aloha example in +[uwb-apps](https://github.com/Decawave/uwb-apps/tree/master/apps/twr_aloha). + +### Setup + +1. Flash one node as the tag (Default configuration) + + $ make -C examples/twr_aloha/ flash term + +2. Flash the second node as an anchor + + $ DW1000_ROLE=0x4 make -C examples/twr_aloha/ flash term + +3. On the tag node begin ranging, you will see ranging estimations where +the "raz" field is "range" in meters. + +``` + main(): This is RIOT! (Version: 2020.10-devel-1384-g5b7ad-wip/uwb-dw1000) + pkg uwb-dw1000 + uwb-core test application + {"utime": 49412,"exec": "/home/francisco/workspace/RIOT/examples/twr_aloha/control.c"} + {"device_id"="deca0130","panid="DECA","addr"="1303","part_id"="cad11303","lot_id"="402c188"} + {"utime": 49412,"msg": "frame_duration = 201 usec"} + {"utime": 49412,"msg": "SHR_duration = 139 usec"} + {"utime": 49412,"msg": "holdoff = 821 usec"} + Node role: TAG + {"utime": 120995,"c": 274,"uid": 4867,"ouid": 4660,"raz": [0.766359],"los": [1.000000]} +> range start + range start + Start ranging + {"utime": 5214098,"c": 274,"uid": 4867,"ouid": 4660,"raz": [0.778875],"los": [1.000000]} + {"utime": 5232368,"c": 274,"uid": 4867,"ouid": 4660,"raz": [0.777146],"los": [1.000000]} + {"utime": 5250631,"c": 274,"uid": 4867,"ouid": 4660,"raz": [0.796009],"los": [1.000000]} + {"utime": 5268894,"c": 274,"uid": 4867,"ouid": 4660,"raz": [0.756952],"los": [1.000000]} + {"utime": 5287157,"c": 274,"uid": 4867,"ouid": 4660,"raz": [0.787994],"los": [1.000000]} +``` + +4. Trying different ranging algorithms + +The algorithm used for ranging is selected by modifying the `mode` variable +in the uwb_ev_cb function in main.c. If multiple modes are enabled it will switch among them. + +To use only one algorithm, compile as follows: + + $ UWB_TWR_ALGORITHM_ONLY_ONE=UWB_DATA_CODE_SS_TWR make -C examples/twr_aloha/ flash term + +The different algorithm options are: + +- UWB_DATA_CODE_SS_TWR +- UWB_DATA_CODE_SS_TWR_EXT +- UWB_DATA_CODE_SS_TWR_ACK +- UWB_DATA_CODE_DS_TWR +- UWB_DATA_CODE_DS_TWR_EXT + +### Notes + +The application example fixes the `short_address` of the anchor to +`ANCHOR_ADDRESS`, by default `0x1234`. All tags will send ranging requests +to that address. + +This value can be overridden with a `CFLAG += -DANCHOR_ADDRESS=$(VALUE)`. + +Ranging request are sent every 40ms, this value can also be overridden +by changing the default value of `RANGE_REQUEST_T_US`, e.g: +`CFLAG += -DRANGE_REQUEST_T_US=10000` to set it at 10ms. diff --git a/examples/twr_aloha/control.c b/examples/twr_aloha/control.c new file mode 100644 index 0000000000..492584cbb6 --- /dev/null +++ b/examples/twr_aloha/control.c @@ -0,0 +1,260 @@ +/* + * Copyright (C) 2020 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup examples + * @{ + * + * @file + * + * @author Francisco Molina + * + * @} + */ + +#include +#include +#include +#include + +#include "uwb/uwb.h" +#include "uwb_rng/uwb_rng.h" +#include "dpl/dpl.h" +#include "control.h" + +#include "shell_commands.h" +#include "shell.h" +#include "xtimer.h" + +static struct dpl_callout _rng_req_callout; +static uint8_t _ranging_enabled_flag; +static struct dpl_event _slot_event; + +/* forward declaration */ +static void _slot_complete_cb(struct dpl_event *ev); +static bool _complete_cb(struct uwb_dev *inst, struct uwb_mac_interface *cbs); +static bool _rx_timeout_cb(struct uwb_dev *inst, struct uwb_mac_interface *cbs); + +static int _range_cli_cmd(int argc, char **argv) +{ + (void)argc; + + if (!strcmp(argv[1], "start")) { + printf("Start ranging\n"); + dpl_callout_reset(&_rng_req_callout, RANGE_REQUEST_T_US); + _ranging_enabled_flag = 1; + } + else if (!strcmp(argv[1], "stop")) { + printf("Stop ranging\n"); + dpl_callout_stop(&_rng_req_callout); + _ranging_enabled_flag = 0; + } + else { + puts("Usage:"); + puts("\trange start: to start ranging"); + puts("\trange stop: to stop ranging"); + } + + return 0; +} + +static const shell_command_t shell_commands[] = { + { "range", "Control command", _range_cli_cmd }, + { NULL, NULL, NULL } +}; + +/* Structure of extension callbacks common for mac layer */ +static struct uwb_mac_interface _uwb_mac_cbs = (struct uwb_mac_interface){ + .id = UWBEXT_APP0, + .complete_cb = _complete_cb, + .rx_timeout_cb = _rx_timeout_cb, +}; + +/** + * @brief Range request complete callback. + * + * This callback is part of the struct uwb_mac_interface extension + * interface and invoked of the completion of a range request in the + * context of this example. The struct uwb_mac_interface is in the + * interrupt context and is used to schedule events an event queue. + * + * Processing should be kept to a minimum given the interrupt context. + * All algorithms activities should be deferred to a thread on an event + * queue. The callback should return true if and only if it can determine + * if it is the sole recipient of this event. + * + * @note The MAC extension interface is a linked-list of callbacks, + * subsequentcallbacks on the list will be not be called if the callback + * returns true. + * + * @param[in] inst Pointer to struct uwb_dev. + * @param[in] cbs Pointer to struct uwb_mac_interface. + * * + * @return true if valid recipient for the event, false otherwise + */ +static bool _complete_cb(struct uwb_dev *inst, struct uwb_mac_interface *cbs) +{ + (void)cbs; + + if (inst->fctrl != FCNTL_IEEE_RANGE_16 && + inst->fctrl != (FCNTL_IEEE_RANGE_16 | UWB_FCTRL_ACK_REQUESTED)) { + return false; + } + /* on completion of a range request setup an event to keep listening, + if is anchor */ + dpl_eventq_put(dpl_eventq_dflt_get(), &_slot_event); + return true; +} + +/** + * @brief API for receive timeout callback. + * + * @param[in] inst Pointer to struct uwb_dev. + * @param[in] cbs Pointer to struct uwb_mac_interface. + * + * @return true on success + */ +static bool _rx_timeout_cb(struct uwb_dev *inst, struct uwb_mac_interface *cbs) +{ + struct uwb_rng_instance *rng = (struct uwb_rng_instance *)cbs->inst_ptr; + + if (inst->role & UWB_ROLE_ANCHOR) { + /* Restart receiver */ + uwb_phy_forcetrxoff(inst); + uwb_rng_listen(rng, 0xfffff, UWB_NONBLOCKING); + } + return true; +} + +/** + * @brief In the example this function represents the event context + * processing of the received range request which has been offloaded from + * ISR context to an event queue. + */ +static void _slot_complete_cb(struct dpl_event *ev) +{ + assert(ev != NULL); + + struct uwb_rng_instance *rng = (struct uwb_rng_instance *) + dpl_event_get_arg(ev); + struct uwb_dev *inst = rng->dev_inst; + + if (inst->role & UWB_ROLE_ANCHOR) { + uwb_rng_listen(rng, 0xfffff, UWB_NONBLOCKING); + } +} + +/** + * @brief An event callback to send range request every RANGE_REQUEST_T_US. + * On every request it will switch the used ranging algorithm. + */ +static void uwb_ev_cb(struct dpl_event *ev) +{ + struct uwb_rng_instance *rng = (struct uwb_rng_instance *)ev->arg; + struct uwb_dev *inst = rng->dev_inst; + + if (inst->role & UWB_ROLE_ANCHOR) { + if (dpl_sem_get_count(&rng->sem) == 1) { + uwb_rng_listen(rng, 0xfffff, UWB_NONBLOCKING); + } + } + else { + int mode_v[8] = { 0 }, mode_i = 0, mode = -1; + static int last_used_mode = 0; + if (IS_USED(MODULE_UWB_CORE_TWR_SS)) { + mode_v[mode_i++] = UWB_DATA_CODE_SS_TWR; + } + if (IS_USED(MODULE_UWB_CORE_TWR_SS_ACK)) { + mode_v[mode_i++] = UWB_DATA_CODE_SS_TWR_ACK; + } + if (IS_USED(MODULE_UWB_CORE_TWR_SS_EXT)) { + mode_v[mode_i++] = UWB_DATA_CODE_SS_TWR_EXT; + } + if (IS_USED(MODULE_UWB_CORE_TWR_DS)) { + mode_v[mode_i++] = UWB_DATA_CODE_DS_TWR; + } + if (IS_USED(MODULE_UWB_CORE_TWR_DS_EXT)) { + mode_v[mode_i++] = UWB_DATA_CODE_DS_TWR_EXT; + } + if (++last_used_mode >= mode_i) { + last_used_mode = 0; + } + mode = mode_v[last_used_mode]; +#ifdef UWB_TWR_ALGORITHM_ONLY_ONE + mode = UWB_TWR_ALGORITHM_ONLY_ONE; +#endif + if (mode > 0) { + uwb_rng_request(rng, ANCHOR_ADDRESS, mode); + } + } + + /* reset the callback if ranging is enabled */ + if (_ranging_enabled_flag) { + dpl_callout_reset(&_rng_req_callout, RANGE_REQUEST_T_US); + } +} + +void init_ranging(void) +{ + struct uwb_dev *udev = uwb_dev_idx_lookup(0); + struct uwb_rng_instance *rng = + (struct uwb_rng_instance *)uwb_mac_find_cb_inst_ptr(udev, UWBEXT_RNG); + + assert(rng); + + /* set up local mac callbacks */ + _uwb_mac_cbs.inst_ptr = rng; + uwb_mac_append_interface(udev, &_uwb_mac_cbs); + + uint32_t utime = xtimer_now_usec(); + + printf("{\"utime\": %" PRIu32 ",\"exec\": \"%s\"}\n", utime, __FILE__); + printf("{\"device_id\"=\"%" PRIx32 "\"", udev->device_id); + printf(",\"panid=\"%X\"", udev->pan_id); + printf(",\"addr\"=\"%X\"", udev->uid); + printf(",\"part_id\"=\"%" PRIx32 "\"", + (uint32_t)(udev->euid & 0xffffffff)); + printf(",\"lot_id\"=\"%" PRIx32 "\"}\n", (uint32_t)(udev->euid >> 32)); + printf("{\"utime\": %"PRIu32",\"msg\": \"frame_duration = %d usec\"}\n", + utime, uwb_phy_frame_duration(udev, sizeof(twr_frame_final_t))); + printf("{\"utime\": %"PRIu32",\"msg\": \"SHR_duration = %d usec\"}\n", + utime, uwb_phy_SHR_duration(udev)); + printf("{\"utime\": %"PRIu32",\"msg\": \"holdoff = %d usec\"}\n", utime, + (uint16_t)ceilf(uwb_dwt_usecs_to_usecs(rng->config. + tx_holdoff_delay))); + + if (IS_USED(MODULE_UWB_CORE_TWR_SS_ACK)) { + uwb_set_autoack(udev, true); + uwb_set_autoack_delay(udev, 12); + } + + dpl_callout_init(&_rng_req_callout, dpl_eventq_dflt_get(), + uwb_ev_cb, rng); + dpl_callout_reset(&_rng_req_callout, RANGE_REQUEST_T_US); + dpl_event_init(&_slot_event, _slot_complete_cb, rng); + + /* Apply config */ + uwb_mac_config(udev, NULL); + uwb_txrf_config(udev, &udev->config.txrf); + + if ((udev->role & UWB_ROLE_ANCHOR)) { + printf("Node role: ANCHOR \n"); + udev->my_short_address = ANCHOR_ADDRESS; + uwb_set_uid(udev, udev->my_short_address); + /* anchor starts listening by default */ + _ranging_enabled_flag = 1; + } + else { + _ranging_enabled_flag = 0; + printf("Node role: TAG \n"); + } + + /* define buffer to be used by the shell */ + char line_buf[SHELL_DEFAULT_BUFSIZE]; + shell_run(shell_commands, line_buf, SHELL_DEFAULT_BUFSIZE); +} diff --git a/examples/twr_aloha/control.h b/examples/twr_aloha/control.h new file mode 100644 index 0000000000..2c3e467d91 --- /dev/null +++ b/examples/twr_aloha/control.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2020 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup examples + * @{ + * + * @file + * + * @author Francisco Molina + * + * @} + */ + + +#ifndef CONTROL_H +#define CONTROL_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "timex.h" + +/** + * @brief Anchor address + */ +#ifndef ANCHOR_ADDRESS +#define ANCHOR_ADDRESS 0x1234 +#endif + +/** + * @brief Range request period + */ +#ifndef RANGE_REQUEST_T_US +#define RANGE_REQUEST_T_US (40 * US_PER_MS) +#endif + +/** + * @brief Starts ranging + */ +void init_ranging(void); + +#ifdef __cplusplus +} +#endif + +#endif /* CONTROL_H */ diff --git a/examples/twr_aloha/main.c b/examples/twr_aloha/main.c new file mode 100644 index 0000000000..cb549a4b98 --- /dev/null +++ b/examples/twr_aloha/main.c @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2020 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup examples + * @{ + * + * @file + * @brief Two way ranging example + * + * @author Francisco Molina + * + * @} + */ + +#include + +#include "control.h" + +int main(void) +{ + puts("pkg uwb-dw1000 + uwb-core test application"); + /* this should start ranging... */ + init_ranging(); + return 1; +}