soc: stm32wba: Implement BLE controller lib APIs over Zephyr
In order to enable BLE support on STM32WBA, following APIs are implemented: - HostStack_: BLE Controller scheduling - ll_sys_: Link layer API required for scheduling - UTIL_TIMER_: BLE Controller timer utility - LINKLAYER_PLAT_: BLE controller utilities Signed-off-by: Erwan Gouriou <erwan.gouriou@st.com>
This commit is contained in:
parent
6ed002ddae
commit
6f6410061d
8 changed files with 641 additions and 0 deletions
|
@ -9,4 +9,14 @@ zephyr_sources_ifdef(CONFIG_PM
|
|||
power.c
|
||||
)
|
||||
|
||||
if(CONFIG_BT_STM32WBA)
|
||||
zephyr_include_directories(hci_if)
|
||||
|
||||
zephyr_sources(hci_if/linklayer_plat.c)
|
||||
zephyr_sources(hci_if/bleplat.c)
|
||||
zephyr_sources(hci_if/host_stack_if.c)
|
||||
zephyr_sources(hci_if/ll_sys_if.c)
|
||||
zephyr_sources(hci_if/stm32_timer.c)
|
||||
endif()
|
||||
|
||||
set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "")
|
||||
|
|
|
@ -13,4 +13,30 @@ config SOC_SERIES
|
|||
config STM32_LPTIM_TIMER
|
||||
default y if PM
|
||||
|
||||
choice BT_HCI_BUS_TYPE
|
||||
default BT_STM32WBA
|
||||
depends on BT
|
||||
endchoice
|
||||
|
||||
config BT_STM32WBA
|
||||
select DYNAMIC_INTERRUPTS
|
||||
select DYNAMIC_DIRECT_INTERRUPTS
|
||||
select ENTROPY_GENERATOR
|
||||
select USE_STM32_HAL_RAMCFG
|
||||
|
||||
if BT_STM32WBA
|
||||
|
||||
choice LIBC_IMPLEMENTATION
|
||||
default NEWLIB_LIBC
|
||||
endchoice
|
||||
|
||||
choice LINKER_ORPHAN_CONFIGURATION
|
||||
default LINKER_ORPHAN_SECTION_PLACE
|
||||
endchoice
|
||||
|
||||
config ENTROPY_STM32_CLK_CHECK
|
||||
default n
|
||||
|
||||
endif
|
||||
|
||||
endif # SOC_SERIES_STM32WBAX
|
||||
|
|
100
soc/arm/st_stm32/stm32wba/hci_if/bleplat.c
Normal file
100
soc/arm/st_stm32/stm32wba/hci_if/bleplat.c
Normal file
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* Copyright (c) 2023 STMicroelectronics
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/irq.h>
|
||||
#include <zephyr/drivers/entropy.h>
|
||||
#include <zephyr/logging/log.h>
|
||||
|
||||
#include "bleplat.h"
|
||||
#include "bpka.h"
|
||||
#include "linklayer_plat.h"
|
||||
|
||||
#define LOG_LEVEL CONFIG_SOC_LOG_LEVEL
|
||||
LOG_MODULE_REGISTER(ble_plat);
|
||||
|
||||
RAMCFG_HandleTypeDef hramcfg_SRAM1;
|
||||
const struct device *rng_dev;
|
||||
|
||||
void BLEPLAT_Init(void)
|
||||
{
|
||||
BPKA_Reset();
|
||||
|
||||
rng_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_entropy));
|
||||
if (!device_is_ready(rng_dev)) {
|
||||
LOG_ERR("error: random device not ready");
|
||||
}
|
||||
}
|
||||
|
||||
void BLEPLAT_RngGet(uint8_t n, uint32_t *val)
|
||||
{
|
||||
LINKLAYER_PLAT_GetRNG((uint8_t *)val, 4 * n);
|
||||
}
|
||||
|
||||
int BLEPLAT_PkaStartP256Key(const uint32_t *local_private_key)
|
||||
{
|
||||
return BPKA_StartP256Key(local_private_key);
|
||||
}
|
||||
|
||||
void BLEPLAT_PkaReadP256Key(uint32_t *local_public_key)
|
||||
{
|
||||
BPKA_ReadP256Key(local_public_key);
|
||||
}
|
||||
|
||||
int BLEPLAT_PkaStartDhKey(const uint32_t *local_private_key,
|
||||
const uint32_t *remote_public_key)
|
||||
{
|
||||
return BPKA_StartDhKey(local_private_key, remote_public_key);
|
||||
}
|
||||
|
||||
int BLEPLAT_PkaReadDhKey(uint32_t *dh_key)
|
||||
{
|
||||
return BPKA_ReadDhKey(dh_key);
|
||||
}
|
||||
|
||||
void BPKACB_Complete(void)
|
||||
{
|
||||
BLEPLATCB_PkaComplete();
|
||||
}
|
||||
|
||||
void MX_RAMCFG_Init(void)
|
||||
{
|
||||
/* Initialize RAMCFG SRAM1 */
|
||||
hramcfg_SRAM1.Instance = RAMCFG_SRAM1;
|
||||
if (HAL_RAMCFG_Init(&hramcfg_SRAM1) != HAL_OK) {
|
||||
LOG_ERR("Could not init RAMCFG");
|
||||
}
|
||||
}
|
||||
|
||||
void *ble_memcpy(void *dst, const void *src, uint8_t n)
|
||||
{
|
||||
memcpy(dst, src, (size_t)n);
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
void *ble_memset(void *dst, uint8_t c, uint16_t n)
|
||||
{
|
||||
memset((void *)dst, (int)c, (size_t)n);
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
int8_t ble_memcmp(const void *a, const void *b, uint16_t n)
|
||||
{
|
||||
return (int8_t)memcmp(a, b, (size_t)n);
|
||||
}
|
||||
|
||||
void Error_Handler(void)
|
||||
{
|
||||
LOG_ERR("");
|
||||
}
|
||||
|
||||
/* BLE ctlr should not disable HSI on its own */
|
||||
void SCM_HSI_CLK_OFF(void) {}
|
||||
|
||||
/* BLE ctlr should not alter RNG clocks */
|
||||
void HW_RNG_DisableClock(uint8_t) {}
|
||||
void HW_RNG_EnableClock(uint8_t) {}
|
82
soc/arm/st_stm32/stm32wba/hci_if/host_stack_if.c
Normal file
82
soc/arm/st_stm32/stm32wba/hci_if/host_stack_if.c
Normal file
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* Copyright (c) 2023 STMicroelectronics
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/init.h>
|
||||
|
||||
#include "app_conf.h"
|
||||
#include "blestack.h"
|
||||
#include "bpka.h"
|
||||
#include "ll_intf.h"
|
||||
|
||||
K_MUTEX_DEFINE(ble_ctlr_stack_mutex);
|
||||
struct k_work_q ble_ctlr_work_q, ll_work_q;
|
||||
struct k_work ble_ctlr_stack_work, bpka_work;
|
||||
|
||||
uint8_t ll_state_busy;
|
||||
|
||||
#define BLE_CTLR_TASK_STACK_SIZE (256 * 7)
|
||||
#define LL_TASK_STACK_SIZE (256 * 7)
|
||||
#define BLE_CTLR_TASK_PRIO (14)
|
||||
#define LL_TASK_PRIO (14)
|
||||
|
||||
K_THREAD_STACK_DEFINE(ble_ctlr_work_area, BLE_CTLR_TASK_STACK_SIZE);
|
||||
K_THREAD_STACK_DEFINE(ll_work_area, LL_TASK_STACK_SIZE);
|
||||
|
||||
void HostStack_Process(void)
|
||||
{
|
||||
k_work_submit_to_queue(&ble_ctlr_work_q, &ble_ctlr_stack_work);
|
||||
}
|
||||
|
||||
static void ble_ctlr_stack_handler(struct k_work *work)
|
||||
{
|
||||
uint8_t running = 0x0;
|
||||
change_state_options_t options;
|
||||
|
||||
k_mutex_lock(&ble_ctlr_stack_mutex, K_FOREVER);
|
||||
running = BleStack_Process();
|
||||
k_mutex_unlock(&ble_ctlr_stack_mutex);
|
||||
|
||||
if (ll_state_busy == 1) {
|
||||
options.combined_value = 0x0F;
|
||||
ll_intf_chng_evnt_hndlr_state(options);
|
||||
ll_state_busy = 0;
|
||||
}
|
||||
|
||||
if (running == BLE_SLEEPMODE_RUNNING) {
|
||||
HostStack_Process();
|
||||
}
|
||||
}
|
||||
|
||||
void BPKACB_Process(void)
|
||||
{
|
||||
k_work_submit_to_queue(&ble_ctlr_work_q, &bpka_work);
|
||||
}
|
||||
|
||||
static void bpka_work_handler(struct k_work *work)
|
||||
{
|
||||
BPKA_BG_Process();
|
||||
}
|
||||
|
||||
static int stm32wba_ble_ctlr_init(void)
|
||||
{
|
||||
k_work_queue_init(&ble_ctlr_work_q);
|
||||
k_work_queue_start(&ble_ctlr_work_q, ble_ctlr_work_area,
|
||||
K_THREAD_STACK_SIZEOF(ble_ctlr_work_area),
|
||||
BLE_CTLR_TASK_PRIO, NULL);
|
||||
|
||||
k_work_queue_init(&ll_work_q);
|
||||
k_work_queue_start(&ll_work_q, ll_work_area,
|
||||
K_THREAD_STACK_SIZEOF(ll_work_area),
|
||||
LL_TASK_PRIO, NULL);
|
||||
|
||||
k_work_init(&ble_ctlr_stack_work, &ble_ctlr_stack_handler);
|
||||
k_work_init(&bpka_work, &bpka_work_handler);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
SYS_INIT(stm32wba_ble_ctlr_init, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);
|
304
soc/arm/st_stm32/stm32wba/hci_if/linklayer_plat.c
Normal file
304
soc/arm/st_stm32/stm32wba/hci_if/linklayer_plat.c
Normal file
|
@ -0,0 +1,304 @@
|
|||
/*
|
||||
* Copyright (c) 2023 STMicroelectronics
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/irq.h>
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/arch/cpu.h>
|
||||
#include <zephyr/sys/util.h>
|
||||
#include <zephyr/drivers/entropy.h>
|
||||
#include <zephyr/logging/log.h>
|
||||
#include <cmsis_core.h>
|
||||
|
||||
#include <linklayer_plat_local.h>
|
||||
|
||||
#include <stm32_ll_pwr.h>
|
||||
|
||||
#include "scm.h"
|
||||
|
||||
#define LOG_LEVEL CONFIG_SOC_LOG_LEVEL
|
||||
LOG_MODULE_REGISTER(linklayer_plat);
|
||||
|
||||
#define RADIO_INTR_PRIO_HIGH_Z (RADIO_INTR_PRIO_HIGH + _IRQ_PRIO_OFFSET)
|
||||
#define RADIO_INTR_PRIO_LOW_Z (RADIO_INTR_PRIO_LOW + _IRQ_PRIO_OFFSET)
|
||||
|
||||
/* 2.4GHz RADIO ISR callbacks */
|
||||
typedef void (*radio_isr_cb_t) (void);
|
||||
|
||||
radio_isr_cb_t radio_callback;
|
||||
radio_isr_cb_t low_isr_callback;
|
||||
|
||||
extern const struct device *rng_dev;
|
||||
|
||||
/* Radio critical sections */
|
||||
volatile int32_t prio_high_isr_counter;
|
||||
volatile int32_t prio_low_isr_counter;
|
||||
volatile int32_t prio_sys_isr_counter;
|
||||
volatile int32_t irq_counter;
|
||||
volatile uint32_t local_basepri_value;
|
||||
|
||||
/* Radio SW low ISR global variable */
|
||||
volatile uint8_t radio_sw_low_isr_is_running_high_prio;
|
||||
|
||||
void LINKLAYER_PLAT_ClockInit(void)
|
||||
{
|
||||
LL_PWR_EnableBkUpAccess();
|
||||
|
||||
/* Select LSE as Sleep CLK */
|
||||
__HAL_RCC_RADIOSLPTIM_CONFIG(RCC_RADIOSTCLKSOURCE_LSE);
|
||||
|
||||
LL_PWR_DisableBkUpAccess();
|
||||
|
||||
/* Enable AHB5ENR peripheral clock (bus CLK) */
|
||||
__HAL_RCC_RADIO_CLK_ENABLE();
|
||||
}
|
||||
|
||||
void LINKLAYER_PLAT_DelayUs(uint32_t delay)
|
||||
{
|
||||
k_busy_wait(delay);
|
||||
}
|
||||
|
||||
void LINKLAYER_PLAT_WaitHclkRdy(void)
|
||||
{
|
||||
while (HAL_RCCEx_GetRadioBusClockReadiness() != RCC_RADIO_BUS_CLOCK_READY) {
|
||||
}
|
||||
}
|
||||
|
||||
void LINKLAYER_PLAT_AclkCtrl(uint8_t enable)
|
||||
{
|
||||
LOG_DBG("enable: %d", enable);
|
||||
if (enable) {
|
||||
/* Enable RADIO baseband clock (active CLK) */
|
||||
HAL_RCCEx_EnableRadioBBClock();
|
||||
|
||||
/* Polling on HSE32 activation */
|
||||
while (LL_RCC_HSE_IsReady() == 0) {
|
||||
}
|
||||
} else {
|
||||
/* Disable RADIO baseband clock (active CLK) */
|
||||
HAL_RCCEx_DisableRadioBBClock();
|
||||
}
|
||||
}
|
||||
|
||||
void LINKLAYER_PLAT_GetRNG(uint8_t *ptr_rnd, uint32_t len)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Read 32-bit random values from HW driver */
|
||||
ret = entropy_get_entropy_isr(rng_dev, (char *)ptr_rnd, len, 0);
|
||||
if (ret < 0) {
|
||||
LOG_ERR("Error: entropy_get_entropy failed: %d", ret);
|
||||
}
|
||||
LOG_DBG("n %d, val: %p", len, (void *)ptr_rnd);
|
||||
}
|
||||
|
||||
void LINKLAYER_PLAT_SetupRadioIT(void (*intr_cb)())
|
||||
{
|
||||
radio_callback = intr_cb;
|
||||
}
|
||||
|
||||
void LINKLAYER_PLAT_SetupSwLowIT(void (*intr_cb)())
|
||||
{
|
||||
low_isr_callback = intr_cb;
|
||||
}
|
||||
|
||||
void radio_high_prio_isr(void)
|
||||
{
|
||||
radio_callback();
|
||||
|
||||
HAL_RCCEx_DisableRequestUponRadioWakeUpEvent();
|
||||
|
||||
__ISB();
|
||||
|
||||
ISR_DIRECT_PM();
|
||||
}
|
||||
|
||||
void radio_low_prio_isr(void)
|
||||
{
|
||||
irq_disable((IRQn_Type)RADIO_SW_LOW_INTR_NUM);
|
||||
|
||||
low_isr_callback();
|
||||
|
||||
/* Check if nested SW radio low interrupt has been requested*/
|
||||
if (radio_sw_low_isr_is_running_high_prio != 0) {
|
||||
NVIC_SetPriority((IRQn_Type) RADIO_SW_LOW_INTR_NUM, RADIO_INTR_PRIO_LOW);
|
||||
radio_sw_low_isr_is_running_high_prio = 0;
|
||||
}
|
||||
|
||||
/* Re-enable SW radio low interrupt */
|
||||
irq_enable((IRQn_Type)RADIO_SW_LOW_INTR_NUM);
|
||||
|
||||
ISR_DIRECT_PM();
|
||||
}
|
||||
|
||||
|
||||
void link_layer_register_isr(void)
|
||||
{
|
||||
ARM_IRQ_DIRECT_DYNAMIC_CONNECT(RADIO_INTR_NUM, 0, 0, reschedule);
|
||||
|
||||
/* Ensure the IRQ is disabled before enabling it at run time */
|
||||
irq_disable((IRQn_Type)RADIO_INTR_NUM);
|
||||
|
||||
irq_connect_dynamic((IRQn_Type)RADIO_INTR_NUM, RADIO_INTR_PRIO_HIGH_Z,
|
||||
(void (*)(const void *))radio_high_prio_isr, NULL, 0);
|
||||
|
||||
irq_enable((IRQn_Type)RADIO_INTR_NUM);
|
||||
|
||||
ARM_IRQ_DIRECT_DYNAMIC_CONNECT(RADIO_SW_LOW_INTR_NUM, 0, 0, reschedule);
|
||||
|
||||
/* Ensure the IRQ is disabled before enabling it at run time */
|
||||
irq_disable((IRQn_Type)RADIO_SW_LOW_INTR_NUM);
|
||||
|
||||
irq_connect_dynamic((IRQn_Type)RADIO_SW_LOW_INTR_NUM, RADIO_SW_LOW_INTR_PRIO,
|
||||
(void (*)(const void *))radio_low_prio_isr, NULL, 0);
|
||||
|
||||
irq_enable((IRQn_Type)RADIO_SW_LOW_INTR_NUM);
|
||||
}
|
||||
|
||||
|
||||
void LINKLAYER_PLAT_TriggerSwLowIT(uint8_t priority)
|
||||
{
|
||||
uint8_t low_isr_priority = RADIO_INTR_PRIO_LOW_Z;
|
||||
|
||||
LOG_DBG("Priotity: %d", priority);
|
||||
|
||||
/* Check if a SW low interrupt as already been raised.
|
||||
* Nested call far radio low isr are not supported
|
||||
**/
|
||||
|
||||
if (NVIC_GetActive(RADIO_SW_LOW_INTR_NUM) == 0) {
|
||||
/* No nested SW low ISR, default behavior */
|
||||
|
||||
if (priority == 0) {
|
||||
low_isr_priority = RADIO_SW_LOW_INTR_PRIO;
|
||||
}
|
||||
|
||||
NVIC_SetPriority((IRQn_Type)RADIO_SW_LOW_INTR_NUM, low_isr_priority);
|
||||
} else {
|
||||
/* Nested call detected */
|
||||
/* No change for SW radio low interrupt priority for the moment */
|
||||
|
||||
if (priority != 0) {
|
||||
/* At the end of current SW radio low ISR, this pending SW
|
||||
* low interrupt will run with RADIO_INTR_PRIO_LOW_Z priority
|
||||
**/
|
||||
radio_sw_low_isr_is_running_high_prio = 1;
|
||||
}
|
||||
}
|
||||
|
||||
NVIC_SetPendingIRQ((IRQn_Type)RADIO_SW_LOW_INTR_NUM);
|
||||
}
|
||||
|
||||
void LINKLAYER_PLAT_EnableIRQ(void)
|
||||
{
|
||||
irq_counter = MAX(0, irq_counter - 1);
|
||||
|
||||
if (irq_counter == 0) {
|
||||
__enable_irq();
|
||||
}
|
||||
}
|
||||
|
||||
void LINKLAYER_PLAT_DisableIRQ(void)
|
||||
{
|
||||
__disable_irq();
|
||||
|
||||
irq_counter++;
|
||||
}
|
||||
|
||||
void LINKLAYER_PLAT_Assert(uint8_t condition)
|
||||
{
|
||||
__ASSERT_NO_MSG(condition);
|
||||
}
|
||||
|
||||
void LINKLAYER_PLAT_EnableSpecificIRQ(uint8_t isr_type)
|
||||
{
|
||||
|
||||
LOG_DBG("isr_type: %d", isr_type);
|
||||
|
||||
if ((isr_type & LL_HIGH_ISR_ONLY) != 0) {
|
||||
prio_high_isr_counter--;
|
||||
if (prio_high_isr_counter == 0) {
|
||||
irq_enable(RADIO_INTR_NUM);
|
||||
}
|
||||
}
|
||||
|
||||
if ((isr_type & LL_LOW_ISR_ONLY) != 0) {
|
||||
prio_low_isr_counter--;
|
||||
if (prio_low_isr_counter == 0) {
|
||||
irq_enable(RADIO_SW_LOW_INTR_NUM);
|
||||
}
|
||||
}
|
||||
|
||||
if ((isr_type & SYS_LOW_ISR) != 0) {
|
||||
prio_sys_isr_counter--;
|
||||
if (prio_sys_isr_counter == 0) {
|
||||
__set_BASEPRI(local_basepri_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LINKLAYER_PLAT_DisableSpecificIRQ(uint8_t isr_type)
|
||||
{
|
||||
|
||||
LOG_DBG("isr_type: %d", isr_type);
|
||||
|
||||
if ((isr_type & LL_HIGH_ISR_ONLY) != 0) {
|
||||
prio_high_isr_counter++;
|
||||
if (prio_high_isr_counter == 1) {
|
||||
irq_disable(RADIO_INTR_NUM);
|
||||
}
|
||||
}
|
||||
|
||||
if ((isr_type & LL_LOW_ISR_ONLY) != 0) {
|
||||
prio_low_isr_counter++;
|
||||
if (prio_low_isr_counter == 1) {
|
||||
irq_disable(RADIO_SW_LOW_INTR_NUM);
|
||||
}
|
||||
}
|
||||
|
||||
if ((isr_type & SYS_LOW_ISR) != 0) {
|
||||
prio_sys_isr_counter++;
|
||||
if (prio_sys_isr_counter == 1) {
|
||||
local_basepri_value = __get_BASEPRI();
|
||||
__set_BASEPRI_MAX(RADIO_INTR_PRIO_LOW_Z << 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LINKLAYER_PLAT_EnableRadioIT(void)
|
||||
{
|
||||
irq_enable((IRQn_Type)RADIO_INTR_NUM);
|
||||
}
|
||||
|
||||
void LINKLAYER_PLAT_DisableRadioIT(void)
|
||||
{
|
||||
irq_disable((IRQn_Type)RADIO_INTR_NUM);
|
||||
}
|
||||
|
||||
void LINKLAYER_PLAT_StartRadioEvt(void)
|
||||
{
|
||||
__HAL_RCC_RADIO_CLK_SLEEP_ENABLE();
|
||||
|
||||
NVIC_SetPriority(RADIO_INTR_NUM, RADIO_INTR_PRIO_HIGH_Z);
|
||||
|
||||
scm_notifyradiostate(SCM_RADIO_ACTIVE);
|
||||
}
|
||||
|
||||
void LINKLAYER_PLAT_StopRadioEvt(void)
|
||||
{
|
||||
__HAL_RCC_RADIO_CLK_SLEEP_DISABLE();
|
||||
|
||||
NVIC_SetPriority(RADIO_INTR_NUM, RADIO_INTR_PRIO_LOW_Z);
|
||||
|
||||
scm_notifyradiostate(SCM_RADIO_NOT_ACTIVE);
|
||||
}
|
||||
|
||||
void LINKLAYER_PLAT_RequestTemperature(void) {}
|
||||
|
||||
void LINKLAYER_PLAT_SCHLDR_TIMING_UPDATE_NOT(Evnt_timing_t *p_evnt_timing) {}
|
||||
|
||||
void LINKLAYER_PLAT_EnableOSContextSwitch(void) {}
|
||||
|
||||
void LINKLAYER_PLAT_DisableOSContextSwitch(void) {}
|
13
soc/arm/st_stm32/stm32wba/hci_if/linklayer_plat_local.h
Normal file
13
soc/arm/st_stm32/stm32wba/hci_if/linklayer_plat_local.h
Normal file
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* Copyright (c) 2023 STMicroelectronics
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _STM32WBA_LINK_LAYER_PLAT_LOCAL_H_
|
||||
#define _STM32WBA_LINK_LAYER_PLAT_LOCAL_H_
|
||||
|
||||
void link_layer_register_isr(void);
|
||||
|
||||
#endif /* _STM32WBA_LINK_LAYER_PLAT_LOCAL_H_ */
|
47
soc/arm/st_stm32/stm32wba/hci_if/ll_sys_if.c
Normal file
47
soc/arm/st_stm32/stm32wba/hci_if/ll_sys_if.c
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (c) 2023 STMicroelectronics
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/kernel.h>
|
||||
|
||||
#include <zephyr/logging/log.h>
|
||||
#define LOG_LEVEL CONFIG_SOC_LOG_LEVEL
|
||||
LOG_MODULE_REGISTER(ll_sys_if);
|
||||
|
||||
#include "ll_intf.h"
|
||||
#include "ll_sys.h"
|
||||
#include "linklayer_plat.h"
|
||||
#include "app_conf.h"
|
||||
|
||||
extern struct k_mutex ble_ctlr_stack_mutex;
|
||||
extern struct k_work_q ll_work_q;
|
||||
struct k_work ll_sys_work;
|
||||
|
||||
void ll_sys_schedule_bg_process(void)
|
||||
{
|
||||
k_work_submit_to_queue(&ll_work_q, &ll_sys_work);
|
||||
}
|
||||
|
||||
void ll_sys_schedule_bg_process_isr(void)
|
||||
{
|
||||
k_work_submit_to_queue(&ll_work_q, &ll_sys_work);
|
||||
}
|
||||
|
||||
static void ll_sys_bg_process_handler(struct k_work *work)
|
||||
{
|
||||
k_mutex_lock(&ble_ctlr_stack_mutex, K_FOREVER);
|
||||
ll_sys_bg_process();
|
||||
k_mutex_unlock(&ble_ctlr_stack_mutex);
|
||||
}
|
||||
|
||||
void ll_sys_bg_process_init(void)
|
||||
{
|
||||
k_work_init(&ll_sys_work, &ll_sys_bg_process_handler);
|
||||
}
|
||||
|
||||
void ll_sys_config_params(void)
|
||||
{
|
||||
ll_intf_config_ll_ctx_params(USE_RADIO_LOW_ISR, NEXT_EVENT_SCHEDULING_FROM_ISR);
|
||||
}
|
59
soc/arm/st_stm32/stm32wba/hci_if/stm32_timer.c
Normal file
59
soc/arm/st_stm32/stm32wba/hci_if/stm32_timer.c
Normal file
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Copyright (c) 2023 STMicroelectronics
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/sys_clock.h>
|
||||
|
||||
#include "stm32_timer.h"
|
||||
|
||||
#define TICKS_PER_MS (CONFIG_SYS_CLOCK_TICKS_PER_SEC / MSEC_PER_SEC)
|
||||
|
||||
static struct k_timer timer;
|
||||
|
||||
UTIL_TIMER_Status_t UTIL_TIMER_Create(UTIL_TIMER_Object_t *timer_object,
|
||||
uint32_t period, UTIL_TIMER_Mode_t mode,
|
||||
void (*callback)(void *), void *argument)
|
||||
{
|
||||
if (timer_object == NULL) {
|
||||
return UTIL_TIMER_INVALID_PARAM;
|
||||
}
|
||||
|
||||
timer_object->ReloadValue = period * TICKS_PER_MS;
|
||||
timer_object->Mode = mode;
|
||||
timer_object->Callback = callback;
|
||||
timer_object->argument = argument;
|
||||
timer_object->IsRunning = false;
|
||||
timer_object->IsReloadStopped = false;
|
||||
timer_object->Next = NULL;
|
||||
|
||||
return UTIL_TIMER_OK;
|
||||
}
|
||||
|
||||
UTIL_TIMER_Status_t UTIL_TIMER_Start(UTIL_TIMER_Object_t *timer_object)
|
||||
{
|
||||
if (timer_object == NULL) {
|
||||
return UTIL_TIMER_INVALID_PARAM;
|
||||
}
|
||||
|
||||
k_timer_user_data_set(&timer, timer_object);
|
||||
k_timer_start(&timer, K_TICKS(timer_object->ReloadValue),
|
||||
K_TICKS(timer_object->ReloadValue));
|
||||
timer_object->IsRunning = true;
|
||||
|
||||
return UTIL_TIMER_OK;
|
||||
}
|
||||
|
||||
UTIL_TIMER_Status_t UTIL_TIMER_Stop(UTIL_TIMER_Object_t *timer_object)
|
||||
{
|
||||
if (timer_object == NULL) {
|
||||
return UTIL_TIMER_INVALID_PARAM;
|
||||
}
|
||||
|
||||
k_timer_stop(&timer);
|
||||
timer_object->IsRunning = false;
|
||||
|
||||
return UTIL_TIMER_OK;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue