From 0bf2702210a70f37a51538b37839e4fd1fb30c4b Mon Sep 17 00:00:00 2001 From: gornekich Date: Thu, 31 Mar 2022 17:57:23 +0300 Subject: [PATCH] Fix GUI freeze after NFC classic read (#1074) * nfc worker: add delay for task switching * device info service: fix rpc version characteristic * firmware: move FreeRTOSConfig.h to target include * dev_info service: fix typo * ble glue: use osThreadFlags instead of osEventFlags * Infrared: fix issue with timer lockup * FuriHal: yeld in flash lock routine * ble: change connection parameters, display actual params * ble: verify connection parameters * ble: fix typo Co-authored-by: Aleksandr Kutuzov --- applications/nfc/nfc_worker.c | 1 + .../targets/f7/Inc}/FreeRTOSConfig.h | 4 +- firmware/targets/f7/ble_glue/ble_app.c | 17 +++-- firmware/targets/f7/ble_glue/ble_glue.c | 17 +++-- .../targets/f7/ble_glue/dev_info_service.c | 12 ++-- firmware/targets/f7/ble_glue/gap.c | 64 ++++++++++++------- firmware/targets/f7/ble_glue/gap.h | 10 ++- firmware/targets/f7/furi_hal/furi_hal_bt.c | 13 ++-- firmware/targets/f7/furi_hal/furi_hal_flash.c | 8 +-- lib/infrared/worker/infrared_worker.c | 31 ++++----- 10 files changed, 96 insertions(+), 81 deletions(-) rename {lib/FreeRTOS-glue => firmware/targets/f7/Inc}/FreeRTOSConfig.h (97%) mode change 100644 => 100755 firmware/targets/f7/ble_glue/dev_info_service.c diff --git a/applications/nfc/nfc_worker.c b/applications/nfc/nfc_worker.c index 17b54260b..a925a8d73 100644 --- a/applications/nfc/nfc_worker.c +++ b/applications/nfc/nfc_worker.c @@ -780,6 +780,7 @@ void nfc_worker_mifare_classic_dict_attack(NfcWorker* nfc_worker) { } } if(nfc_worker->state != NfcWorkerStateReadMifareClassic) break; + osDelay(1); } if(nfc_worker->state != NfcWorkerStateReadMifareClassic) break; if(sector_key_found) { diff --git a/lib/FreeRTOS-glue/FreeRTOSConfig.h b/firmware/targets/f7/Inc/FreeRTOSConfig.h similarity index 97% rename from lib/FreeRTOS-glue/FreeRTOSConfig.h rename to firmware/targets/f7/Inc/FreeRTOSConfig.h index 2f7b1df45..ee56922b1 100644 --- a/lib/FreeRTOS-glue/FreeRTOSConfig.h +++ b/firmware/targets/f7/Inc/FreeRTOSConfig.h @@ -77,11 +77,13 @@ to exclude the API function. */ /* CMSIS-RTOS V2 flags */ #define configUSE_OS2_THREAD_SUSPEND_RESUME 1 #define configUSE_OS2_THREAD_ENUMERATE 1 -#define configUSE_OS2_EVENTFLAGS_FROM_ISR 1 #define configUSE_OS2_THREAD_FLAGS 1 #define configUSE_OS2_TIMER 1 #define configUSE_OS2_MUTEX 1 +// NEVER TO BE USED, because of their hard realtime nature +// #define configUSE_OS2_EVENTFLAGS_FROM_ISR 1 + /* CMSIS-RTOS */ #define configTASK_NOTIFICATION_ARRAY_ENTRIES 2 #define CMSIS_TASK_NOTIFY_INDEX 1 diff --git a/firmware/targets/f7/ble_glue/ble_app.c b/firmware/targets/f7/ble_glue/ble_app.c index 052b3a9f3..d76b4e7bf 100644 --- a/firmware/targets/f7/ble_glue/ble_app.c +++ b/firmware/targets/f7/ble_glue/ble_app.c @@ -24,7 +24,6 @@ typedef struct { osMutexId_t hci_mtx; osSemaphoreId_t hci_sem; FuriThread* thread; - osEventFlagsId_t event_flags; } BleApp; static BleApp* ble_app = NULL; @@ -39,7 +38,6 @@ bool ble_app_init() { // Allocate semafore and mutex for ble command buffer access ble_app->hci_mtx = osMutexNew(NULL); ble_app->hci_sem = osSemaphoreNew(1, 0, NULL); - ble_app->event_flags = osEventFlagsNew(NULL); // HCI transport layer thread to handle user asynch events ble_app->thread = furi_thread_alloc(); furi_thread_set_name(ble_app->thread, "BleHciDriver"); @@ -108,15 +106,14 @@ void ble_app_get_key_storage_buff(uint8_t** addr, uint16_t* size) { void ble_app_thread_stop() { if(ble_app) { - osEventFlagsSet(ble_app->event_flags, BLE_APP_FLAG_KILL_THREAD); + osThreadId_t thread_id = furi_thread_get_thread_id(ble_app->thread); + furi_assert(thread_id); + osThreadFlagsSet(thread_id, BLE_APP_FLAG_KILL_THREAD); furi_thread_join(ble_app->thread); furi_thread_free(ble_app->thread); - // Wait to make sure that EventFlags delivers pending events before memory free - osDelay(50); // Free resources osMutexDelete(ble_app->hci_mtx); osSemaphoreDelete(ble_app->hci_sem); - osEventFlagsDelete(ble_app->event_flags); free(ble_app); ble_app = NULL; memset(&ble_app_cmd_buffer, 0, sizeof(ble_app_cmd_buffer)); @@ -125,9 +122,9 @@ void ble_app_thread_stop() { static int32_t ble_app_hci_thread(void* arg) { uint32_t flags = 0; + while(1) { - flags = osEventFlagsWait( - ble_app->event_flags, BLE_APP_FLAG_ALL, osFlagsWaitAny, osWaitForever); + flags = osThreadFlagsWait(BLE_APP_FLAG_ALL, osFlagsWaitAny, osWaitForever); if(flags & BLE_APP_FLAG_KILL_THREAD) { break; } @@ -142,7 +139,9 @@ static int32_t ble_app_hci_thread(void* arg) { // Called by WPAN lib void hci_notify_asynch_evt(void* pdata) { if(ble_app) { - osEventFlagsSet(ble_app->event_flags, BLE_APP_FLAG_HCI_EVENT); + osThreadId_t thread_id = furi_thread_get_thread_id(ble_app->thread); + furi_assert(thread_id); + osThreadFlagsSet(thread_id, BLE_APP_FLAG_HCI_EVENT); } } diff --git a/firmware/targets/f7/ble_glue/ble_glue.c b/firmware/targets/f7/ble_glue/ble_glue.c index d8ccf3854..9142a261a 100644 --- a/firmware/targets/f7/ble_glue/ble_glue.c +++ b/firmware/targets/f7/ble_glue/ble_glue.c @@ -40,7 +40,6 @@ typedef enum { typedef struct { osMutexId_t shci_mtx; osSemaphoreId_t shci_sem; - osEventFlagsId_t event_flags; FuriThread* thread; BleGlueStatus status; BleGlueKeyStorageChangedCallback callback; @@ -83,7 +82,6 @@ void ble_glue_init() { ble_glue->shci_mtx = osMutexNew(NULL); ble_glue->shci_sem = osSemaphoreNew(1, 0, NULL); - ble_glue->event_flags = osEventFlagsNew(NULL); // FreeRTOS system task creation ble_glue->thread = furi_thread_alloc(); @@ -257,15 +255,14 @@ static void ble_glue_clear_shared_memory() { void ble_glue_thread_stop() { if(ble_glue) { - osEventFlagsSet(ble_glue->event_flags, BLE_GLUE_FLAG_KILL_THREAD); + osThreadId_t thread_id = furi_thread_get_thread_id(ble_glue->thread); + furi_assert(thread_id); + osThreadFlagsSet(thread_id, BLE_GLUE_FLAG_KILL_THREAD); furi_thread_join(ble_glue->thread); furi_thread_free(ble_glue->thread); - // Wait to make sure that EventFlags delivers pending events before memory free - osDelay(50); // Free resources osMutexDelete(ble_glue->shci_mtx); osSemaphoreDelete(ble_glue->shci_sem); - osEventFlagsDelete(ble_glue->event_flags); ble_glue_clear_shared_memory(); free(ble_glue); ble_glue = NULL; @@ -275,9 +272,9 @@ void ble_glue_thread_stop() { // Wrap functions static int32_t ble_glue_shci_thread(void* context) { uint32_t flags = 0; + while(true) { - flags = osEventFlagsWait( - ble_glue->event_flags, BLE_GLUE_FLAG_ALL, osFlagsWaitAny, osWaitForever); + flags = osThreadFlagsWait(BLE_GLUE_FLAG_ALL, osFlagsWaitAny, osWaitForever); if(flags & BLE_GLUE_FLAG_SHCI_EVENT) { shci_user_evt_proc(); } @@ -292,7 +289,9 @@ static int32_t ble_glue_shci_thread(void* context) { void shci_notify_asynch_evt(void* pdata) { UNUSED(pdata); if(ble_glue) { - osEventFlagsSet(ble_glue->event_flags, BLE_GLUE_FLAG_SHCI_EVENT); + osThreadId_t thread_id = furi_thread_get_thread_id(ble_glue->thread); + furi_assert(thread_id); + osThreadFlagsSet(thread_id, BLE_GLUE_FLAG_SHCI_EVENT); } } diff --git a/firmware/targets/f7/ble_glue/dev_info_service.c b/firmware/targets/f7/ble_glue/dev_info_service.c old mode 100644 new mode 100755 index ebee56ba1..4adfce59c --- a/firmware/targets/f7/ble_glue/dev_info_service.c +++ b/firmware/targets/f7/ble_glue/dev_info_service.c @@ -8,8 +8,6 @@ #define TAG "BtDevInfoSvc" -#define DEV_INFO_RPC_VERSION_CHAR_MAX_SIZE (10) - typedef struct { uint16_t service_handle; uint16_t man_name_char_handle; @@ -26,6 +24,7 @@ static const char dev_info_serial_num[] = "1.0"; static const char dev_info_firmware_rev_num[] = TOSTRING(TARGET); static const char dev_info_software_rev_num[] = GIT_COMMIT " " GIT_BRANCH " " GIT_BRANCH_NUM " " BUILD_DATE; +static const char dev_info_rpc_version[] = TOSTRING(PROTOBUF_MAJOR_VERSION.PROTOBUF_MINOR_VERSION); static const uint8_t dev_info_rpc_version_uuid[] = {0x33, 0xa9, 0xb5, 0x3e, 0x87, 0x5d, 0x1a, 0x8e, 0xc8, 0x47, 0x5e, 0xae, 0x6d, 0x66, 0xf6, 0x03}; @@ -107,7 +106,7 @@ void dev_info_svc_start() { dev_info_svc->service_handle, UUID_TYPE_128, (const Char_UUID_t*)dev_info_rpc_version_uuid, - DEV_INFO_RPC_VERSION_CHAR_MAX_SIZE, + strlen(dev_info_rpc_version), CHAR_PROP_READ, ATTR_PERMISSION_AUTHEN_READ, GATT_DONT_NOTIFY_EVENTS, @@ -155,18 +154,15 @@ void dev_info_svc_start() { if(status) { FURI_LOG_E(TAG, "Failed to update software revision char: %d", status); } - string_t rpc_version; - string_init_printf(rpc_version, "%d.%d", PROTOBUF_MAJOR_VERSION, PROTOBUF_MINOR_VERSION); status = aci_gatt_update_char_value( dev_info_svc->service_handle, dev_info_svc->rpc_version_char_handle, 0, - strlen(string_get_cstr(rpc_version)), - (uint8_t*)string_get_cstr(rpc_version)); + strlen(dev_info_rpc_version), + (uint8_t*)dev_info_rpc_version); if(status) { FURI_LOG_E(TAG, "Failed to update rpc version char: %d", status); } - string_clear(rpc_version); } void dev_info_svc_stop() { diff --git a/firmware/targets/f7/ble_glue/gap.c b/firmware/targets/f7/ble_glue/gap.c index c4f628556..b21095ed7 100644 --- a/firmware/targets/f7/ble_glue/gap.c +++ b/firmware/targets/f7/ble_glue/gap.c @@ -10,6 +10,8 @@ #define FAST_ADV_TIMEOUT 30000 #define INITIAL_ADV_TIMEOUT 60000 +#define GAP_INTERVAL_TO_MS(x) (uint16_t)((x)*1.25) + typedef struct { uint16_t gap_svc_handle; uint16_t dev_name_char_handle; @@ -23,6 +25,7 @@ typedef struct { typedef struct { GapSvc service; GapConfig* config; + GapConnectionParams connection_params; GapState state; osMutexId_t state_mutex; GapEventCallback on_event_cb; @@ -58,6 +61,33 @@ static GapScan* gap_scan = NULL; static void gap_advertise_start(GapState new_state); static int32_t gap_app(void* context); +static void gap_verify_connection_parameters(Gap* gap) { + furi_assert(gap); + + FURI_LOG_I( + TAG, + "Connection parameters: Connection Interval: %d (%d ms), Slave Latency: %d, Supervision Timeout: %d", + gap->connection_params.conn_interval, + GAP_INTERVAL_TO_MS(gap->connection_params.conn_interval), + gap->connection_params.slave_latency, + gap->connection_params.supervisor_timeout); + + // Send connection parameters request update if necessary + GapConnectionParamsRequest* params = &gap->config->conn_param; + if(params->conn_int_min > gap->connection_params.conn_interval || + params->conn_int_max < gap->connection_params.conn_interval) { + FURI_LOG_W(TAG, "Unsupported connection interval. Request connection parameters update"); + if(aci_l2cap_connection_parameter_update_req( + gap->service.connection_handle, + params->conn_int_min, + params->conn_int_max, + gap->connection_params.slave_latency, + gap->connection_params.supervisor_timeout)) { + FURI_LOG_E(TAG, "Failed to request connection parameters update"); + } + } +} + SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void* pckt) { hci_event_pckt* event_pckt; evt_le_meta_event* meta_evt; @@ -97,12 +127,11 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void* pckt) { case EVT_LE_CONN_UPDATE_COMPLETE: { hci_le_connection_update_complete_event_rp0* event = (hci_le_connection_update_complete_event_rp0*)meta_evt->data; - FURI_LOG_I( - TAG, - "Connection interval: %d, latency: %d, supervision timeout: %d", - event->Conn_Interval, - event->Conn_Latency, - event->Supervision_Timeout); + gap->connection_params.conn_interval = event->Conn_Interval; + gap->connection_params.slave_latency = event->Conn_Latency; + gap->connection_params.supervisor_timeout = event->Supervision_Timeout; + FURI_LOG_I(TAG, "Connection parameters event complete"); + gap_verify_connection_parameters(gap); break; } @@ -124,31 +153,22 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void* pckt) { case EVT_LE_CONN_COMPLETE: furi_hal_power_insomnia_enter(); - hci_le_connection_complete_event_rp0* connection_complete_event = + hci_le_connection_complete_event_rp0* event = (hci_le_connection_complete_event_rp0*)meta_evt->data; - FURI_LOG_I( - TAG, - "Connection complete for connection handle 0x%x", - connection_complete_event->Connection_Handle); + gap->connection_params.conn_interval = event->Conn_Interval; + gap->connection_params.slave_latency = event->Conn_Latency; + gap->connection_params.supervisor_timeout = event->Supervision_Timeout; // Stop advertising as connection completed osTimerStop(gap->advertise_timer); // Update connection status and handle gap->state = GapStateConnected; - gap->service.connection_handle = connection_complete_event->Connection_Handle; - GapConnectionParams* params = &gap->config->conn_param; - if(aci_l2cap_connection_parameter_update_req( - gap->service.connection_handle, - params->conn_int_min, - params->conn_int_max, - params->slave_latency, - params->supervisor_timeout)) { - FURI_LOG_W(TAG, "Failed to request connection parameters update"); - } + gap->service.connection_handle = event->Connection_Handle; + gap_verify_connection_parameters(gap); // Start pairing by sending security request - aci_gap_slave_security_req(connection_complete_event->Connection_Handle); + aci_gap_slave_security_req(event->Connection_Handle); break; case EVT_LE_ADVERTISING_REPORT: { diff --git a/firmware/targets/f7/ble_glue/gap.h b/firmware/targets/f7/ble_glue/gap.h index 1a2e7962c..7ad4e8196 100644 --- a/firmware/targets/f7/ble_glue/gap.h +++ b/firmware/targets/f7/ble_glue/gap.h @@ -55,12 +55,18 @@ typedef enum { GapPairingPinCodeVerifyYesNo, } GapPairing; +typedef struct { + uint16_t conn_interval; + uint16_t slave_latency; + uint16_t supervisor_timeout; +} GapConnectionParams; + typedef struct { uint16_t conn_int_min; uint16_t conn_int_max; uint16_t slave_latency; uint16_t supervisor_timeout; -} GapConnectionParams; +} GapConnectionParamsRequest; typedef struct { uint16_t adv_service_uuid; @@ -69,7 +75,7 @@ typedef struct { GapPairing pairing_method; uint8_t mac_address[GAP_MAC_ADDR_SIZE]; char adv_name[FURI_HAL_VERSION_DEVICE_NAME_LENGTH]; - GapConnectionParams conn_param; + GapConnectionParamsRequest conn_param; } GapConfig; bool gap_init(GapConfig* config, GapEventCallback on_event_cb, void* context); diff --git a/firmware/targets/f7/furi_hal/furi_hal_bt.c b/firmware/targets/f7/furi_hal/furi_hal_bt.c index d9a62b87c..a8b854953 100755 --- a/firmware/targets/f7/furi_hal/furi_hal_bt.c +++ b/firmware/targets/f7/furi_hal/furi_hal_bt.c @@ -44,8 +44,8 @@ FuriHalBtProfileConfig profile_config[FuriHalBtProfileNumber] = { .mac_address = FURI_HAL_BT_DEFAULT_MAC_ADDR, .conn_param = { - .conn_int_min = 0x08, - .conn_int_max = 0x18, + .conn_int_min = 0x18, // 30 ms + .conn_int_max = 0x24, // 45 ms .slave_latency = 0, .supervisor_timeout = 0, }, @@ -62,13 +62,12 @@ FuriHalBtProfileConfig profile_config[FuriHalBtProfileNumber] = { .bonding_mode = true, .pairing_method = GapPairingPinCodeVerifyYesNo, .mac_address = FURI_HAL_BT_DEFAULT_MAC_ADDR, - // TODO optimize .conn_param = { - .conn_int_min = 0x12, - .conn_int_max = 0x1e, - .slave_latency = 6, - .supervisor_timeout = 700, + .conn_int_min = 0x18, // 30 ms + .conn_int_max = 0x24, // 45 ms + .slave_latency = 0, + .supervisor_timeout = 0, }, }, }, diff --git a/firmware/targets/f7/furi_hal/furi_hal_flash.c b/firmware/targets/f7/furi_hal/furi_hal_flash.c index 5ce2f1d43..fc1dbd2f8 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_flash.c +++ b/firmware/targets/f7/furi_hal/furi_hal_flash.c @@ -124,18 +124,14 @@ static void furi_hal_flash_begin_with_core2(bool erase_flag) { // Actually we already have mutex for it, but specification is specification if(LL_HSEM_IsSemaphoreLocked(HSEM, CFG_HW_BLOCK_FLASH_REQ_BY_CPU1_SEMID)) { taskEXIT_CRITICAL(); - continue; - } - - // - if(LL_HSEM_IsSemaphoreLocked(HSEM, CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID)) { - taskEXIT_CRITICAL(); + osThreadYield(); continue; } // Take sempahopre and prevent core2 from anything funky if(LL_HSEM_1StepLock(HSEM, CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID) != 0) { taskEXIT_CRITICAL(); + osThreadYield(); continue; } diff --git a/lib/infrared/worker/infrared_worker.c b/lib/infrared/worker/infrared_worker.c index 86a88367a..4439a7133 100644 --- a/lib/infrared/worker/infrared_worker.c +++ b/lib/infrared/worker/infrared_worker.c @@ -51,7 +51,6 @@ struct InfraredWorkerSignal { struct InfraredWorker { FuriThread* thread; StreamBufferHandle_t stream; - osEventFlagsId_t events; InfraredWorkerSignal signal; InfraredWorkerState state; @@ -93,7 +92,8 @@ static void infrared_worker_furi_hal_message_sent_isr_callback(void* context); static void infrared_worker_rx_timeout_callback(void* context) { InfraredWorker* instance = context; - uint32_t flags_set = osEventFlagsSet(instance->events, INFRARED_WORKER_RX_TIMEOUT_RECEIVED); + uint32_t flags_set = osThreadFlagsSet( + furi_thread_get_thread_id(instance->thread), INFRARED_WORKER_RX_TIMEOUT_RECEIVED); furi_check(flags_set & INFRARED_WORKER_RX_TIMEOUT_RECEIVED); } @@ -110,7 +110,7 @@ static void infrared_worker_rx_callback(void* context, bool level, uint32_t dura INFRARED_WORKER_OVERRUN; portYIELD_FROM_ISR(xHigherPriorityTaskWoken); - uint32_t flags_set = osEventFlagsSet(instance->events, events); + uint32_t flags_set = osThreadFlagsSet(furi_thread_get_thread_id(instance->thread), events); furi_check(flags_set & events); } @@ -152,7 +152,8 @@ static void instance->signal.timings[instance->signal.timings_cnt] = duration; ++instance->signal.timings_cnt; } else { - uint32_t flags_set = osEventFlagsSet(instance->events, INFRARED_WORKER_OVERRUN); + uint32_t flags_set = osThreadFlagsSet( + furi_thread_get_thread_id(instance->thread), INFRARED_WORKER_OVERRUN); furi_check(flags_set & INFRARED_WORKER_OVERRUN); instance->rx.overrun = true; } @@ -166,8 +167,7 @@ static int32_t infrared_worker_rx_thread(void* thread_context) { TickType_t last_blink_time = 0; while(1) { - events = - osEventFlagsWait(instance->events, INFRARED_WORKER_ALL_RX_EVENTS, 0, osWaitForever); + events = osThreadFlagsWait(INFRARED_WORKER_ALL_RX_EVENTS, 0, osWaitForever); furi_check(events & INFRARED_WORKER_ALL_RX_EVENTS); /* at least one caught */ if(events & INFRARED_WORKER_RX_RECEIVED) { @@ -238,7 +238,6 @@ InfraredWorker* infrared_worker_alloc() { instance->blink_enable = false; instance->notification = furi_record_open("notification"); instance->state = InfraredWorkerStateIdle; - instance->events = osEventFlagsNew(NULL); return instance; } @@ -252,7 +251,6 @@ void infrared_worker_free(InfraredWorker* instance) { infrared_free_encoder(instance->infrared_encoder); vStreamBufferDelete(instance->stream); furi_thread_free(instance->thread); - osEventFlagsDelete(instance->events); free(instance); } @@ -263,7 +261,6 @@ void infrared_worker_rx_start(InfraredWorker* instance) { xStreamBufferSetTriggerLevel(instance->stream, sizeof(LevelDuration)); - osEventFlagsClear(instance->events, INFRARED_WORKER_ALL_EVENTS); furi_thread_set_callback(instance->thread, infrared_worker_rx_thread); furi_thread_start(instance->thread); @@ -285,7 +282,7 @@ void infrared_worker_rx_stop(InfraredWorker* instance) { furi_hal_infrared_async_rx_set_capture_isr_callback(NULL, NULL); furi_hal_infrared_async_rx_stop(); - osEventFlagsSet(instance->events, INFRARED_WORKER_EXIT); + osThreadFlagsSet(furi_thread_get_thread_id(instance->thread), INFRARED_WORKER_EXIT); furi_thread_join(instance->thread); BaseType_t xReturn = xStreamBufferReset(instance->stream); @@ -330,7 +327,6 @@ void infrared_worker_tx_start(InfraredWorker* instance) { // size have to be greater than api hal infrared async tx buffer size xStreamBufferSetTriggerLevel(instance->stream, sizeof(InfraredWorkerTiming)); - osEventFlagsClear(instance->events, INFRARED_WORKER_ALL_EVENTS); furi_thread_set_callback(instance->thread, infrared_worker_tx_thread); instance->tx.steady_signal_sent = false; @@ -346,7 +342,8 @@ void infrared_worker_tx_start(InfraredWorker* instance) { static void infrared_worker_furi_hal_message_sent_isr_callback(void* context) { InfraredWorker* instance = context; - uint32_t flags_set = osEventFlagsSet(instance->events, INFRARED_WORKER_TX_MESSAGE_SENT); + uint32_t flags_set = osThreadFlagsSet( + furi_thread_get_thread_id(instance->thread), INFRARED_WORKER_TX_MESSAGE_SENT); furi_check(flags_set & INFRARED_WORKER_TX_MESSAGE_SENT); } @@ -372,7 +369,8 @@ static FuriHalInfraredTxGetDataState state = FuriHalInfraredTxGetDataStateDone; } - uint32_t flags_set = osEventFlagsSet(instance->events, INFRARED_WORKER_TX_FILL_BUFFER); + uint32_t flags_set = osThreadFlagsSet( + furi_thread_get_thread_id(instance->thread), INFRARED_WORKER_TX_FILL_BUFFER); furi_check(flags_set & INFRARED_WORKER_TX_FILL_BUFFER); return state; @@ -500,7 +498,7 @@ static int32_t infrared_worker_tx_thread(void* thread_context) { furi_hal_infrared_async_tx_wait_termination(); instance->state = InfraredWorkerStateStartTx; - events = osEventFlagsGet(instance->events); + events = osThreadFlagsGet(); if(events & INFRARED_WORKER_EXIT) { exit = true; break; @@ -508,8 +506,7 @@ static int32_t infrared_worker_tx_thread(void* thread_context) { break; case InfraredWorkerStateRunTx: - events = osEventFlagsWait( - instance->events, INFRARED_WORKER_ALL_TX_EVENTS, 0, osWaitForever); + events = osThreadFlagsWait(INFRARED_WORKER_ALL_TX_EVENTS, 0, osWaitForever); furi_check(events & INFRARED_WORKER_ALL_TX_EVENTS); /* at least one caught */ if(events & INFRARED_WORKER_EXIT) { @@ -561,7 +558,7 @@ void infrared_worker_tx_stop(InfraredWorker* instance) { furi_assert(instance); furi_assert(instance->state != InfraredWorkerStateRunRx); - osEventFlagsSet(instance->events, INFRARED_WORKER_EXIT); + osThreadFlagsSet(furi_thread_get_thread_id(instance->thread), INFRARED_WORKER_EXIT); furi_thread_join(instance->thread); furi_hal_infrared_async_tx_set_data_isr_callback(NULL, NULL); furi_hal_infrared_async_tx_set_signal_sent_isr_callback(NULL, NULL);