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 0000000000..0af7be3d93 Binary files /dev/null and b/pkg/uwb-core/patches/0001-uwb-uwb.c-use-RIOT-specific-uwb_dev_idx_lookup.patch differ 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 0000000000..9877337b9f Binary files /dev/null and b/pkg/uwb-core/patches/0002-lib-twr_-enable-stats-optionally.patch differ 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 0000000000..774f3d5191 Binary files /dev/null and b/pkg/uwb-core/patches/0003-lib-tofdb-use-DPL_ENOENT-instead-of-OS_ENOENT.patch differ 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 0000000000..a2d71e5d61 Binary files /dev/null and b/pkg/uwb-core/patches/0004-sys-uwbcfg-use-DPL_ENOENT-instead-of-OS_ENOENT.patch differ 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 0000000000..a9388932ad Binary files /dev/null and b/pkg/uwb-core/patches/0005-treewide-use-dpl_log.h-instaed-of-log.h-to-avoid-con.patch differ 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 0000000000..a6c242b808 Binary files /dev/null and b/pkg/uwb-core/patches/0006-lib-json-src-use-fmt-to-avoid-newlib-issue.patch differ diff --git a/pkg/uwb-core/patches/0007-lib-uwb_rng-always-set-rssi-to-vrssi-0.patch b/pkg/uwb-core/patches/0007-lib-uwb_rng-always-set-rssi-to-vrssi-0.patch new file mode 100644 index 0000000000..9277b171f4 Binary files /dev/null and b/pkg/uwb-core/patches/0007-lib-uwb_rng-always-set-rssi-to-vrssi-0.patch differ 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 0000000000..300f04078b Binary files /dev/null and b/pkg/uwb-core/patches/0008-porting-dpl-add-riot-files.patch differ diff --git a/sys/auto_init/auto_init.c b/sys/auto_init/auto_init.c index 7859c4f004..c24c0d4209 100644 --- a/sys/auto_init/auto_init.c +++ b/sys/auto_init/auto_init.c @@ -113,6 +113,11 @@ void auto_init(void) extern void openwsn_bootstrap(void); openwsn_bootstrap(); } + if (IS_USED(MODULE_AUTO_INIT_UWB_CORE)) { + LOG_DEBUG("Bootstrapping uwb core.\n"); + extern void uwb_core_init(void); + uwb_core_init(); + } if (IS_USED(MODULE_GCOAP) && !IS_ACTIVE(CONFIG_GCOAP_NO_AUTO_INIT)) { LOG_DEBUG("Auto init gcoap.\n");