Skip to content

Commit 34e7f6f

Browse files
pi-anldpgeorge
authored andcommitted
stm32/rfcore: Add stm.rfcore_ble_hci function for raw BLE HCI comms.
1 parent 352f253 commit 34e7f6f

File tree

4 files changed

+62
-4
lines changed

4 files changed

+62
-4
lines changed

docs/library/stm.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,3 +102,14 @@ the second CPU, the RF core.
102102
Execute a HCI command on the SYS channel. The execution is synchronous.
103103

104104
Returns a bytes object with the result of the SYS command.
105+
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.

ports/stm32/modstm.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ STATIC const mp_rom_map_elem_t stm_module_globals_table[] = {
5050
{ MP_ROM_QSTR(MP_QSTR_rfcore_status), MP_ROM_PTR(&rfcore_status_obj) },
5151
{ MP_ROM_QSTR(MP_QSTR_rfcore_fw_version), MP_ROM_PTR(&rfcore_fw_version_obj) },
5252
{ MP_ROM_QSTR(MP_QSTR_rfcore_sys_hci), MP_ROM_PTR(&rfcore_sys_hci_obj) },
53+
{ MP_ROM_QSTR(MP_QSTR_rfcore_ble_hci), MP_ROM_PTR(&rfcore_ble_hci_obj) },
5354
#endif
5455
};
5556

ports/stm32/rfcore.c

Lines changed: 49 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
/******************************************************************************/
@@ -793,4 +792,50 @@ STATIC mp_obj_t rfcore_sys_hci(size_t n_args, const mp_obj_t *args) {
793792
}
794793
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(rfcore_sys_hci_obj, 3, 4, rfcore_sys_hci);
795794

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