mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-05-05 05:09:09 -07:00
add is_connected api for expansion \w @Willy-JL
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user