From 3622c2da07ccf67e0e690e65189ff9126987bb0b Mon Sep 17 00:00:00 2001 From: Francisco Molina Date: Fri, 14 Aug 2020 15:50:26 +0200 Subject: [PATCH] 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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