mirror of
https://github.com/espressif/esp-nimble.git
synced 2026-10-19 11:37:56 +00:00
nimble/transport: Update Dialog CMAC transport
This commit is contained in:
@@ -1,2 +0,0 @@
|
||||
/src/libble_stack_da1469x.a
|
||||
|
||||
@@ -20,7 +20,28 @@
|
||||
#include "syscfg/syscfg.h"
|
||||
#include "mcu/mcu.h"
|
||||
|
||||
#if MYNEWT_VAL(BLE_HOST) || MYNEWT_VAL(BLE_HCI_BRIDGE)
|
||||
#if MYNEWT_VAL(BLE_CONTROLLER)
|
||||
void
|
||||
cmac_diag_setup_cmac(void)
|
||||
{
|
||||
MCU_DIAG_MAP( 0, 4, DSER);
|
||||
MCU_DIAG_MAP( 1, 6, CMAC_ON_ERROR);
|
||||
MCU_DIAG_MAP( 2, 2, PHY_TX_EN);
|
||||
MCU_DIAG_MAP( 3, 2, PHY_RX_EN);
|
||||
MCU_DIAG_MAP( 4, 2, PHY_TXRX_DATA_COMB);
|
||||
MCU_DIAG_MAP( 5, 2, PHY_TXRX_DATA_EN_COMB);
|
||||
MCU_DIAG_MAP( 6, 5, EV1US_FRAME_START);
|
||||
MCU_DIAG_MAP( 7, 5, EV_BS_START);
|
||||
MCU_DIAG_MAP( 8, 5, EV1C_BS_STOP);
|
||||
MCU_DIAG_MAP( 9, 5, EV1US_PHY_TO_IDLE);
|
||||
MCU_DIAG_MAP(10, 9, CALLBACK_IRQ);
|
||||
MCU_DIAG_MAP(11, 9, FIELD_IRQ);
|
||||
MCU_DIAG_MAP(12, 9, FRAME_IRQ);
|
||||
MCU_DIAG_MAP(13, 3, SLP_TIMER_ACTIVE);
|
||||
MCU_DIAG_MAP(14, 4, SLEEPING);
|
||||
MCU_DIAG_MAP(15, 8, LL_TIMER1_00);
|
||||
}
|
||||
#else
|
||||
void
|
||||
cmac_diag_setup_host(void)
|
||||
{
|
||||
@@ -43,26 +64,3 @@ cmac_diag_setup_host(void)
|
||||
mcu_gpio_set_pin_function(41, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAGX); /* DIAG_15 @ P1.09 */
|
||||
}
|
||||
#endif
|
||||
|
||||
#if MYNEWT_VAL(BLE_CONTROLLER)
|
||||
void
|
||||
cmac_diag_setup_cmac(void)
|
||||
{
|
||||
MCU_DIAG_MAP( 0, 4, DSER);
|
||||
MCU_DIAG_MAP( 1, 6, CMAC_ON_ERROR);
|
||||
MCU_DIAG_MAP( 2, 2, PHY_TX_EN);
|
||||
MCU_DIAG_MAP( 3, 2, PHY_RX_EN);
|
||||
MCU_DIAG_MAP( 4, 2, PHY_TXRX_DATA_COMB);
|
||||
MCU_DIAG_MAP( 5, 2, PHY_TXRX_DATA_EN_COMB);
|
||||
MCU_DIAG_MAP( 6, 5, EV1US_FRAME_START);
|
||||
MCU_DIAG_MAP( 7, 5, EV_BS_START);
|
||||
MCU_DIAG_MAP( 8, 5, EV1C_BS_STOP);
|
||||
MCU_DIAG_MAP( 9, 5, EV1US_PHY_TO_IDLE);
|
||||
MCU_DIAG_MAP(10, 9, CALLBACK_IRQ);
|
||||
MCU_DIAG_MAP(11, 9, FIELD_IRQ);
|
||||
MCU_DIAG_MAP(12, 9, FRAME_IRQ);
|
||||
MCU_DIAG_MAP(13, 3, SLP_TIMER_ACTIVE);
|
||||
MCU_DIAG_MAP(14, 4, SLEEPING);
|
||||
MCU_DIAG_MAP(15, 8, LL_TIMER1_00);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -131,10 +131,10 @@ struct cmac_shared_data {
|
||||
uint8_t mbox_c2s_buf[ MYNEWT_VAL(CMAC_MBOX_SIZE_C2S) ];
|
||||
};
|
||||
|
||||
#if MYNEWT_VAL(BLE_HOST) || MYNEWT_VAL(BLE_HCI_BRIDGE)
|
||||
extern volatile struct cmac_shared_data *g_cmac_shared_data;
|
||||
#elif MYNEWT_VAL(BLE_CONTROLLER)
|
||||
#if MYNEWT_VAL(BLE_CONTROLLER)
|
||||
extern volatile struct cmac_shared_data g_cmac_shared_data;
|
||||
#else
|
||||
extern volatile struct cmac_shared_data *g_cmac_shared_data;
|
||||
#endif
|
||||
|
||||
/* cmac_mbox */
|
||||
@@ -162,10 +162,10 @@ void cmac_rand_set_isr_cb(cmac_rand_isr_cb_t cb);
|
||||
void cmac_shared_init(void);
|
||||
void cmac_shared_sync(void);
|
||||
|
||||
#if MYNEWT_VAL(BLE_HOST) || MYNEWT_VAL(BLE_HCI_BRIDGE)
|
||||
#define CMAC_SHARED_LOCK_VAL 0x40000000
|
||||
#elif MYNEWT_VAL(BLE_CONTROLLER)
|
||||
#if MYNEWT_VAL(BLE_CONTROLLER)
|
||||
#define CMAC_SHARED_LOCK_VAL 0xc0000000
|
||||
#else
|
||||
#define CMAC_SHARED_LOCK_VAL 0x40000000
|
||||
#endif
|
||||
|
||||
static inline void
|
||||
|
||||
@@ -35,8 +35,5 @@ pkg.ign_files.BLE_CONTROLLER:
|
||||
pkg.post_link_cmds.BLE_CONTROLLER:
|
||||
scripts/create_cmac_bin.sh: 100
|
||||
|
||||
pkg.pre_link_cmds.BLE_HOST:
|
||||
scripts/build_libcmac.sh: 100
|
||||
|
||||
pkg.pre_link_cmds.BLE_HCI_BRIDGE:
|
||||
pkg.pre_link_cmds.!BLE_CONTROLLER:
|
||||
scripts/build_libcmac.sh: 100
|
||||
|
||||
@@ -65,7 +65,7 @@ static struct os_event g_cmac_host_rand_ev = {
|
||||
|
||||
static void cmac_host_rand_chk_fill(void);
|
||||
|
||||
#if MYNEWT_VAL(BLE_HCI_BRIDGE) && MYNEWT_VAL_CHOICE(BLE_HCI_TRANSPORT, uart)
|
||||
#if MYNEWT_VAL_CHOICE(BLE_TRANSPORT_HS, uart)
|
||||
static void cmac_host_error_w4flush(struct os_event *ev);
|
||||
static struct os_event g_cmac_host_error_ev = {
|
||||
.ev_cb = cmac_host_error_w4flush
|
||||
@@ -113,7 +113,7 @@ cmac2sys_isr(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if MYNEWT_VAL(BLE_HCI_BRIDGE) && MYNEWT_VAL_CHOICE(BLE_HCI_TRANSPORT, uart)
|
||||
#if MYNEWT_VAL_CHOICE(BLE_TRANSPORT_HS, uart)
|
||||
NVIC_DisableIRQ(CMAC2SYS_IRQn);
|
||||
/* Wait until UART is flushed and then assert */
|
||||
cmac_host_error_w4flush(NULL);
|
||||
@@ -162,8 +162,8 @@ cmac_host_rand_chk_fill(void)
|
||||
}
|
||||
}
|
||||
|
||||
#if MYNEWT_VAL(BLE_HCI_BRIDGE) && MYNEWT_VAL_CHOICE(BLE_HCI_TRANSPORT, uart)
|
||||
#if MYNEWT_VAL(BLE_HCI_UART_PORT) < 0 || MYNEWT_VAL(BLE_HCI_UART_PORT) > 2
|
||||
#if MYNEWT_VAL_CHOICE(BLE_TRANSPORT_HS, uart)
|
||||
#if MYNEWT_VAL(BLE_TRANSPORT_UART_PORT) < 0 || MYNEWT_VAL(BLE_TRANSPORT_UART_PORT) > 2
|
||||
#error Invalid BLE_HCI_UART_PORT
|
||||
#endif
|
||||
static void
|
||||
@@ -183,7 +183,7 @@ cmac_host_error_w4flush(struct os_event *ev)
|
||||
|
||||
do {
|
||||
cmac_mbox_read();
|
||||
while ((regs[MYNEWT_VAL(BLE_HCI_UART_PORT)]->UART_LSR_REG &
|
||||
while ((regs[MYNEWT_VAL(BLE_TRANSPORT_UART_PORT)]->UART_LSR_REG &
|
||||
UART_UART_LSR_REG_UART_TEMT_Msk) == 0) {
|
||||
/* Wait until both FIFO and shift registers are empty */
|
||||
}
|
||||
|
||||
@@ -49,10 +49,10 @@ cmac_mbox_set_write_notif_cb(cmac_mbox_write_notif_cb *cb)
|
||||
int
|
||||
cmac_mbox_has_data(void)
|
||||
{
|
||||
#if MYNEWT_VAL(BLE_HOST) || MYNEWT_VAL(BLE_HCI_BRIDGE)
|
||||
volatile struct cmac_mbox *mbox = &g_cmac_shared_data->mbox_c2s;
|
||||
#else
|
||||
#if MYNEWT_VAL(BLE_CONTROLLER)
|
||||
volatile struct cmac_mbox *mbox = &g_cmac_shared_data.mbox_s2c;
|
||||
#else
|
||||
volatile struct cmac_mbox *mbox = &g_cmac_shared_data->mbox_c2s;
|
||||
#endif
|
||||
|
||||
return mbox->rd_off != mbox->wr_off;
|
||||
@@ -61,14 +61,14 @@ cmac_mbox_has_data(void)
|
||||
int
|
||||
cmac_mbox_read(void)
|
||||
{
|
||||
#if MYNEWT_VAL(BLE_HOST) || MYNEWT_VAL(BLE_HCI_BRIDGE)
|
||||
volatile struct cmac_mbox *mbox = &g_cmac_shared_data->mbox_c2s;
|
||||
uint8_t *mbox_buf = (uint8_t *)&g_cmac_shared_data->mbox_c2s_buf;
|
||||
const uint16_t mbox_size = MYNEWT_VAL(CMAC_MBOX_SIZE_C2S);
|
||||
#else
|
||||
#if MYNEWT_VAL(BLE_CONTROLLER)
|
||||
volatile struct cmac_mbox *mbox = &g_cmac_shared_data.mbox_s2c;
|
||||
uint8_t *mbox_buf = (uint8_t *)&g_cmac_shared_data.mbox_s2c_buf;
|
||||
const uint16_t mbox_size = MYNEWT_VAL(CMAC_MBOX_SIZE_S2C);
|
||||
#else
|
||||
volatile struct cmac_mbox *mbox = &g_cmac_shared_data->mbox_c2s;
|
||||
uint8_t *mbox_buf = (uint8_t *)&g_cmac_shared_data->mbox_c2s_buf;
|
||||
const uint16_t mbox_size = MYNEWT_VAL(CMAC_MBOX_SIZE_C2S);
|
||||
#endif
|
||||
uint16_t rd_off;
|
||||
uint16_t wr_off;
|
||||
@@ -108,14 +108,14 @@ cmac_mbox_read(void)
|
||||
int
|
||||
cmac_mbox_write(const void *data, uint16_t len)
|
||||
{
|
||||
#if MYNEWT_VAL(BLE_HOST) || MYNEWT_VAL(BLE_HCI_BRIDGE)
|
||||
volatile struct cmac_mbox *mbox = &g_cmac_shared_data->mbox_s2c;
|
||||
uint8_t *mbox_buf = (uint8_t *)&g_cmac_shared_data->mbox_s2c_buf;
|
||||
const uint16_t mbox_size = MYNEWT_VAL(CMAC_MBOX_SIZE_S2C);
|
||||
#else
|
||||
#if MYNEWT_VAL(BLE_CONTROLLER)
|
||||
volatile struct cmac_mbox *mbox = &g_cmac_shared_data.mbox_c2s;
|
||||
uint8_t *mbox_buf = (uint8_t *)&g_cmac_shared_data.mbox_c2s_buf;
|
||||
const uint16_t mbox_size = MYNEWT_VAL(CMAC_MBOX_SIZE_C2S);
|
||||
#else
|
||||
volatile struct cmac_mbox *mbox = &g_cmac_shared_data->mbox_s2c;
|
||||
uint8_t *mbox_buf = (uint8_t *)&g_cmac_shared_data->mbox_s2c_buf;
|
||||
const uint16_t mbox_size = MYNEWT_VAL(CMAC_MBOX_SIZE_S2C);
|
||||
#endif
|
||||
uint16_t rd_off;
|
||||
uint16_t wr_off;
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#include "os/os_arch.h"
|
||||
#include "os/os.h"
|
||||
|
||||
#if MYNEWT_VAL(BLE_HOST) || MYNEWT_VAL(BLE_HCI_BRIDGE)
|
||||
#if !MYNEWT_VAL(BLE_CONTROLLER)
|
||||
int
|
||||
cmac_rand_is_active(void)
|
||||
{
|
||||
|
||||
@@ -34,18 +34,18 @@
|
||||
#define min(_a, _b) ((_a) < (_b) ? (_a) : (_b))
|
||||
#endif
|
||||
|
||||
#if MYNEWT_VAL(BLE_HOST) || MYNEWT_VAL(BLE_HCI_BRIDGE)
|
||||
#if MYNEWT_VAL(BLE_CONTROLLER)
|
||||
volatile struct cmac_shared_data g_cmac_shared_data __attribute__((section(".shdata")));
|
||||
#else
|
||||
volatile struct cmac_shared_data *g_cmac_shared_data;
|
||||
#include "mcu/da1469x_clock.h"
|
||||
#define MCU_DIAG_SER(_x)
|
||||
#elif MYNEWT_VAL(BLE_CONTROLLER)
|
||||
volatile struct cmac_shared_data g_cmac_shared_data __attribute__((section(".shdata")));
|
||||
#endif
|
||||
|
||||
void
|
||||
cmac_shared_init(void)
|
||||
{
|
||||
#if MYNEWT_VAL(BLE_HOST) || MYNEWT_VAL(BLE_HCI_BRIDGE)
|
||||
#if !MYNEWT_VAL(BLE_CONTROLLER)
|
||||
g_cmac_shared_data = (void *)(MCU_MEM_SYSRAM_START_ADDRESS +
|
||||
MEMCTRL->CMI_SHARED_BASE_REG);
|
||||
|
||||
@@ -77,15 +77,6 @@ cmac_shared_sync(void)
|
||||
* to wait until CMAC finished initialization as otherwise host may start
|
||||
* sending HCI packets which will timeout as there is no one to read them.
|
||||
*/
|
||||
#if MYNEWT_VAL(BLE_HOST) || MYNEWT_VAL(BLE_HCI_BRIDGE)
|
||||
assert(g_cmac_shared_data->magic_sys == 0);
|
||||
|
||||
while (g_cmac_shared_data->magic_cmac != CMAC_SHARED_MAGIC_CMAC);
|
||||
g_cmac_shared_data->magic_sys = CMAC_SHARED_MAGIC_SYS;
|
||||
|
||||
NVIC_EnableIRQ(CMAC2SYS_IRQn);
|
||||
#endif
|
||||
|
||||
#if MYNEWT_VAL(BLE_CONTROLLER)
|
||||
assert(g_cmac_shared_data.magic_cmac == 0);
|
||||
|
||||
@@ -94,5 +85,12 @@ cmac_shared_sync(void)
|
||||
|
||||
NVIC_SetPriority(SYS2CMAC_IRQn, 3);
|
||||
NVIC_EnableIRQ(SYS2CMAC_IRQn);
|
||||
#else
|
||||
assert(g_cmac_shared_data->magic_sys == 0);
|
||||
|
||||
while (g_cmac_shared_data->magic_cmac != CMAC_SHARED_MAGIC_CMAC);
|
||||
g_cmac_shared_data->magic_sys = CMAC_SHARED_MAGIC_SYS;
|
||||
|
||||
NVIC_EnableIRQ(CMAC2SYS_IRQn);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -100,5 +100,5 @@ syscfg.defs:
|
||||
priority.
|
||||
value: 0
|
||||
|
||||
syscfg.restrictions.BLE_HOST:
|
||||
syscfg.restrictions.!BLE_CONTROLLER:
|
||||
- TRNG
|
||||
|
||||
@@ -26,11 +26,8 @@ pkg.keywords:
|
||||
- bluetooth
|
||||
|
||||
pkg.deps:
|
||||
- nimble
|
||||
- nimble/transport/common/hci_h4
|
||||
- nimble/transport/dialog_cmac/cmac_driver
|
||||
|
||||
pkg.apis:
|
||||
- ble_transport
|
||||
|
||||
pkg.init:
|
||||
ble_hci_cmac_init: 100
|
||||
|
||||
@@ -1,202 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "syscfg/syscfg.h"
|
||||
#include "os/mynewt.h"
|
||||
#include "nimble/ble.h"
|
||||
#include "nimble/ble_hci_trans.h"
|
||||
#include "nimble/hci_common.h"
|
||||
#include "ble_hci_cmac_priv.h"
|
||||
|
||||
/*
|
||||
* If controller-to-host flow control is enabled we need to hold an extra command
|
||||
* buffer for HCI_Host_Number_Of_Completed_Packets which can be sent at any time.
|
||||
*/
|
||||
#if MYNEWT_VAL(BLE_HS_FLOW_CTRL) || MYNEWT_VAL(BLE_LL_CFG_FEAT_CTRL_TO_HOST_FLOW_CONTROL)
|
||||
#define HCI_CMD_COUNT 2
|
||||
#else
|
||||
#define HCI_CMD_COUNT 1
|
||||
#endif
|
||||
|
||||
#define POOL_ACL_BLOCK_SIZE OS_ALIGN(MYNEWT_VAL(BLE_ACL_BUF_SIZE) + \
|
||||
BLE_MBUF_MEMBLOCK_OVERHEAD + \
|
||||
BLE_HCI_DATA_HDR_SZ, OS_ALIGNMENT)
|
||||
|
||||
#if !MYNEWT_VAL(BLE_HCI_BRIDGE)
|
||||
static uint8_t ble_hci_pool_cmd_mempool_buf[
|
||||
OS_MEMPOOL_BYTES(HCI_CMD_COUNT, BLE_HCI_TRANS_CMD_SZ)];
|
||||
static struct os_mempool ble_hci_pool_cmd_mempool;
|
||||
|
||||
static uint8_t ble_hci_pool_evt_hi_mempool_buf[
|
||||
OS_MEMPOOL_BYTES(MYNEWT_VAL(BLE_HCI_EVT_HI_BUF_COUNT),
|
||||
MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE))];
|
||||
static struct os_mempool ble_hci_pool_evt_hi_mempool;
|
||||
|
||||
static uint8_t ble_hci_pool_evt_lo_mempool_buf[
|
||||
OS_MEMPOOL_BYTES(MYNEWT_VAL(BLE_HCI_EVT_LO_BUF_COUNT),
|
||||
MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE))];
|
||||
static struct os_mempool ble_hci_pool_evt_lo_mempool;
|
||||
#endif
|
||||
|
||||
static uint8_t ble_hci_pool_acl_mempool_buf[
|
||||
OS_MEMPOOL_BYTES(MYNEWT_VAL(BLE_ACL_BUF_COUNT),
|
||||
POOL_ACL_BLOCK_SIZE)];
|
||||
static struct os_mempool_ext ble_hci_pool_acl_mempool;
|
||||
static struct os_mbuf_pool ble_hci_pool_acl_mbuf_pool;
|
||||
|
||||
__attribute__((weak)) void ble_hci_trans_notify_free(void);
|
||||
|
||||
static os_mempool_put_fn *g_ble_hci_pool_acl_mempool_put_cb;
|
||||
static void *g_ble_hci_pool_acl_mempool_put_arg;
|
||||
|
||||
#if !MYNEWT_VAL(BLE_HCI_BRIDGE)
|
||||
int
|
||||
ble_hci_trans_reset(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t *
|
||||
ble_hci_trans_buf_alloc(int type)
|
||||
{
|
||||
uint8_t *buf;
|
||||
|
||||
switch (type) {
|
||||
case BLE_HCI_TRANS_BUF_CMD:
|
||||
buf = os_memblock_get(&ble_hci_pool_cmd_mempool);
|
||||
break;
|
||||
case BLE_HCI_TRANS_BUF_EVT_HI:
|
||||
buf = os_memblock_get(&ble_hci_pool_evt_hi_mempool);
|
||||
if (buf) {
|
||||
break;
|
||||
}
|
||||
/* no break */
|
||||
case BLE_HCI_TRANS_BUF_EVT_LO:
|
||||
buf = os_memblock_get(&ble_hci_pool_evt_lo_mempool);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
buf = NULL;
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
void
|
||||
ble_hci_trans_buf_free(uint8_t *buf)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (os_memblock_from(&ble_hci_pool_cmd_mempool, buf)) {
|
||||
rc = os_memblock_put(&ble_hci_pool_cmd_mempool, buf);
|
||||
assert(rc == 0);
|
||||
} else if (os_memblock_from(&ble_hci_pool_evt_hi_mempool, buf)) {
|
||||
rc = os_memblock_put(&ble_hci_pool_evt_hi_mempool, buf);
|
||||
assert(rc == 0);
|
||||
} else {
|
||||
assert(os_memblock_from(&ble_hci_pool_evt_lo_mempool, buf));
|
||||
rc = os_memblock_put(&ble_hci_pool_evt_lo_mempool, buf);
|
||||
assert(rc == 0);
|
||||
}
|
||||
|
||||
ble_hci_trans_notify_free();
|
||||
}
|
||||
#endif
|
||||
|
||||
struct os_mbuf *
|
||||
ble_hci_cmac_alloc_acl_mbuf(void)
|
||||
{
|
||||
return os_mbuf_get_pkthdr(&ble_hci_pool_acl_mbuf_pool,
|
||||
sizeof(struct ble_mbuf_hdr));
|
||||
}
|
||||
|
||||
static os_error_t
|
||||
ble_hci_cmac_free_acl_cb(struct os_mempool_ext *mpe, void *data, void *arg)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (g_ble_hci_pool_acl_mempool_put_cb) {
|
||||
rc = g_ble_hci_pool_acl_mempool_put_cb(mpe, data,
|
||||
g_ble_hci_pool_acl_mempool_put_arg);
|
||||
} else {
|
||||
rc = os_memblock_put_from_cb(&mpe->mpe_mp, data);
|
||||
}
|
||||
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
ble_hci_trans_notify_free();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#if !MYNEWT_VAL(BLE_HCI_BRIDGE)
|
||||
int
|
||||
ble_hci_trans_set_acl_free_cb(os_mempool_put_fn *cb, void *arg)
|
||||
{
|
||||
g_ble_hci_pool_acl_mempool_put_cb = cb;
|
||||
g_ble_hci_pool_acl_mempool_put_arg = arg;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
ble_hci_cmac_init(void)
|
||||
{
|
||||
int rc;
|
||||
|
||||
SYSINIT_ASSERT_ACTIVE();
|
||||
|
||||
#if !MYNEWT_VAL(BLE_HCI_BRIDGE)
|
||||
rc = os_mempool_init(&ble_hci_pool_cmd_mempool,
|
||||
HCI_CMD_COUNT, BLE_HCI_TRANS_CMD_SZ,
|
||||
ble_hci_pool_cmd_mempool_buf, "ble_hci_cmd");
|
||||
SYSINIT_PANIC_ASSERT(rc == 0);
|
||||
|
||||
rc = os_mempool_init(&ble_hci_pool_evt_hi_mempool,
|
||||
MYNEWT_VAL(BLE_HCI_EVT_HI_BUF_COUNT),
|
||||
MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE),
|
||||
ble_hci_pool_evt_hi_mempool_buf, "ble_hci_evt_hi");
|
||||
SYSINIT_PANIC_ASSERT(rc == 0);
|
||||
|
||||
rc = os_mempool_init(&ble_hci_pool_evt_lo_mempool,
|
||||
MYNEWT_VAL(BLE_HCI_EVT_LO_BUF_COUNT),
|
||||
MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE),
|
||||
ble_hci_pool_evt_lo_mempool_buf, "ble_hci_evt_lo");
|
||||
SYSINIT_PANIC_ASSERT(rc == 0);
|
||||
#endif
|
||||
|
||||
rc = os_mempool_ext_init(&ble_hci_pool_acl_mempool,
|
||||
MYNEWT_VAL(BLE_ACL_BUF_COUNT), POOL_ACL_BLOCK_SIZE,
|
||||
ble_hci_pool_acl_mempool_buf, "ble_hci_acl");
|
||||
SYSINIT_PANIC_ASSERT(rc == 0);
|
||||
|
||||
rc = os_mbuf_pool_init(&ble_hci_pool_acl_mbuf_pool,
|
||||
&ble_hci_pool_acl_mempool.mpe_mp, POOL_ACL_BLOCK_SIZE,
|
||||
MYNEWT_VAL(BLE_ACL_BUF_COUNT));
|
||||
SYSINIT_PANIC_ASSERT(rc == 0);
|
||||
|
||||
ble_hci_pool_acl_mempool.mpe_put_cb = ble_hci_cmac_free_acl_cb;
|
||||
}
|
||||
@@ -1,174 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include "syscfg/syscfg.h"
|
||||
|
||||
#if MYNEWT_VAL(BLE_HOST) || MYNEWT_VAL(BLE_HCI_BRIDGE)
|
||||
|
||||
#include "cmac_driver/cmac_shared.h"
|
||||
#include "cmac_driver/cmac_host.h"
|
||||
#include "nimble/ble_hci_trans.h"
|
||||
#include "os/os_mbuf.h"
|
||||
#include "ble_hci_trans_h4.h"
|
||||
#include "ble_hci_cmac_priv.h"
|
||||
|
||||
struct ble_hci_cmac_hs_api {
|
||||
ble_hci_trans_rx_cmd_fn *evt_cb;
|
||||
void *evt_arg;
|
||||
ble_hci_trans_rx_acl_fn *acl_cb;
|
||||
void *acl_arg;
|
||||
};
|
||||
|
||||
static struct ble_hci_cmac_hs_api g_ble_hci_cmac_hs_api;
|
||||
static struct ble_hci_trans_h4_rx_state g_ble_hci_cmac_hs_rx_state;
|
||||
static bool g_ble_hci_cmac_hs_read_err;
|
||||
|
||||
#if MYNEWT_VAL(BLE_HCI_BRIDGE)
|
||||
/*
|
||||
* TODO: Remove/fix functions ble_ll_data_buffer_overflow() ble_ll_hw_error()
|
||||
* Following two functions are added to allowed build of HCI bridge configurations.
|
||||
* Those functions are only used by UART transport, in RAM transport configuration
|
||||
* they can be called directly in bridge mode controller code is on other core
|
||||
* and those can't be called.
|
||||
*/
|
||||
void
|
||||
ble_ll_data_buffer_overflow(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
ble_ll_hw_error(uint8_t err)
|
||||
{
|
||||
(void)err;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
ble_hci_cmac_hs_frame_cb(uint8_t pkt_type, void *data)
|
||||
{
|
||||
int rc;
|
||||
|
||||
switch (pkt_type) {
|
||||
case BLE_HCI_TRANS_H4_PKT_TYPE_ACL:
|
||||
rc = g_ble_hci_cmac_hs_api.acl_cb(data, g_ble_hci_cmac_hs_api.acl_arg);
|
||||
break;
|
||||
case BLE_HCI_TRANS_H4_PKT_TYPE_EVT:
|
||||
rc = g_ble_hci_cmac_hs_api.evt_cb(data, g_ble_hci_cmac_hs_api.evt_arg);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
ble_hci_cmac_hs_mbox_read_cb(const void *data, uint16_t len)
|
||||
{
|
||||
int rlen;
|
||||
os_sr_t sr;
|
||||
|
||||
rlen = ble_hci_trans_h4_rx(&g_ble_hci_cmac_hs_rx_state, data, len,
|
||||
ble_hci_cmac_hs_frame_cb);
|
||||
if (rlen < 0) {
|
||||
/*
|
||||
* There was oom error, we need to wait for buffer to be freed and
|
||||
* trigger another read.
|
||||
*/
|
||||
OS_ENTER_CRITICAL(sr);
|
||||
g_ble_hci_cmac_hs_read_err = true;
|
||||
OS_EXIT_CRITICAL(sr);
|
||||
}
|
||||
|
||||
return rlen;
|
||||
}
|
||||
|
||||
static void
|
||||
ble_hci_cmac_hs_mbox_write_notif_cb(void)
|
||||
{
|
||||
cmac_host_signal2cmac();
|
||||
}
|
||||
|
||||
int
|
||||
ble_hci_trans_hs_cmd_tx(uint8_t *cmd)
|
||||
{
|
||||
uint8_t pkt_type = BLE_HCI_TRANS_H4_PKT_TYPE_CMD;
|
||||
|
||||
cmac_mbox_write(&pkt_type, sizeof(pkt_type));
|
||||
cmac_mbox_write(cmd, cmd[2] + 3);
|
||||
|
||||
ble_hci_trans_buf_free(cmd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ble_hci_trans_hs_acl_tx(struct os_mbuf *om)
|
||||
{
|
||||
uint8_t pkt_type = BLE_HCI_TRANS_H4_PKT_TYPE_ACL;
|
||||
struct os_mbuf *om_next;
|
||||
|
||||
cmac_mbox_write(&pkt_type, sizeof(pkt_type));
|
||||
|
||||
while (om) {
|
||||
om_next = SLIST_NEXT(om, om_next);
|
||||
|
||||
cmac_mbox_write(om->om_data, om->om_len);
|
||||
|
||||
os_mbuf_free(om);
|
||||
om = om_next;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
ble_hci_trans_notify_free(void)
|
||||
{
|
||||
os_sr_t sr;
|
||||
|
||||
OS_ENTER_CRITICAL(sr);
|
||||
if (g_ble_hci_cmac_hs_read_err) {
|
||||
g_ble_hci_cmac_hs_read_err = false;
|
||||
/* Just trigger an interrupt, it will trigger read */
|
||||
NVIC_SetPendingIRQ(CMAC2SYS_IRQn);
|
||||
}
|
||||
OS_EXIT_CRITICAL(sr);
|
||||
}
|
||||
|
||||
void
|
||||
ble_hci_trans_cfg_hs(ble_hci_trans_rx_cmd_fn *evt_cb, void *evt_arg,
|
||||
ble_hci_trans_rx_acl_fn *acl_cb, void *acl_arg)
|
||||
{
|
||||
g_ble_hci_cmac_hs_api.evt_cb = evt_cb;
|
||||
g_ble_hci_cmac_hs_api.evt_arg = evt_arg;
|
||||
g_ble_hci_cmac_hs_api.acl_cb = acl_cb;
|
||||
g_ble_hci_cmac_hs_api.acl_arg = acl_arg;
|
||||
|
||||
/* We can now handle data from CMAC, initialize it */
|
||||
cmac_mbox_set_read_cb(ble_hci_cmac_hs_mbox_read_cb);
|
||||
cmac_mbox_set_write_notif_cb(ble_hci_cmac_hs_mbox_write_notif_cb);
|
||||
cmac_host_init();
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,146 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "syscfg/syscfg.h"
|
||||
|
||||
#if MYNEWT_VAL(BLE_CONTROLLER)
|
||||
|
||||
#if !MYNEWT_VAL(MCU_DEBUG_DSER_BLE_HCI_CMAC_LL)
|
||||
#define MCU_DIAG_SER_DISABLE
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include "mcu/mcu.h"
|
||||
#include "cmac_driver/cmac_shared.h"
|
||||
#include "nimble/ble_hci_trans.h"
|
||||
#include "os/os_mbuf.h"
|
||||
#include "ble_hci_trans_h4.h"
|
||||
#include "ble_hci_cmac_priv.h"
|
||||
|
||||
struct ble_hci_cmac_ll_api {
|
||||
ble_hci_trans_rx_cmd_fn *cmd_cb;
|
||||
void *cmd_arg;
|
||||
ble_hci_trans_rx_acl_fn *acl_cb;
|
||||
void *acl_arg;
|
||||
};
|
||||
|
||||
static struct ble_hci_cmac_ll_api g_ble_hci_cmac_ll_api;
|
||||
static struct ble_hci_trans_h4_rx_state g_ble_hci_cmac_ll_rx_state;
|
||||
|
||||
static int
|
||||
ble_hci_cmac_ll_frame_cb(uint8_t pkt_type, void *data)
|
||||
{
|
||||
int rc;
|
||||
|
||||
MCU_DIAG_SER('F');
|
||||
|
||||
switch (pkt_type) {
|
||||
case BLE_HCI_TRANS_H4_PKT_TYPE_CMD:
|
||||
rc = g_ble_hci_cmac_ll_api.cmd_cb(data, g_ble_hci_cmac_ll_api.cmd_arg);
|
||||
break;
|
||||
case BLE_HCI_TRANS_H4_PKT_TYPE_ACL:
|
||||
rc = g_ble_hci_cmac_ll_api.acl_cb(data, g_ble_hci_cmac_ll_api.acl_arg);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
ble_hci_cmac_ll_mbox_read_cb(const void *data, uint16_t len)
|
||||
{
|
||||
int rlen;
|
||||
|
||||
MCU_DIAG_SER('R');
|
||||
rlen = ble_hci_trans_h4_rx(&g_ble_hci_cmac_ll_rx_state, data, len,
|
||||
ble_hci_cmac_ll_frame_cb);
|
||||
|
||||
/* There should be no oom on LL side due to flow control used */
|
||||
assert(rlen >= 0);
|
||||
|
||||
return rlen;
|
||||
}
|
||||
|
||||
static void
|
||||
ble_hci_cmac_ll_mbox_write_notif_cb(void)
|
||||
{
|
||||
MCU_DIAG_SER('W');
|
||||
CMAC->CM_EV_SET_REG = CMAC_CM_EV_SET_REG_EV1C_CMAC2SYS_IRQ_SET_Msk;
|
||||
}
|
||||
|
||||
int
|
||||
ble_hci_trans_ll_evt_tx(uint8_t *evt)
|
||||
{
|
||||
uint8_t pkt_type = BLE_HCI_TRANS_H4_PKT_TYPE_EVT;
|
||||
os_sr_t sr;
|
||||
|
||||
OS_ENTER_CRITICAL(sr);
|
||||
|
||||
cmac_mbox_write(&pkt_type, sizeof(pkt_type));
|
||||
cmac_mbox_write(evt, evt[1] + 2);
|
||||
|
||||
ble_hci_trans_buf_free(evt);
|
||||
|
||||
OS_EXIT_CRITICAL(sr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ble_hci_trans_ll_acl_tx(struct os_mbuf *om)
|
||||
{
|
||||
uint8_t pkt_type = BLE_HCI_TRANS_H4_PKT_TYPE_ACL;
|
||||
struct os_mbuf *om_next;
|
||||
|
||||
cmac_mbox_write(&pkt_type, sizeof(pkt_type));
|
||||
|
||||
while (om) {
|
||||
om_next = SLIST_NEXT(om, om_next);
|
||||
|
||||
cmac_mbox_write(om->om_data, om->om_len);
|
||||
|
||||
os_mbuf_free(om);
|
||||
om = om_next;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
ble_hci_trans_cfg_ll(ble_hci_trans_rx_cmd_fn *cmd_cb, void *cmd_arg,
|
||||
ble_hci_trans_rx_acl_fn *acl_cb, void *acl_arg)
|
||||
{
|
||||
g_ble_hci_cmac_ll_api.cmd_cb = cmd_cb;
|
||||
g_ble_hci_cmac_ll_api.cmd_arg = cmd_arg;
|
||||
g_ble_hci_cmac_ll_api.acl_cb = acl_cb;
|
||||
g_ble_hci_cmac_ll_api.acl_arg = acl_arg;
|
||||
|
||||
/* Setup callbacks for mailboxes */
|
||||
cmac_mbox_set_read_cb(ble_hci_cmac_ll_mbox_read_cb);
|
||||
cmac_mbox_set_write_notif_cb(ble_hci_cmac_ll_mbox_write_notif_cb);
|
||||
|
||||
/* Synchronize with SYS */
|
||||
cmac_shared_sync();
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,29 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _BLE_HCI_CMAC_PRIV_H_
|
||||
#define _BLE_HCI_CMAC_PRIV_H_
|
||||
|
||||
#include "os/os_mbuf.h"
|
||||
|
||||
struct os_mbuf *ble_hci_cmac_alloc_acl_mbuf(void);
|
||||
|
||||
void ble_hci_trans_notify_free(void);
|
||||
|
||||
#endif /* _BLE_HCI_CMAC_PRIV_H_ */
|
||||
@@ -1,332 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include "syscfg/syscfg.h"
|
||||
#include "os/os_mbuf.h"
|
||||
#include "nimble/ble_hci_trans.h"
|
||||
#include "nimble/hci_common.h"
|
||||
#include "ble_hci_trans_h4.h"
|
||||
#include "ble_hci_cmac_priv.h"
|
||||
|
||||
#define RXS_STATE_W4_PKT_TYPE 0
|
||||
#define RXS_STATE_W4_HEADER 1
|
||||
#define RXS_STATE_W4_PAYLOAD 2
|
||||
#define RXS_STATE_COMPLETED 3
|
||||
|
||||
struct input_buffer {
|
||||
const uint8_t *buf;
|
||||
uint16_t len;
|
||||
};
|
||||
|
||||
static int
|
||||
ble_hci_trans_h4_ib_adjust(struct input_buffer *ib, uint16_t len)
|
||||
{
|
||||
assert(ib->len >= len);
|
||||
|
||||
ib->buf += len;
|
||||
ib->len -= len;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static void
|
||||
ble_hci_trans_h4_rxs_start(struct ble_hci_trans_h4_rx_state *rxs, uint8_t pkt_type)
|
||||
{
|
||||
rxs->pkt_type = pkt_type;
|
||||
rxs->len = 0;
|
||||
rxs->expected_len = 0;
|
||||
|
||||
switch (rxs->pkt_type) {
|
||||
#if MYNEWT_VAL(BLE_CONTROLLER)
|
||||
case BLE_HCI_TRANS_H4_PKT_TYPE_CMD:
|
||||
rxs->min_len = 3;
|
||||
break;
|
||||
#endif
|
||||
case BLE_HCI_TRANS_H4_PKT_TYPE_ACL:
|
||||
rxs->min_len = 4;
|
||||
break;
|
||||
#if MYNEWT_VAL(BLE_HOST) || MYNEWT_VAL(BLE_HCI_BRIDGE)
|
||||
case BLE_HCI_TRANS_H4_PKT_TYPE_EVT:
|
||||
rxs->min_len = 2;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
/* XXX sync loss */
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
ble_hci_trans_h4_pull_min_len(struct ble_hci_trans_h4_rx_state *rxs,
|
||||
struct input_buffer *ib)
|
||||
{
|
||||
uint16_t len;
|
||||
|
||||
len = min(ib->len, rxs->min_len - rxs->len);
|
||||
memcpy(&rxs->hdr[rxs->len], ib->buf, len);
|
||||
|
||||
rxs->len += len;
|
||||
ble_hci_trans_h4_ib_adjust(ib, len);
|
||||
|
||||
return rxs->len != rxs->min_len;
|
||||
}
|
||||
|
||||
static int
|
||||
ble_hci_trans_h4_rx_state_w4_header(struct ble_hci_trans_h4_rx_state *rxs,
|
||||
struct input_buffer *ib)
|
||||
{
|
||||
#if MYNEWT_VAL(BLE_HOST) || MYNEWT_VAL(BLE_HCI_BRIDGE)
|
||||
int pool;
|
||||
#endif
|
||||
int rc;
|
||||
|
||||
rc = ble_hci_trans_h4_pull_min_len(rxs, ib);
|
||||
if (rc) {
|
||||
/* need more data */
|
||||
return 1;
|
||||
}
|
||||
|
||||
switch (rxs->pkt_type) {
|
||||
#if MYNEWT_VAL(BLE_CONTROLLER)
|
||||
case BLE_HCI_TRANS_H4_PKT_TYPE_CMD:
|
||||
rxs->buf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_CMD);
|
||||
if (!rxs->buf) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(rxs->buf, rxs->hdr, rxs->len);
|
||||
rxs->expected_len = rxs->hdr[2] + 3;
|
||||
break;
|
||||
#endif
|
||||
case BLE_HCI_TRANS_H4_PKT_TYPE_ACL:
|
||||
rxs->om = ble_hci_cmac_alloc_acl_mbuf();
|
||||
if (!rxs->om) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
os_mbuf_append(rxs->om, rxs->hdr, rxs->len);
|
||||
rxs->expected_len = get_le16(&rxs->hdr[2]) + 4;
|
||||
break;
|
||||
#if MYNEWT_VAL(BLE_HOST) || MYNEWT_VAL(BLE_HCI_BRIDGE)
|
||||
case BLE_HCI_TRANS_H4_PKT_TYPE_EVT:
|
||||
pool = BLE_HCI_TRANS_BUF_EVT_HI;
|
||||
if (rxs->hdr[0] == BLE_HCI_EVCODE_LE_META) {
|
||||
/* For LE Meta event we need 3 bytes to parse header */
|
||||
rxs->min_len = 3;
|
||||
rc = ble_hci_trans_h4_pull_min_len(rxs, ib);
|
||||
if (rc) {
|
||||
/* need more data */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Advertising reports shall be allocated from low-prio pool */
|
||||
if ((rxs->hdr[2] == BLE_HCI_LE_SUBEV_ADV_RPT) ||
|
||||
(rxs->hdr[2] == BLE_HCI_LE_SUBEV_EXT_ADV_RPT)) {
|
||||
pool = BLE_HCI_TRANS_BUF_EVT_LO;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX Events originally allocated from hi-pool can use lo-pool as
|
||||
* fallback and cannot be dropped. Events allocated from lo-pool
|
||||
* can be dropped to avoid oom while scanning which means that
|
||||
* any advertising or extended advertising report can be silently
|
||||
* discarded by transport. While this is perfectly fine for legacy
|
||||
* advertising, for extended advertising it means we can drop start
|
||||
* or end of chain report and host won't be able to reassemble
|
||||
* chain properly... so just need to make sure pool on host side is
|
||||
* large enough to catch up with controller.
|
||||
*/
|
||||
rxs->buf = ble_hci_trans_buf_alloc(pool);
|
||||
if (!rxs->buf && pool == BLE_HCI_TRANS_BUF_EVT_HI) {
|
||||
rxs->buf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_LO);
|
||||
if (!rxs->buf) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (rxs->buf) {
|
||||
memcpy(rxs->buf, rxs->hdr, rxs->len);
|
||||
}
|
||||
|
||||
rxs->expected_len = rxs->hdr[1] + 2;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
ble_hci_trans_h4_rx_state_w4_payload(struct ble_hci_trans_h4_rx_state *rxs,
|
||||
struct input_buffer *ib)
|
||||
{
|
||||
uint16_t mbuf_len;
|
||||
uint16_t len;
|
||||
int rc;
|
||||
|
||||
len = min(ib->len, rxs->expected_len - rxs->len);
|
||||
|
||||
switch (rxs->pkt_type) {
|
||||
#if MYNEWT_VAL(BLE_CONTROLLER)
|
||||
case BLE_HCI_TRANS_H4_PKT_TYPE_CMD:
|
||||
#endif
|
||||
#if MYNEWT_VAL(BLE_HOST) || MYNEWT_VAL(BLE_HCI_BRIDGE)
|
||||
case BLE_HCI_TRANS_H4_PKT_TYPE_EVT:
|
||||
#endif
|
||||
if (rxs->buf) {
|
||||
memcpy(&rxs->buf[rxs->len], ib->buf, len);
|
||||
}
|
||||
break;
|
||||
case BLE_HCI_TRANS_H4_PKT_TYPE_ACL:
|
||||
assert(rxs->om);
|
||||
|
||||
mbuf_len = OS_MBUF_PKTLEN(rxs->om);
|
||||
rc = os_mbuf_append(rxs->om, ib->buf, len);
|
||||
if (rc) {
|
||||
/*
|
||||
* Some data may already be appended so need to adjust rxs only by
|
||||
* the size of appended data.
|
||||
*/
|
||||
len = OS_MBUF_PKTLEN(rxs->om) - mbuf_len;
|
||||
rxs->len += len;
|
||||
ble_hci_trans_h4_ib_adjust(ib, len);
|
||||
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
|
||||
rxs->len += len;
|
||||
ble_hci_trans_h4_ib_adjust(ib, len);
|
||||
|
||||
/* return 1 if need more data */
|
||||
return rxs->len != rxs->expected_len;
|
||||
}
|
||||
|
||||
static void
|
||||
ble_hci_trans_h4_rx_state_completed(struct ble_hci_trans_h4_rx_state *rxs,
|
||||
ble_hci_trans_h4_frame_cb *frame_cb)
|
||||
{
|
||||
int rc;
|
||||
|
||||
switch (rxs->pkt_type) {
|
||||
#if MYNEWT_VAL(BLE_CONTROLLER)
|
||||
case BLE_HCI_TRANS_H4_PKT_TYPE_CMD:
|
||||
#endif
|
||||
#if MYNEWT_VAL(BLE_HOST) || MYNEWT_VAL(BLE_HCI_BRIDGE)
|
||||
case BLE_HCI_TRANS_H4_PKT_TYPE_EVT:
|
||||
#endif
|
||||
if (rxs->buf) {
|
||||
rc = frame_cb(rxs->pkt_type, rxs->buf);
|
||||
if (rc != 0) {
|
||||
ble_hci_trans_buf_free(rxs->buf);
|
||||
}
|
||||
rxs->buf = NULL;
|
||||
}
|
||||
break;
|
||||
case BLE_HCI_TRANS_H4_PKT_TYPE_ACL:
|
||||
if (rxs->om) {
|
||||
rc = frame_cb(rxs->pkt_type, rxs->om);
|
||||
if (rc != 0) {
|
||||
os_mbuf_free_chain(rxs->om);
|
||||
}
|
||||
rxs->om = NULL;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
ble_hci_trans_h4_rx(struct ble_hci_trans_h4_rx_state *rxs, const uint8_t *buf,
|
||||
uint16_t len, ble_hci_trans_h4_frame_cb *frame_cb)
|
||||
{
|
||||
struct input_buffer ib = {
|
||||
.buf = buf,
|
||||
.len = len,
|
||||
};
|
||||
int rc = 0;
|
||||
|
||||
while (ib.len && (rc >= 0)) {
|
||||
rc = 0;
|
||||
switch (rxs->state) {
|
||||
case RXS_STATE_W4_PKT_TYPE:
|
||||
ble_hci_trans_h4_rxs_start(rxs, ib.buf[0]);
|
||||
ble_hci_trans_h4_ib_adjust(&ib, 1);
|
||||
rxs->state = RXS_STATE_W4_HEADER;
|
||||
/* no break */
|
||||
|
||||
case RXS_STATE_W4_HEADER:
|
||||
rc = ble_hci_trans_h4_rx_state_w4_header(rxs, &ib);
|
||||
if (rc) {
|
||||
break;
|
||||
}
|
||||
rxs->state = RXS_STATE_W4_PAYLOAD;
|
||||
/* no break */
|
||||
|
||||
case RXS_STATE_W4_PAYLOAD:
|
||||
rc = ble_hci_trans_h4_rx_state_w4_payload(rxs, &ib);
|
||||
if (rc) {
|
||||
break;
|
||||
}
|
||||
rxs->state = RXS_STATE_COMPLETED;
|
||||
/* no break */
|
||||
|
||||
case RXS_STATE_COMPLETED:
|
||||
ble_hci_trans_h4_rx_state_completed(rxs, frame_cb);
|
||||
rxs->state = RXS_STATE_W4_PKT_TYPE;
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
/* consume all remaining data */
|
||||
ble_hci_trans_h4_ib_adjust(&ib, ib.len);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate consumed bytes
|
||||
*
|
||||
* Note: we should always consume some bytes unless there is an oom error.
|
||||
* It's also possible that we have an oom error but already consumed some
|
||||
* data, in such case just return success and error will be returned on next
|
||||
* pass.
|
||||
*/
|
||||
len = len - ib.len;
|
||||
if (len == 0) {
|
||||
assert(rc < 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _BLE_HCI_TRANS_H4_H_
|
||||
#define _BLE_HCI_TRANS_H4_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define BLE_HCI_TRANS_H4_PKT_TYPE_NONE 0x00
|
||||
#define BLE_HCI_TRANS_H4_PKT_TYPE_CMD 0x01
|
||||
#define BLE_HCI_TRANS_H4_PKT_TYPE_ACL 0x02
|
||||
#define BLE_HCI_TRANS_H4_PKT_TYPE_EVT 0x04
|
||||
|
||||
struct ble_hci_trans_h4_rx_state {
|
||||
uint8_t state;
|
||||
uint8_t pkt_type;
|
||||
uint8_t min_len;
|
||||
uint16_t len;
|
||||
uint16_t expected_len;
|
||||
uint8_t hdr[4];
|
||||
union {
|
||||
uint8_t *buf;
|
||||
struct os_mbuf *om;
|
||||
};
|
||||
};
|
||||
|
||||
typedef int (ble_hci_trans_h4_frame_cb)(uint8_t pkt_type, void *data);
|
||||
|
||||
int ble_hci_trans_h4_rx(struct ble_hci_trans_h4_rx_state *rxs,
|
||||
const uint8_t *buf, uint16_t len,
|
||||
ble_hci_trans_h4_frame_cb *frame_cb);
|
||||
|
||||
#endif /* _BLE_HCI_TRANS_H4_H_ */
|
||||
@@ -0,0 +1,213 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <syscfg/syscfg.h>
|
||||
#if MYNEWT_VAL(BLE_CONTROLLER)
|
||||
/* to enable dser diag */
|
||||
#include <mcu/mcu.h>
|
||||
#endif /* BLE_CONTROLLER */
|
||||
#include <cmac_driver/cmac_shared.h>
|
||||
#if !MYNEWT_VAL(BLE_CONTROLLER)
|
||||
#include <cmac_driver/cmac_host.h>
|
||||
#endif /* !BLE_CONTROLLER */
|
||||
#include <os/os_mbuf.h>
|
||||
#include <os/os_mempool.h>
|
||||
#include <nimble/transport.h>
|
||||
#include <nimble/transport/hci_h4.h>
|
||||
|
||||
static struct hci_h4_sm hci_cmac_h4sm;
|
||||
|
||||
static int
|
||||
hci_cmac_acl_tx(struct os_mbuf *om)
|
||||
{
|
||||
uint8_t pkt_type = HCI_H4_ACL;
|
||||
struct os_mbuf *om_next;
|
||||
|
||||
cmac_mbox_write(&pkt_type, sizeof(pkt_type));
|
||||
|
||||
while (om) {
|
||||
om_next = SLIST_NEXT(om, om_next);
|
||||
|
||||
cmac_mbox_write(om->om_data, om->om_len);
|
||||
|
||||
os_mbuf_free(om);
|
||||
om = om_next;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if !MYNEWT_VAL(BLE_CONTROLLER)
|
||||
static int
|
||||
hci_cmac_hs_frame_cb(uint8_t pkt_type, void *data)
|
||||
{
|
||||
int rc;
|
||||
|
||||
switch (pkt_type) {
|
||||
case HCI_H4_ACL:
|
||||
rc = ble_transport_to_hs_acl(data);
|
||||
break;
|
||||
case HCI_H4_EVT:
|
||||
rc = ble_transport_to_hs_evt(data);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
hci_cmac_hs_mbox_read_cb(const void *data, uint16_t len)
|
||||
{
|
||||
int rlen;
|
||||
|
||||
rlen = hci_h4_sm_rx(&hci_cmac_h4sm, data, len);
|
||||
assert(rlen >= 0);
|
||||
|
||||
return rlen;
|
||||
}
|
||||
|
||||
static void
|
||||
hci_cmac_hs_mbox_write_notif_cb(void)
|
||||
{
|
||||
cmac_host_signal2cmac();
|
||||
}
|
||||
|
||||
void
|
||||
ble_transport_ll_init(void)
|
||||
{
|
||||
hci_h4_sm_init(&hci_cmac_h4sm, &hci_h4_allocs_from_ll, hci_cmac_hs_frame_cb);
|
||||
|
||||
/* We can now handle data from CMAC, initialize it */
|
||||
cmac_mbox_set_read_cb(hci_cmac_hs_mbox_read_cb);
|
||||
cmac_mbox_set_write_notif_cb(hci_cmac_hs_mbox_write_notif_cb);
|
||||
cmac_host_init();
|
||||
}
|
||||
#endif /* !BLE_CONTROLLER */
|
||||
|
||||
#if MYNEWT_VAL(BLE_CONTROLLER)
|
||||
#if !MYNEWT_VAL(MCU_DEBUG_DSER_BLE_HCI_CMAC_LL)
|
||||
#define MCU_DIAG_SER_DISABLE
|
||||
#endif
|
||||
|
||||
static int
|
||||
hci_cmac_ll_frame_cb(uint8_t pkt_type, void *data)
|
||||
{
|
||||
int rc;
|
||||
|
||||
switch (pkt_type) {
|
||||
case HCI_H4_CMD:
|
||||
rc = ble_transport_to_ll_cmd(data);
|
||||
break;
|
||||
case HCI_H4_ACL:
|
||||
rc = ble_transport_to_ll_acl(data);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
hci_cmac_ll_mbox_read_cb(const void *data, uint16_t len)
|
||||
{
|
||||
int rlen;
|
||||
|
||||
MCU_DIAG_SER('R');
|
||||
rlen = hci_h4_sm_rx(&hci_cmac_h4sm, data, len);
|
||||
assert(rlen >= 0);
|
||||
|
||||
return rlen;
|
||||
}
|
||||
|
||||
static void
|
||||
hci_cmac_ll_mbox_write_notif_cb(void)
|
||||
{
|
||||
MCU_DIAG_SER('W');
|
||||
CMAC->CM_EV_SET_REG = CMAC_CM_EV_SET_REG_EV1C_CMAC2SYS_IRQ_SET_Msk;
|
||||
}
|
||||
|
||||
void
|
||||
ble_transport_hs_init(void)
|
||||
{
|
||||
hci_h4_sm_init(&hci_cmac_h4sm, &hci_h4_allocs_from_hs, hci_cmac_ll_frame_cb);
|
||||
|
||||
/* Setup callbacks for mailboxes */
|
||||
cmac_mbox_set_read_cb(hci_cmac_ll_mbox_read_cb);
|
||||
cmac_mbox_set_write_notif_cb(hci_cmac_ll_mbox_write_notif_cb);
|
||||
|
||||
/* Synchronize with SYS */
|
||||
cmac_shared_sync();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !MYNEWT_VAL(BLE_CONTROLLER)
|
||||
int
|
||||
ble_transport_to_ll_cmd(void *buf)
|
||||
{
|
||||
uint8_t pkt_type = HCI_H4_CMD;
|
||||
uint8_t *cmd = buf;
|
||||
|
||||
cmac_mbox_write(&pkt_type, sizeof(pkt_type));
|
||||
cmac_mbox_write(cmd, cmd[2] + 3);
|
||||
|
||||
ble_transport_free(buf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ble_transport_to_ll_acl(struct os_mbuf *om)
|
||||
{
|
||||
return hci_cmac_acl_tx(om);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if MYNEWT_VAL(BLE_CONTROLLER)
|
||||
int
|
||||
ble_transport_to_hs_acl(struct os_mbuf *om)
|
||||
{
|
||||
return hci_cmac_acl_tx(om);
|
||||
}
|
||||
|
||||
int
|
||||
ble_transport_to_hs_evt(void *buf)
|
||||
{
|
||||
uint8_t pkt_type = HCI_H4_EVT;
|
||||
uint8_t *evt = buf;
|
||||
os_sr_t sr;
|
||||
|
||||
OS_ENTER_CRITICAL(sr);
|
||||
|
||||
cmac_mbox_write(&pkt_type, sizeof(pkt_type));
|
||||
cmac_mbox_write(evt, evt[1] + 2);
|
||||
|
||||
ble_transport_free(buf);
|
||||
|
||||
OS_EXIT_CRITICAL(sr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* BLE_CONTROLLER */
|
||||
@@ -1,27 +0,0 @@
|
||||
# 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.
|
||||
#
|
||||
|
||||
syscfg.vals.'!BLE_HCI_BRIDGE':
|
||||
BLE_HCI_EVT_HI_BUF_COUNT: 2
|
||||
BLE_HCI_EVT_LO_BUF_COUNT: 8
|
||||
BLE_HCI_EVT_BUF_SIZE: 70
|
||||
BLE_ACL_BUF_COUNT: 4
|
||||
BLE_ACL_BUF_SIZE: 255
|
||||
|
||||
syscfg.vals.'!BLE_HCI_BRIDGE && (BLE_EXT_ADV || BLE_LL_CFG_FEAT_LL_EXT_ADV)':
|
||||
BLE_HCI_EVT_BUF_SIZE: 257
|
||||
Reference in New Issue
Block a user