1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

pkg/mynewt-core: initial commit

This commit is contained in:
Francisco Molina 2021-07-05 14:30:19 +02:00
parent 2bde4b65b0
commit 0cdc5826fd
No known key found for this signature in database
GPG Key ID: 3E94EAC3DBDEEDA8
31 changed files with 1801 additions and 0 deletions

46
pkg/mynewt-core/Makefile Normal file
View File

@ -0,0 +1,46 @@
PKG_NAME=mynewt-core
PKG_URL=https://github.com/apache/mynewt-core.git
PKG_VERSION=de203365f207dda658657a7525253e02f68503a1
PKG_LICENSE=Apache-2.0
include $(RIOTBASE)/pkg/pkg.mk
CFLAGS += -Wno-unused-parameter
CFLAGS += -Wno-unused-but-set-variable
CFLAGS += -Wno-sign-compare
MYNEWT_CORE_MODULES := mynewt-core_os \
mynewt-core_util \
mynewt-core_nrf5x_hal \
#
MYNEWT_CORE_PATH_util = util/mem/src
MYNEWT_CORE_PATH_os = kernel/os/src
ifneq (,$(filter nrf52,$(CPU)))
MYNEWT_CORE_PATH_nrf5x_hal = hw/mcu/nordic/nrf52xxx/src/
endif
ifneq (,$(filter nrf51,$(CPU)))
MYNEWT_CORE_PATH_nrf5x_hal = hw/mcu/nordic/nrf51xxx/src/
endif
.PHONY: rm_riot_provided_headers
all: $(filter $(MYNEWT_CORE_MODULES),$(USEMODULE))
@true
mynewt-core_%: rm_riot_provided_headers
"$(MAKE)" -C $(PKG_SOURCE_DIR)/$(MYNEWT_CORE_PATH_$*) -f $(RIOTPKG)/$(PKG_NAME)/$@.mk MODULE=$@
# The following mynewt-core headers are provided by RIOT, remove them from
# mynewt-core include paths to avoid header conflicts
MYNEWT_CORE_HAL_HEADERS = hal_gpio.h hal_spi.h
MYNEWT_CORE_OS_HEADERS = os.h mynewt.h os_dev.h os_eventq.h os_time.h
MYNEWT_CORE_HAL_HEADERS_PATH = hw/hal/include/hal
MYNEWT_CORE_OS_HEADERS_PATH = kernel/os/include/os/os_time
rm_riot_provided_headers:
$(Q)for i in $(MYNEWT_CORE_OS_HEADERS); \
do rm -f "$(PKG_SOURCE_DIR)/$(MYNEWT_CORE_OS_HEADERS_PATH)/$$i"; done
$(Q)for i in $(MYNEWT_CORE_HAL_HEADERS); \
do rm -f "$(PKG_SOURCE_DIR)/$(MYNEWT_CORE_HAL_HEADERS_PATH)/$$i"; done

View File

@ -0,0 +1,17 @@
USEMODULE += event_callback
USEMODULE += sema
USEMODULE += ztimer
USEMODULE += ztimer_msec
USEMODULE += mynewt-core
DEFAULT_MODULE += auto_init_mynewt-core
# MyNewt `os_hw_is_in_critical` function needs to know whether ISR are masked
# of if the function is being called in ISR context. There is no such function
# in RIOT except for arm (__get_PRIMASK), therefore unless a similar function
# is provided for other arch, this port is currently only enabled for those arch.
# Note: that this should not be a hindrance since nimble only works on nordic
# and uwb-core breakouts are all arm.
FEATURES_REQUIRED += arch_arm
FEATURES_BLACKLIST += arch_arm7

View File

@ -0,0 +1,16 @@
INCLUDES += -I$(RIOTPKG)/mynewt-core/include \
-I$(PKGDIRBASE)/mynewt-core/kernel/os/include \
-I$(PKGDIRBASE)/mynewt-core/hw/hal/include \
-I$(PKGDIRBASE)/mynewt-core/util/mem/include \
-I$(PKGDIRBASE)/mynewt-core/sys/stats/stub/include \
#
DIRS += $(RIOTPKG)/mynewt-core/contrib \
#
ifneq (,$(filter nrf5%,$(CPU)))
# OS_CPUTIME is set to 32.767 Hz
CFLAGS += -DMYNEWT_VAL_OS_CPUTIME_FREQ=32768
else
CFLAGS += -DMYNEWT_VAL_OS_CPUTIME_FREQ=CONFIG_ZTIMER_MSEC_BASE_FREQ
endif

View File

@ -0,0 +1,12 @@
MODULE = mynewt-core
# exclude submodule sources from *.c wildcard source selection
SRC := $(filter-out nrf5x_isr.c cputime.c,$(wildcard *.c))
ifneq (,$(filter nrf%,$(CPU)))
SRC += nrf5x_isr.c
else
SRC += cputime.c
endif
include $(RIOTBASE)/Makefile.base

View File

@ -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_mynewt_core
* @{
*
* @file
* @brief mynewt-core callout
*
* @author Francisco Molina <francois-xavier.molina@inria.fr>
* @}
*/
#include <assert.h>
#include "ztimer.h"
#include "os/os.h"
#include "os/os_callout.h"
static void _os_callout_timer_cb(void* arg)
{
struct os_callout *c = (struct os_callout *) arg;
assert(c);
/* post the event if there is a queue, otherwise call the callback
here */
if (c->c_evq) {
os_eventq_put(c->c_evq, &c->c_ev);
} else {
c->c_ev.e.callback(&c->c_ev);
}
}
void os_callout_init(struct os_callout *c, struct os_eventq *q,
os_event_fn *e_cb, void *e_arg)
{
os_event_init(&c->c_ev, e_cb, e_arg);
c->c_evq = q;
c->timer.callback = _os_callout_timer_cb;
c->timer.arg = (void*) c;
}
int os_callout_reset(struct os_callout *c, os_time_t ticks)
{
ztimer_set(ZTIMER_MSEC, &c->timer, ticks);
return OS_OK;
}
void os_callout_stop(struct os_callout *c)
{
ztimer_remove(ZTIMER_MSEC, &(c->timer));
}

View File

@ -0,0 +1,34 @@
/*
* Copyright (C) 2021 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_mynewt_core
* @{
*
* @file
* @brief mynewt-core bootstrapping functions
*
* @author Francisco Molina <francois-xavier.molina@inria.fr>
* @}
*/
#include <assert.h>
#include "os/os_cputime.h"
#include "hal/hal_timer.h"
void mynewt_core_init(void)
{
#if (MYNEWT_VAL_OS_CPUTIME_TIMER_NUM >= 0) && (defined(CPU_NRF51) || defined(CPU_NRF52))
int rc = hal_timer_init(5, NULL);
assert(rc == 0);
rc = os_cputime_init(MYNEWT_VAL_OS_CPUTIME_FREQ);
assert(rc == 0);
(void) rc;
#endif
}

View File

@ -0,0 +1,77 @@
/*
* 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_mynewt_core
* @{
*
* @file
* @brief cputime implementation for non nrf5x BOARDs
*
* @author Francisco Molina <francois-xavier.molina@inria.fr>
* @}
*/
#include "os/os_cputime.h"
#include "ztimer.h"
#include "hal/hal_timer.h"
uint32_t os_cputime_get32(void)
{
return ztimer_now(ZTIMER_MSEC_BASE);
}
void os_cputime_delay_ticks(uint32_t ticks)
{
ztimer_sleep(ZTIMER_MSEC_BASE, ticks);
}
void os_cputime_delay_usecs(uint32_t usecs)
{
ztimer_sleep(ZTIMER_MSEC_BASE, os_cputime_usecs_to_ticks(usecs));
}
int os_cputime_init(uint32_t clock_freq)
{
(void)clock_freq;
return 0;
}
void os_cputime_timer_init(struct hal_timer *timer, hal_timer_cb fp,
void *arg)
{
timer->timer.callback = fp;
timer->timer.arg = arg;
}
int os_cputime_timer_start(struct hal_timer *timer, uint32_t cputime)
{
uint32_t now = ztimer_now(ZTIMER_MSEC_BASE);
/* taken from mynewt-core 'hal_timer' implementations, this will
only work with timeouts at most 2**32-1 away, so it will have the same
limitations as their implementation does */
if ((int32_t)(cputime - now) <= 0) {
ztimer_set(ZTIMER_MSEC_BASE, &timer->timer, 0);
}
else {
ztimer_set(ZTIMER_MSEC_BASE, &timer->timer, cputime - now);
}
return 0;
}
int os_cputime_timer_relative(struct hal_timer *timer, uint32_t usecs)
{
ztimer_set(ZTIMER_MSEC_BASE, &timer->timer, os_cputime_usecs_to_ticks(usecs));
return 0;
}
void os_cputime_timer_stop(struct hal_timer *timer)
{
ztimer_remove(ZTIMER_MSEC_BASE, &timer->timer);
}

View File

@ -0,0 +1,57 @@
/*
* 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_mynewt_core
* @{
*
* @file
* @brief Decawave Porting Layer mutex RIOT wrapper
*
* @author Francisco Molina <francois-xavier.molina@inria.fr>
* @}
*/
#include "os/os_mutex.h"
os_error_t os_mutex_init(struct os_mutex *mu)
{
if (!mu) {
return OS_INVALID_PARM;
}
mutex_init(&mu->mutex);
return OS_OK;
}
os_error_t os_mutex_release(struct os_mutex *mu)
{
if (!mu) {
return OS_INVALID_PARM;
}
mutex_unlock(&mu->mutex);
return OS_OK;
}
os_error_t os_mutex_pend(struct os_mutex *mu, uint32_t timeout)
{
int rc = OS_OK;
if (!mu) {
return OS_INVALID_PARM;
}
if (!timeout) {
rc = mutex_trylock(&mu->mutex);
}
else {
/* TODO: no timeout equivalent */
mutex_lock(&mu->mutex);
}
return rc;
}

View File

@ -0,0 +1,56 @@
/*
* Copyright (C) 2021 Freie Universität Berlin
*
* 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_mynewt_core
* @{
*
* @file
* @brief mynewt-core isr mapping
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
* @}
*/
#include "mcu/mcu.h"
#include "cpu.h"
static void (*radio_isr_addr)(void);
static void (*rng_isr_addr)(void);
static void (*rtc0_isr_addr)(void);
void isr_radio(void)
{
radio_isr_addr();
}
void isr_rng(void)
{
rng_isr_addr();
}
void isr_rtc0(void)
{
rtc0_isr_addr();
}
void nrf5x_hw_set_isr(int irqn, void (*addr)(void))
{
switch (irqn) {
case RADIO_IRQn:
radio_isr_addr = addr;
break;
case RNG_IRQn:
rng_isr_addr = addr;
break;
case RTC0_IRQn:
rtc0_isr_addr = addr;
break;
}
}

View File

@ -0,0 +1,41 @@
/*
* 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_mynewt_core
* @{
*
* @file
* @brief Decawave Porting Layer semaphore RIOT wrapper
*
* @author Francisco Molina <francois-xavier.molina@inria.fr>
* @}
*/
#include <stdio.h>
#include "irq.h"
#include "os/os_sem.h"
os_error_t os_sem_init(struct os_sem *sem, uint16_t tokens)
{
sema_create(&sem->sema, tokens);
return OS_OK;
}
os_error_t os_sem_release(struct os_sem *sem)
{
int ret = sema_post(&sem->sema);
return (ret) ? OS_ERROR : OS_OK;
}
os_error_t os_sem_pend(struct os_sem *sem, os_time_t timeout)
{
int ret = sema_wait_timed_ztimer(&sem->sema, ZTIMER_MSEC, timeout);
return (ret) ? OS_ERROR : OS_OK;
}

View File

@ -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_mynewt_core
* @{
*
* @file
* @brief Decawave Porting Layer tasks RIOT wrapper
*
* @author Francisco Molina <francois-xavier.molina@inria.fr>
* @}
*/
#include "os/os_error.h"
#include "os/os_task.h"
#include "thread.h"
#ifndef LOG_LEVEL
#define LOG_LEVEL LOG_INFO
#endif
#include "log.h"
#ifdef __cplusplus
extern "C" {
#endif
int os_task_init(struct os_task *t, const char *name, os_task_func_t func,
void *arg, uint8_t prio, os_time_t sanity_itvl,
os_stack_t *stack_bottom, uint16_t stack_size)
{
(void) sanity_itvl;
LOG_INFO("[mynewt-core]: 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) ? OS_ERROR : OS_OK;;
}
int os_task_remove(struct os_task *t)
{
thread_zombify();
return thread_kill_zombie(t->pid);
}
uint8_t os_task_count(void)
{
return sched_num_threads;
}
void os_task_yield(void)
{
thread_yield();
}
#ifdef __cplusplus
}
#endif

12
pkg/mynewt-core/doc.txt Normal file
View File

@ -0,0 +1,12 @@
/**
* @defgroup pkg_mynewt_core mynewt-core
* @ingroup pkg
* @brief Apache MyNewt package for MyNewt based packages: uwb-core, nimble
* @see https://github.com/apache/mynewt-core
*/
# Apache MyNewt mynewt-core Package
Packages like @ref pkg_uwb_core and @ref nimble where developed with MyNewt
as their default OS. Some of the features provided by that OS are not abstracted.
For those cases and to avoid header re-definitions mynewt-core is pulled in.

View File

@ -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 <francois-xavier.molina@inria.fr>
* @}
*/
#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 */

View File

@ -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 <francois-xavier.molina@inria.fr>
* @}
*/
#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 */

View File

@ -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_mynewt_core
* @{
*
* @file
* @brief System logging header for mynewt-core
*
* @author Francisco Molina <francois-xavier.molina@inria.fr>
* @}
*/
#ifndef LOG_LOG_H
#define LOG_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_LOG_H */

View File

@ -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_mynewt_core
* @{
*
* @file
* @brief Abstraction layer for RIOT adaption
*
* @author Francisco Molina <francois-xavier.molina@inria.fr>
* @}
*/
#ifndef MCU_MCU_H
#define MCU_MCU_H
#include "cpu.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Set nrf5x radio ISR callback
*
* @param[in] irqn IRQ number
* @param[in] addr the ISR callback
*/
void nrf5x_hw_set_isr(int irqn, void (*addr)(void));
/**
* @name Entering and exiting critical section defines
* @{
*/
#define __HAL_DISABLE_INTERRUPTS(x) \
do { \
x = irq_disable(); \
} while (0);
#define __HAL_ENABLE_INTERRUPTS(x) \
do { \
if (x) { \
irq_restore(x); \
} \
else { \
irq_enable(); \
} \
} while (0);
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* MCU_MCU_H */

View File

@ -0,0 +1,36 @@
/*
* 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_mynewt_core
* @{
*
* @file
* @brief mynewt-core header
*
* @author Francisco Molina <francois-xavier.molina@inria.fr>
* @}
*/
#ifndef OS_MYNEWT_H
#define OS_MYNEWT_H
#include <stdlib.h>
#include "syscfg/syscfg.h"
#include "sysinit/sysinit.h"
#include "os/os.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif /* OS_MYNEWT_H */

View File

@ -0,0 +1,146 @@
/**
* Apache Mynewt
* Copyright 2015-2021 The Apache Software Foundation
*
* This product includes software developed at
* The Apache Software Foundation (http://www.apache.org/).
*
* Portions of this software were developed at
* Runtime Inc, copyright 2015.
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* @ingroup pkg_mynewt_core
* @{
*
* @file
* @brief mynewt-core error types
*
* @}
*/
#ifndef OS_OS_H
#define OS_OS_H
#include <assert.h>
#include <stdint.h>
#include "irq.h"
#include "os/os_types.h"
#include "os/os_error.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @name MyNewt os/%.h required macros
* @{
*
* PLEASE NOTE: Following macro definitions where copied directly from
* apache/mynewt-core and are under the copyright specified in
* the header.
*
*/
#ifndef min
#define min(a, b) ((a)<(b)?(a):(b))
#endif
#ifndef max
#define max(a, b) ((a)>(b)?(a):(b))
#endif
#define OS_ALIGN(__n, __a) ( \
(((__n) & ((__a) - 1)) == 0) ? \
(__n) : \
((__n) + ((__a) - ((__n) & ((__a) - 1)))) \
)
#define OS_ALIGNMENT (4)
/** @} */
/**
* @brief CPU status register
*/
typedef uint32_t os_sr_t;
/**
* @name Entering and exiting critical section defines
* @{
*/
#define OS_ENTER_CRITICAL(_sr) (_sr = os_hw_enter_critical())
#define OS_EXIT_CRITICAL(_sr) (os_hw_exit_critical(_sr))
#define OS_ASSERT_CRITICAL() assert(os_hw_is_in_critical())
/** @} */
/**
* @brief Disable ISRs
*
* @return current isr context
*/
static inline uint32_t os_hw_enter_critical(void)
{
uint32_t ctx = irq_disable();
return ctx;
}
/**
* @brief Restores ISR context
*
* @param[in] ctx ISR context to restore.
*/
static inline void os_hw_exit_critical(uint32_t ctx)
{
irq_restore((unsigned)ctx);
}
/**
* @brief Check if is in critical section
*
* @return true, if in critical section, false otherwise
*/
static inline bool os_hw_is_in_critical(void)
{
return (irq_is_in() || __get_PRIMASK());
}
/* Mynewt components (not abstracted in NPL or DPL) */
#include "os/endian.h"
#include "os/os_callout.h"
#include "os/os_cputime.h"
#include "os/os_dev.h"
#include "os/os_eventq.h"
#include "os/os_mbuf.h"
#include "os/os_mempool.h"
#include "os/os_mutex.h"
#include "os/os_sem.h"
#include "os/os_task.h"
#include "os/os_time.h"
#include "os/os_trace_api.h"
#include "os/queue.h"
#if IS_USED(MODULE_NIMBLE)
#include "nimble/nimble_npl.h"
#endif
#ifdef __cplusplus
}
#endif
#endif /* OS_OS_H */

View File

@ -0,0 +1,44 @@
/*
* 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_mynewt_core
* @{
*
* @file
* @brief Abstraction layer for RIOT adaption
*
* @author Francisco Molina <francois-xavier.molina@inria.fr>
* @}
*/
#ifndef OS_OS_DEV_H
#define OS_OS_DEV_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Device structure.
*/
struct os_dev {
};
/**
* @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 */

View File

@ -0,0 +1,236 @@
/*
* 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_mynewt_core
* @{
*
* @file
* @brief mynewt-core event and event queue abstraction
*
* @author Francisco Molina <francois-xavier.molina@inria.fr>
* @}
*/
#ifndef OS_OS_EVENTQ_H
#define OS_OS_EVENTQ_H
#include <os/os_types.h>
#include "event/callback.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Event wrapper
*/
struct os_event
{
event_callback_t e; /**< the event callback */
void *arg; /**< the event argument */
};
/**
* @brief Event queue wrapper
*/
struct os_eventq
{
event_queue_t q; /**< the event queue */
};
/**
* @brief Event callback function
*/
typedef void os_event_fn(struct os_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 os_event_init(struct os_event *ev, os_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 os_event_is_queued(struct os_event *ev)
{
return (ev->e.super.list_node.next != NULL);
}
/**
* @brief Returns event argument
*
* @param[in] ev event
*/
static inline void *os_event_get_arg(struct os_event *ev)
{
return ev->arg;
}
/**
* @brief Set the event argument
*
* @param[in] ev event
* @param[in] arg arg to set event
*/
static inline void os_event_set_arg(struct os_event *ev, void *arg)
{
ev->arg = arg;
}
/**
* @brief Runs an event
*
* @param[in] ev event to run
*/
static inline void os_event_run(struct os_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 os_eventq_init(struct os_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 os_eventq_inited(struct os_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 os_eventq_deinit(struct os_eventq *evq)
{
(void) evq;
/* Can't deinit an eventq in RIOT */
}
/**
* @brief Get next event from event queue
*
* @param[in] evq the event queue to pull an event from
* @param[in] tmo timeout, OS_WAIT_FOREVER to block, 0 to return immediately
*
* @return the event from the queue
*/
static inline struct os_event * os_eventq_get(struct os_eventq *evq, os_time_t tmo)
{
if (evq->q.waiter == NULL) {
event_queue_claim(&evq->q);
}
if (tmo == 0) {
return (struct os_event *)event_get(&evq->q);
} else if (tmo == OS_WAIT_FOREVER) {
return (struct os_event *)event_wait(&evq->q);
} else {
return (struct os_event *)event_wait_timeout_ztimer(&evq->q,
ZTIMER_MSEC,
(uint32_t)tmo);
}
}
/**
* @brief Get next event from event queue, non-blocking
*
* @return event from the queue, or NULL if none available.
*/
static inline struct os_event * os_eventq_get_no_wait(struct os_eventq *evq)
{
if (evq->q.waiter == NULL) {
event_queue_claim(&evq->q);
}
return (struct os_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 os_eventq_put(struct os_eventq *evq, struct os_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 os_eventq_remove(struct os_eventq *evq, struct os_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 os_eventq_run(struct os_eventq *evq)
{
struct os_event *ev = os_eventq_get(evq, OS_WAIT_FOREVER);
os_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 os_eventq_is_empty(struct os_eventq *evq)
{
return clist_count(&(evq->q.event_list)) == 0;
}
#ifdef __cplusplus
}
#endif
#endif /* OS_OS_EVENTQ_H */

View File

@ -0,0 +1,116 @@
/*
* 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_mynewt_core
* @{
*
* @file
* @brief mynewt-core time abstraction
*
* @author Francisco Molina <francois-xavier.molina@inria.fr>
* @}
*/
#ifndef OS_OS_TIME_H
#define OS_OS_TIME_H
#include "os/os_error.h"
#include "ztimer.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Ticks per seconds, ztimer_msec is used as system timer
*/
#define OS_TICKS_PER_SEC (MS_PER_SEC)
/**
* @brief Returns the low 32 bits of cputime.
*
* @return uint32_t The lower 32 bits of cputime
*/
static inline os_time_t os_time_get(void)
{
return ztimer_now(ZTIMER_MSEC);
}
/**
* @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 os_error_t OS_OK - no error
*/
static inline os_error_t os_time_ms_to_ticks(uint32_t ms, os_time_t *out_ticks)
{
*out_ticks = ms;
return OS_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 os_error_t OS_OK - no error
*/
static inline os_error_t os_time_ticks_to_ms(os_time_t ticks, uint32_t *out_ms)
{
*out_ms = ticks;
return OS_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 os_time_t os_time_ms_to_ticks32(uint32_t ms)
{
return ms;
}
/**
* @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 os_time_t os_time_ticks_to_ms32(os_time_t ticks)
{
return ticks;
}
/**
* @brief Wait until the number of ticks has elapsed, BLOICKING.
*
* @param[in] ticks The number of ticks to wait.
*/
static inline void os_time_delay(os_time_t ticks)
{
if (irq_is_in()) {
ztimer_spin(ZTIMER_MSEC, ticks);
}
else {
ztimer_sleep(ZTIMER_MSEC, ticks);
}
}
#ifdef __cplusplus
}
#endif
#endif /* OS_OS_TIME_H */

View File

@ -0,0 +1,59 @@
/*
* 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_mynewt_core
* @{
*
* @file
* @brief mynewt-core types
*
* @author Francisco Molina <francois-xavier.molina@inria.fr>
* @}
*/
#ifndef OS_OS_TYPES_H
#define OS_OS_TYPES_H
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @name Error codes not abstracted in mynewt-core/kernel/os
* @{
*/
#define SYS_EINVAL (-2)
#define SYS_ENOMEM (-1)
/** @} */
/**
* @name Macro to wait forever on events and mutexes
* @{
*/
#define OS_TIMEOUT_NEVER (UINT32_MAX)
#define OS_WAIT_FOREVER (OS_TIMEOUT_NEVER)
/** @} */
/**
* @brief time type
*/
typedef uint32_t os_time_t;
/**
* @brief stack buffer type
*/
typedef char os_stack_t;
#ifdef __cplusplus
}
#endif
#endif /* OS_OS_TYPES_H */

View File

@ -0,0 +1,122 @@
/**
* Apache Mynewt
* Copyright 2015-2021 The Apache Software Foundation
*
* This product includes software developed at
* The Apache Software Foundation (http://www.apache.org/).
*
* Portions of this software were developed at
* Runtime Inc, copyright 2015.
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* @ingroup pkg_mynewt_core
* @{
*
* @file
* @brief mynewt-core system configurations
*
* @}
*/
#ifndef SYSCFG_SYSCFG_H
#define SYSCFG_SYSCFG_H
#include "kernel_defines.h"
/**
* @name MyNewt header inclusion macro definitions
* @{
*
* PLEASE NOTE: Following macro definitions where copied directly from
* apache/mynewt-core and are under the copyright specified in
* the header.
*
* 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
/** @} */
/**
* @brief TIMER 5 (RTC_DEV0) will be mynewt-core OS_CPUTIME timer
*/
#ifndef MYNEWT_VAL_OS_CPUTIME_TIMER_NUM
#define MYNEWT_VAL_OS_CPUTIME_TIMER_NUM (5)
#endif
/**
* @brief Enable TIMER 5 (RTC_DEV0)
*/
#ifndef MYNEWT_VAL_TIMER_5
#define MYNEWT_VAL_TIMER_5 (1)
#endif
#if IS_USED(MODULE_NIMBLE)
/*** @mynewt-nimble */
#undef MYNEWT_VAL
#undef MYNEWT_VAL_CHOICE
#include "npl_sycfg.h"
#endif
#if IS_USED(MODULE_UWB_CORE)
/*** @decawave-mynewt-core/hw/drivers/uwb */
#include "dpl_syscfg/syscfg_uwb.h"
/*** @decawave-mynewt-core/lib/twr_ds */
#include "dpl_syscfg/syscfg_twr_ds.h"
/*** @decawave-mynewt-core/lib/twr_ds_ext */
#include "dpl_syscfg/syscfg_twr_ds_ext.h"
/*** @decawave-mynewt-core/lib/twr_ss */
#include "dpl_syscfg/syscfg_twr_ss.h"
/*** @decawave-mynewt-core/lib/twr_ss_ack */
#include "dpl_syscfg/syscfg_twr_ss_ack.h"
/*** @decawave-mynewt-core/lib/twr_ss_ext */
#include "dpl_syscfg/syscfg_twr_ss_ext.h"
/*** @decawave-mynewt-core/lib/uwb_rng */
#include "dpl_syscfg/syscfg_uwb_rng.h"
/*** @decawave-mynewt-core/sys/uwbcfg */
#include "dpl_syscfg/syscfg_uwbcfg.h"
#endif
#if IS_USED(MODULE_UWB_DW1000)
/*** @decawave-uwb-dw1000/hw/drivers/uwb/uwb_dw1000 */
#include "syscfg_uwb_dw1000.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif /* SYSCFG_SYSCFG_H */

View File

@ -0,0 +1,43 @@
/*
* 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_mynewt_core
* @{
*
* @file
* @brief sysinit abstraction layer for RIOT adaption
*
* @author Francisco Molina <francois-xavier.molina@inria.fr>
* @}
*/
#ifndef SYSINIT_SYSINIT_H
#define SYSINIT_SYSINIT_H
#include "assert.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief assert macro
*/
#define SYSINIT_PANIC_ASSERT(rc) assert(rc);
/**
* @brief empty definition
*/
#define SYSINIT_ASSERT_ACTIVE()
#ifdef __cplusplus
}
#endif
#endif /* SYSINIT_SYSINIT_H */

View File

@ -0,0 +1,5 @@
MODULE = mynewt-core_nrf5x_hal
SRC := hal_timer.c
include $(RIOTBASE)/Makefile.base

View File

@ -0,0 +1,15 @@
MODULE = mynewt-core_os
SRC := \
endian.c \
os_mbuf.c \
os_mempool.c \
os_msys.c \
os_cputime_pwr2.c \
#
ifneq (,$(filter nrf%,$(CPU)))
SRC += os_cputime.c
endif
include $(RIOTBASE)/Makefile.base

View File

@ -0,0 +1,5 @@
MODULE = mynewt-core_util
SRC := mem.c
include $(RIOTBASE)/Makefile.base

View File

@ -123,6 +123,11 @@ void auto_init(void)
extern void openwsn_bootstrap(void);
openwsn_bootstrap();
}
if (IS_USED(MODULE_AUTO_INIT_MYNEWT_CORE)) {
LOG_DEBUG("Bootstrapping mynewt-core.\n");
extern void mynewt_core_init(void);
mynewt_core_init();
}
if (IS_USED(MODULE_AUTO_INIT_UWB_CORE)) {
LOG_DEBUG("Bootstrapping uwb core.\n");
extern void uwb_core_init(void);