From 25d686fdfbc86bc65cada723c7a35ba46247b07a Mon Sep 17 00:00:00 2001 From: HaxSam Date: Fri, 1 Mar 2024 09:49:39 +0100 Subject: [PATCH 1/5] add is_connected api for expansion \w @Willy-JL --- applications/services/expansion/expansion.c | 47 ++++++++++++++++--- applications/services/expansion/expansion.h | 8 ++++ .../services/expansion/expansion_worker.c | 3 +- .../services/expansion/expansion_worker.h | 7 ++- 4 files changed, 56 insertions(+), 9 deletions(-) diff --git a/applications/services/expansion/expansion.c b/applications/services/expansion/expansion.c index 5b834b48d..ef760eede 100644 --- a/applications/services/expansion/expansion.c +++ b/applications/services/expansion/expansion.c @@ -18,6 +18,7 @@ typedef enum { ExpansionStateDisabled, ExpansionStateEnabled, ExpansionStateRunning, + ExpansionStateConnectionEstablished, } ExpansionState; typedef enum { @@ -26,6 +27,7 @@ typedef enum { ExpansionMessageTypeSetListenSerial, ExpansionMessageTypeModuleConnected, ExpansionMessageTypeModuleDisconnected, + ExpansionMessageTypeConnectionEstablished, } ExpansionMessageType; typedef union { @@ -68,13 +70,21 @@ static void expansion_detect_callback(void* context) { UNUSED(status); } -static void expansion_worker_callback(void* context) { +static void expansion_worker_callback(void* context, ExpansionWorkerCallbackReason reason) { furi_assert(context); Expansion* instance = context; - ExpansionMessage message = { - .type = ExpansionMessageTypeModuleDisconnected, - .api_lock = NULL, // Not locking the API here to avoid a deadlock + ExpansionMessage message; + switch(reason) { + case ExpansionWorkerCallbackReasonExit: + message.type = ExpansionMessageTypeModuleDisconnected; + message.api_lock = NULL; // Not locking the API here to avoid a deadlock + break; + + case ExpansionWorkerCallbackReasonConnected: + message.type = ExpansionMessageTypeConnectionEstablished; + message.api_lock = api_lock_alloc_locked(); + break; }; const FuriStatus status = furi_message_queue_put(instance->queue, &message, FuriWaitForever); @@ -105,7 +115,9 @@ static void if(instance->state == ExpansionStateDisabled) { return; - } else if(instance->state == ExpansionStateRunning) { + } else if( + instance->state == ExpansionStateRunning || + instance->state == ExpansionStateConnectionEstablished) { expansion_worker_stop(instance->worker); expansion_worker_free(instance->worker); } else { @@ -122,7 +134,8 @@ static void expansion_control_handler_set_listen_serial( const ExpansionMessageData* data) { furi_check(data->serial_id < FuriHalSerialIdMax); - if(instance->state == ExpansionStateRunning) { + if(instance->state == ExpansionStateRunning || + instance->state == ExpansionStateConnectionEstablished) { expansion_worker_stop(instance->worker); expansion_worker_free(instance->worker); @@ -160,7 +173,8 @@ static void expansion_control_handler_module_disconnected( Expansion* instance, const ExpansionMessageData* data) { UNUSED(data); - if(instance->state != ExpansionStateRunning) { + if(instance->state != ExpansionStateRunning && + instance->state != ExpansionStateConnectionEstablished) { return; } @@ -170,6 +184,18 @@ static void expansion_control_handler_module_disconnected( instance->serial_id, expansion_detect_callback, instance); } +static void expansion_control_handler_module_connection_established( + Expansion* instance, + const ExpansionMessageData* data) { + UNUSED(data); + if(instance->state != ExpansionStateRunning && + instance->state != ExpansionStateConnectionEstablished) { + return; + } + + instance->state = ExpansionStateConnectionEstablished; +} + typedef void (*ExpansionControlHandler)(Expansion*, const ExpansionMessageData*); static const ExpansionControlHandler expansion_control_handlers[] = { @@ -178,6 +204,8 @@ static const ExpansionControlHandler expansion_control_handlers[] = { [ExpansionMessageTypeSetListenSerial] = expansion_control_handler_set_listen_serial, [ExpansionMessageTypeModuleConnected] = expansion_control_handler_module_connected, [ExpansionMessageTypeModuleDisconnected] = expansion_control_handler_module_disconnected, + [ExpansionMessageTypeConnectionEstablished] = + expansion_control_handler_module_connection_established, }; static int32_t expansion_control(void* context) { @@ -249,6 +277,11 @@ void expansion_disable(Expansion* instance) { api_lock_wait_unlock_and_free(message.api_lock); } +bool expansion_is_connected(Expansion* instance) { + furi_check(instance); + return instance->state == ExpansionStateConnectionEstablished; +} + void expansion_set_listen_serial(Expansion* instance, FuriHalSerialId serial_id) { furi_check(instance); furi_check(serial_id < FuriHalSerialIdMax); diff --git a/applications/services/expansion/expansion.h b/applications/services/expansion/expansion.h index e169b3c15..6643291a9 100644 --- a/applications/services/expansion/expansion.h +++ b/applications/services/expansion/expansion.h @@ -50,6 +50,14 @@ void expansion_enable(Expansion* instance); */ void expansion_disable(Expansion* instance); +/** + * @brief Check support for expansion modules if its currently connected. + * + * @param[in,out] instance pointer to the Expansion instance. + * + */ +bool expansion_is_connected(Expansion* instance); + /** * @brief Enable support for expansion modules on designated serial port. * diff --git a/applications/services/expansion/expansion_worker.c b/applications/services/expansion/expansion_worker.c index fd92063d2..4047212eb 100644 --- a/applications/services/expansion/expansion_worker.c +++ b/applications/services/expansion/expansion_worker.c @@ -223,6 +223,7 @@ static bool expansion_worker_handle_state_handshake( if(furi_hal_serial_is_baud_rate_supported(instance->serial_handle, baud_rate)) { instance->state = ExpansionWorkerStateConnected; + instance->callback(instance->cb_context, ExpansionWorkerCallbackReasonConnected); // Send response at previous baud rate if(!expansion_worker_send_status_response(instance, ExpansionFrameErrorNone)) break; furi_hal_serial_set_br(instance->serial_handle, baud_rate); @@ -351,7 +352,7 @@ static int32_t expansion_worker(void* context) { // Do not invoke worker callback on user-requested exit if((instance->exit_reason != ExpansionWorkerExitReasonUser) && (instance->callback != NULL)) { - instance->callback(instance->cb_context); + instance->callback(instance->cb_context, ExpansionWorkerCallbackReasonExit); } return 0; diff --git a/applications/services/expansion/expansion_worker.h b/applications/services/expansion/expansion_worker.h index 761f79c1d..cd1da41c8 100644 --- a/applications/services/expansion/expansion_worker.h +++ b/applications/services/expansion/expansion_worker.h @@ -17,6 +17,11 @@ */ typedef struct ExpansionWorker ExpansionWorker; +typedef enum { + ExpansionWorkerCallbackReasonExit, + ExpansionWorkerCallbackReasonConnected, +} ExpansionWorkerCallbackReason; + /** * @brief Worker callback type. * @@ -24,7 +29,7 @@ typedef struct ExpansionWorker ExpansionWorker; * * @param[in,out] context pointer to a user-defined object. */ -typedef void (*ExpansionWorkerCallback)(void* context); +typedef void (*ExpansionWorkerCallback)(void* context, ExpansionWorkerCallbackReason reason); /** * @brief Create an expansion worker instance. From 695fe03f80e800c7f4ab93070fd5830979349370 Mon Sep 17 00:00:00 2001 From: HaxSam Date: Fri, 1 Mar 2024 09:56:59 +0100 Subject: [PATCH 2/5] forgot api_symbols for expansion --- targets/f7/api_symbols.csv | 1 + 1 file changed, 1 insertion(+) diff --git a/targets/f7/api_symbols.csv b/targets/f7/api_symbols.csv index 0f538b0dd..a42949f17 100644 --- a/targets/f7/api_symbols.csv +++ b/targets/f7/api_symbols.csv @@ -1033,6 +1033,7 @@ Function,-,exp2l,long double,long double Function,+,expansion_disable,void,Expansion* Function,+,expansion_enable,void,Expansion* Function,+,expansion_get_settings,ExpansionSettings*,Expansion* +Function,+,expansion_is_connected,_Bool,Expansion* Function,+,expansion_set_listen_serial,void,"Expansion*, FuriHalSerialId" Function,-,expansion_settings_load,_Bool,ExpansionSettings* Function,+,expansion_settings_save,_Bool,ExpansionSettings* From fdd88ea823050663cbd82225e70fe83d338bdca1 Mon Sep 17 00:00:00 2001 From: HaxSam Date: Fri, 1 Mar 2024 15:42:12 +0100 Subject: [PATCH 3/5] return command added --- applications/services/expansion/expansion.h | 1 + 1 file changed, 1 insertion(+) diff --git a/applications/services/expansion/expansion.h b/applications/services/expansion/expansion.h index 6643291a9..9f810c414 100644 --- a/applications/services/expansion/expansion.h +++ b/applications/services/expansion/expansion.h @@ -55,6 +55,7 @@ void expansion_disable(Expansion* instance); * * @param[in,out] instance pointer to the Expansion instance. * + * @return Boolean indicating if the expansion module is connected. */ bool expansion_is_connected(Expansion* instance); From e79e49edc6928d53121df29b5a4a2e01304177d0 Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Tue, 5 Mar 2024 22:08:29 +0000 Subject: [PATCH 4/5] Improve some naming for expansion is connected --- applications/services/expansion/expansion.c | 5 ++--- applications/services/expansion/expansion.h | 4 ++-- applications/services/expansion/expansion_worker.h | 1 + 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/applications/services/expansion/expansion.c b/applications/services/expansion/expansion.c index ef760eede..174d91162 100644 --- a/applications/services/expansion/expansion.c +++ b/applications/services/expansion/expansion.c @@ -184,7 +184,7 @@ static void expansion_control_handler_module_disconnected( instance->serial_id, expansion_detect_callback, instance); } -static void expansion_control_handler_module_connection_established( +static void expansion_control_handler_connection_established( Expansion* instance, const ExpansionMessageData* data) { UNUSED(data); @@ -204,8 +204,7 @@ static const ExpansionControlHandler expansion_control_handlers[] = { [ExpansionMessageTypeSetListenSerial] = expansion_control_handler_set_listen_serial, [ExpansionMessageTypeModuleConnected] = expansion_control_handler_module_connected, [ExpansionMessageTypeModuleDisconnected] = expansion_control_handler_module_disconnected, - [ExpansionMessageTypeConnectionEstablished] = - expansion_control_handler_module_connection_established, + [ExpansionMessageTypeConnectionEstablished] = expansion_control_handler_connection_established, }; static int32_t expansion_control(void* context) { diff --git a/applications/services/expansion/expansion.h b/applications/services/expansion/expansion.h index 9f810c414..1b0879b1e 100644 --- a/applications/services/expansion/expansion.h +++ b/applications/services/expansion/expansion.h @@ -51,11 +51,11 @@ void expansion_enable(Expansion* instance); void expansion_disable(Expansion* instance); /** - * @brief Check support for expansion modules if its currently connected. + * @brief Check if an expansion module is connected. * * @param[in,out] instance pointer to the Expansion instance. * - * @return Boolean indicating if the expansion module is connected. + * @returns true if the module is connected and initialized, false otherwise. */ bool expansion_is_connected(Expansion* instance); diff --git a/applications/services/expansion/expansion_worker.h b/applications/services/expansion/expansion_worker.h index cd1da41c8..faab2887f 100644 --- a/applications/services/expansion/expansion_worker.h +++ b/applications/services/expansion/expansion_worker.h @@ -28,6 +28,7 @@ typedef enum { * @see expansion_worker_set_callback() * * @param[in,out] context pointer to a user-defined object. + * @param[in] reason reason for the callback. */ typedef void (*ExpansionWorkerCallback)(void* context, ExpansionWorkerCallbackReason reason); From 25965abed3ee06a2389a743f8e4de9910e8a4ce1 Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Tue, 5 Mar 2024 22:19:08 +0000 Subject: [PATCH 5/5] Expansion is_connected in event queue --- applications/services/expansion/expansion.c | 25 +++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/applications/services/expansion/expansion.c b/applications/services/expansion/expansion.c index 174d91162..9c64d0b5a 100644 --- a/applications/services/expansion/expansion.c +++ b/applications/services/expansion/expansion.c @@ -28,10 +28,14 @@ typedef enum { ExpansionMessageTypeModuleConnected, ExpansionMessageTypeModuleDisconnected, ExpansionMessageTypeConnectionEstablished, + ExpansionMessageTypeIsConnected, } ExpansionMessageType; typedef union { - FuriHalSerialId serial_id; + union { + FuriHalSerialId serial_id; + bool* is_connected; + }; } ExpansionMessageData; typedef struct { @@ -196,6 +200,11 @@ static void expansion_control_handler_connection_established( instance->state = ExpansionStateConnectionEstablished; } +static void + expansion_control_handler_is_connected(Expansion* instance, const ExpansionMessageData* data) { + *data->is_connected = instance->state == ExpansionStateConnectionEstablished; +} + typedef void (*ExpansionControlHandler)(Expansion*, const ExpansionMessageData*); static const ExpansionControlHandler expansion_control_handlers[] = { @@ -205,6 +214,7 @@ static const ExpansionControlHandler expansion_control_handlers[] = { [ExpansionMessageTypeModuleConnected] = expansion_control_handler_module_connected, [ExpansionMessageTypeModuleDisconnected] = expansion_control_handler_module_disconnected, [ExpansionMessageTypeConnectionEstablished] = expansion_control_handler_connection_established, + [ExpansionMessageTypeIsConnected] = expansion_control_handler_is_connected, }; static int32_t expansion_control(void* context) { @@ -278,7 +288,18 @@ void expansion_disable(Expansion* instance) { bool expansion_is_connected(Expansion* instance) { furi_check(instance); - return instance->state == ExpansionStateConnectionEstablished; + bool is_connected; + + ExpansionMessage message = { + .type = ExpansionMessageTypeIsConnected, + .data.is_connected = &is_connected, + .api_lock = api_lock_alloc_locked(), + }; + + furi_message_queue_put(instance->queue, &message, FuriWaitForever); + api_lock_wait_unlock_and_free(message.api_lock); + + return is_connected; } void expansion_set_listen_serial(Expansion* instance, FuriHalSerialId serial_id) {