mirror of
https://github.com/DarkFlippers/unleashed-firmware.git
synced 2024-12-25 22:32:29 +03:00
[FL-2612, FL-2618, FL-2619, FL-2622] CLI, threads, notifications, archive fixes (#1354)
* CLI, notifications, archive fixes * Led blink fix * Fix thread flags notification index * Archive: fix infinite tab switch on empty SD card Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
parent
ece142a667
commit
e17dae2d00
@ -15,8 +15,9 @@ static void
|
|||||||
|
|
||||||
int32_t load_offset = 0;
|
int32_t load_offset = 0;
|
||||||
browser->is_root = is_root;
|
browser->is_root = is_root;
|
||||||
|
ArchiveTabEnum tab = archive_get_tab(browser);
|
||||||
|
|
||||||
if((item_cnt == 0) && (archive_is_home(browser))) {
|
if((item_cnt == 0) && (archive_is_home(browser)) && (tab != ArchiveTabBrowser)) {
|
||||||
archive_switch_tab(browser, browser->last_tab_switch_dir);
|
archive_switch_tab(browser, browser->last_tab_switch_dir);
|
||||||
} else if(!string_start_with_str_p(browser->path, "/app:")) {
|
} else if(!string_start_with_str_p(browser->path, "/app:")) {
|
||||||
with_view_model(
|
with_view_model(
|
||||||
@ -389,6 +390,22 @@ void archive_favorites_move_mode(ArchiveBrowserView* browser, bool active) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool archive_is_dir_exists(string_t path) {
|
||||||
|
if(string_equal_str_p(path, "/any")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool state = false;
|
||||||
|
FileInfo file_info;
|
||||||
|
Storage* storage = furi_record_open("storage");
|
||||||
|
if(storage_common_stat(storage, string_get_cstr(path), &file_info) == FSE_OK) {
|
||||||
|
if(file_info.flags & FSF_DIRECTORY) {
|
||||||
|
state = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
furi_record_close("storage");
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
void archive_switch_tab(ArchiveBrowserView* browser, InputKey key) {
|
void archive_switch_tab(ArchiveBrowserView* browser, InputKey key) {
|
||||||
furi_assert(browser);
|
furi_assert(browser);
|
||||||
ArchiveTabEnum tab = archive_get_tab(browser);
|
ArchiveTabEnum tab = archive_get_tab(browser);
|
||||||
@ -418,11 +435,15 @@ void archive_switch_tab(ArchiveBrowserView* browser, InputKey key) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ArchiveTabEnum tab = archive_get_tab(browser);
|
tab = archive_get_tab(browser);
|
||||||
bool skip_assets = (strcmp(archive_get_tab_ext(tab), "*") == 0) ? false : true;
|
if(archive_is_dir_exists(browser->path)) {
|
||||||
file_browser_worker_set_config(
|
bool skip_assets = (strcmp(archive_get_tab_ext(tab), "*") == 0) ? false : true;
|
||||||
browser->worker, browser->path, archive_get_tab_ext(tab), skip_assets);
|
file_browser_worker_set_config(
|
||||||
tab_empty = false; // Empty check will be performed later
|
browser->worker, browser->path, archive_get_tab_ext(tab), skip_assets);
|
||||||
|
tab_empty = false; // Empty check will be performed later
|
||||||
|
} else {
|
||||||
|
tab_empty = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if((tab_empty) && (tab != ArchiveTabBrowser)) {
|
if((tab_empty) && (tab != ArchiveTabBrowser)) {
|
||||||
|
@ -229,18 +229,22 @@ static void cli_handle_enter(Cli* cli) {
|
|||||||
|
|
||||||
// Search for command
|
// Search for command
|
||||||
furi_check(osMutexAcquire(cli->mutex, osWaitForever) == osOK);
|
furi_check(osMutexAcquire(cli->mutex, osWaitForever) == osOK);
|
||||||
CliCommand* cli_command = CliCommandTree_get(cli->commands, command);
|
CliCommand* cli_command_ptr = CliCommandTree_get(cli->commands, command);
|
||||||
if(cli_command) {
|
|
||||||
|
if(cli_command_ptr) {
|
||||||
|
CliCommand cli_command;
|
||||||
|
memcpy(&cli_command, cli_command_ptr, sizeof(CliCommand));
|
||||||
|
furi_check(osMutexRelease(cli->mutex) == osOK);
|
||||||
cli_nl(cli);
|
cli_nl(cli);
|
||||||
cli_execute_command(cli, cli_command, args);
|
cli_execute_command(cli, &cli_command, args);
|
||||||
} else {
|
} else {
|
||||||
|
furi_check(osMutexRelease(cli->mutex) == osOK);
|
||||||
cli_nl(cli);
|
cli_nl(cli);
|
||||||
printf(
|
printf(
|
||||||
"`%s` command not found, use `help` or `?` to list all available commands",
|
"`%s` command not found, use `help` or `?` to list all available commands",
|
||||||
string_get_cstr(command));
|
string_get_cstr(command));
|
||||||
cli_putc(cli, CliSymbolAsciiBell);
|
cli_putc(cli, CliSymbolAsciiBell);
|
||||||
}
|
}
|
||||||
furi_check(osMutexRelease(cli->mutex) == osOK);
|
|
||||||
|
|
||||||
cli_reset(cli);
|
cli_reset(cli);
|
||||||
cli_prompt(cli);
|
cli_prompt(cli);
|
||||||
|
@ -199,6 +199,7 @@ static int32_t vcp_worker(void* context) {
|
|||||||
furi_hal_cdc_set_callbacks(VCP_IF_NUM, NULL, NULL);
|
furi_hal_cdc_set_callbacks(VCP_IF_NUM, NULL, NULL);
|
||||||
// Restore previous USB mode (if it was set during init)
|
// Restore previous USB mode (if it was set during init)
|
||||||
if((vcp->usb_if_prev != &usb_cdc_single) && (vcp->usb_if_prev != &usb_cdc_dual)) {
|
if((vcp->usb_if_prev != &usb_cdc_single) && (vcp->usb_if_prev != &usb_cdc_dual)) {
|
||||||
|
furi_hal_usb_unlock();
|
||||||
furi_hal_usb_set_config(vcp->usb_if_prev, NULL);
|
furi_hal_usb_set_config(vcp->usb_if_prev, NULL);
|
||||||
}
|
}
|
||||||
xStreamBufferReceive(vcp->tx_stream, vcp->data_buffer, USB_CDC_PKT_LEN, 0);
|
xStreamBufferReceive(vcp->tx_stream, vcp->data_buffer, USB_CDC_PKT_LEN, 0);
|
||||||
|
@ -158,7 +158,7 @@ static bool desktop_view_locked_input(InputEvent* event, void* context) {
|
|||||||
const bool pin_locked = model->pin_locked;
|
const bool pin_locked = model->pin_locked;
|
||||||
view_commit_model(locked_view->view, is_changed);
|
view_commit_model(locked_view->view, is_changed);
|
||||||
|
|
||||||
if(view_state == DesktopViewLockedStateUnlocked || event->type != InputTypeShort) {
|
if(view_state == DesktopViewLockedStateUnlocked) {
|
||||||
return view_state != DesktopViewLockedStateUnlocked;
|
return view_state != DesktopViewLockedStateUnlocked;
|
||||||
} else if(view_state == DesktopViewLockedStateLocked && pin_locked) {
|
} else if(view_state == DesktopViewLockedStateLocked && pin_locked) {
|
||||||
locked_view->callback(DesktopLockedEventShowPinInput, locked_view->context);
|
locked_view->callback(DesktopLockedEventShowPinInput, locked_view->context);
|
||||||
@ -173,10 +173,12 @@ static bool desktop_view_locked_input(InputEvent* event, void* context) {
|
|||||||
desktop_view_locked_update_hint_icon_timeout(locked_view);
|
desktop_view_locked_update_hint_icon_timeout(locked_view);
|
||||||
|
|
||||||
if(event->key == InputKeyBack) {
|
if(event->key == InputKeyBack) {
|
||||||
locked_view->lock_lastpress = press_time;
|
if(event->type == InputTypeShort) {
|
||||||
locked_view->lock_count++;
|
locked_view->lock_lastpress = press_time;
|
||||||
if(locked_view->lock_count == UNLOCK_CNT) {
|
locked_view->lock_count++;
|
||||||
locked_view->callback(DesktopLockedEventUnlocked, locked_view->context);
|
if(locked_view->lock_count == UNLOCK_CNT) {
|
||||||
|
locked_view->callback(DesktopLockedEventUnlocked, locked_view->context);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
locked_view->lock_count = 0;
|
locked_view->lock_count = 0;
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
#include <dolphin/dolphin.h>
|
#include <dolphin/dolphin.h>
|
||||||
#include <toolbox/path.h>
|
#include <toolbox/path.h>
|
||||||
|
|
||||||
|
#define EMULATE_TIMEOUT_TICKS 10
|
||||||
|
|
||||||
static void ibutton_scene_emulate_callback(void* context, bool emulated) {
|
static void ibutton_scene_emulate_callback(void* context, bool emulated) {
|
||||||
iButton* ibutton = context;
|
iButton* ibutton = context;
|
||||||
if(emulated) {
|
if(emulated) {
|
||||||
@ -95,11 +97,23 @@ bool ibutton_scene_emulate_on_event(void* context, SceneManagerEvent event) {
|
|||||||
bool consumed = false;
|
bool consumed = false;
|
||||||
|
|
||||||
if(event.type == SceneManagerEventTypeTick) {
|
if(event.type == SceneManagerEventTypeTick) {
|
||||||
|
uint32_t cnt = scene_manager_get_scene_state(ibutton->scene_manager, iButtonSceneEmulate);
|
||||||
|
if(cnt > 0) {
|
||||||
|
cnt--;
|
||||||
|
if(cnt == 0) {
|
||||||
|
ibutton_notification_message(ibutton, iButtonNotificationMessageEmulateBlink);
|
||||||
|
}
|
||||||
|
scene_manager_set_scene_state(ibutton->scene_manager, iButtonSceneEmulate, cnt);
|
||||||
|
}
|
||||||
consumed = true;
|
consumed = true;
|
||||||
} else if(event.type == SceneManagerEventTypeCustom) {
|
} else if(event.type == SceneManagerEventTypeCustom) {
|
||||||
consumed = true;
|
consumed = true;
|
||||||
if(event.event == iButtonCustomEventWorkerEmulated) {
|
if(event.event == iButtonCustomEventWorkerEmulated) {
|
||||||
ibutton_notification_message(ibutton, iButtonNotificationMessageYellowBlink);
|
if(scene_manager_get_scene_state(ibutton->scene_manager, iButtonSceneEmulate) == 0) {
|
||||||
|
ibutton_notification_message(ibutton, iButtonNotificationMessageYellowBlink);
|
||||||
|
}
|
||||||
|
scene_manager_set_scene_state(
|
||||||
|
ibutton->scene_manager, iButtonSceneEmulate, EMULATE_TIMEOUT_TICKS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,6 +93,9 @@ void notification_reset_notification_led_layer(NotificationLedLayer* layer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void notification_reset_notification_layer(NotificationApp* app, uint8_t reset_mask) {
|
void notification_reset_notification_layer(NotificationApp* app, uint8_t reset_mask) {
|
||||||
|
if(reset_mask & reset_blink_mask) {
|
||||||
|
furi_hal_light_blink_stop();
|
||||||
|
}
|
||||||
if(reset_mask & reset_red_mask) {
|
if(reset_mask & reset_red_mask) {
|
||||||
notification_reset_notification_led_layer(&app->led[0]);
|
notification_reset_notification_led_layer(&app->led[0]);
|
||||||
}
|
}
|
||||||
@ -102,9 +105,6 @@ void notification_reset_notification_layer(NotificationApp* app, uint8_t reset_m
|
|||||||
if(reset_mask & reset_blue_mask) {
|
if(reset_mask & reset_blue_mask) {
|
||||||
notification_reset_notification_led_layer(&app->led[2]);
|
notification_reset_notification_led_layer(&app->led[2]);
|
||||||
}
|
}
|
||||||
if(reset_mask & reset_blink_mask) {
|
|
||||||
furi_hal_light_blink_stop();
|
|
||||||
}
|
|
||||||
if(reset_mask & reset_vibro_mask) {
|
if(reset_mask & reset_vibro_mask) {
|
||||||
notification_vibro_off();
|
notification_vibro_off();
|
||||||
}
|
}
|
||||||
@ -243,6 +243,9 @@ void notification_process_notification_message(
|
|||||||
notification_message->data.led_blink.on_time,
|
notification_message->data.led_blink.on_time,
|
||||||
notification_message->data.led_blink.period);
|
notification_message->data.led_blink.period);
|
||||||
reset_mask |= reset_blink_mask;
|
reset_mask |= reset_blink_mask;
|
||||||
|
reset_mask |= reset_red_mask;
|
||||||
|
reset_mask |= reset_green_mask;
|
||||||
|
reset_mask |= reset_blue_mask;
|
||||||
break;
|
break;
|
||||||
case NotificationMessageTypeLedBlinkColor:
|
case NotificationMessageTypeLedBlinkColor:
|
||||||
led_active = true;
|
led_active = true;
|
||||||
@ -251,6 +254,9 @@ void notification_process_notification_message(
|
|||||||
case NotificationMessageTypeLedBlinkStop:
|
case NotificationMessageTypeLedBlinkStop:
|
||||||
furi_hal_light_blink_stop();
|
furi_hal_light_blink_stop();
|
||||||
reset_mask &= ~reset_blink_mask;
|
reset_mask &= ~reset_blink_mask;
|
||||||
|
reset_mask |= reset_red_mask;
|
||||||
|
reset_mask |= reset_green_mask;
|
||||||
|
reset_mask |= reset_blue_mask;
|
||||||
break;
|
break;
|
||||||
case NotificationMessageTypeVibro:
|
case NotificationMessageTypeVibro:
|
||||||
if(notification_message->data.vibro.on) {
|
if(notification_message->data.vibro.on) {
|
||||||
@ -326,7 +332,7 @@ void notification_process_notification_message(
|
|||||||
reset_mask |= reset_green_mask;
|
reset_mask |= reset_green_mask;
|
||||||
reset_mask |= reset_blue_mask;
|
reset_mask |= reset_blue_mask;
|
||||||
|
|
||||||
if(need_minimal_delay) {
|
if((need_minimal_delay) && (reset_notifications)) {
|
||||||
notification_apply_notification_leds(app, led_off_values);
|
notification_apply_notification_leds(app, led_off_values);
|
||||||
furi_hal_delay_ms(minimal_delay);
|
furi_hal_delay_ms(minimal_delay);
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
#include <task.h>
|
#include <task.h>
|
||||||
#include <m-string.h>
|
#include <m-string.h>
|
||||||
|
|
||||||
|
#define THREAD_NOTIFY_INDEX 1 // Index 0 is used for stream buffers
|
||||||
|
|
||||||
struct FuriThread {
|
struct FuriThread {
|
||||||
FuriThreadState state;
|
FuriThreadState state;
|
||||||
int32_t ret;
|
int32_t ret;
|
||||||
@ -221,13 +223,14 @@ uint32_t furi_thread_flags_set(FuriThreadId thread_id, uint32_t flags) {
|
|||||||
if(FURI_IS_IRQ_MODE()) {
|
if(FURI_IS_IRQ_MODE()) {
|
||||||
yield = pdFALSE;
|
yield = pdFALSE;
|
||||||
|
|
||||||
(void)xTaskNotifyFromISR(hTask, flags, eSetBits, &yield);
|
(void)xTaskNotifyIndexedFromISR(hTask, THREAD_NOTIFY_INDEX, flags, eSetBits, &yield);
|
||||||
(void)xTaskNotifyAndQueryFromISR(hTask, 0, eNoAction, &rflags, NULL);
|
(void)xTaskNotifyAndQueryIndexedFromISR(
|
||||||
|
hTask, THREAD_NOTIFY_INDEX, 0, eNoAction, &rflags, NULL);
|
||||||
|
|
||||||
portYIELD_FROM_ISR(yield);
|
portYIELD_FROM_ISR(yield);
|
||||||
} else {
|
} else {
|
||||||
(void)xTaskNotify(hTask, flags, eSetBits);
|
(void)xTaskNotifyIndexed(hTask, THREAD_NOTIFY_INDEX, flags, eSetBits);
|
||||||
(void)xTaskNotifyAndQuery(hTask, 0, eNoAction, &rflags);
|
(void)xTaskNotifyAndQueryIndexed(hTask, THREAD_NOTIFY_INDEX, 0, eNoAction, &rflags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Return flags after setting */
|
/* Return flags after setting */
|
||||||
@ -245,11 +248,13 @@ uint32_t furi_thread_flags_clear(uint32_t flags) {
|
|||||||
} else {
|
} else {
|
||||||
hTask = xTaskGetCurrentTaskHandle();
|
hTask = xTaskGetCurrentTaskHandle();
|
||||||
|
|
||||||
if(xTaskNotifyAndQuery(hTask, 0, eNoAction, &cflags) == pdPASS) {
|
if(xTaskNotifyAndQueryIndexed(hTask, THREAD_NOTIFY_INDEX, 0, eNoAction, &cflags) ==
|
||||||
|
pdPASS) {
|
||||||
rflags = cflags;
|
rflags = cflags;
|
||||||
cflags &= ~flags;
|
cflags &= ~flags;
|
||||||
|
|
||||||
if(xTaskNotify(hTask, cflags, eSetValueWithOverwrite) != pdPASS) {
|
if(xTaskNotifyIndexed(hTask, THREAD_NOTIFY_INDEX, cflags, eSetValueWithOverwrite) !=
|
||||||
|
pdPASS) {
|
||||||
rflags = (uint32_t)osError;
|
rflags = (uint32_t)osError;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -270,7 +275,8 @@ uint32_t furi_thread_flags_get(void) {
|
|||||||
} else {
|
} else {
|
||||||
hTask = xTaskGetCurrentTaskHandle();
|
hTask = xTaskGetCurrentTaskHandle();
|
||||||
|
|
||||||
if(xTaskNotifyAndQuery(hTask, 0, eNoAction, &rflags) != pdPASS) {
|
if(xTaskNotifyAndQueryIndexed(hTask, THREAD_NOTIFY_INDEX, 0, eNoAction, &rflags) !=
|
||||||
|
pdPASS) {
|
||||||
rflags = (uint32_t)osError;
|
rflags = (uint32_t)osError;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -300,7 +306,7 @@ uint32_t furi_thread_flags_wait(uint32_t flags, uint32_t options, uint32_t timeo
|
|||||||
|
|
||||||
t0 = xTaskGetTickCount();
|
t0 = xTaskGetTickCount();
|
||||||
do {
|
do {
|
||||||
rval = xTaskNotifyWait(0, clear, &nval, tout);
|
rval = xTaskNotifyWaitIndexed(THREAD_NOTIFY_INDEX, 0, clear, &nval, tout);
|
||||||
|
|
||||||
if(rval == pdPASS) {
|
if(rval == pdPASS) {
|
||||||
rflags &= flags;
|
rflags &= flags;
|
||||||
|
Loading…
Reference in New Issue
Block a user