mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
220 lines
5.8 KiB
C
220 lines
5.8 KiB
C
/*
|
|
* Copyright (C) 2018 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_nimble
|
|
* @{
|
|
*
|
|
* @file
|
|
* @brief Glue code for running NimBLE for RIOT
|
|
*
|
|
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
|
*
|
|
* @}
|
|
*/
|
|
|
|
#include <assert.h>
|
|
|
|
#include "thread.h"
|
|
#include "nimble_riot.h"
|
|
|
|
#include "nimble/nimble_port.h"
|
|
#include "host/ble_hs.h"
|
|
#include "host/util/util.h"
|
|
|
|
#ifdef MODULE_NIMBLE_SVC_GAP
|
|
#include "services/gap/ble_svc_gap.h"
|
|
#endif
|
|
#ifdef MODULE_NIMBLE_SVC_GATT
|
|
#include "services/gatt/ble_svc_gatt.h"
|
|
#endif
|
|
#ifdef MODULE_NIMBLE_SVC_IPSS
|
|
#include "services/ipss/ble_svc_ipss.h"
|
|
#endif
|
|
|
|
#ifdef MODULE_NIMBLE_STATCONN
|
|
#include "nimble_statconn.h"
|
|
#endif
|
|
|
|
#ifdef MODULE_NIMBLE_AUTOADV
|
|
#include "nimble_autoadv_params.h"
|
|
#include "nimble_autoadv.h"
|
|
#endif
|
|
|
|
#if defined(MODULE_NIMBLE_AUTOCONN) && !defined(MODULE_NIMBLE_AUTOCONN_NOAUTOINIT)
|
|
#include "nimble_autoconn.h"
|
|
#include "nimble_autoconn_params.h"
|
|
#endif
|
|
|
|
#ifdef MODULE_NIMBLE_CONTROLLER
|
|
#if defined(CPU_FAM_NRF52) || defined(CPU_FAM_NRF51)
|
|
#include "nrf_clock.h"
|
|
#endif
|
|
#include "controller/ble_ll.h"
|
|
|
|
static char _stack_controller[NIMBLE_CONTROLLER_STACKSIZE];
|
|
#endif
|
|
|
|
#ifdef MODULE_NIMBLE_RPBLE
|
|
#include "nimble_rpble.h"
|
|
#include "nimble_rpble_params.h"
|
|
#endif
|
|
|
|
#ifdef MODULE_NIMBLE_HOST
|
|
static char _stack_host[NIMBLE_HOST_STACKSIZE];
|
|
|
|
uint8_t nimble_riot_own_addr_type;
|
|
|
|
static void *_host_thread(void *arg)
|
|
{
|
|
(void)arg;
|
|
|
|
nimble_port_init();
|
|
|
|
#ifdef MODULE_NIMBLE_CONTROLLER
|
|
/* XXX: NimBLE needs the nRF5x's LF clock to run */
|
|
#if defined(CPU_FAM_NRF52) || defined(CPU_FAM_NRF51)
|
|
clock_start_lf();
|
|
#endif
|
|
|
|
/* Run the controller
|
|
*
|
|
* Create task where NimBLE LL will run. This one is required as LL has its
|
|
* own event queue and should have highest priority.
|
|
*/
|
|
thread_create(_stack_controller, sizeof(_stack_controller),
|
|
NIMBLE_CONTROLLER_PRIO,
|
|
0,
|
|
(thread_task_func_t)nimble_port_ll_task_func, NULL,
|
|
"nimble_ctrl");
|
|
|
|
/* XXX: seeding of the used PRNG is done when this function is called the
|
|
* first time. However, this could potentially be in interrupt context,
|
|
* leading to an malloc call in that context, breaking with the used
|
|
* thread safe malloc wrapper in RIOT. So we better do this seeding in
|
|
* a deterministic fashion right here.
|
|
* -> this fix is temporary until a proper fix is merged to NimBLE
|
|
* upstream */
|
|
ble_ll_rand();
|
|
#endif
|
|
|
|
nimble_port_run();
|
|
|
|
/* never reached */
|
|
return NULL;
|
|
}
|
|
#endif
|
|
|
|
void nimble_riot_init(void)
|
|
{
|
|
int res;
|
|
(void)res;
|
|
|
|
#if !IS_USED(MODULE_MYNEWT_CORE) && IS_ACTIVE(NIMBLE_CFG_CONTROLLER)
|
|
/* in mynewt-nimble and uwb-core OS_CPUTIMER_TIMER_NUM == 5 is NRF_RTC0,
|
|
for nimble this must be used for the BLE stack and must go through
|
|
mynewt timer initialization for it to work properly. The RTC frequency
|
|
should be set to the highest possible value so, 32768Hz */
|
|
assert(MYNEWT_VAL_OS_CPUTIME_TIMER_NUM == 5);
|
|
assert(MYNEWT_VAL_OS_CPUTIME_FREQ == 32768);
|
|
int rc = hal_timer_init(MYNEWT_VAL_OS_CPUTIME_TIMER_NUM, NULL);
|
|
assert(rc == 0);
|
|
rc = hal_timer_config(MYNEWT_VAL_OS_CPUTIME_TIMER_NUM,
|
|
MYNEWT_VAL_OS_CPUTIME_FREQ);
|
|
assert(rc == 0);
|
|
(void)rc;
|
|
#endif
|
|
|
|
/* and finally initialize and run the host */
|
|
thread_create(_stack_host, sizeof(_stack_host),
|
|
NIMBLE_HOST_PRIO,
|
|
0,
|
|
_host_thread, NULL,
|
|
"nimble_host");
|
|
|
|
/* make sure synchronization of host and controller is done, this should
|
|
* always be the case at this point */
|
|
while (!ble_hs_synced()) {}
|
|
|
|
/* for reducing code duplication, we read our own address type once here
|
|
* so it can be reused later on */
|
|
res = ble_hs_util_ensure_addr(0);
|
|
assert(res == 0);
|
|
res = ble_hs_id_infer_auto(0, &nimble_riot_own_addr_type);
|
|
assert(res == 0);
|
|
|
|
#ifdef MODULE_NIMBLE_NETIF
|
|
extern void nimble_netif_init(void);
|
|
nimble_netif_init();
|
|
#ifdef MODULE_SHELL_CMD_NIMBLE_NETIF
|
|
extern void sc_nimble_netif_init(void);
|
|
sc_nimble_netif_init();
|
|
#endif
|
|
#endif
|
|
|
|
/* initialize the configured, built-in services */
|
|
#ifdef MODULE_NIMBLE_SVC_GAP
|
|
ble_svc_gap_init();
|
|
#endif
|
|
#ifdef MODULE_NIMBLE_SVC_GATT
|
|
ble_svc_gatt_init();
|
|
#endif
|
|
#ifdef MODULE_NIMBLE_SVC_IPSS
|
|
ble_svc_ipss_init();
|
|
#endif
|
|
|
|
#ifdef MODULE_NIMBLE_STATCONN
|
|
nimble_statconn_init();
|
|
#endif
|
|
|
|
#if defined(MODULE_NIMBLE_AUTOCONN) && !defined(MODULE_NIMBLE_AUTOCONN_NOAUTOINIT)
|
|
ble_gatts_start();
|
|
/* CAUTION: this must be called after nimble_netif_init() and also only
|
|
* after the GATT server has been initialized */
|
|
res = nimble_autoconn_init(&nimble_autoconn_params, NULL, 0);
|
|
assert(res == NIMBLE_AUTOCONN_OK);
|
|
nimble_autoconn_enable();
|
|
#endif
|
|
|
|
#ifdef MODULE_STDIO_NIMBLE
|
|
extern void stdio_nimble_init(void);
|
|
/* stdio_nimble_init() needs to be called after nimble stack initialization
|
|
* and before nimble_autoadv_init() */
|
|
stdio_nimble_init();
|
|
#endif
|
|
|
|
#ifdef MODULE_NIMBLE_AUTOADV
|
|
nimble_autoadv_init(&nimble_autoadv_cfg);
|
|
#endif
|
|
|
|
#ifdef MODULE_NIMBLE_RPBLE
|
|
res = nimble_rpble_init(&nimble_rpble_params);
|
|
assert(res == 0);
|
|
#endif
|
|
}
|
|
|
|
#if MYNEWT_VAL_BLE_EXT_ADV
|
|
int nimble_riot_get_phy_hci(uint8_t mode)
|
|
{
|
|
switch (mode) {
|
|
case NIMBLE_PHY_1M:
|
|
return BLE_HCI_LE_PHY_1M;
|
|
#if IS_USED(MODULE_NIMBLE_PHY_2MBIT)
|
|
case NIMBLE_PHY_2M:
|
|
return BLE_HCI_LE_PHY_2M;
|
|
#endif
|
|
#if IS_USED(MODULE_NIMBLE_PHY_CODED)
|
|
case NIMBLE_PHY_CODED:
|
|
return BLE_HCI_LE_PHY_CODED;
|
|
#endif
|
|
default:
|
|
return -1;
|
|
}
|
|
}
|
|
#endif
|