drivers/cyw43: Make the CYW43 Bluetooth HCI driver more portable.
This commit allows other ports to reuse the CYW43 HCI driver, by replacing all Bluetooth UART and control named pins with defines in config files and using `mpbthci` abstract functions (i.e. `mp_bluetooth_hci_*`) instead of the STM32 specific UART functions. Note: the function `cywbt_wait_cts_low` does not need to switch the CTS pin from alternate function to GPIO to read it. At least on stm32, mimxrt it's possible to just read the pin input. For example, see the STM32F7 RM0410 section 6.3.11, and the `SION` for IMXRT. So this function can also be available for other ports if the pin mode switching is removed. Signed-off-by: iabdalkader <i.abdalkader@gmail.com>
This commit is contained in:
parent
fc495240a6
commit
a453b4f31d
@ -29,8 +29,6 @@
|
||||
|
||||
#include "py/runtime.h"
|
||||
#include "py/mphal.h"
|
||||
#include "pin_static_af.h"
|
||||
#include "uart.h"
|
||||
#include "extmod/mpbthci.h"
|
||||
|
||||
#if MICROPY_PY_NETWORK_CYW43
|
||||
@ -38,33 +36,41 @@
|
||||
#include "lib/cyw43-driver/src/cyw43_config.h"
|
||||
#include "lib/cyw43-driver/firmware/cyw43_btfw_4343A1.h"
|
||||
|
||||
// Provided by the port.
|
||||
extern pyb_uart_obj_t mp_bluetooth_hci_uart_obj;
|
||||
|
||||
// Provided by the port, and also possibly shared with the stack.
|
||||
extern uint8_t mp_bluetooth_hci_cmd_buf[4 + 256];
|
||||
|
||||
/******************************************************************************/
|
||||
// CYW BT HCI low-level driver
|
||||
|
||||
#ifdef CYW43_PIN_BT_CTS
|
||||
// This code is not portable and currently only builds on stm32 port.
|
||||
|
||||
#include "pin_static_af.h"
|
||||
#include "uart.h"
|
||||
|
||||
// Provided by the port.
|
||||
extern pyb_uart_obj_t mp_bluetooth_hci_uart_obj;
|
||||
|
||||
STATIC void cywbt_wait_cts_low(void) {
|
||||
mp_hal_pin_config(pyb_pin_BT_CTS, MP_HAL_PIN_MODE_INPUT, MP_HAL_PIN_PULL_UP, 0);
|
||||
mp_hal_pin_config(CYW43_PIN_BT_CTS, MP_HAL_PIN_MODE_INPUT, MP_HAL_PIN_PULL_UP, 0);
|
||||
for (int i = 0; i < 200; ++i) {
|
||||
if (mp_hal_pin_read(pyb_pin_BT_CTS) == 0) {
|
||||
if (mp_hal_pin_read(CYW43_PIN_BT_CTS) == 0) {
|
||||
break;
|
||||
}
|
||||
mp_hal_delay_ms(1);
|
||||
}
|
||||
mp_hal_pin_config_alt(pyb_pin_BT_CTS, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, AF_FN_UART, mp_bluetooth_hci_uart_obj.uart_id);
|
||||
mp_hal_pin_config_alt(CYW43_PIN_BT_CTS, MP_HAL_PIN_MODE_ALT,
|
||||
MP_HAL_PIN_PULL_UP, AF_FN_UART, mp_bluetooth_hci_uart_obj.uart_id);
|
||||
}
|
||||
#endif
|
||||
|
||||
STATIC int cywbt_hci_cmd_raw(size_t len, uint8_t *buf) {
|
||||
uart_tx_strn(&mp_bluetooth_hci_uart_obj, (void*)buf, len);
|
||||
for (int i = 0; i < 6; ++i) {
|
||||
while (!uart_rx_any(&mp_bluetooth_hci_uart_obj)) {
|
||||
mp_bluetooth_hci_uart_write((void *)buf, len);
|
||||
for (int c, i = 0; i < 6; ++i) {
|
||||
while ((c = mp_bluetooth_hci_uart_readchar()) == -1) {
|
||||
MICROPY_EVENT_POLL_HOOK
|
||||
}
|
||||
buf[i] = uart_rx_char(&mp_bluetooth_hci_uart_obj);
|
||||
buf[i] = c;
|
||||
}
|
||||
|
||||
// expect a command complete event (event 0x0e)
|
||||
@ -80,11 +86,11 @@ STATIC int cywbt_hci_cmd_raw(size_t len, uint8_t *buf) {
|
||||
*/
|
||||
|
||||
int sz = buf[2] - 3;
|
||||
for (int i = 0; i < sz; ++i) {
|
||||
while (!uart_rx_any(&mp_bluetooth_hci_uart_obj)) {
|
||||
for (int c, i = 0; i < sz; ++i) {
|
||||
while ((c = mp_bluetooth_hci_uart_readchar()) == -1) {
|
||||
MICROPY_EVENT_POLL_HOOK
|
||||
}
|
||||
buf[i] = uart_rx_char(&mp_bluetooth_hci_uart_obj);
|
||||
buf[i] = c;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -150,12 +156,15 @@ STATIC int cywbt_download_firmware(const uint8_t *firmware) {
|
||||
|
||||
// RF switch must select high path during BT patch boot
|
||||
#if MICROPY_HW_ENABLE_RF_SWITCH
|
||||
mp_hal_pin_config(pyb_pin_WL_GPIO_1, MP_HAL_PIN_MODE_INPUT, MP_HAL_PIN_PULL_UP, 0);
|
||||
mp_hal_pin_config(CYW43_PIN_WL_GPIO_1, MP_HAL_PIN_MODE_INPUT, MP_HAL_PIN_PULL_UP, 0);
|
||||
#endif
|
||||
mp_hal_delay_ms(10); // give some time for CTS to go high
|
||||
#ifdef CYW43_PIN_BT_CTS
|
||||
cywbt_wait_cts_low();
|
||||
#endif
|
||||
#if MICROPY_HW_ENABLE_RF_SWITCH
|
||||
mp_hal_pin_config(pyb_pin_WL_GPIO_1, MP_HAL_PIN_MODE_INPUT, MP_HAL_PIN_PULL_DOWN, 0); // Select chip antenna (could also select external)
|
||||
// Select chip antenna (could also select external)
|
||||
mp_hal_pin_config(CYW43_PIN_WL_GPIO_1, MP_HAL_PIN_MODE_INPUT, MP_HAL_PIN_PULL_DOWN, 0);
|
||||
#endif
|
||||
|
||||
mp_bluetooth_hci_uart_set_baudrate(115200);
|
||||
@ -168,25 +177,33 @@ STATIC int cywbt_download_firmware(const uint8_t *firmware) {
|
||||
int mp_bluetooth_hci_controller_init(void) {
|
||||
// This is called immediately after the UART is initialised during stack initialisation.
|
||||
|
||||
mp_hal_pin_output(pyb_pin_BT_REG_ON);
|
||||
mp_hal_pin_low(pyb_pin_BT_REG_ON);
|
||||
mp_hal_pin_input(pyb_pin_BT_HOST_WAKE);
|
||||
mp_hal_pin_output(pyb_pin_BT_DEV_WAKE);
|
||||
mp_hal_pin_low(pyb_pin_BT_DEV_WAKE);
|
||||
mp_hal_pin_output(CYW43_PIN_BT_REG_ON);
|
||||
mp_hal_pin_low(CYW43_PIN_BT_REG_ON);
|
||||
#ifdef CYW43_PIN_BT_HOST_WAKE
|
||||
mp_hal_pin_input(CYW43_PIN_BT_HOST_WAKE);
|
||||
#endif
|
||||
#ifdef CYW43_PIN_BT_DEV_WAKE
|
||||
mp_hal_pin_output(CYW43_PIN_BT_DEV_WAKE);
|
||||
mp_hal_pin_low(CYW43_PIN_BT_DEV_WAKE);
|
||||
#endif
|
||||
|
||||
#if MICROPY_HW_ENABLE_RF_SWITCH
|
||||
// TODO don't select antenna if wifi is enabled
|
||||
mp_hal_pin_config(pyb_pin_WL_GPIO_4, MP_HAL_PIN_MODE_OUTPUT, MP_HAL_PIN_PULL_NONE, 0); // RF-switch power
|
||||
mp_hal_pin_high(pyb_pin_WL_GPIO_4); // Turn the RF-switch on
|
||||
mp_hal_pin_config(CYW43_PIN_WL_GPIO_4, MP_HAL_PIN_MODE_OUTPUT, MP_HAL_PIN_PULL_NONE, 0); // RF-switch power
|
||||
mp_hal_pin_high(CYW43_PIN_WL_GPIO_4); // Turn the RF-switch on
|
||||
#endif
|
||||
|
||||
uint8_t buf[256];
|
||||
|
||||
mp_hal_pin_low(pyb_pin_BT_REG_ON);
|
||||
mp_hal_pin_low(CYW43_PIN_BT_REG_ON);
|
||||
mp_bluetooth_hci_uart_set_baudrate(115200);
|
||||
mp_hal_delay_ms(100);
|
||||
mp_hal_pin_high(pyb_pin_BT_REG_ON);
|
||||
mp_hal_pin_high(CYW43_PIN_BT_REG_ON);
|
||||
#ifdef CYW43_PIN_BT_CTS
|
||||
cywbt_wait_cts_low();
|
||||
#else
|
||||
mp_hal_delay_ms(100);
|
||||
#endif
|
||||
|
||||
// Reset
|
||||
cywbt_hci_cmd(0x03, 0x0003, 0, NULL);
|
||||
@ -197,7 +214,7 @@ int mp_bluetooth_hci_controller_init(void) {
|
||||
mp_bluetooth_hci_uart_set_baudrate(MICROPY_HW_BLE_UART_BAUDRATE_DOWNLOAD_FIRMWARE);
|
||||
#endif
|
||||
|
||||
cywbt_download_firmware((const uint8_t*)&cyw43_btfw_4343A1[0]);
|
||||
cywbt_download_firmware((const uint8_t *)&cyw43_btfw_4343A1[0]);
|
||||
|
||||
// Reset
|
||||
cywbt_hci_cmd(0x03, 0x0003, 0, NULL);
|
||||
@ -219,31 +236,33 @@ int mp_bluetooth_hci_controller_init(void) {
|
||||
// cywbt_hci_cmd(0x03, 0x0013, 248, buf);
|
||||
|
||||
// Configure sleep mode
|
||||
cywbt_hci_cmd(0x3f, 0x27, 12, (const uint8_t*)"\x01\x02\x02\x00\x00\x00\x01\x00\x00\x00\x00\x00");
|
||||
cywbt_hci_cmd(0x3f, 0x27, 12, (const uint8_t *)"\x01\x02\x02\x00\x00\x00\x01\x00\x00\x00\x00\x00");
|
||||
|
||||
// HCI_Write_LE_Host_Support
|
||||
cywbt_hci_cmd(3, 109, 2, (const uint8_t*)"\x01\x00");
|
||||
cywbt_hci_cmd(3, 109, 2, (const uint8_t *)"\x01\x00");
|
||||
|
||||
mp_hal_pin_high(pyb_pin_BT_DEV_WAKE); // let sleep
|
||||
#ifdef CYW43_PIN_BT_DEV_WAKE
|
||||
mp_hal_pin_high(CYW43_PIN_BT_DEV_WAKE); // let sleep
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mp_bluetooth_hci_controller_deinit(void) {
|
||||
mp_hal_pin_low(pyb_pin_BT_REG_ON);
|
||||
mp_hal_pin_low(CYW43_PIN_BT_REG_ON);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef pyb_pin_BT_DEV_WAKE
|
||||
#ifdef CYW43_PIN_BT_DEV_WAKE
|
||||
STATIC uint32_t bt_sleep_ticks;
|
||||
#endif
|
||||
|
||||
int mp_bluetooth_hci_controller_sleep_maybe(void) {
|
||||
#ifdef pyb_pin_BT_DEV_WAKE
|
||||
if (mp_hal_pin_read(pyb_pin_BT_DEV_WAKE) == 0) {
|
||||
#ifdef CYW43_PIN_BT_DEV_WAKE
|
||||
if (mp_hal_pin_read(CYW43_PIN_BT_DEV_WAKE) == 0) {
|
||||
if (mp_hal_ticks_ms() - bt_sleep_ticks > 500) {
|
||||
mp_hal_pin_high(pyb_pin_BT_DEV_WAKE); // let sleep
|
||||
mp_hal_pin_high(CYW43_PIN_BT_DEV_WAKE); // let sleep
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -251,8 +270,8 @@ int mp_bluetooth_hci_controller_sleep_maybe(void) {
|
||||
}
|
||||
|
||||
bool mp_bluetooth_hci_controller_woken(void) {
|
||||
#ifdef pyb_pin_BT_HOST_WAKE
|
||||
bool host_wake = mp_hal_pin_read(pyb_pin_BT_HOST_WAKE);
|
||||
#ifdef CYW43_PIN_BT_HOST_WAKE
|
||||
bool host_wake = mp_hal_pin_read(CYW43_PIN_BT_HOST_WAKE);
|
||||
/*
|
||||
// this is just for info/tracing purposes
|
||||
static bool last_host_wake = false;
|
||||
@ -268,11 +287,11 @@ bool mp_bluetooth_hci_controller_woken(void) {
|
||||
}
|
||||
|
||||
int mp_bluetooth_hci_controller_wakeup(void) {
|
||||
#ifdef pyb_pin_BT_DEV_WAKE
|
||||
#ifdef CYW43_PIN_BT_DEV_WAKE
|
||||
bt_sleep_ticks = mp_hal_ticks_ms();
|
||||
|
||||
if (mp_hal_pin_read(pyb_pin_BT_DEV_WAKE) == 1) {
|
||||
mp_hal_pin_low(pyb_pin_BT_DEV_WAKE); // wake up
|
||||
if (mp_hal_pin_read(CYW43_PIN_BT_DEV_WAKE) == 1) {
|
||||
mp_hal_pin_low(CYW43_PIN_BT_DEV_WAKE); // wake up
|
||||
// Use delay_us rather than delay_ms to prevent running the scheduler (which
|
||||
// might result in more BLE operations).
|
||||
mp_hal_delay_us(5000); // can't go lower than this
|
||||
|
@ -93,6 +93,13 @@
|
||||
#define CYW43_PIN_WL_REG_ON pyb_pin_WL_REG_ON
|
||||
#define CYW43_PIN_WL_HOST_WAKE pyb_pin_WL_HOST_WAKE
|
||||
#define CYW43_PIN_WL_SDIO_1 pyb_pin_WL_SDIO_1
|
||||
#define CYW43_PIN_WL_GPIO_1 pyb_pin_WL_GPIO_1
|
||||
#define CYW43_PIN_WL_GPIO_4 pyb_pin_WL_GPIO_4
|
||||
|
||||
#define CYW43_PIN_BT_REG_ON pyb_pin_BT_REG_ON
|
||||
#define CYW43_PIN_BT_HOST_WAKE pyb_pin_BT_HOST_WAKE
|
||||
#define CYW43_PIN_BT_DEV_WAKE pyb_pin_BT_DEV_WAKE
|
||||
#define CYW43_PIN_BT_CTS pyb_pin_BT_CTS
|
||||
|
||||
#if MICROPY_HW_ENABLE_RF_SWITCH
|
||||
#define CYW43_PIN_WL_RFSW_VDD pyb_pin_WL_RFSW_VDD
|
||||
|
Loading…
Reference in New Issue
Block a user