diff --git a/pkg/uwb-dw1000/Makefile b/pkg/uwb-dw1000/Makefile new file mode 100644 index 0000000000..1635ceaec4 --- /dev/null +++ b/pkg/uwb-dw1000/Makefile @@ -0,0 +1,26 @@ +PKG_NAME=uwb-dw1000 +PKG_URL=https://github.com/Decawave/uwb-dw1000/ +PKG_VERSION=6eaa85e6d429450d19a6ddeb2de05303016c0dd2 +PKG_LICENSE=Apache-2.0 + +include $(RIOTBASE)/pkg/pkg.mk + +CFLAGS += -Wno-address-of-packed-member +CFLAGS += -Wno-enum-conversion +CFLAGS += -Wno-maybe-uninitialized +CFLAGS += -Wno-missing-braces +CFLAGS += -Wno-missing-declarations +CFLAGS += -Wno-sign-compare +CFLAGS += -Wno-return-type +CFLAGS += -Wno-unused-but-set-variable +CFLAGS += -Wno-unused-function +CFLAGS += -Wno-unused-parameter +CFLAGS += -Wno-unused-variable +CFLAGS += -fms-extensions + +ifneq (,$(filter llvm,$(TOOLCHAIN))) + CFLAGS += -Wno-microsoft-anon-tag +endif + +all: + "$(MAKE)" -C $(PKG_SOURCE_DIR)/hw/drivers/uwb/uwb_dw1000/src -f $(RIOTPKG)/uwb-dw1000/uwb-dw1000.mk MODULE=uwb-dw1000 diff --git a/pkg/uwb-dw1000/Makefile.dep b/pkg/uwb-dw1000/Makefile.dep new file mode 100644 index 0000000000..b64241bd0b --- /dev/null +++ b/pkg/uwb-dw1000/Makefile.dep @@ -0,0 +1,13 @@ +USEMODULE += uwb-dw1000_hal +DEFAULT_MODULE += auto_init_uwb-dw1000 + +USEMODULE += xtimer + +FEATURES_REQUIRED += periph_gpio_irq +FEATURES_REQUIRED += periph_spi + +# Some of the pkg operation would overflow on 16bit +FEATURES_REQUIRED += arch_32bit + +# LLVM ARM shows issues with missing definitions for stdatomic +TOOLCHAINS_BLACKLIST += llvm diff --git a/pkg/uwb-dw1000/Makefile.include b/pkg/uwb-dw1000/Makefile.include new file mode 100644 index 0000000000..f34b7a9ab3 --- /dev/null +++ b/pkg/uwb-dw1000/Makefile.include @@ -0,0 +1,5 @@ +INCLUDES += -I$(PKGDIRBASE)/uwb-dw1000/hw/drivers/uwb/uwb_dw1000/include \ + -I$(RIOTPKG)/uwb-dw1000/include \ + # + +DIRS += $(RIOTPKG)/uwb-dw1000/hal diff --git a/pkg/uwb-dw1000/README.md b/pkg/uwb-dw1000/README.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/pkg/uwb-dw1000/doc.txt b/pkg/uwb-dw1000/doc.txt new file mode 100644 index 0000000000..d54f7da58b --- /dev/null +++ b/pkg/uwb-dw1000/doc.txt @@ -0,0 +1,41 @@ +/** + * @defgroup pkg_uwb_dw1000 Driver implementation for the uwb-core driver for Decawave DW1000 transceiver + * @ingroup pkg + * @brief uwb-core driver for Decawave DW1000 transceiver + * @see https://github.com/Decawave/uwb-dw1000 + */ + +# Decawave uwb-dw1000 RIOT Port + +The distribution https://github.com/decawave/uwb-core contains the +device driver implementation for the Decawave Impulse Radio-Ultra +Wideband (IR-UWB) transceiver(s). The driver includes hardware abstraction +layers (HAL), media access control (MAC) layer, Ranging Services (RNG). + +## Abstraction details + +uwb-dw1000 is meant as a hardware and architecture agnostic driver. It +was developed with MyNewt as its default OS, but its abstractions are +well defined which makes it easy to use with another OS. + +A porting layer DPL (Decawave Porting Layer) has been implemented that +wraps around OS functionalities and modules: mutex, semaphores, threads, +etc.. In most cases the mapping is direct although some specific +functionalities might not be supported. This layer is found in the uwb-core +pkg. + +A hardware abstraction layer is defined under `hal` which wraps around +modules such as: periph_gpio, periph_spi, etc. + +Since the library was used on top of mynewt most configuration values +are prefixed with `MYNEWT_VAL_%`, all configurations can be found under +`pkg/uwb-dw1000/include/syscfg`. + +## Todos + +The uwb-dw1000 can be used to provide a netdev driver for the dw1000 +module. + +uwb-dw1000 repository uses fixed length arrays to keep track of the +devices that are present. This port uses linked list but some of the +upstream code is not compatible with this. diff --git a/pkg/uwb-dw1000/hal/Makefile b/pkg/uwb-dw1000/hal/Makefile new file mode 100644 index 0000000000..0cf360bd67 --- /dev/null +++ b/pkg/uwb-dw1000/hal/Makefile @@ -0,0 +1,3 @@ +MODULE = uwb-dw1000_hal + +include $(RIOTBASE)/Makefile.base diff --git a/pkg/uwb-dw1000/hal/uwb_dw1000.c b/pkg/uwb-dw1000/hal/uwb_dw1000.c new file mode 100644 index 0000000000..db6e5e64d2 --- /dev/null +++ b/pkg/uwb-dw1000/hal/uwb_dw1000.c @@ -0,0 +1,170 @@ +/* + * Copyright (C) 2020 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup pkg_uwb_dw1000 + * @{ + * + * @file + * @brief Glue code for running uwb-core for RIOT + * + * @author Francisco Molina + * @} + */ + +#include "dpl/dpl.h" +#include "dw1000/dw1000_phy.h" +#include "dw1000/dw1000_hal.h" +#include "uwb_dw1000.h" +#include "uwb_dw1000_config.h" + +#include "uwb/uwb.h" +#include "uwb/uwb_mac.h" + +#include "utlist.h" +#include "thread.h" + +#ifndef LOG_LEVEL +#define LOG_LEVEL LOG_NONE +#endif +#include "log.h" + + +#ifndef DW1000_THREAD_PRIORITY +#define DW1000_THREAD_PRIORITY MYNEWT_VAL_UWB_DEV_TASK_PRIO +#endif + +/* Link list head */ +static struct _dw1000_dev_instance_t * dw1000_instance_head; + +/* Default instance configuration */ +static const dw1000_dev_instance_t dw1000_instance_config_default = { + .uwb_dev = { + .idx = 0, + .role = DW1000_ROLE_DEFAULT, + .task_prio = DW1000_THREAD_PRIORITY, + .status = {0}, + .rx_ant_separation = DW1000_RX_ANTSEP_DEFAULT, + .attrib = { + .nsfd = DW1000_NSFD_DEFAULT, + .nsync = DW1000_NSYNC_DEFAULT, + .nphr = DW1000_NPHR_DEFAULT , + }, + .config = { + .channel = DW1000_CHANNEL_DEFAULT, + .prf = DW1000_PRF_DEFAULT, + .dataRate = DW1000_DATARATE_DEFAULT, + .rx = { + .pacLength = DW1000_PACLEN_DEFAULT, + .preambleCodeIndex = DW1000_RX_PREAM_CIDX_DEFAULT, + .sfdType = DW1000_RX_SFD_TYPE_DEFAULT, + .phrMode = DW1000_RX_PHR_MODE_DEFAULT, + .sfdTimeout = DW1000_RX_SFD_TO_DEFAULT, + .timeToRxStable = DW1000_RX_STABLE_TIME_US , + .frameFilter = DW1000_FRAME_FILTER_DEFAULT, + .xtalTrim = DW1000_XTAL_TRIM_DEFAULT, + }, + .tx ={ + .preambleCodeIndex = DW1000_TX_PREAM_CIDX_DEAULT, + .preambleLength = DW1000_TX_PREAM_LEN_DEFAULT, + }, + .txrf={ + .PGdly = DW1000_CHANNEL_DEFAULT, + .BOOSTNORM = dw1000_power_value(DW1000_txrf_config_9db, 2.5), + .BOOSTP500 = dw1000_power_value(DW1000_txrf_config_9db, 2.5), + .BOOSTP250 = dw1000_power_value(DW1000_txrf_config_9db, 2.5), + .BOOSTP125 = dw1000_power_value(DW1000_txrf_config_9db, 2.5) + }, + .trxoff_enable = DW1000_TRXOFF_ENABLE, + .rxdiag_enable = DW1000_RX_DIAGNOSTIC, + .dblbuffon_enabled = DW1000_DOUBLE_BUFFER_ENABLE, + .LDE_enable = DW1000_LDE_ENABLE, + .LDO_enable = DW1000_LDO_ENABLE, + .sleep_enable = DW1000_SLEEP_ENABLE, + .wakeup_rx_enable = DW1000_WAKEUP_RX_ENABLE, + .rxauto_enable = DW1000_RX_AUTO_ENABLE, + .cir_enable = 0, /**< Default behavior for CIR interface */ + .cir_pdoa_slave = 0, /**< First instance should not act as pdoa slave */ + .blocking_spi_transfers = 1, /**< Nonblocking spi transfers are not supported */ + }, + } +}; + +void _uwb_dw1000_set_idx(dw1000_dev_instance_t* dev) +{ + int count = 0; + dw1000_dev_instance_t *elt = NULL; + LL_COUNT(dw1000_instance_head, elt, count); + dev->uwb_dev.idx = count++; + /* prepend to list */ + LL_PREPEND(dw1000_instance_head, dev); +} + +void uwb_dw1000_setup(dw1000_dev_instance_t* dev, dw1000_params_t* params) +{ + /* set semaphore */ + dpl_sem_init(params->spi_sem, 0x1); + /* set default uwb config */ + memcpy(dev, &dw1000_instance_config_default, + sizeof(dw1000_dev_instance_t)); + /* set uwb_dev idx */ + _uwb_dw1000_set_idx(dev); + /* this will set the configuration and init uwb_dev which ATM only + allocates an RX and TX buffer if none is yet available */ + dw1000_dev_init((struct os_dev *) dev, (void *) params); +} + +void uwb_dw1000_config_and_start(dw1000_dev_instance_t* dev) +{ + dw1000_dev_config(dev); +} + +void uwb_dw1000_set_buffs(dw1000_dev_instance_t* dev, uint8_t* tx_buf, + uint8_t* rx_buf) +{ + dev->uwb_dev.rxbuf = rx_buf; + dev->uwb_dev.txbuf = tx_buf; +} + +void uwb_dw1000_init(void) +{ + dw1000_instance_head = NULL; +} + +struct uwb_dev* uwb_dev_idx_lookup(int idx) +{ + dw1000_dev_instance_t *current = dw1000_instance_head; + + while (current) { + if (current->uwb_dev.idx == idx) { + LOG_DEBUG("uwb_dev: found dev of idx %d\n", idx); + break; + } + current = current->next; + } + + return (struct uwb_dev*) ¤t->uwb_dev; +} + +/** + * API to choose DW1000 instances based on parameters. + * + * @param idx Indicates number of instances for the chosen bsp. + * @return dw1000_dev_instance_t + */ + +struct _dw1000_dev_instance_t * hal_dw1000_inst(uint8_t idx) +{ + dw1000_dev_instance_t *current = dw1000_instance_head; + + for (uint8_t i = 0; i < idx; i++) { + current = current->next; + } + + return current; +} diff --git a/pkg/uwb-dw1000/hal/uwb_dw1000_spi.c b/pkg/uwb-dw1000/hal/uwb_dw1000_spi.c new file mode 100644 index 0000000000..be8bc8833d --- /dev/null +++ b/pkg/uwb-dw1000/hal/uwb_dw1000_spi.c @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2020 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup pkg_uwb_dw1000 + * @{ + * + * @file + * @brief SPI abstraction layer implementation + * + * @author Francisco Molina + * @} + */ + +#include "hal/hal_spi.h" +#include "periph/spi.h" + +static uint32_t spi_clk[SPI_NUMOF] = { SPI_CLK_1MHZ }; +static uint32_t spi_mode[SPI_NUMOF] = { SPI_MODE_0 }; + +int hal_spi_set_txrx_cb(int spi_num, hal_spi_txrx_cb txrx_cb, void *arg) +{ + (void) txrx_cb; + (void) spi_num; + (void) arg; + return 0; +} + +int hal_spi_init(int spi_num, void *cfg, uint8_t spi_type) +{ + (void) cfg; + (void) spi_type; + spi_init(spi_num); + return 0; +} + +int hal_spi_config(int spi_num, struct hal_spi_settings *settings) +{ + spi_clk[spi_num] = settings->baudrate; + spi_mode[spi_num] = settings->data_mode; + return 0; +} + +int hal_spi_enable(int spi_num) +{ + (void) spi_num; + return 0; +} + +int hal_spi_disable(int spi_num) +{ + (void) spi_num; + return 0; +} + +int hal_spi_txrx(int spi_num, void *txbuf, void *rxbuf, int cnt) +{ + spi_acquire(spi_num, + SPI_CS_UNDEF, + spi_mode[spi_num], + spi_clk[spi_num]); + + spi_transfer_bytes(spi_num, + SPI_CS_UNDEF, + false, + txbuf, + rxbuf, + cnt); + + spi_release(spi_num); + return 0; +} + +int hal_spi_txrx_noblock(int spi_num, void *txbuf, void *rxbuf, int cnt) +{ + (void) spi_num; + (void) txbuf; + (void) rxbuf; + (void) cnt; + return 0; +} + +int hal_spi_deinit(int spi_num) +{ + (void) spi_num; + return 0; +} diff --git a/pkg/uwb-dw1000/include/hal/hal_gpio.h b/pkg/uwb-dw1000/include/hal/hal_gpio.h new file mode 100644 index 0000000000..b09ba8beea --- /dev/null +++ b/pkg/uwb-dw1000/include/hal/hal_gpio.h @@ -0,0 +1,197 @@ +/* + * Copyright (C) 2020 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup pkg_uwb_dw1000 + * @{ + * + * @file + * @brief GPIO abstraction layer RIOT adaption + * + * @author Francisco Molina + * @} + */ + +#ifndef HAL_HAL_GPIO_H +#define HAL_HAL_GPIO_H + +#include "periph/gpio.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Map hal_gpio_pull_t enum types to gpio_mode_t enum types + */ +enum { + /** Pull-up/down not enabled */ + HAL_GPIO_PULL_NONE = GPIO_IN, + /** Pull-up enabled */ + HAL_GPIO_PULL_UP = GPIO_IN_PU, + /** Pull-down enabled */ + HAL_GPIO_PULL_DOWN = GPIO_IN_PD +}; +/** + * @brief hal_gpio_pull type + */ +typedef gpio_mode_t hal_gpio_pull_t; + +/** + * @brief Map hal_gpio_irq_trig_t enum types to gpio_flank_t enum types + */ +enum { +#ifdef GPIO_NONE + HAL_GPIO_TRIG_NONE = GPIO_NONE, +#endif + /** IRQ occurs on rising edge */ + HAL_GPIO_TRIG_RISING = GPIO_RISING, + /** IRQ occurs on falling edge */ + HAL_GPIO_TRIG_FALLING = GPIO_FALLING, + /** IRQ occurs on either edge */ + HAL_GPIO_TRIG_BOTH = GPIO_BOTH, + /** IRQ occurs when line is low */ +#ifdef GPIO_LOW + HAL_GPIO_TRIG_LOW = GPIO_LOW, +#endif + /** IRQ occurs when line is high */ +#ifdef GPIO_HIGH + HAL_GPIO_TRIG_HIGH = GPIO_HIGH +#endif +}; +/** + * @brief hal_gpio_irq_trig type + */ +typedef gpio_flank_t hal_gpio_irq_trig_t; + +/** + * @brief Function proto for GPIO irq handler functions + */ +typedef gpio_cb_t hal_gpio_irq_handler_t; + +/** + * Initializes the specified pin as an input + * + * @param pin Pin number to set as input + * @param pull pull type + * + * @return int 0: no error; -1 otherwise. + */ +static inline int hal_gpio_init_in(gpio_t pin, hal_gpio_pull_t pull) +{ + return gpio_init(pin, pull); +} + +/** + * Initialize the specified pin as an output, setting the pin to the specified + * value. + * + * @param pin Pin number to set as output + * @param val Value to set pin + * + * @return int 0: no error; -1 otherwise. + */ +static inline int hal_gpio_init_out(gpio_t pin, int val) +{ + int res = gpio_init(pin, GPIO_OUT); + gpio_write(pin, val); + return res; +} + +/** + * Write a value (either high or low) to the specified pin. + * + * @param pin Pin to set + * @param val Value to set pin (0:low 1:high) + */ +static inline void hal_gpio_write(gpio_t pin, int val) +{ + gpio_write(pin, val); +} + +/** + * Reads the specified pin. + * + * @param pin Pin number to read + * + * @return int 0: low, 1: high + */ +static inline int hal_gpio_read(gpio_t pin) +{ + return gpio_read(pin); +} + +/** + * Toggles the specified pin + * + * @param pin Pin number to toggle + * + * @return current gpio state int 0: low, 1: high + */ +static inline int hal_gpio_toggle(gpio_t pin) +{ + gpio_toggle(pin); + return gpio_read(pin); +} + +/** + * Initialize a given pin to trigger a GPIO IRQ callback. + * + * @param pin The pin to trigger GPIO interrupt on + * @param handler The handler function to call + * @param arg The argument to provide to the IRQ handler + * @param trig The trigger mode (e.g. rising, falling) + * @param pull The mode of the pin (e.g. pullup, pulldown) + * + * @return 0 on success, non-zero error code on failure. + */ +static inline int hal_gpio_irq_init(gpio_t pin, + hal_gpio_irq_handler_t handler, + void *arg, + hal_gpio_irq_trig_t trig, + hal_gpio_pull_t pull) +{ + return gpio_init_int(pin, pull, trig, handler, arg); +} + +/** + * Release a pin from being configured to trigger IRQ on state change. + * + * @param pin The pin to release + */ +static inline void hal_gpio_irq_release(gpio_t pin) +{ + /* can't release the interrupt so ar least disable it */ + gpio_irq_disable(pin); +} + +/** + * Enable IRQs on the passed pin + * + * @param pin The pin to enable IRQs on + */ +static inline void hal_gpio_irq_enable(gpio_t pin) +{ + gpio_irq_enable(pin); +} + +/** + * Disable IRQs on the passed pin + * + * @param pin The pin to disable IRQs on + */ +static inline void hal_gpio_irq_disable(gpio_t pin) +{ + gpio_irq_disable(pin); +} + +#ifdef __cplusplus +} +#endif + +#endif /* HAL_HAL_GPIO_H */ diff --git a/pkg/uwb-dw1000/include/hal/hal_spi.h b/pkg/uwb-dw1000/include/hal/hal_spi.h new file mode 100644 index 0000000000..da13747bb1 --- /dev/null +++ b/pkg/uwb-dw1000/include/hal/hal_spi.h @@ -0,0 +1,169 @@ +/* + * Copyright (C) 2020 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup pkg_uwb_dw1000 + * @{ + * + * @file + * @brief SPI abstraction layer RIOT adaption + * + * @author Francisco Molina + * @} + */ + +#ifndef HAL_HAL_SPI_H +#define HAL_HAL_SPI_H + +#include "periph/spi.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** SPI mode 0 */ +#define HAL_SPI_MODE0 (SPI_MODE_0) +/** SPI mode 1 */ +#define HAL_SPI_MODE1 (SPI_MODE_1) +/** SPI mode 2 */ +#define HAL_SPI_MODE2 (SPI_MODE_2) +/** SPI mode 3 */ +#define HAL_SPI_MODE3 (SPI_MODE_3) + +/** + * @brief Prototype for tx/rx callback + */ +typedef void (*hal_spi_txrx_cb)(void *arg, int len); + +/** + * @brief since one spi device can control multiple devices, some configuration + * can be changed on the fly from the hal + */ +struct hal_spi_settings { + /** Data mode of SPI driver, defined by HAL_SPI_MODEn */ + spi_mode_t data_mode; + /** Baudrate in kHz */ + spi_clk_t baudrate; +}; + +/** + * @brief Configure the spi. Must be called after the spi is initialized (after + * hal_spi_init is called) and when the spi is disabled (user must call + * hal_spi_disable if the spi has been enabled through hal_spi_enable prior + * to calling this function). Can also be used to reconfigure an initialized + * SPI (assuming it is disabled as described previously). + * + * @param spi_num The number of the SPI to configure. + * @param psettings The settings to configure this SPI with + * + * @return int 0 on success, non-zero error code on failure. + */ +int hal_spi_config(int spi_num, struct hal_spi_settings *psettings); + +/** + * @brief Sets the txrx callback (executed at interrupt context) when the + * buffer is transferred by the master or the slave using the non-blocking API. + * Cannot be called when the spi is enabled. This callback will also be called + * when chip select is de-asserted on the slave. + * + * NOTE: This callback is only used for the non-blocking interface and must + * be called prior to using the non-blocking API. + * + * @param spi_num SPI interface on which to set callback + * @param txrx_cb Callback function + * @param arg Argument to be passed to callback function + * + * @return int 0 on success, non-zero error code on failure. + */ +int hal_spi_set_txrx_cb(int spi_num, hal_spi_txrx_cb txrx_cb, void *arg); + +/** + * @brief Enables the SPI. This does not start a transmit or receive operation; + * it is used for power mgmt. Cannot be called when a SPI transfer is in + * progress. + * + * @param spi_num + * + * @return int 0 on success, non-zero error code on failure. + */ +int hal_spi_enable(int spi_num); + +/** + * @brief Disables the SPI. Used for power mgmt. It will halt any current SPI transfers + * in progress. + * + * @param spi_num + * + * @return int 0 on success, non-zero error code on failure. + */ +int hal_spi_disable(int spi_num); + +/** + * @brief Blocking interface to send a buffer and store the received values from the + * slave. The transmit and receive buffers are either arrays of 8-bit (uint8_t) + * values or 16-bit values depending on whether the spi is configured for 8 bit + * data or more than 8 bits per value. The 'cnt' parameter is the number of + * 8-bit or 16-bit values. Thus, if 'cnt' is 10, txbuf/rxbuf would point to an + * array of size 10 (in bytes) if the SPI is using 8-bit data; otherwise + * txbuf/rxbuf would point to an array of size 20 bytes (ten, uint16_t values). + * + * NOTE: these buffers are in the native endian-ness of the platform. + * + * MASTER: master sends all the values in the buffer and stores the + * stores the values in the receive buffer if rxbuf is not NULL. + * The txbuf parameter cannot be NULL. + * SLAVE: cannot be called for a slave; returns -1 + * + * @param spi_num SPI interface to use + * @param txbuf Pointer to buffer where values to transmit are stored. + * @param rxbuf Pointer to buffer to store values received from peer. + * @param cnt Number of 8-bit or 16-bit values to be transferred. + * + * @return int 0 on success, non-zero error code on failure. + */ +int hal_spi_txrx(int spi_num, void *txbuf, void *rxbuf, int cnt); + +/** + * @brief Non-blocking interface to send a buffer and store received values. Can be + * used for both master and slave SPI types. The user must configure the + * callback (using hal_spi_set_txrx_cb); the txrx callback is executed at + * interrupt context when the buffer is sent. + * + * The transmit and receive buffers are either arrays of 8-bit (uint8_t) + * values or 16-bit values depending on whether the spi is configured for 8 bit + * data or more than 8 bits per value. The 'cnt' parameter is the number of + * 8-bit or 16-bit values. Thus, if 'cnt' is 10, txbuf/rxbuf would point to an + * array of size 10 (in bytes) if the SPI is using 8-bit data; otherwise + * txbuf/rxbuf would point to an array of size 20 bytes (ten, uint16_t values). + * + * NOTE: these buffers are in the native endian-ness of the platform. + * + * MASTER: master sends all the values in the buffer and stores the + * stores the values in the receive buffer if rxbuf is not NULL. + * The txbuf parameter cannot be NULL + * SLAVE: Slave "preloads" the data to be sent to the master (values + * stored in txbuf) and places received data from master in rxbuf + * (if not NULL). The txrx callback occurs when len values are + * transferred or master de-asserts chip select. If txbuf is NULL, + * the slave transfers its default byte. Both rxbuf and txbuf cannot + * be NULL. + * + * @param spi_num SPI interface to use + * @param txbuf Pointer to buffer where values to transmit are stored. + * @param rxbuf Pointer to buffer to store values received from peer. + * @param cnt Number of 8-bit or 16-bit values to be transferred. + * + * @return int 0 on success, non-zero error code on failure. + */ +int hal_spi_txrx_noblock(int spi_num, void *txbuf, void *rxbuf, int cnt); + +#ifdef __cplusplus +} +#endif + +#endif /* HAL_HAL_SPI_H */ diff --git a/pkg/uwb-dw1000/include/hal/hal_timer.h b/pkg/uwb-dw1000/include/hal/hal_timer.h new file mode 100644 index 0000000000..a3b72c3bb5 --- /dev/null +++ b/pkg/uwb-dw1000/include/hal/hal_timer.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2020 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup pkg_uwb_dw1000 + * @{ + * + * @file + * @brief Timer abstraction layer RIOT adaption + * + * @author Francisco Molina + * @} + */ + +#ifndef HAL_HAL_TIMER_H +#define HAL_HAL_TIMER_H + +#include "xtimer.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief HAL timer callback + */ +typedef xtimer_callback_t hal_timer_cb; + +/** + * @brief The HAL timer structure. + */ +struct hal_timer { + xtimer_t timer; /**< the timer */ +}; + +#ifdef __cplusplus +} +#endif + +#endif /* HAL_HAL_TIMER_H */ diff --git a/pkg/uwb-dw1000/include/syscfg_uwb_dw1000.h b/pkg/uwb-dw1000/include/syscfg_uwb_dw1000.h new file mode 100644 index 0000000000..7e62e91bf1 --- /dev/null +++ b/pkg/uwb-dw1000/include/syscfg_uwb_dw1000.h @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2020 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup pkg_uwb_core + * @{ + * + * @file + * @brief uwb-dw1000 module configurations + * taken from decawave-uwb-dw1000/hw/drivers/uwb/uwb_dw1000 + * + * @author Francisco Molina + * @} + */ + +#ifndef SYSCFG_UWB_DW1000_H +#define SYSCFG_UWB_DW1000_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Used to check that the UWB_DEV has been setup correctly + * at compile time. + * @note (UWB_DEV_RXDIAG_MAXLEN > 19) + */ +#ifndef MYNEWT_VAL_UWB_DW1000_API_CHECKS +#define MYNEWT_VAL_UWB_DW1000_API_CHECKS (1) +#endif + +/** + * @brief Size of spi read/write buffer, sets the + * maximum allowed nonblocking read operation + */ +#ifndef MYNEWT_VAL_DW1000_HAL_SPI_BUFFER_SIZE +#define MYNEWT_VAL_DW1000_HAL_SPI_BUFFER_SIZE (256) +#endif + +/** + * @brief The maximum number of bytes in a single transfer that the + * SPI hardware supports. + * + * @note RIOT spi implementation will take care of splitting if this max + * value is exceeded. If asynchronous (non-blocking) spi is ever + * added to RIOT this value will need to be adapted to the platform + * specific value. + */ +#ifndef MYNEWT_VAL_DW1000_HAL_SPI_MAX_CNT +#define MYNEWT_VAL_DW1000_HAL_SPI_MAX_CNT (1024) +#endif + +/** + * @brief Max size spi read in bytes that is always done with blocking io. + * Reads longer than this value will be done with non-blocking io. + * @note Ignore in RIOT since non-blocking SPI is not yet enabled + */ +#ifndef MYNEWT_VAL_DW1000_DEVICE_SPI_RD_MAX_NOBLOCK +#define MYNEWT_VAL_DW1000_DEVICE_SPI_RD_MAX_NOBLOCK (9) +#endif + +/** + * @brief Enable range bias correction polynomial + */ +#ifndef MYNEWT_VAL_DW1000_BIAS_CORRECTION_ENABLED +#define MYNEWT_VAL_DW1000_BIAS_CORRECTION_ENABLED (0) +#endif + +/** + * @brief Tx Power dBm + */ +#ifndef MYNEWT_VAL_DW1000_DEVICE_TX_PWR +#define MYNEWT_VAL_DW1000_DEVICE_TX_PWR (((float)-14.3f)) +#endif + +/** + * @brief Antenna Gain dB + */ +#ifndef MYNEWT_VAL_DW1000_DEVICE_ANT_GAIN +#define MYNEWT_VAL_DW1000_DEVICE_ANT_GAIN (((float)1.0f)) +#endif + +/** + * @brief Enable showing rx and tx activity on leds + */ +#ifndef MYNEWT_VAL_DW1000_RXTX_LEDS +#define MYNEWT_VAL_DW1000_RXTX_LEDS (1) +#endif + +/** + * @brief Enable showing rx and tx activity on gpios + */ +#ifndef MYNEWT_VAL_DW1000_RXTX_GPIO +#define MYNEWT_VAL_DW1000_RXTX_GPIO (0) +#endif + +/** + * @brief Toggle LED_1 for every range packet received + */ +#ifndef MYNEWT_VAL_DW1000_RNG_INDICATE_LED +#define MYNEWT_VAL_DW1000_RNG_INDICATE_LED (0) +#endif + +/** + * @brief Expose event counter cli api + */ +#ifndef MYNEWT_VAL_DW1000_CLI_EVENT_COUNTERS +#define MYNEWT_VAL_DW1000_CLI_EVENT_COUNTERS (0) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* SYSCFG_UWB_DW1000_H */ diff --git a/pkg/uwb-dw1000/include/uwb_dw1000.h b/pkg/uwb-dw1000/include/uwb_dw1000.h new file mode 100644 index 0000000000..e63d26b9b6 --- /dev/null +++ b/pkg/uwb-dw1000/include/uwb_dw1000.h @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2020 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup pkg_uwb_dw1000 + * + * @{ + * + * @file + * @brief Abstraction layer for RIOT adaption + * + * @author Francisco Molina + * @} + */ +#ifndef UWB_DW1000_H +#define UWB_DW1000_H + +#include + +#include "dw1000/dw1000_dev.h" +#include "dw1000/dw1000_hal.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Device initialization parameters + */ +typedef struct dw1000_dev_cfg dw1000_params_t; + +/** + * @brief Device descriptor for the driver + */ +typedef struct { + dw1000_dev_instance_t dev; /**< dwDevice parent struct */ +} uwb_dw1000_t; + +/** + * @brief Sets device linked list to 0, not really needed... + */ +void uwb_dw1000_init(void); + +/** + * @brief Sets the tx and rx buffer for the uwb_dev in the dw1000 instance + * + * @note If this is not set before uwb_dw1000_setup() is called then + * the buffers will be dynamically allocated. + * + * @param[in] dev dw1000 device instance pointer + * @param[in] tx_buf transmit buffer + * @param[in] rx_buf receive buffer + */ +void uwb_dw1000_set_buffs(dw1000_dev_instance_t* dev, uint8_t* tx_buf, + uint8_t* rx_buf); + +/** + * @brief Setup a dw1000 device + * + * This will setup the dw1000 dev instance and the uwb_dev instance within. + * + * @param[out] dev dw1000 device descriptor + * @param[in] params receive buffer + */ +void uwb_dw1000_setup(dw1000_dev_instance_t* dev, dw1000_params_t* params); + +/** + * @brief Configure and start the dw1000 + * + * This will wakeup and setup the dw1000 device, configure the mac and + * phy. Setting up the mac will also call dw1000_tasks_init() that will + * handle the device interrupts. + * + * @param[out] dev dw1000 device descriptor + */ +void uwb_dw1000_config_and_start(dw1000_dev_instance_t* dev); + +#ifdef __cplusplus +} +#endif + +#endif /* UWB_DW1000_H */ diff --git a/pkg/uwb-dw1000/include/uwb_dw1000_config.h b/pkg/uwb-dw1000/include/uwb_dw1000_config.h new file mode 100644 index 0000000000..40b1f01d9b --- /dev/null +++ b/pkg/uwb-dw1000/include/uwb_dw1000_config.h @@ -0,0 +1,263 @@ +/* + * Copyright (C) 2020 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup pkg_uwb_core + * @{ + * + * @file + * @brief uwb-dw1000 radio configurations + * + * @author Francisco Molina + * @} + */ + +#ifndef UWB_DW1000_CONFIG_H +#define UWB_DW1000_CONFIG_H + +#include "dw1000/dw1000_regs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Default UWB Role + * + * - Tag "0x00" + * - Node "0x01" + * - Pan master "0x02" + * - Anchor "0x04" + * - Panmaster "0x07" + */ +#ifndef DW1000_ROLE_DEFAULT +#define DW1000_ROLE_DEFAULT 0x0 +#endif + +/** + * @brief Default Number of symbols in start of frame delimiter + */ +#ifndef DW1000_NSFD_DEFAULT +#define DW1000_NSFD_DEFAULT 8 +#endif + +/** + * @brief Default Number of symbols in preamble sequence + */ +#ifndef DW1000_NSYNC_DEFAULT +#define DW1000_NSYNC_DEFAULT 128 +#endif + +/** + * @brief Default Number of symbols in phy header + */ +#ifndef DW1000_NPHR_DEFAULT +#define DW1000_NPHR_DEFAULT 21 +#endif + + +/** + * @brief Default channel + */ +#ifndef DW1000_CHANNEL_DEFAULT +#define DW1000_CHANNEL_DEFAULT 5 +#if DW1000_CHANNEL_DEFAULT > 7 || DW1000_CHANNEL_DEFAULT < 1 +#error "DW1000_CHANNEL_DEFAULT must be 1..7" +#endif +#endif + +/** + * @brief Default Pulse generator delay + */ +#ifndef DW1000_TX_PGDELAY_DEFAULT +#if DW1000_CHANNEL_DEFAULT == 1 +#define DW1000_TX_PGDELAY_DEFAULT TC_PGDELAY_CH1 +#elif DW1000_CHANNEL_DEFAULT == 2 +#define DW1000_TX_PGDELAY_DEFAULT TC_PGDELAY_CH2 +#elif DW1000_CHANNEL_DEFAULT == 3 +#define DW1000_TX_PGDELAY_DEFAULT TC_PGDELAY_CH3 +#elif DW1000_CHANNEL_DEFAULT == 4 +#define DW1000_TX_PGDELAY_DEFAULT TC_PGDELAY_CH4 +#elif DW1000_CHANNEL_DEFAULT == 5 +#define DW1000_TX_PGDELAY_DEFAULT TC_PGDELAY_CH5 +#elif DW1000_CHANNEL_DEFAULT == 6 +#define DW1000_TX_PGDELAY_DEFAULT TC_PGDELAY_CH7 +#elif DW1000_CHANNEL_DEFAULT == 7 +#define DW1000_TX_PGDELAY_DEFAULT TC_PGDELAY_CH7 +#endif +#endif + +/** + * @brief Default UWB Pulse Repetition Frequency (MHz) + * + * - DWT_PRF_16M + * - DWT_PRF_64M + */ +#ifndef DW1000_PRF_DEFAULT +#define DW1000_PRF_DEFAULT DWT_PRF_64M +#endif + +/** + * @brief Default UWB Datarate (110k, 850k, 6m8) + * + * - DWT_BR_110K + * - DWT_BR_850K + * - DWT_BR_6M8 + */ +#ifndef DW1000_DATARATE_DEFAULT +#define DW1000_DATARATE_DEFAULT DWT_BR_6M8 +#endif + +/** + * @brief Default UWB Acquisition Chunk Size (Relates to RX preamble length) + * + * - 8 + * - 16 + * - 32 + * - 64 + */ +#ifndef DW1000_PACLEN_DEFAULT +#define DW1000_PACLEN_DEFAULT DWT_PAC8 +#endif + +/** + * @brief Default UWB RX Preamble Code Index + */ +#ifndef DW1000_RX_PREAM_CIDX_DEFAULT +#define DW1000_RX_PREAM_CIDX_DEFAULT 9 +#endif + +/** + * @brief Default UWB SFD Type + * + * - true: use non standard SFD for better performance + * - false: use standard SFD + */ +#ifndef DW1000_RX_SFD_TYPE_DEFAULT +#define DW1000_RX_SFD_TYPE_DEFAULT true +#endif + +/** + * @brief Default UWB SFD Timeout (-1=auto, timeout in symbols) + * + */ +#ifndef DW1000_RX_SFD_TO_DEFAULT +#define DW1000_RX_SFD_TO_DEFAULT (128 + 1 + 8 - 8) /* (preamble length + 1 + SFD length - PAC size) */ +#endif + +/** + * @brief Default UWB PHR Mode + * + * - 0x0 - standard DWT_PHRMODE_STD + * - 0x3 - extended frames DWT_PHRMODE_EXT + */ +#ifndef DW1000_RX_PHR_MODE_DEFAULT +#define DW1000_RX_PHR_MODE_DEFAULT DWT_PHRMODE_EXT +#endif + +/** + * @brief Enable RX Frame Quality diagnositics (rssi, fppl, etc.) + */ +#ifndef DW1000_RX_DIAGNOSTIC +#define DW1000_RX_DIAGNOSTIC 0 +#endif + + +/** + * @brief Default UWB RX Antenna separation distance in m + */ +#ifndef DW1000_TX_PREAM_CIDX_DEAULT +#define DW1000_TX_PREAM_CIDX_DEAULT 9 +#endif + +/** + * @brief Default UWB Preamble Length + * + * - DWT_PLEN_4096 : Standard preamble length 4096 symbols + * - DWT_PLEN_2048 : Non-standard preamble length 2048 symbols + * - DWT_PLEN_1536 : Non-standard preamble length 1536 symbols + * - DWT_PLEN_1024 : Standard preamble length 1024 symbols + * - DWT_PLEN_512 : Non-standard preamble length 512 symbols + * - DWT_PLEN_256 : Non-standard preamble length 256 symbols + * - DWT_PLEN_128 : Non-standard preamble length 128 symbols + * - DWT_PLEN_64 : Standard preamble length 64 symbols + * - DWT_PLEN_32 : When setting length 32 symbols this is 0x0, which is programmed to byte 2 of the TX_FCTRL register + * - DWT_PLEN_72 : Non-standard length 72 + */ +#ifndef DW1000_TX_PREAM_LEN_DEFAULT +#define DW1000_TX_PREAM_LEN_DEFAULT DWT_PLEN_128 +#endif + +/** + * @brief Default UWB RX Antenna separation distance in m + */ +#ifndef DW1000_RX_ANTSEP_DEFAULT +#define DW1000_RX_ANTSEP_DEFAULT 0.0205 +#endif + +/** + * @brief Default MAC FrameFilter (0x0000 = no filter) + */ +#ifndef DW1000_FRAME_FILTER_DEFAULT +#define DW1000_FRAME_FILTER_DEFAULT 0x0000 +#endif + +/** + * @brief Default MAC FrameFilter Crystal Trim value, 0xff == not set + */ +#ifndef DW1000_XTAL_TRIM_DEFAULT +#define DW1000_XTAL_TRIM_DEFAULT 0x10 +#endif + +/** + * @brief Time until the Receiver is stable, (in us) + */ +#ifndef DW1000_RX_STABLE_TIME_US +#define DW1000_RX_STABLE_TIME_US 6 +#endif + +/** + * @brief Enables forced TRXOFF in start_tx and start_tx interface + */ +#define DW1000_TRXOFF_ENABLE 1 + +/** + * @brief Enables double buffer + */ +#define DW1000_DOUBLE_BUFFER_ENABLE false + +/** + * @brief Load LDE microcode on wake up + */ +#define DW1000_LDE_ENABLE true + +/** + * @brief Load the LDO tune value on wake up + */ +#define DW1000_LDO_ENABLE false + +/** + * @brief Enable sleep + */ +#define DW1000_SLEEP_ENABLE true + +/** + * @brief Wakeup to Rx state + */ +#define DW1000_WAKEUP_RX_ENABLE true + +/** + * @brief On error re-enable + */ +#define DW1000_RX_AUTO_ENABLE true + +#ifdef __cplusplus +} +#endif + +#endif /* UWB_DW1000_CONFIG_H */ diff --git a/pkg/uwb-dw1000/include/uwb_dw1000_params.h b/pkg/uwb-dw1000/include/uwb_dw1000_params.h new file mode 100644 index 0000000000..11fc23ce67 --- /dev/null +++ b/pkg/uwb-dw1000/include/uwb_dw1000_params.h @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2020 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup pkg_uwb_dw1000 + * + * @{ + * @file + * @brief Default configuration + * + * @author Francisco Molina + */ + +#ifndef UWB_DW1000_PARAMS_H +#define UWB_DW1000_PARAMS_H + +#include "board.h" +#include "uwb_dw1000.h" +#include "dpl/dpl_sem.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @name Set default configuration parameters + * @{ + */ +#ifndef DW1000_SPI_SEM +static struct dpl_sem sem_spi; +#define DW1000_SPI_SEM &sem_spi +#endif +#ifndef DW1000_PARAM_SPI +#define DW1000_PARAM_SPI (SPI_DEV(1)) +#endif +#ifndef DW1000_PARAM_SPI_CLK_LOW +#define DW1000_PARAM_SPI_CLK_LOW (SPI_CLK_1MHZ) +#endif +#ifndef DW1000_PARAM_SPI_CLK_HIGH +#define DW1000_PARAM_SPI_CLK_HIGH (SPI_CLK_10MHZ) +#endif +#ifndef DW1000_SPI_MODE +#define DW1000_SPI_MODE (SPI_MODE_0) +#endif +#ifndef DW1000_PARAM_CS_PIN +#define DW1000_PARAM_CS_PIN (GPIO_PIN(0, 17)) +#endif +#ifndef DW1000_PARAM_IRQ_PIN +#define DW1000_PARAM_IRQ_PIN (GPIO_PIN(0, 19)) +#endif +#ifndef DW1000_PARAM_RESET_PIN +#define DW1000_PARAM_RESET_PIN (GPIO_PIN(0, 24)) +#endif +#ifndef DW1000_RX_ANTENNA_DELAY +#define DW1000_RX_ANTENNA_DELAY (0x4042) +#endif +#ifndef DW1000_TX_ANTENNA_DELAY +#define DW1000_TX_ANTENNA_DELAY (0x4042) +#endif +#ifndef DW1000_EXT_CLOCK_DELAY +#define DW1000_EXT_CLOCK_DELAY (0) +#endif + +#ifndef DW1000_PARAMS +#define DW1000_PARAMS { .spi_sem = DW1000_SPI_SEM, \ + .spi_baudrate = DW1000_PARAM_SPI_CLK_HIGH, \ + .spi_baudrate_low = DW1000_PARAM_SPI_CLK_LOW, \ + .spi_num = DW1000_PARAM_SPI, \ + .rst_pin = DW1000_PARAM_RESET_PIN, \ + .irq_pin = DW1000_PARAM_IRQ_PIN, \ + .ss_pin = DW1000_PARAM_CS_PIN, \ + .rx_antenna_delay = DW1000_RX_ANTENNA_DELAY, \ + .tx_antenna_delay = DW1000_TX_ANTENNA_DELAY, \ + .ext_clock_delay = DW1000_EXT_CLOCK_DELAY } +#endif +/**@}*/ + +/** + * @brief Configuration struct + */ +static const dw1000_params_t dw1000_params[] = +{ + DW1000_PARAMS +}; + +#ifdef __cplusplus +} +#endif + +#endif /* UWB_DW1000_PARAMS_H */ +/** @} */ diff --git a/pkg/uwb-dw1000/patches/0001-uwb_dw1000-include-dw1000-dw1000_dev-add-linked-list.patch b/pkg/uwb-dw1000/patches/0001-uwb_dw1000-include-dw1000-dw1000_dev-add-linked-list.patch new file mode 100644 index 0000000000..9b39d60598 --- /dev/null +++ b/pkg/uwb-dw1000/patches/0001-uwb_dw1000-include-dw1000-dw1000_dev-add-linked-list.patch @@ -0,0 +1,25 @@ +From 068dbad87ebebc9cf5d91bb9397dbd148420769e Mon Sep 17 00:00:00 2001 +From: Francisco Molina +Date: Fri, 14 Aug 2020 13:38:05 +0200 +Subject: [PATCH 1/5] uwb_dw1000/include/dw1000/dw1000_dev: add linked list + next ptr + +--- + hw/drivers/uwb/uwb_dw1000/include/dw1000/dw1000_dev.h | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/hw/drivers/uwb/uwb_dw1000/include/dw1000/dw1000_dev.h b/hw/drivers/uwb/uwb_dw1000/include/dw1000/dw1000_dev.h +index aec0bec..2dcd7f8 100644 +--- a/hw/drivers/uwb/uwb_dw1000/include/dw1000/dw1000_dev.h ++++ b/hw/drivers/uwb/uwb_dw1000/include/dw1000/dw1000_dev.h +@@ -204,6 +204,7 @@ typedef struct _dw1000_dev_instance_t{ + /* To allow translation from ticks to usecs in gdb during backtrace*/ + uint32_t bt_ticks2usec; + #endif ++ struct _dw1000_dev_instance_t* next; + } dw1000_dev_instance_t; + + //! SPI and other init parameters +-- +2.28.0 + diff --git a/pkg/uwb-dw1000/patches/0002-uwb_dw1000-dw1000_hal-send-spi-cmd-and-data-separetl.patch b/pkg/uwb-dw1000/patches/0002-uwb_dw1000-dw1000_hal-send-spi-cmd-and-data-separetl.patch new file mode 100644 index 0000000000..38356d4e37 --- /dev/null +++ b/pkg/uwb-dw1000/patches/0002-uwb_dw1000-dw1000_hal-send-spi-cmd-and-data-separetl.patch @@ -0,0 +1,57 @@ +From 8fc632df3880e9bc53766b8e2559c6e71c4d3c28 Mon Sep 17 00:00:00 2001 +From: Francisco Molina +Date: Fri, 14 Aug 2020 13:55:11 +0200 +Subject: [PATCH 2/5] uwb_dw1000/dw1000_hal: send spi cmd and data separetly + for RIOT + +--- + hw/drivers/uwb/uwb_dw1000/src/dw1000_hal.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/hw/drivers/uwb/uwb_dw1000/src/dw1000_hal.c b/hw/drivers/uwb/uwb_dw1000/src/dw1000_hal.c +index c9107fa..b85e32a 100644 +--- a/hw/drivers/uwb/uwb_dw1000/src/dw1000_hal.c ++++ b/hw/drivers/uwb/uwb_dw1000/src/dw1000_hal.c +@@ -310,7 +310,7 @@ hal_dw1000_read(struct _dw1000_dev_instance_t * inst, + + hal_gpio_write(inst->ss_pin, 0); + +-#if !defined(MYNEWT) ++#if !defined(MYNEWT) && !defined(RIOT) + /* Linux mode really, for when we can't split the command and data */ + assert(cmd_size + length < inst->uwb_dev.txbuf_size); + assert(cmd_size + length < MYNEWT_VAL(DW1000_HAL_SPI_MAX_CNT)); +@@ -322,7 +322,7 @@ hal_dw1000_read(struct _dw1000_dev_instance_t * inst, + inst->uwb_dev.txbuf, cmd_size+length); + memcpy(buffer, inst->uwb_dev.txbuf + cmd_size, length); + #else +- rc = hal_spi_txrx(inst->spi_num, (void*)cmd, 0, cmd_size); ++ rc = hal_spi_txrx(inst->spi_num, (void*)cmd, NULL, cmd_size); + assert(rc == DPL_OK); + int step = (inst->uwb_dev.txbuf_size > MYNEWT_VAL(DW1000_HAL_SPI_MAX_CNT)) ? + MYNEWT_VAL(DW1000_HAL_SPI_MAX_CNT) : inst->uwb_dev.txbuf_size; +@@ -537,7 +537,7 @@ hal_dw1000_write(struct _dw1000_dev_instance_t * inst, const uint8_t * cmd, uint + + hal_gpio_write(inst->ss_pin, 0); + +-#if !defined(MYNEWT) ++#if !defined(MYNEWT) && !defined(RIOT) + /* Linux mode really, for when we can't split the command and data */ + assert(cmd_size + length < inst->uwb_dev.txbuf_size); + assert(cmd_size + length < MYNEWT_VAL(DW1000_HAL_SPI_MAX_CNT)); +@@ -549,10 +549,10 @@ hal_dw1000_write(struct _dw1000_dev_instance_t * inst, const uint8_t * cmd, uint + 0, cmd_size+length); + assert(rc == DPL_OK); + #else +- rc = hal_spi_txrx(inst->spi_num, (void*)cmd, 0, cmd_size); ++ rc = hal_spi_txrx(inst->spi_num, (void*)cmd, NULL, cmd_size); + assert(rc == DPL_OK); + if (length) { +- hal_spi_txrx(inst->spi_num, (void*)buffer, 0, length); ++ hal_spi_txrx(inst->spi_num, (void*)buffer, NULL, length); + } + #endif + +-- +2.28.0 + diff --git a/pkg/uwb-dw1000/patches/0003-uwb_dw1000-dw1000_hal-define-even-if-DW1000_DEVICE_0.patch b/pkg/uwb-dw1000/patches/0003-uwb_dw1000-dw1000_hal-define-even-if-DW1000_DEVICE_0.patch new file mode 100644 index 0000000000..c103f8d71b --- /dev/null +++ b/pkg/uwb-dw1000/patches/0003-uwb_dw1000-dw1000_hal-define-even-if-DW1000_DEVICE_0.patch @@ -0,0 +1,36 @@ +From ed15486f7890a3ffb0426c153cefb951d822e93e Mon Sep 17 00:00:00 2001 +From: Francisco Molina +Date: Fri, 14 Aug 2020 13:56:25 +0200 +Subject: [PATCH 3/5] uwb_dw1000/dw1000_hal: define even if DW1000_DEVICE_0 is + unset + +In RIOT multiple DW1000 devices will be speficied thorugh a link +list so `hal_dw1000_inst` must be customly defined. + +The rest of the api should still be defined +--- + hw/drivers/uwb/uwb_dw1000/src/dw1000_hal.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/hw/drivers/uwb/uwb_dw1000/src/dw1000_hal.c b/hw/drivers/uwb/uwb_dw1000/src/dw1000_hal.c +index b85e32a..90ccd6c 100644 +--- a/hw/drivers/uwb/uwb_dw1000/src/dw1000_hal.c ++++ b/hw/drivers/uwb/uwb_dw1000/src/dw1000_hal.c +@@ -262,6 +262,8 @@ hal_dw1000_inst(uint8_t idx) + return 0; + } + ++#endif ++ + /** + * API to reset all the gpio pins. + * +@@ -756,5 +758,3 @@ hal_dw1000_get_rst(struct _dw1000_dev_instance_t * inst) + { + return hal_gpio_read(inst->rst_pin); + } +- +-#endif +-- +2.28.0 + diff --git a/pkg/uwb-dw1000/patches/0004-uwb_dw1000-dw1000_hal-replace-OS_-_CRTICAL-with-DPL_.patch b/pkg/uwb-dw1000/patches/0004-uwb_dw1000-dw1000_hal-replace-OS_-_CRTICAL-with-DPL_.patch new file mode 100644 index 0000000000..26c64f4c27 --- /dev/null +++ b/pkg/uwb-dw1000/patches/0004-uwb_dw1000-dw1000_hal-replace-OS_-_CRTICAL-with-DPL_.patch @@ -0,0 +1,35 @@ +From 445e0e92d874d9af5b4e679328e07ec32e79b07a Mon Sep 17 00:00:00 2001 +From: Francisco Molina +Date: Fri, 14 Aug 2020 15:19:26 +0200 +Subject: [PATCH 4/5] uwb_dw1000/dw1000_hal: replace OS_%_CRTICAL with + DPL_%_CRITICAL + +--- + hw/drivers/uwb/uwb_dw1000/src/dw1000_hal.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/hw/drivers/uwb/uwb_dw1000/src/dw1000_hal.c b/hw/drivers/uwb/uwb_dw1000/src/dw1000_hal.c +index 90ccd6c..30539a5 100644 +--- a/hw/drivers/uwb/uwb_dw1000/src/dw1000_hal.c ++++ b/hw/drivers/uwb/uwb_dw1000/src/dw1000_hal.c +@@ -723,7 +723,7 @@ hal_dw1000_wakeup(struct _dw1000_dev_instance_t * inst) + goto early_exit; + } + +- OS_ENTER_CRITICAL(sr); ++ DPL_ENTER_CRITICAL(sr); + + hal_spi_disable(inst->spi_num); + hal_gpio_write(inst->ss_pin, 0); +@@ -738,7 +738,7 @@ hal_dw1000_wakeup(struct _dw1000_dev_instance_t * inst) + // (check PLL bit in IRQ?) + dpl_cputime_delay_usecs(5000); + +- OS_EXIT_CRITICAL(sr); ++ DPL_EXIT_CRITICAL(sr); + + rc = dpl_sem_release(inst->spi_sem); + assert(rc == DPL_OK); +-- +2.28.0 + diff --git a/pkg/uwb-dw1000/patches/0005-uwb_dw1000-dw1000_hal-os_sr_t-by-dpl_sr_t.patch b/pkg/uwb-dw1000/patches/0005-uwb_dw1000-dw1000_hal-os_sr_t-by-dpl_sr_t.patch new file mode 100644 index 0000000000..0c48acdbd1 --- /dev/null +++ b/pkg/uwb-dw1000/patches/0005-uwb_dw1000-dw1000_hal-os_sr_t-by-dpl_sr_t.patch @@ -0,0 +1,25 @@ +From 715f6687e3b2b77f63303e3c231fbeb2c8588e97 Mon Sep 17 00:00:00 2001 +From: Francisco Molina +Date: Thu, 17 Sep 2020 12:26:44 +0200 +Subject: [PATCH 5/5] uwb_dw1000/dw1000_hal: os_sr_t by dpl_sr_t + +--- + hw/drivers/uwb/uwb_dw1000/src/dw1000_hal.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/hw/drivers/uwb/uwb_dw1000/src/dw1000_hal.c b/hw/drivers/uwb/uwb_dw1000/src/dw1000_hal.c +index 30539a5..4cff459 100644 +--- a/hw/drivers/uwb/uwb_dw1000/src/dw1000_hal.c ++++ b/hw/drivers/uwb/uwb_dw1000/src/dw1000_hal.c +@@ -715,7 +715,7 @@ int + hal_dw1000_wakeup(struct _dw1000_dev_instance_t * inst) + { + int rc = DPL_OK; +- os_sr_t sr; ++ dpl_sr_t sr; + assert(inst->spi_sem); + rc = dpl_sem_pend(inst->spi_sem, DPL_TIMEOUT_NEVER); + if (rc != DPL_OK) { +-- +2.28.0 + diff --git a/pkg/uwb-dw1000/patches/0006-dw1000-dw1000_dev-use-gpio_t-types-for-dev_cfg.patch b/pkg/uwb-dw1000/patches/0006-dw1000-dw1000_dev-use-gpio_t-types-for-dev_cfg.patch new file mode 100644 index 0000000000..f8f8656392 --- /dev/null +++ b/pkg/uwb-dw1000/patches/0006-dw1000-dw1000_dev-use-gpio_t-types-for-dev_cfg.patch @@ -0,0 +1,29 @@ +From e8207fa0b9ececc5e1d5e3c4fe1bc491b4d74884 Mon Sep 17 00:00:00 2001 +From: Francisco Molina +Date: Wed, 7 Oct 2020 14:11:43 +0200 +Subject: [PATCH 6/6] dw1000/dw1000_dev: use gpio_t types for dev_cfg + +--- + hw/drivers/uwb/uwb_dw1000/include/dw1000/dw1000_dev.h | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/hw/drivers/uwb/uwb_dw1000/include/dw1000/dw1000_dev.h b/hw/drivers/uwb/uwb_dw1000/include/dw1000/dw1000_dev.h +index 2dcd7f8..e149054 100644 +--- a/hw/drivers/uwb/uwb_dw1000/include/dw1000/dw1000_dev.h ++++ b/hw/drivers/uwb/uwb_dw1000/include/dw1000/dw1000_dev.h +@@ -214,9 +214,9 @@ struct dw1000_dev_cfg { + int spi_baudrate; //!< SPI Baudrate (<20MHz) + int spi_baudrate_low; //!< Low SPI Baudrate (<2MHz) + uint8_t spi_num; //!< SPI number +- uint8_t rst_pin; //!< Reset pin +- uint8_t irq_pin; //!< Interrupt request pin +- uint8_t ss_pin; //!< Slave select pin ++ gpio_t rst_pin; //!< Reset pin ++ gpio_t irq_pin; //!< Interrupt request pin ++ gpio_t ss_pin; //!< Slave select pin + + uint16_t rx_antenna_delay; //!< Receive antenna delay + uint16_t tx_antenna_delay; //!< Transmit antenna delay +-- +2.28.0 + diff --git a/pkg/uwb-dw1000/patches/0007-uwb_dw1000-dw1000_mac-avoid-conflict-with-msp430-N.patch b/pkg/uwb-dw1000/patches/0007-uwb_dw1000-dw1000_mac-avoid-conflict-with-msp430-N.patch new file mode 100644 index 0000000000..30b0dfd633 --- /dev/null +++ b/pkg/uwb-dw1000/patches/0007-uwb_dw1000-dw1000_mac-avoid-conflict-with-msp430-N.patch @@ -0,0 +1,47 @@ +From cea55ec226b13c3c57c492af76d08573e834f164 Mon Sep 17 00:00:00 2001 +From: Francisco Molina +Date: Wed, 7 Oct 2020 16:14:22 +0200 +Subject: [PATCH 7/7] uwb_dw1000/dw1000_mac: avoid conflict with msp430 #N + +--- + hw/drivers/uwb/uwb_dw1000/src/dw1000_mac.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/hw/drivers/uwb/uwb_dw1000/src/dw1000_mac.c b/hw/drivers/uwb/uwb_dw1000/src/dw1000_mac.c +index c4e5a3e..0d520b9 100644 +--- a/hw/drivers/uwb/uwb_dw1000/src/dw1000_mac.c ++++ b/hw/drivers/uwb/uwb_dw1000/src/dw1000_mac.c +@@ -1841,25 +1841,25 @@ dpl_float32_t + dw1000_calc_fppl(struct _dw1000_dev_instance_t * inst, + struct _dw1000_dev_rxdiag_t * diag) + { +- dpl_float32_t A, N, v, fppl; ++ dpl_float32_t A, n, v, fppl; + if (diag->pacc_cnt == 0 || + (!diag->fp_amp && !diag->fp_amp2 && !diag->fp_amp3)) { + return DPL_FLOAT32_NAN(); + } + A = (inst->uwb_dev.config.prf == DWT_PRF_16M) ? DPL_FLOAT32_INIT(113.77f) : DPL_FLOAT32_INIT(121.74f); + #ifdef __KERNEL__ +- N = ui32_to_f32(diag->pacc_cnt); ++ n = ui32_to_f32(diag->pacc_cnt); + v = f32_add(f32_add(ui32_to_f32(diag->fp_amp*diag->fp_amp), + ui32_to_f32(diag->fp_amp2*diag->fp_amp2)), + ui32_to_f32(diag->fp_amp3*diag->fp_amp3)); +- v = f32_div(v, f32_mul(N, N)); ++ v = f32_div(v, f32_mul(n, n)); + fppl = f32_sub(f32_mul(DPL_FLOAT32_INIT(10.0), f64_to_f32(log10_soft(f32_to_f64(v)))), A); + #else +- N = (float)(diag->pacc_cnt); ++ n = (float)(diag->pacc_cnt); + v = (float)(diag->fp_amp*diag->fp_amp) + + (float)(diag->fp_amp2*diag->fp_amp2) + + (float)(diag->fp_amp3*diag->fp_amp3); +- v /= N * N; ++ v /= n * n; + fppl = 10.0f * log10f(v) - A; + #endif + return fppl; +-- +2.28.0 + diff --git a/pkg/uwb-dw1000/uwb-dw1000.mk b/pkg/uwb-dw1000/uwb-dw1000.mk new file mode 100644 index 0000000000..a6dc811168 --- /dev/null +++ b/pkg/uwb-dw1000/uwb-dw1000.mk @@ -0,0 +1,13 @@ +# exclude submodule sources from *.c wildcard source selection + +IGNORE_SRC = \ + dw1000_pkg.c \ + dw1000_cli.c \ + dw1000_cli_priv.c \ + dw1000_sysfs.c \ + dw1000_debugfs.c \ + # + +SRC := $(filter-out $(IGNORE_SRC),$(wildcard *.c)) + +include $(RIOTBASE)/Makefile.base