Open ble controller adaptation code

N/A

Signed-off-by: jsun <jsun@bouffalolab.com>
This commit is contained in:
jsun
2021-09-24 11:15:02 +08:00
committed by Xiang Xiao
parent 04d63cf8b0
commit c58fddb915
4 changed files with 278 additions and 15 deletions
+1 -1
View File
@@ -84,7 +84,7 @@ CHIP_CSRCS += bl602_glb.c bl602_gpio.c bl602_hbn.c bl602_systemreset.c
ifeq ($(CONFIG_BL602_WIRELESS),y)
WIRELESS_DRV_UNPACK = bl_blob
WIRELESS_DRV_VERSION = 1.9.1-dev
WIRELESS_DRV_VERSION = 1.9.1-ble-test
WIRELESS_DRV_ZIP = v$(WIRELESS_DRV_VERSION).zip
WIRELESS_DRV_URL = https://github.com/bouffalolab/bl_blob/archive/refs/heads
@@ -79,6 +79,7 @@ CONFIG_NETUTILS_IPERF=y
CONFIG_NET_ARP_IPIN=y
CONFIG_NET_ARP_SEND=y
CONFIG_NET_BROADCAST=y
CONFIG_NET_ETH_PKTSIZE=1518
CONFIG_NET_ICMP=y
CONFIG_NET_ICMP_SOCKET=y
CONFIG_NET_TCP=y
@@ -137,18 +137,6 @@ SECTIONS
*(.srodata.cst2)
*(.srodata .srodata.*)
. = ALIGN(8);
*(._k_queue.static.*)
*(._k_sem.static.*)
*(._k_mutex.static.*)
_net_buf_pool_list = .;
KEEP(*(SORT_BY_NAME("._net_buf_pool.static.*")))
_bt_gatt_service_static_list_start = .;
KEEP(*(SORT_BY_NAME("._bt_gatt_service_static.static.*")))
_bt_gatt_service_static_list_end = .;
_bt_l2cap_fixed_chan_list_start = .;
KEEP(*(SORT_BY_NAME("._bt_l2cap_fixed_chan.static.*")))
_bt_l2cap_fixed_chan_list_end = .;
} > ram_tcm AT > flash
.boot2 (NOLOAD) :
@@ -53,6 +53,17 @@
#include <bl602_spiflash.h>
#endif
#if defined(CONFIG_BL602_BLE_CONTROLLER)
#include <nuttx/kmalloc.h>
#include <nuttx/net/bluetooth.h>
#include <nuttx/wireless/bluetooth/bt_driver.h>
#include <nuttx/wireless/bluetooth/bt_uart.h>
#include <nuttx/mm/circbuf.h>
#if defined(CONFIG_UART_BTH4)
#include <nuttx/serial/uart_bth4.h>
#endif
#endif /* CONFIG_BL602_BLE_CONTROLLER */
#ifdef CONFIG_FS_ROMFS
#include <nuttx/drivers/ramdisk.h>
@@ -83,8 +94,271 @@ extern int bl602_net_initialize(void);
#endif
#if defined(CONFIG_BL602_BLE_CONTROLLER)
extern void bl602_hci_uart_init(uint8_t uartid);
#endif
struct bthci_s
{
FAR struct bt_driver_s drv;
int id;
int fd;
sq_entry_t link;
};
struct uart_rxchannel
{
void (*callback)(void *, uint8_t);
void *dummy;
uint32_t remain_size;
uint8_t *remain_data;
};
struct uart_env_tag
{
struct uart_rxchannel rx;
};
static FAR struct bthci_s *hci_dev;
static FAR struct circbuf_s circbuf_rd;
static struct uart_env_tag uart_env;
static int bthci_send(FAR struct bt_driver_s *drv,
enum bt_buf_type_e type,
FAR void *data,
size_t len);
static int bthci_open(FAR struct bt_driver_s *drv);
static void bthci_close(FAR struct bt_driver_s *drv);
static int bthci_receive(uint8_t *data, uint32_t len);
static int bthci_register(void);
extern void rw_main_task_post_from_fw(void);
extern void bl602_hci_uart_api_init(void *ble_uart_read,
void *ble_uart_write);
static void ble_uart_read(uint8_t *bufptr,
uint32_t size,
void (*callback)(void *, uint8_t),
void *dummy)
{
irqstate_t flags;
if (!bufptr || !size || !callback)
return;
if (circbuf_used(&circbuf_rd) >= size)
{
flags = enter_critical_section();
size_t nread = circbuf_read(&circbuf_rd, bufptr, size);
leave_critical_section(flags);
if (nread != size)
{
printf("%s\n", __func__);
}
callback(dummy, 0);
/* rw_main_task_post_from_fw(); */
return;
}
uart_env.rx.callback = callback;
uart_env.rx.dummy = dummy;
uart_env.rx.remain_size = size;
uart_env.rx.remain_data = bufptr;
}
static void ble_uart_write(const uint8_t *bufptr,
uint32_t size,
void (*callback)(void *, uint8_t),
void *dummy)
{
if (!bufptr || !size || !callback)
return;
bthci_receive((uint8_t *)bufptr, size);
callback(dummy, 0);
return;
}
static int bthci_send(FAR struct bt_driver_s *drv,
enum bt_buf_type_e type,
FAR void *data,
size_t len)
{
FAR char *hdr = (FAR char *)data - drv->head_reserve;
void (*callback)(void *, uint8_t) = NULL;
void *dummy = NULL;
int nlen;
int rlen;
irqstate_t flags;
if (type == BT_CMD)
{
*hdr = H4_CMD;
}
else if (type == BT_ACL_OUT)
{
*hdr = H4_ACL;
}
else if (type == BT_ISO_OUT)
{
*hdr = H4_ISO;
}
else
{
return -EINVAL;
}
/* Host send to controller */
flags = enter_critical_section();
nlen = circbuf_write(&circbuf_rd, hdr, len + H4_HEADER_SIZE);
if (uart_env.rx.remain_size &&
circbuf_used(&circbuf_rd) >= uart_env.rx.remain_size)
{
/* Read data */
rlen = circbuf_read(&circbuf_rd,
uart_env.rx.remain_data,
uart_env.rx.remain_size);
if (rlen < uart_env.rx.remain_size)
{
printf("bthci_send rlen is error\n");
}
/* printf("Rx len[%d]\n", len); */
uart_env.rx.remain_data += rlen;
uart_env.rx.remain_size -= rlen;
callback = uart_env.rx.callback;
dummy = uart_env.rx.dummy;
if (callback != NULL && !uart_env.rx.remain_size)
{
uart_env.rx.callback = NULL;
uart_env.rx.dummy = NULL;
callback(dummy, 0);
}
}
leave_critical_section(flags);
return nlen;
}
static void bthci_close(FAR struct bt_driver_s *drv)
{
}
static int bthci_receive(uint8_t *data, uint32_t len)
{
enum bt_buf_type_e type;
if (len <= 0)
{
return len;
}
if (data[0] == H4_EVT)
{
type = BT_EVT;
}
else if (data[0] == H4_ACL)
{
type = BT_ACL_IN;
}
else if (data[0] == H4_ISO)
{
type = BT_ISO_IN;
}
else
{
return -EINVAL;
}
return bt_netdev_receive(&hci_dev->drv,
type,
data + H4_HEADER_SIZE,
len - H4_HEADER_SIZE);
}
static int bthci_open(FAR struct bt_driver_s *drv)
{
return OK;
}
static FAR struct bthci_s *bthci_alloc(void)
{
/* Register the driver with the Bluetooth stack */
FAR struct bthci_s *dev;
FAR struct bt_driver_s *drv;
dev = (FAR struct bthci_s *)kmm_zalloc(sizeof(*dev));
if (dev == NULL)
{
return NULL;
}
dev->id = 0;
dev->fd = -1;
drv = &dev->drv;
drv->head_reserve = H4_HEADER_SIZE;
drv->open = bthci_open;
drv->send = bthci_send;
drv->close = bthci_close;
return dev;
}
int bthci_register(void)
{
int ret;
hci_dev = bthci_alloc();
if (hci_dev == NULL)
{
return -ENOMEM;
}
#if defined(CONFIG_UART_BTH4)
ret = uart_bth4_register("/dev/ttyHCI0", &hci_dev->drv);
#elif defined(CONFIG_NET_BLUETOOTH)
ret = bt_netdev_register(&hci_dev->drv);
#elif defined(BL602_BLE_CONTROLLER)
#error "Must select CONFIG_UART_BTH4 or CONFIG_NET_BLUETOOTH"
#endif
if (ret < 0)
{
printf("register faile[%d] errno %d\n", ret, errno);
kmm_free(hci_dev);
}
return ret;
}
void bl602_hci_uart_init(uint8_t uartid)
{
int ret;
if (uartid)
return;
ret = circbuf_init(&circbuf_rd, NULL, 512);
if (ret < 0)
{
circbuf_uninit(&circbuf_rd);
return;
}
bl602_hci_uart_api_init(ble_uart_read, ble_uart_write);
bthci_register();
rw_main_task_post_from_fw();
return;
}
#endif /* CONFIG_BL602_BLE_CONTROLLER */
/****************************************************************************
* Name: bl602_bringup