Skip to content

Commit 75413aa

Browse files
committed
stm32/rfcore: Add stm.rfcore_ble_hci function for raw BLE HCI comms.
Signed-off-by: Andrew Leech <[email protected]>
1 parent 90aeac8 commit 75413aa

File tree

4 files changed

+61
-4
lines changed

4 files changed

+61
-4
lines changed

docs/library/stm.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,17 @@ the second CPU, the RF core.
103103

104104
Returns a bytes object with the result of the SYS command.
105105

106+
.. function:: rfcore_ble_hci(command[, response_buf])
107+
108+
Execute a HCI command on the BLE channel. The execution is synchronous.
109+
110+
Takes a *command* byte/bytearray with pre-formatted HCI packet.
111+
112+
Optionally takes a pre-allocated bytearray buffer for the response packet.
113+
114+
Returns response length if *response_buf* is provided, else a bytes object with the
115+
response HCI packet.
116+
106117
Functions specific to STM32WLxx MCUs
107118
------------------------------------
108119

ports/stm32/modstm.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ static const mp_rom_map_elem_t stm_module_globals_table[] = {
5353
{ MP_ROM_QSTR(MP_QSTR_rfcore_status), MP_ROM_PTR(&rfcore_status_obj) },
5454
{ MP_ROM_QSTR(MP_QSTR_rfcore_fw_version), MP_ROM_PTR(&rfcore_fw_version_obj) },
5555
{ MP_ROM_QSTR(MP_QSTR_rfcore_sys_hci), MP_ROM_PTR(&rfcore_sys_hci_obj) },
56+
{ MP_ROM_QSTR(MP_QSTR_rfcore_ble_hci), MP_ROM_PTR(&rfcore_ble_hci_obj) },
5657
#endif
5758

5859
#if defined(STM32WL)

ports/stm32/rfcore.c

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -503,7 +503,7 @@ static ssize_t tl_sys_hci_cmd_resp(uint16_t opcode, const uint8_t *buf, size_t l
503503
return tl_sys_wait_ack(ipcc_membuf_sys_cmd_buf, timeout_ms);
504504
}
505505

506-
static int tl_ble_wait_resp(void) {
506+
static size_t tl_ble_wait_resp(parse_hci_info_t *parse) {
507507
uint32_t t0 = mp_hal_ticks_ms();
508508
while (!LL_C2_IPCC_IsActiveFlag_CHx(IPCC, IPCC_CH_BLE)) {
509509
if (mp_hal_ticks_ms() - t0 > BLE_ACK_TIMEOUT_MS) {
@@ -513,16 +513,15 @@ static int tl_ble_wait_resp(void) {
513513
}
514514

515515
// C2 set IPCC flag -- process the data, clear the flag, and re-enable IRQs.
516-
tl_check_msg(&ipcc_mem_ble_evt_queue, IPCC_CH_BLE, NULL);
517-
return 0;
516+
return tl_check_msg(&ipcc_mem_ble_evt_queue, IPCC_CH_BLE, parse);
518517
}
519518

520519
// Synchronously send a BLE command.
521520
static void tl_ble_hci_cmd_resp(uint16_t opcode, const uint8_t *buf, size_t len) {
522521
// Poll for completion rather than wait for IRQ->scheduler.
523522
LL_C1_IPCC_DisableReceiveChannel(IPCC, IPCC_CH_BLE);
524523
tl_hci_cmd(ipcc_membuf_ble_cmd_buf, IPCC_CH_BLE, HCI_KIND_BT_CMD, opcode, buf, len);
525-
tl_ble_wait_resp();
524+
tl_ble_wait_resp(NULL);
526525
}
527526

528527
/******************************************************************************/
@@ -797,4 +796,49 @@ static mp_obj_t rfcore_sys_hci(size_t n_args, const mp_obj_t *args) {
797796
}
798797
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(rfcore_sys_hci_obj, 3, 4, rfcore_sys_hci);
799798

799+
static void rfcore_ble_hci_response_to_buffer(void *env, const uint8_t *buf, size_t len) {
800+
DEBUG_printf("rfcore_ble_hci_response_to_buffer len 0x%x\n", len);
801+
mp_obj_t *rsp = (mp_obj_t *)env;
802+
if (*rsp == mp_const_none) {
803+
*rsp = mp_obj_new_bytes(buf, len);
804+
} else {
805+
mp_buffer_info_t bufinfo;
806+
mp_get_buffer_raise(*rsp, &bufinfo, MP_BUFFER_WRITE);
807+
if (bufinfo.len < len) {
808+
mp_raise_OSError(-len);
809+
}
810+
memcpy(bufinfo.buf, buf, len);
811+
}
812+
}
813+
814+
static mp_obj_t rfcore_ble_hci(size_t n_args, const mp_obj_t *args) {
815+
if (ipcc_mem_dev_info_tab.fus.table_state == MAGIC_IPCC_MEM_INCORRECT) {
816+
mp_raise_OSError(MP_EINVAL);
817+
}
818+
mp_obj_t cmd = args[0];
819+
mp_obj_t rsp = mp_const_none;
820+
bool return_len = false;
821+
if (n_args == 2) {
822+
rsp = args[1];
823+
// response buffer passed in, so return rsp length.
824+
return_len = true;
825+
}
826+
827+
mp_buffer_info_t bufinfo = {0};
828+
mp_get_buffer_raise(cmd, &bufinfo, MP_BUFFER_READ);
829+
830+
// Poll for completion rather than wait for IRQ->scheduler. Is re-enabled in tl_check_msg.
831+
LL_C1_IPCC_DisableReceiveChannel(IPCC, IPCC_CH_BLE);
832+
833+
rfcore_ble_hci_cmd(bufinfo.len, bufinfo.buf);
834+
835+
parse_hci_info_t parse = { rfcore_ble_hci_response_to_buffer, &rsp, false };
836+
size_t ret_len = tl_ble_wait_resp(&parse);
837+
if (return_len) {
838+
return MP_OBJ_NEW_SMALL_INT(ret_len);
839+
}
840+
return rsp;
841+
}
842+
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(rfcore_ble_hci_obj, 1, 2, rfcore_ble_hci);
843+
800844
#endif // defined(STM32WB)

ports/stm32/rfcore.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,5 +44,6 @@ void rfcore_end_flash_erase(void);
4444
MP_DECLARE_CONST_FUN_OBJ_0(rfcore_status_obj);
4545
MP_DECLARE_CONST_FUN_OBJ_1(rfcore_fw_version_obj);
4646
MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(rfcore_sys_hci_obj);
47+
MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(rfcore_ble_hci_obj);
4748

4849
#endif // MICROPY_INCLUDED_STM32_RFCORE_H

0 commit comments

Comments
 (0)