Skip to content

Commit

Permalink
nimble/transport: Add support for IPC ICBMsg transport
Browse files Browse the repository at this point in the history
Tested with nRF5340.
  • Loading branch information
mkasenberg committed Oct 3, 2024
1 parent caecb2c commit 76f90e2
Show file tree
Hide file tree
Showing 11 changed files with 353 additions and 2 deletions.
2 changes: 2 additions & 0 deletions nimble/controller/src/ble_ll.c
Original file line number Diff line number Diff line change
Expand Up @@ -2006,7 +2006,9 @@ void
ble_transport_ll_init(void)
{
/* Tell the host that we are ready to receive packets */
#if MYNEWT_VAL(BLE_LL_HCI_NOOP_AFTER_INIT)
ble_ll_hci_send_noop();
#endif
}

int
Expand Down
8 changes: 8 additions & 0 deletions nimble/controller/syscfg.yml
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,11 @@ syscfg.defs:
Enables LLCP tracing using HCI vendor-specific events.
value: '0'

BLE_LL_HCI_NOOP_AFTER_INIT:
description: >
Enables sending the NO-OP opcode HCI event after LL init.
value: '1'

# Configuration for LL supported features.
#
# There are a total 8 features that the LL can support. These can be found
Expand Down Expand Up @@ -643,6 +648,9 @@ syscfg.vals.BLE_LL_ISO_BROADCASTER:
syscfg.vals.'!BLE_HOST && !BABBLESIM':
BLE_LL_HCI_VS_EVENT_ON_ASSERT: 1

syscfg.vals.'BLE_TRANSPORT_HS=="ipc_icbmsg"':
BLE_LL_HCI_NOOP_AFTER_INIT: 0

syscfg.restrictions:
- BLE_TRANSPORT_LL == "native"
- BLE_LL_PUBLIC_DEV_ADDR <= 0xffffffffffff
Expand Down
21 changes: 21 additions & 0 deletions nimble/transport/common/hci_ipc/include/nimble/transport/hci_ipc.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,26 @@
#define _HCI_IPC_H_

#include <stdint.h>
#include <syscfg/syscfg.h>

#if MYNEWT_VAL(IPC_ICBMSG)
#include "nimble/hci_common.h"
#define HCI_IPC_TYPE_CMD 0x01
#define HCI_IPC_TYPE_ACL 0x02
/* #define HCI_IPC_TYPE_SCO 0x03 */
#define HCI_IPC_TYPE_EVT 0x04
#define HCI_IPC_TYPE_ISO 0x05
/* These two are not used actually */
#define HCI_IPC_TYPE_EVT_DISCARDABLE 0x06
#define HCI_IPC_TYPE_EVT_IN_CMD 0x07
#else
#define HCI_IPC_TYPE_CMD 0x01
#define HCI_IPC_TYPE_ACL 0x02
#define HCI_IPC_TYPE_EVT 0x04
#define HCI_IPC_TYPE_EVT_DISCARDABLE 0x05
#define HCI_IPC_TYPE_EVT_IN_CMD 0x06
#define HCI_IPC_TYPE_ISO 0x07
#endif

struct __attribute__((packed)) hci_ipc_hdr {
uint8_t type;
Expand Down Expand Up @@ -55,15 +68,20 @@ struct hci_ipc_shm {
void hci_ipc_init(volatile struct hci_ipc_shm *shm, struct hci_ipc_sm *sm);
int hci_ipc_rx(struct hci_ipc_sm *sm, const uint8_t *buf, uint16_t len);

#if !MYNEWT_VAL(IPC_ICBMSG)
extern void hci_ipc_atomic_put(volatile uint16_t *num);
extern uint16_t hci_ipc_atomic_get(volatile uint16_t *num);

/* Just to optimize static inlines below, do not use directly! */
extern volatile struct hci_ipc_shm *g_ipc_shm;
#endif

static inline int
hci_ipc_get(uint8_t type)
{
#if MYNEWT_VAL(IPC_ICBMSG)
return 1;
#else
volatile struct hci_ipc_shm *shm = g_ipc_shm;

switch (type) {
Expand All @@ -76,11 +94,13 @@ hci_ipc_get(uint8_t type)
}

return 0;
#endif
}

static inline void
hci_ipc_put(uint8_t type)
{
#if !MYNEWT_VAL(IPC_ICBMSG)
volatile struct hci_ipc_shm *shm = g_ipc_shm;

switch (type) {
Expand All @@ -94,6 +114,7 @@ hci_ipc_put(uint8_t type)
hci_ipc_atomic_put(&shm->n2a_num_evt_disc);
break;
}
#endif
}

#endif /* _HCI_IPC_H_ */
33 changes: 32 additions & 1 deletion nimble/transport/common/hci_ipc/src/hci_ipc.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,11 @@ hci_ipc_alloc(struct hci_ipc_sm *sm)
static bool
hci_ipc_has_hdr(struct hci_ipc_sm *sm)
{
#if MYNEWT_VAL(IPC_ICBMSG)
return sm->hdr_len == sizeof(sm->hdr.type);
#else
return sm->hdr_len == sizeof(sm->hdr);
#endif
}

static void
Expand Down Expand Up @@ -137,9 +141,33 @@ hci_ipc_frame(struct hci_ipc_sm *sm)
sm->buf = NULL;
}

#if MYNEWT_VAL(IPC_ICBMSG)
static uint16_t
hci_ipc_get_pkt_size(const uint8_t *buf, uint8_t type)
{
switch (type) {
case HCI_IPC_TYPE_ACL:
return sizeof(struct hci_data_hdr) + get_le16(&((struct hci_data_hdr *)buf)->hdh_len);
case HCI_IPC_TYPE_EVT:
return sizeof(struct ble_hci_ev) + ((struct ble_hci_ev *)buf)->length;
case HCI_IPC_TYPE_CMD:
return sizeof(struct ble_hci_cmd) + ((struct ble_hci_cmd *)buf)->length;
case HCI_IPC_TYPE_ISO:
return sizeof(struct ble_hci_iso) + get_le16(&((struct ble_hci_iso *)buf)->length);
}

return 0;
}
#endif

static uint16_t
hci_ipc_copy_to_hdr(struct hci_ipc_sm *sm, const uint8_t *buf, uint16_t len)
{
#if MYNEWT_VAL(IPC_ICBMSG)
len = 1;
sm->hdr.type = buf[0];
sm->hdr.length = hci_ipc_get_pkt_size(buf + 1, sm->hdr.type);
#else
uint16_t rem_hdr_len;
uint8_t *p;

Expand All @@ -152,6 +180,7 @@ hci_ipc_copy_to_hdr(struct hci_ipc_sm *sm, const uint8_t *buf, uint16_t len)

p = (void *)&sm->hdr;
memcpy(p + sm->hdr_len, buf, len);
#endif

sm->hdr_len += len;

Expand Down Expand Up @@ -225,10 +254,11 @@ hci_ipc_rx(struct hci_ipc_sm *sm, const uint8_t *buf, uint16_t len)
void
hci_ipc_init(volatile struct hci_ipc_shm *shm, struct hci_ipc_sm *sm)
{
memset(sm, 0, sizeof(*sm));
#if !MYNEWT_VAL(IPC_ICBMSG)
assert(g_ipc_shm == NULL);

g_ipc_shm = shm;
memset(sm, 0, sizeof(*sm));

#if MYNEWT_VAL(BLE_CONTROLLER)
while (shm->n2a_num_evt_disc == 0) {
Expand All @@ -239,4 +269,5 @@ hci_ipc_init(volatile struct hci_ipc_shm *shm, struct hci_ipc_sm *sm)
shm->n2a_num_evt = MYNEWT_VAL(BLE_TRANSPORT_EVT_COUNT);
shm->n2a_num_evt_disc = MYNEWT_VAL(BLE_TRANSPORT_EVT_DISCARDABLE_COUNT);
#endif
#endif
}
24 changes: 24 additions & 0 deletions nimble/transport/common/hci_ipc/syscfg.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# 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.defs:
IPC_ICBMSG:
description: 'Enables controller support for the Central role.'
value: 0

syscfg.vals.'BLE_TRANSPORT_LL=="ipc_icbmsg" || BLE_TRANSPORT_HS=="ipc_icbmsg"':
IPC_ICBMSG: 1
36 changes: 36 additions & 0 deletions nimble/transport/ipc_icbmsg/pkg.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#
# 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.
#

pkg.name: nimble/transport/ipc_icbmsg
pkg.description: HCI transport via IPC with ICBMsg backend
pkg.author: "Apache Mynewt <dev@mynewt.apache.org>"
pkg.homepage: "http://mynewt.apache.org/"
pkg.keywords:
- ble
- bluetooth
- ipc_icbmsg

pkg.deps:
- nimble
- nimble/transport/common/hci_ipc
- "@apache-mynewt-core/kernel/os"
- "@apache-mynewt-core/hw/drivers/ipc_icbmsg"

pkg.apis:
- ble_transport
Loading

0 comments on commit 76f90e2

Please sign in to comment.