@@ -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.
521520STATIC 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}
794793MP_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)
0 commit comments