diff --git a/applications/debug/expansion_test/expansion_test.c b/applications/debug/expansion_test/expansion_test.c index 73863798e..0b4b0b27c 100644 --- a/applications/debug/expansion_test/expansion_test.c +++ b/applications/debug/expansion_test/expansion_test.c @@ -96,6 +96,7 @@ static void expansion_test_app_start(ExpansionTestApp* instance) { instance->thread_id = furi_thread_get_current_id(); instance->expansion = furi_record_open(RECORD_EXPANSION); instance->handle = furi_hal_serial_control_acquire(MODULE_SERIAL_ID); + furi_check(instance->handle); // Configure the serial port furi_hal_serial_init(instance->handle, EXPANSION_PROTOCOL_DEFAULT_BAUD_RATE); // Start waiting for the initial pulse diff --git a/applications/main/gpio/gpio_app.c b/applications/main/gpio/gpio_app.c index 020fbf79a..85c2ece84 100644 --- a/applications/main/gpio/gpio_app.c +++ b/applications/main/gpio/gpio_app.c @@ -70,7 +70,12 @@ GpioApp* gpio_app_alloc() { GpioAppViewUsbUartCfg, variable_item_list_get_view(app->var_item_list)); - scene_manager_next_scene(app->scene_manager, GpioSceneStart); + if(furi_hal_serial_control_is_busy(FuriHalSerialIdUsart) || + furi_hal_serial_control_is_busy(FuriHalSerialIdLpuart)) { + scene_manager_next_scene(app->scene_manager, GpioSceneErrorExpansion); + } else { + scene_manager_next_scene(app->scene_manager, GpioSceneStart); + } return app; } diff --git a/applications/main/gpio/scenes/gpio_scene_config.h b/applications/main/gpio/scenes/gpio_scene_config.h index d6fd24d19..3d3fb2f4e 100644 --- a/applications/main/gpio/scenes/gpio_scene_config.h +++ b/applications/main/gpio/scenes/gpio_scene_config.h @@ -3,4 +3,5 @@ ADD_SCENE(gpio, test, Test) ADD_SCENE(gpio, usb_uart, UsbUart) ADD_SCENE(gpio, usb_uart_cfg, UsbUartCfg) ADD_SCENE(gpio, usb_uart_close_rpc, UsbUartCloseRpc) +ADD_SCENE(gpio, error_expansion, ErrorExpansion) ADD_SCENE(gpio, exit_confirm, ExitConfirm) diff --git a/applications/main/gpio/scenes/gpio_scene_error_expansion.c b/applications/main/gpio/scenes/gpio_scene_error_expansion.c new file mode 100644 index 000000000..4f30f8b9d --- /dev/null +++ b/applications/main/gpio/scenes/gpio_scene_error_expansion.c @@ -0,0 +1,43 @@ +#include "../gpio_app_i.h" +#include "../gpio_custom_event.h" + +void gpio_scene_error_expansion_on_enter(void* context) { + GpioApp* app = context; + + widget_add_icon_element(app->widget, 78, 0, &I_ActiveConnection_50x64); + widget_add_string_multiline_element( + app->widget, 3, 2, AlignLeft, AlignTop, FontPrimary, "Ext. Module\nis connected!"); + widget_add_string_multiline_element( + app->widget, + 3, + 30, + AlignLeft, + AlignTop, + FontSecondary, + "Disconnect External\n" + "Module\n" + "to use this function."); + + view_dispatcher_switch_to_view(app->view_dispatcher, GpioAppViewUsbUartCloseRpc); +} + +bool gpio_scene_error_expansion_on_event(void* context, SceneManagerEvent event) { + GpioApp* app = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == GpioCustomEventErrorBack) { + if(!scene_manager_previous_scene(app->scene_manager)) { + scene_manager_stop(app->scene_manager); + view_dispatcher_stop(app->view_dispatcher); + } + consumed = true; + } + } + return consumed; +} + +void gpio_scene_error_expansion_on_exit(void* context) { + GpioApp* app = context; + widget_reset(app->widget); +} diff --git a/targets/f18/api_symbols.csv b/targets/f18/api_symbols.csv index 5259db0f3..4a79c5553 100644 --- a/targets/f18/api_symbols.csv +++ b/targets/f18/api_symbols.csv @@ -1,5 +1,5 @@ entry,status,name,type,params -Version,+,52.0,, +Version,+,53.0,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/cli/cli.h,, Header,+,applications/services/cli/cli_vcp.h,, @@ -1277,11 +1277,12 @@ Function,+,furi_hal_serial_async_rx_stop,void,FuriHalSerialHandle* Function,+,furi_hal_serial_control_acquire,FuriHalSerialHandle*,FuriHalSerialId Function,+,furi_hal_serial_control_deinit,void, Function,+,furi_hal_serial_control_init,void, +Function,+,furi_hal_serial_control_is_busy,_Bool,FuriHalSerialId Function,+,furi_hal_serial_control_release,void,FuriHalSerialHandle* -Function,+,furi_hal_serial_control_resume,void, +Function,-,furi_hal_serial_control_resume,void, Function,+,furi_hal_serial_control_set_expansion_callback,void,"FuriHalSerialId, FuriHalSerialControlExpansionCallback, void*" Function,+,furi_hal_serial_control_set_logging_config,void,"FuriHalSerialId, uint32_t" -Function,+,furi_hal_serial_control_suspend,void, +Function,-,furi_hal_serial_control_suspend,void, Function,+,furi_hal_serial_deinit,void,FuriHalSerialHandle* Function,+,furi_hal_serial_disable_direction,void,"FuriHalSerialHandle*, FuriHalSerialDirection" Function,+,furi_hal_serial_dma_rx,size_t,"FuriHalSerialHandle*, uint8_t*, size_t" diff --git a/targets/f7/api_symbols.csv b/targets/f7/api_symbols.csv index c5c5cf2a0..075d1049a 100644 --- a/targets/f7/api_symbols.csv +++ b/targets/f7/api_symbols.csv @@ -1,5 +1,5 @@ entry,status,name,type,params -Version,+,52.0,, +Version,+,53.0,, Header,+,applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/cli/cli.h,, @@ -1443,11 +1443,12 @@ Function,+,furi_hal_serial_async_rx_stop,void,FuriHalSerialHandle* Function,+,furi_hal_serial_control_acquire,FuriHalSerialHandle*,FuriHalSerialId Function,+,furi_hal_serial_control_deinit,void, Function,+,furi_hal_serial_control_init,void, +Function,+,furi_hal_serial_control_is_busy,_Bool,FuriHalSerialId Function,+,furi_hal_serial_control_release,void,FuriHalSerialHandle* -Function,+,furi_hal_serial_control_resume,void, +Function,-,furi_hal_serial_control_resume,void, Function,+,furi_hal_serial_control_set_expansion_callback,void,"FuriHalSerialId, FuriHalSerialControlExpansionCallback, void*" Function,+,furi_hal_serial_control_set_logging_config,void,"FuriHalSerialId, uint32_t" -Function,+,furi_hal_serial_control_suspend,void, +Function,-,furi_hal_serial_control_suspend,void, Function,+,furi_hal_serial_deinit,void,FuriHalSerialHandle* Function,+,furi_hal_serial_disable_direction,void,"FuriHalSerialHandle*, FuriHalSerialDirection" Function,+,furi_hal_serial_dma_rx,size_t,"FuriHalSerialHandle*, uint8_t*, size_t" diff --git a/targets/f7/ble_glue/tl_dbg_conf.h b/targets/f7/ble_glue/tl_dbg_conf.h index daaa9d82b..240cd5f2f 100644 --- a/targets/f7/ble_glue/tl_dbg_conf.h +++ b/targets/f7/ble_glue/tl_dbg_conf.h @@ -38,7 +38,7 @@ extern "C" { #endif #if(TL_SHCI_CMD_DBG_RAW_EN != 0) -#define TL_SHCI_CMD_DBG_RAW(_PDATA_, _SIZE_) furi_hal_console_tx_with_new_line(_PDATA_, _SIZE_) +#define TL_SHCI_CMD_DBG_RAW(_PDATA_, _SIZE_) furi_log_tx(_PDATA_, _SIZE_) #else #define TL_SHCI_CMD_DBG_RAW(...) #endif @@ -52,7 +52,7 @@ extern "C" { #endif #if(TL_SHCI_EVT_DBG_RAW_EN != 0) -#define TL_SHCI_EVT_DBG_RAW(_PDATA_, _SIZE_) furi_hal_console_tx_with_new_line(_PDATA_, _SIZE_) +#define TL_SHCI_EVT_DBG_RAW(_PDATA_, _SIZE_) furi_log_tx(_PDATA_, _SIZE_) #else #define TL_SHCI_EVT_DBG_RAW(...) #endif @@ -69,7 +69,7 @@ extern "C" { #endif #if(TL_HCI_CMD_DBG_RAW_EN != 0) -#define TL_HCI_CMD_DBG_RAW(_PDATA_, _SIZE_) furi_hal_console_tx_with_new_line(_PDATA_, _SIZE_) +#define TL_HCI_CMD_DBG_RAW(_PDATA_, _SIZE_) furi_log_tx(_PDATA_, _SIZE_) #else #define TL_HCI_CMD_DBG_RAW(...) #endif @@ -83,7 +83,7 @@ extern "C" { #endif #if(TL_HCI_EVT_DBG_RAW_EN != 0) -#define TL_HCI_EVT_DBG_RAW(_PDATA_, _SIZE_) furi_hal_console_tx_with_new_line(_PDATA_, _SIZE_) +#define TL_HCI_EVT_DBG_RAW(_PDATA_, _SIZE_) furi_log_tx(_PDATA_, _SIZE_) #else #define TL_HCI_EVT_DBG_RAW(...) #endif diff --git a/targets/f7/furi_hal/furi_hal_os.c b/targets/f7/furi_hal/furi_hal_os.c index 9045295a1..85f2d2e45 100644 --- a/targets/f7/furi_hal/furi_hal_os.c +++ b/targets/f7/furi_hal/furi_hal_os.c @@ -194,7 +194,8 @@ void vPortSuppressTicksAndSleep(TickType_t expected_idle_ticks) { if(completed_ticks > 0) { if(completed_ticks > expected_idle_ticks) { #ifdef FURI_HAL_OS_DEBUG - furi_hal_console_printf(">%lu\r\n", completed_ticks - expected_idle_ticks); + furi_log_print_raw_format( + FuriLogLevelDebug, ">%lu\r\n", completed_ticks - expected_idle_ticks); #endif completed_ticks = expected_idle_ticks; } diff --git a/targets/f7/furi_hal/furi_hal_power.c b/targets/f7/furi_hal/furi_hal_power.c index 483316c00..f03aea75f 100644 --- a/targets/f7/furi_hal/furi_hal_power.c +++ b/targets/f7/furi_hal/furi_hal_power.c @@ -173,7 +173,13 @@ static inline bool furi_hal_power_deep_sleep_available() { } static inline void furi_hal_power_light_sleep() { +#ifdef FURI_HAL_POWER_DEBUG + furi_hal_gpio_write(FURI_HAL_POWER_DEBUG_WFI_GPIO, 1); +#endif __WFI(); +#ifdef FURI_HAL_POWER_DEBUG + furi_hal_gpio_write(FURI_HAL_POWER_DEBUG_WFI_GPIO, 0); +#endif } static inline void furi_hal_power_suspend_aux_periphs() { @@ -223,7 +229,13 @@ static inline void furi_hal_power_deep_sleep() { __force_stores(); #endif +#ifdef FURI_HAL_POWER_DEBUG + furi_hal_gpio_write(FURI_HAL_POWER_DEBUG_STOP_GPIO, 1); +#endif __WFI(); +#ifdef FURI_HAL_POWER_DEBUG + furi_hal_gpio_write(FURI_HAL_POWER_DEBUG_STOP_GPIO, 0); +#endif LL_LPM_EnableSleep(); @@ -250,21 +262,9 @@ static inline void furi_hal_power_deep_sleep() { void furi_hal_power_sleep() { if(furi_hal_power_deep_sleep_available()) { -#ifdef FURI_HAL_POWER_DEBUG - furi_hal_gpio_write(FURI_HAL_POWER_DEBUG_STOP_GPIO, 1); -#endif furi_hal_power_deep_sleep(); -#ifdef FURI_HAL_POWER_DEBUG - furi_hal_gpio_write(FURI_HAL_POWER_DEBUG_STOP_GPIO, 0); -#endif } else { -#ifdef FURI_HAL_POWER_DEBUG - furi_hal_gpio_write(FURI_HAL_POWER_DEBUG_WFI_GPIO, 1); -#endif furi_hal_power_light_sleep(); -#ifdef FURI_HAL_POWER_DEBUG - furi_hal_gpio_write(FURI_HAL_POWER_DEBUG_WFI_GPIO, 0); -#endif } } diff --git a/targets/f7/furi_hal/furi_hal_serial_control.c b/targets/f7/furi_hal/furi_hal_serial_control.c index 0c95d12c1..37454823b 100644 --- a/targets/f7/furi_hal/furi_hal_serial_control.c +++ b/targets/f7/furi_hal/furi_hal_serial_control.c @@ -9,10 +9,9 @@ typedef enum { FuriHalSerialControlMessageTypeStop, - FuriHalSerialControlMessageTypeSuspend, - FuriHalSerialControlMessageTypeResume, FuriHalSerialControlMessageTypeAcquire, FuriHalSerialControlMessageTypeRelease, + FuriHalSerialControlMessageTypeIsBusy, FuriHalSerialControlMessageTypeLogging, FuriHalSerialControlMessageTypeExpansionSetCallback, FuriHalSerialControlMessageTypeExpansionIrq, @@ -92,29 +91,6 @@ static bool furi_hal_serial_control_handler_stop(void* input, void* output) { return false; } -static bool furi_hal_serial_control_handler_suspend(void* input, void* output) { - UNUSED(input); - UNUSED(output); - - for(size_t i = 0; i < FuriHalSerialIdMax; i++) { - furi_hal_serial_tx_wait_complete(&furi_hal_serial_control->handles[i]); - furi_hal_serial_suspend(&furi_hal_serial_control->handles[i]); - } - - return true; -} - -static bool furi_hal_serial_control_handler_resume(void* input, void* output) { - UNUSED(input); - UNUSED(output); - - for(size_t i = 0; i < FuriHalSerialIdMax; i++) { - furi_hal_serial_resume(&furi_hal_serial_control->handles[i]); - } - - return true; -} - static bool furi_hal_serial_control_handler_acquire(void* input, void* output) { FuriHalSerialId serial_id = *(FuriHalSerialId*)input; if(furi_hal_serial_control->handles[serial_id].in_use) { @@ -148,6 +124,13 @@ static bool furi_hal_serial_control_handler_release(void* input, void* output) { return true; } +static bool furi_hal_serial_control_handler_is_busy(void* input, void* output) { + FuriHalSerialId serial_id = *(FuriHalSerialId*)input; + *(bool*)output = furi_hal_serial_control->handles[serial_id].in_use; + + return true; +} + static bool furi_hal_serial_control_handler_logging(void* input, void* output) { UNUSED(output); @@ -211,10 +194,9 @@ typedef bool (*FuriHalSerialControlCommandHandler)(void* input, void* output); static const FuriHalSerialControlCommandHandler furi_hal_serial_control_handlers[] = { [FuriHalSerialControlMessageTypeStop] = furi_hal_serial_control_handler_stop, - [FuriHalSerialControlMessageTypeSuspend] = furi_hal_serial_control_handler_suspend, - [FuriHalSerialControlMessageTypeResume] = furi_hal_serial_control_handler_resume, [FuriHalSerialControlMessageTypeAcquire] = furi_hal_serial_control_handler_acquire, [FuriHalSerialControlMessageTypeRelease] = furi_hal_serial_control_handler_release, + [FuriHalSerialControlMessageTypeIsBusy] = furi_hal_serial_control_handler_is_busy, [FuriHalSerialControlMessageTypeLogging] = furi_hal_serial_control_handler_logging, [FuriHalSerialControlMessageTypeExpansionSetCallback] = furi_hal_serial_control_handler_expansion_set_callback, @@ -277,21 +259,18 @@ void furi_hal_serial_control_deinit(void) { void furi_hal_serial_control_suspend(void) { furi_check(furi_hal_serial_control); - FuriHalSerialControlMessage message; - message.type = FuriHalSerialControlMessageTypeSuspend; - message.api_lock = api_lock_alloc_locked(); - furi_message_queue_put(furi_hal_serial_control->queue, &message, FuriWaitForever); - api_lock_wait_unlock_and_free(message.api_lock); + for(size_t i = 0; i < FuriHalSerialIdMax; i++) { + furi_hal_serial_tx_wait_complete(&furi_hal_serial_control->handles[i]); + furi_hal_serial_suspend(&furi_hal_serial_control->handles[i]); + } } void furi_hal_serial_control_resume(void) { furi_check(furi_hal_serial_control); - FuriHalSerialControlMessage message; - message.type = FuriHalSerialControlMessageTypeResume; - message.api_lock = api_lock_alloc_locked(); - furi_message_queue_put(furi_hal_serial_control->queue, &message, FuriWaitForever); - api_lock_wait_unlock_and_free(message.api_lock); + for(size_t i = 0; i < FuriHalSerialIdMax; i++) { + furi_hal_serial_resume(&furi_hal_serial_control->handles[i]); + } } FuriHalSerialHandle* furi_hal_serial_control_acquire(FuriHalSerialId serial_id) { @@ -322,6 +301,22 @@ void furi_hal_serial_control_release(FuriHalSerialHandle* handle) { api_lock_wait_unlock_and_free(message.api_lock); } +bool furi_hal_serial_control_is_busy(FuriHalSerialId serial_id) { + furi_check(furi_hal_serial_control); + + bool result = false; + + FuriHalSerialControlMessage message; + message.type = FuriHalSerialControlMessageTypeIsBusy; + message.api_lock = api_lock_alloc_locked(); + message.input = &serial_id; + message.output = &result; + furi_message_queue_put(furi_hal_serial_control->queue, &message, FuriWaitForever); + api_lock_wait_unlock_and_free(message.api_lock); + + return result; +} + void furi_hal_serial_control_set_logging_config(FuriHalSerialId serial_id, uint32_t baud_rate) { furi_check(serial_id <= FuriHalSerialIdMax); furi_check(baud_rate >= 9600 && baud_rate <= 4000000); diff --git a/targets/f7/furi_hal/furi_hal_serial_control.h b/targets/f7/furi_hal/furi_hal_serial_control.h index 01fdf0a88..463f43181 100644 --- a/targets/f7/furi_hal/furi_hal_serial_control.h +++ b/targets/f7/furi_hal/furi_hal_serial_control.h @@ -12,10 +12,18 @@ void furi_hal_serial_control_init(void); /** De-Initialize Serial Control */ void furi_hal_serial_control_deinit(void); -/** Suspend All Serial Interfaces */ +/** Suspend All Serial Interfaces + * + * @warning this is internal method, can only be used in suppress tick + * callback + */ void furi_hal_serial_control_suspend(void); -/** Resume All Serial Interfaces */ +/** Resume All Serial Interfaces + * + * @warning this is internal method, can only be used in suppress tick + * callback + */ void furi_hal_serial_control_resume(void); /** Acquire Serial Interface Handler @@ -32,6 +40,14 @@ FuriHalSerialHandle* furi_hal_serial_control_acquire(FuriHalSerialId serial_id); */ void furi_hal_serial_control_release(FuriHalSerialHandle* handle); +/** Acquire Serial Interface Handler + * + * @param[in] serial_id The serial transceiver identifier + * + * @return true if handle is acquired by someone + */ +bool furi_hal_serial_control_is_busy(FuriHalSerialId serial_id); + /** Acquire Serial Interface Handler * * @param[in] serial_id The serial transceiver identifier. Use FuriHalSerialIdMax to disable logging. diff --git a/targets/furi_hal_include/furi_hal_power.h b/targets/furi_hal_include/furi_hal_power.h index 5edda6ba1..ebe0fe614 100644 --- a/targets/furi_hal_include/furi_hal_power.h +++ b/targets/furi_hal_include/furi_hal_power.h @@ -58,7 +58,7 @@ void furi_hal_power_insomnia_enter(); */ void furi_hal_power_insomnia_exit(); -/** Check if sleep availble +/** Check if sleep available * * @return true if available */