[FL-2383, FL-2384] iButton, Desktop bug fixes (#1062)
* iButton HAL: correct init and emulation sequence * FuriHal: cleanup init/deinit routines for emulation timer * FuriHal: cleanup TIM initialization routines in RFID and SubGhz * iButton: delay in emulate loop * Desktop: fix crash caused by invalid animation manager state, described in FL-2384 Co-authored-by: Aleksandr Kutuzov <alleteam@gmail.com>
This commit is contained in:
parent
413a03defb
commit
425a74a001
@ -4,8 +4,6 @@
|
|||||||
#include <furi.h>
|
#include <furi.h>
|
||||||
#include <furi_hal.h>
|
#include <furi_hal.h>
|
||||||
|
|
||||||
#include <loader/loader.h>
|
|
||||||
|
|
||||||
#include "animations/animation_manager.h"
|
#include "animations/animation_manager.h"
|
||||||
#include "desktop/scenes/desktop_scene.h"
|
#include "desktop/scenes/desktop_scene.h"
|
||||||
#include "desktop/scenes/desktop_scene_i.h"
|
#include "desktop/scenes/desktop_scene_i.h"
|
||||||
@ -15,6 +13,18 @@
|
|||||||
#include "desktop_i.h"
|
#include "desktop_i.h"
|
||||||
#include "desktop_helpers.h"
|
#include "desktop_helpers.h"
|
||||||
|
|
||||||
|
static void desktop_loader_callback(const void* message, void* context) {
|
||||||
|
furi_assert(context);
|
||||||
|
Desktop* desktop = context;
|
||||||
|
const LoaderEvent* event = message;
|
||||||
|
|
||||||
|
if(event->type == LoaderEventTypeApplicationStarted) {
|
||||||
|
view_dispatcher_send_custom_event(desktop->view_dispatcher, DesktopGlobalBeforeAppStarted);
|
||||||
|
} else if(event->type == LoaderEventTypeApplicationStopped) {
|
||||||
|
view_dispatcher_send_custom_event(desktop->view_dispatcher, DesktopGlobalAfterAppFinished);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void desktop_lock_icon_callback(Canvas* canvas, void* context) {
|
static void desktop_lock_icon_callback(Canvas* canvas, void* context) {
|
||||||
furi_assert(canvas);
|
furi_assert(canvas);
|
||||||
canvas_draw_icon(canvas, 0, 0, &I_Lock_8x8);
|
canvas_draw_icon(canvas, 0, 0, &I_Lock_8x8);
|
||||||
@ -23,6 +33,16 @@ static void desktop_lock_icon_callback(Canvas* canvas, void* context) {
|
|||||||
static bool desktop_custom_event_callback(void* context, uint32_t event) {
|
static bool desktop_custom_event_callback(void* context, uint32_t event) {
|
||||||
furi_assert(context);
|
furi_assert(context);
|
||||||
Desktop* desktop = (Desktop*)context;
|
Desktop* desktop = (Desktop*)context;
|
||||||
|
|
||||||
|
switch(event) {
|
||||||
|
case DesktopGlobalBeforeAppStarted:
|
||||||
|
animation_manager_unload_and_stall_animation(desktop->animation_manager);
|
||||||
|
return true;
|
||||||
|
case DesktopGlobalAfterAppFinished:
|
||||||
|
animation_manager_load_and_continue_animation(desktop->animation_manager);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return scene_manager_handle_custom_event(desktop->scene_manager, event);
|
return scene_manager_handle_custom_event(desktop->scene_manager, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,7 +61,6 @@ static void desktop_tick_event_callback(void* context) {
|
|||||||
Desktop* desktop_alloc() {
|
Desktop* desktop_alloc() {
|
||||||
Desktop* desktop = malloc(sizeof(Desktop));
|
Desktop* desktop = malloc(sizeof(Desktop));
|
||||||
|
|
||||||
desktop->unload_animation_semaphore = osSemaphoreNew(1, 0, NULL);
|
|
||||||
desktop->animation_manager = animation_manager_alloc();
|
desktop->animation_manager = animation_manager_alloc();
|
||||||
desktop->gui = furi_record_open("gui");
|
desktop->gui = furi_record_open("gui");
|
||||||
desktop->scene_thread = furi_thread_alloc();
|
desktop->scene_thread = furi_thread_alloc();
|
||||||
@ -122,12 +141,13 @@ Desktop* desktop_alloc() {
|
|||||||
gui_add_view_port(desktop->gui, desktop->lock_viewport, GuiLayerStatusBarLeft);
|
gui_add_view_port(desktop->gui, desktop->lock_viewport, GuiLayerStatusBarLeft);
|
||||||
|
|
||||||
// Special case: autostart application is already running
|
// Special case: autostart application is already running
|
||||||
Loader* loader = furi_record_open("loader");
|
desktop->loader = furi_record_open("loader");
|
||||||
if(loader_is_locked(loader) &&
|
if(loader_is_locked(desktop->loader) &&
|
||||||
animation_manager_is_animation_loaded(desktop->animation_manager)) {
|
animation_manager_is_animation_loaded(desktop->animation_manager)) {
|
||||||
animation_manager_unload_and_stall_animation(desktop->animation_manager);
|
animation_manager_unload_and_stall_animation(desktop->animation_manager);
|
||||||
}
|
}
|
||||||
furi_record_close("loader");
|
desktop->app_start_stop_subscription = furi_pubsub_subscribe(
|
||||||
|
loader_get_pubsub(desktop->loader), desktop_loader_callback, desktop);
|
||||||
|
|
||||||
return desktop;
|
return desktop;
|
||||||
}
|
}
|
||||||
@ -135,6 +155,11 @@ Desktop* desktop_alloc() {
|
|||||||
void desktop_free(Desktop* desktop) {
|
void desktop_free(Desktop* desktop) {
|
||||||
furi_assert(desktop);
|
furi_assert(desktop);
|
||||||
|
|
||||||
|
furi_pubsub_unsubscribe(
|
||||||
|
loader_get_pubsub(desktop->loader), desktop->app_start_stop_subscription);
|
||||||
|
desktop->loader = NULL;
|
||||||
|
furi_record_close("loader");
|
||||||
|
|
||||||
view_dispatcher_remove_view(desktop->view_dispatcher, DesktopViewIdMain);
|
view_dispatcher_remove_view(desktop->view_dispatcher, DesktopViewIdMain);
|
||||||
view_dispatcher_remove_view(desktop->view_dispatcher, DesktopViewIdLockMenu);
|
view_dispatcher_remove_view(desktop->view_dispatcher, DesktopViewIdLockMenu);
|
||||||
view_dispatcher_remove_view(desktop->view_dispatcher, DesktopViewIdLocked);
|
view_dispatcher_remove_view(desktop->view_dispatcher, DesktopViewIdLocked);
|
||||||
@ -159,8 +184,6 @@ void desktop_free(Desktop* desktop) {
|
|||||||
popup_free(desktop->hw_mismatch_popup);
|
popup_free(desktop->hw_mismatch_popup);
|
||||||
desktop_view_pin_timeout_free(desktop->pin_timeout_view);
|
desktop_view_pin_timeout_free(desktop->pin_timeout_view);
|
||||||
|
|
||||||
osSemaphoreDelete(desktop->unload_animation_semaphore);
|
|
||||||
|
|
||||||
furi_record_close("gui");
|
furi_record_close("gui");
|
||||||
desktop->gui = NULL;
|
desktop->gui = NULL;
|
||||||
|
|
||||||
|
@ -18,6 +18,8 @@
|
|||||||
#include <gui/modules/popup.h>
|
#include <gui/modules/popup.h>
|
||||||
#include <gui/scene_manager.h>
|
#include <gui/scene_manager.h>
|
||||||
|
|
||||||
|
#include <loader/loader.h>
|
||||||
|
|
||||||
#define STATUS_BAR_Y_SHIFT 13
|
#define STATUS_BAR_Y_SHIFT 13
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@ -57,7 +59,7 @@ struct Desktop {
|
|||||||
ViewPort* lock_viewport;
|
ViewPort* lock_viewport;
|
||||||
|
|
||||||
AnimationManager* animation_manager;
|
AnimationManager* animation_manager;
|
||||||
osSemaphoreId_t unload_animation_semaphore;
|
Loader* loader;
|
||||||
FuriPubSubSubscription* app_start_stop_subscription;
|
FuriPubSubSubscription* app_start_stop_subscription;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -60,10 +60,8 @@ bool desktop_scene_lock_menu_on_event(void* context, SceneManagerEvent event) {
|
|||||||
desktop->scene_manager, DesktopSceneLocked, SCENE_LOCKED_FIRST_ENTER);
|
desktop->scene_manager, DesktopSceneLocked, SCENE_LOCKED_FIRST_ENTER);
|
||||||
scene_manager_next_scene(desktop->scene_manager, DesktopSceneLocked);
|
scene_manager_next_scene(desktop->scene_manager, DesktopSceneLocked);
|
||||||
} else {
|
} else {
|
||||||
Loader* loader = furi_record_open("loader");
|
|
||||||
LoaderStatus status =
|
LoaderStatus status =
|
||||||
loader_start(loader, "Desktop", DESKTOP_SETTINGS_RUN_PIN_SETUP_ARG);
|
loader_start(desktop->loader, "Desktop", DESKTOP_SETTINGS_RUN_PIN_SETUP_ARG);
|
||||||
furi_record_close("loader");
|
|
||||||
if(status == LoaderStatusOk) {
|
if(status == LoaderStatusOk) {
|
||||||
scene_manager_set_scene_state(desktop->scene_manager, DesktopSceneLockMenu, 1);
|
scene_manager_set_scene_state(desktop->scene_manager, DesktopSceneLockMenu, 1);
|
||||||
} else {
|
} else {
|
||||||
|
@ -12,21 +12,6 @@
|
|||||||
|
|
||||||
#define TAG "DesktopSrv"
|
#define TAG "DesktopSrv"
|
||||||
|
|
||||||
static void desktop_scene_main_app_started_callback(const void* message, void* context) {
|
|
||||||
furi_assert(context);
|
|
||||||
Desktop* desktop = context;
|
|
||||||
const LoaderEvent* event = message;
|
|
||||||
|
|
||||||
if(event->type == LoaderEventTypeApplicationStarted) {
|
|
||||||
view_dispatcher_send_custom_event(
|
|
||||||
desktop->view_dispatcher, DesktopMainEventBeforeAppStarted);
|
|
||||||
osSemaphoreAcquire(desktop->unload_animation_semaphore, osWaitForever);
|
|
||||||
} else if(event->type == LoaderEventTypeApplicationStopped) {
|
|
||||||
view_dispatcher_send_custom_event(
|
|
||||||
desktop->view_dispatcher, DesktopMainEventAfterAppFinished);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void desktop_scene_main_new_idle_animation_callback(void* context) {
|
static void desktop_scene_main_new_idle_animation_callback(void* context) {
|
||||||
furi_assert(context);
|
furi_assert(context);
|
||||||
Desktop* desktop = context;
|
Desktop* desktop = context;
|
||||||
@ -85,12 +70,6 @@ void desktop_scene_main_on_enter(void* context) {
|
|||||||
animation_manager_set_interact_callback(
|
animation_manager_set_interact_callback(
|
||||||
desktop->animation_manager, desktop_scene_main_interact_animation_callback);
|
desktop->animation_manager, desktop_scene_main_interact_animation_callback);
|
||||||
|
|
||||||
furi_assert(osSemaphoreGetCount(desktop->unload_animation_semaphore) == 0);
|
|
||||||
Loader* loader = furi_record_open("loader");
|
|
||||||
desktop->app_start_stop_subscription = furi_pubsub_subscribe(
|
|
||||||
loader_get_pubsub(loader), desktop_scene_main_app_started_callback, desktop);
|
|
||||||
furi_record_close("loader");
|
|
||||||
|
|
||||||
desktop_main_set_callback(main_view, desktop_scene_main_callback, desktop);
|
desktop_main_set_callback(main_view, desktop_scene_main_callback, desktop);
|
||||||
|
|
||||||
view_dispatcher_switch_to_view(desktop->view_dispatcher, DesktopViewIdMain);
|
view_dispatcher_switch_to_view(desktop->view_dispatcher, DesktopViewIdMain);
|
||||||
@ -127,13 +106,11 @@ bool desktop_scene_main_on_event(void* context, SceneManagerEvent event) {
|
|||||||
case DesktopMainEventOpenFavorite:
|
case DesktopMainEventOpenFavorite:
|
||||||
LOAD_DESKTOP_SETTINGS(&desktop->settings);
|
LOAD_DESKTOP_SETTINGS(&desktop->settings);
|
||||||
if(desktop->settings.favorite < FLIPPER_APPS_COUNT) {
|
if(desktop->settings.favorite < FLIPPER_APPS_COUNT) {
|
||||||
Loader* loader = furi_record_open("loader");
|
LoaderStatus status = loader_start(
|
||||||
LoaderStatus status =
|
desktop->loader, FLIPPER_APPS[desktop->settings.favorite].name, NULL);
|
||||||
loader_start(loader, FLIPPER_APPS[desktop->settings.favorite].name, NULL);
|
|
||||||
if(status != LoaderStatusOk) {
|
if(status != LoaderStatusOk) {
|
||||||
FURI_LOG_E(TAG, "loader_start failed: %d", status);
|
FURI_LOG_E(TAG, "loader_start failed: %d", status);
|
||||||
}
|
}
|
||||||
furi_record_close("loader");
|
|
||||||
} else {
|
} else {
|
||||||
FURI_LOG_E(TAG, "Can't find favorite application");
|
FURI_LOG_E(TAG, "Can't find favorite application");
|
||||||
}
|
}
|
||||||
@ -152,15 +129,6 @@ bool desktop_scene_main_on_event(void* context, SceneManagerEvent event) {
|
|||||||
animation_manager_interact_process(desktop->animation_manager);
|
animation_manager_interact_process(desktop->animation_manager);
|
||||||
consumed = true;
|
consumed = true;
|
||||||
break;
|
break;
|
||||||
case DesktopMainEventBeforeAppStarted:
|
|
||||||
animation_manager_unload_and_stall_animation(desktop->animation_manager);
|
|
||||||
osSemaphoreRelease(desktop->unload_animation_semaphore);
|
|
||||||
consumed = true;
|
|
||||||
break;
|
|
||||||
case DesktopMainEventAfterAppFinished:
|
|
||||||
animation_manager_load_and_continue_animation(desktop->animation_manager);
|
|
||||||
consumed = true;
|
|
||||||
break;
|
|
||||||
case DesktopLockedEventUpdate:
|
case DesktopLockedEventUpdate:
|
||||||
desktop_view_locked_update(desktop->locked_view);
|
desktop_view_locked_update(desktop->locked_view);
|
||||||
consumed = true;
|
consumed = true;
|
||||||
@ -177,16 +145,6 @@ bool desktop_scene_main_on_event(void* context, SceneManagerEvent event) {
|
|||||||
void desktop_scene_main_on_exit(void* context) {
|
void desktop_scene_main_on_exit(void* context) {
|
||||||
Desktop* desktop = (Desktop*)context;
|
Desktop* desktop = (Desktop*)context;
|
||||||
|
|
||||||
/**
|
|
||||||
* We're allowed to leave this scene only when any other app & loader
|
|
||||||
* is finished, that's why we can be sure there is no task waiting
|
|
||||||
* for start/stop semaphore
|
|
||||||
*/
|
|
||||||
Loader* loader = furi_record_open("loader");
|
|
||||||
furi_pubsub_unsubscribe(loader_get_pubsub(loader), desktop->app_start_stop_subscription);
|
|
||||||
furi_record_close("loader");
|
|
||||||
furi_assert(osSemaphoreGetCount(desktop->unload_animation_semaphore) == 0);
|
|
||||||
|
|
||||||
animation_manager_set_new_idle_callback(desktop->animation_manager, NULL);
|
animation_manager_set_new_idle_callback(desktop->animation_manager, NULL);
|
||||||
animation_manager_set_check_callback(desktop->animation_manager, NULL);
|
animation_manager_set_check_callback(desktop->animation_manager, NULL);
|
||||||
animation_manager_set_interact_callback(desktop->animation_manager, NULL);
|
animation_manager_set_interact_callback(desktop->animation_manager, NULL);
|
||||||
|
@ -7,8 +7,6 @@ typedef enum {
|
|||||||
DesktopMainEventOpenMenu,
|
DesktopMainEventOpenMenu,
|
||||||
DesktopMainEventOpenDebug,
|
DesktopMainEventOpenDebug,
|
||||||
DesktopMainEventRightShort,
|
DesktopMainEventRightShort,
|
||||||
DesktopMainEventBeforeAppStarted,
|
|
||||||
DesktopMainEventAfterAppFinished,
|
|
||||||
|
|
||||||
DesktopLockedEventUnlocked,
|
DesktopLockedEventUnlocked,
|
||||||
DesktopLockedEventUpdate,
|
DesktopLockedEventUpdate,
|
||||||
@ -37,4 +35,7 @@ typedef enum {
|
|||||||
DesktopAnimationEventNewIdleAnimation,
|
DesktopAnimationEventNewIdleAnimation,
|
||||||
DesktopAnimationEventInteractAnimation,
|
DesktopAnimationEventInteractAnimation,
|
||||||
|
|
||||||
|
// Global events
|
||||||
|
DesktopGlobalBeforeAppStarted,
|
||||||
|
DesktopGlobalAfterAppFinished,
|
||||||
} DesktopEvent;
|
} DesktopEvent;
|
||||||
|
@ -209,6 +209,7 @@ void ibutton_cli_emulate(Cli* cli, string_t args) {
|
|||||||
|
|
||||||
while(!exit) {
|
while(!exit) {
|
||||||
exit = cli_cmd_interrupt_received(cli);
|
exit = cli_cmd_interrupt_received(cli);
|
||||||
|
delay(100);
|
||||||
};
|
};
|
||||||
|
|
||||||
worker->stop_emulate();
|
worker->stop_emulate();
|
||||||
|
@ -49,6 +49,11 @@ void furi_hal_ibutton_emulate_start(
|
|||||||
LL_TIM_DeInit(FURI_HAL_IBUTTON_TIMER);
|
LL_TIM_DeInit(FURI_HAL_IBUTTON_TIMER);
|
||||||
FURI_CRITICAL_EXIT();
|
FURI_CRITICAL_EXIT();
|
||||||
|
|
||||||
|
furi_hal_interrupt_set_timer_isr(FURI_HAL_IBUTTON_TIMER, furi_hal_ibutton_emulate_isr);
|
||||||
|
NVIC_SetPriority(
|
||||||
|
FURI_HAL_IBUTTON_TIMER_IRQ, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0));
|
||||||
|
NVIC_EnableIRQ(FURI_HAL_IBUTTON_TIMER_IRQ);
|
||||||
|
|
||||||
LL_TIM_SetPrescaler(FURI_HAL_IBUTTON_TIMER, 0);
|
LL_TIM_SetPrescaler(FURI_HAL_IBUTTON_TIMER, 0);
|
||||||
LL_TIM_SetCounterMode(FURI_HAL_IBUTTON_TIMER, LL_TIM_COUNTERMODE_UP);
|
LL_TIM_SetCounterMode(FURI_HAL_IBUTTON_TIMER, LL_TIM_COUNTERMODE_UP);
|
||||||
LL_TIM_SetAutoReload(FURI_HAL_IBUTTON_TIMER, period);
|
LL_TIM_SetAutoReload(FURI_HAL_IBUTTON_TIMER, period);
|
||||||
@ -61,12 +66,6 @@ void furi_hal_ibutton_emulate_start(
|
|||||||
|
|
||||||
LL_TIM_EnableIT_UPDATE(FURI_HAL_IBUTTON_TIMER);
|
LL_TIM_EnableIT_UPDATE(FURI_HAL_IBUTTON_TIMER);
|
||||||
|
|
||||||
furi_hal_interrupt_set_timer_isr(FURI_HAL_IBUTTON_TIMER, furi_hal_ibutton_emulate_isr);
|
|
||||||
|
|
||||||
NVIC_SetPriority(
|
|
||||||
FURI_HAL_IBUTTON_TIMER_IRQ, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0));
|
|
||||||
NVIC_EnableIRQ(FURI_HAL_IBUTTON_TIMER_IRQ);
|
|
||||||
|
|
||||||
LL_TIM_EnableCounter(FURI_HAL_IBUTTON_TIMER);
|
LL_TIM_EnableCounter(FURI_HAL_IBUTTON_TIMER);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,6 +79,11 @@ void furi_hal_ibutton_emulate_stop() {
|
|||||||
if(furi_hal_ibutton->state == FuriHalIbuttonStateRunning) {
|
if(furi_hal_ibutton->state == FuriHalIbuttonStateRunning) {
|
||||||
furi_hal_ibutton->state = FuriHalIbuttonStateIdle;
|
furi_hal_ibutton->state = FuriHalIbuttonStateIdle;
|
||||||
LL_TIM_DisableCounter(FURI_HAL_IBUTTON_TIMER);
|
LL_TIM_DisableCounter(FURI_HAL_IBUTTON_TIMER);
|
||||||
|
|
||||||
|
FURI_CRITICAL_ENTER();
|
||||||
|
LL_TIM_DeInit(FURI_HAL_IBUTTON_TIMER);
|
||||||
|
FURI_CRITICAL_EXIT();
|
||||||
|
|
||||||
furi_hal_interrupt_set_timer_isr(FURI_HAL_IBUTTON_TIMER, NULL);
|
furi_hal_interrupt_set_timer_isr(FURI_HAL_IBUTTON_TIMER, NULL);
|
||||||
|
|
||||||
furi_hal_ibutton->callback = NULL;
|
furi_hal_ibutton->callback = NULL;
|
||||||
|
@ -193,7 +193,6 @@ void furi_hal_rfid_tim_emulate_start(FuriHalRfidEmulateCallback callback, void*
|
|||||||
}
|
}
|
||||||
|
|
||||||
furi_hal_interrupt_set_timer_isr(FURI_HAL_RFID_EMULATE_TIMER, furi_hal_rfid_emulate_isr);
|
furi_hal_interrupt_set_timer_isr(FURI_HAL_RFID_EMULATE_TIMER, furi_hal_rfid_emulate_isr);
|
||||||
|
|
||||||
NVIC_SetPriority(
|
NVIC_SetPriority(
|
||||||
FURI_HAL_RFID_EMULATE_TIMER_IRQ, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0));
|
FURI_HAL_RFID_EMULATE_TIMER_IRQ, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0));
|
||||||
NVIC_EnableIRQ(FURI_HAL_RFID_EMULATE_TIMER_IRQ);
|
NVIC_EnableIRQ(FURI_HAL_RFID_EMULATE_TIMER_IRQ);
|
||||||
@ -204,9 +203,9 @@ void furi_hal_rfid_tim_emulate_start(FuriHalRfidEmulateCallback callback, void*
|
|||||||
}
|
}
|
||||||
|
|
||||||
void furi_hal_rfid_tim_emulate_stop() {
|
void furi_hal_rfid_tim_emulate_stop() {
|
||||||
furi_hal_interrupt_set_timer_isr(FURI_HAL_RFID_EMULATE_TIMER, NULL);
|
|
||||||
LL_TIM_DisableCounter(FURI_HAL_RFID_EMULATE_TIMER);
|
LL_TIM_DisableCounter(FURI_HAL_RFID_EMULATE_TIMER);
|
||||||
LL_TIM_DisableAllOutputs(FURI_HAL_RFID_EMULATE_TIMER);
|
LL_TIM_DisableAllOutputs(FURI_HAL_RFID_EMULATE_TIMER);
|
||||||
|
furi_hal_interrupt_set_timer_isr(FURI_HAL_RFID_EMULATE_TIMER, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void furi_hal_rfid_tim_reset() {
|
void furi_hal_rfid_tim_reset() {
|
||||||
|
@ -732,10 +732,6 @@ void furi_hal_subghz_start_async_rx(FuriHalSubGhzCaptureCallback callback, void*
|
|||||||
LL_TIM_CC_EnableChannel(TIM2, LL_TIM_CHANNEL_CH1);
|
LL_TIM_CC_EnableChannel(TIM2, LL_TIM_CHANNEL_CH1);
|
||||||
LL_TIM_CC_EnableChannel(TIM2, LL_TIM_CHANNEL_CH2);
|
LL_TIM_CC_EnableChannel(TIM2, LL_TIM_CHANNEL_CH2);
|
||||||
|
|
||||||
// Enable NVIC
|
|
||||||
NVIC_SetPriority(TIM2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0));
|
|
||||||
NVIC_EnableIRQ(TIM2_IRQn);
|
|
||||||
|
|
||||||
// Start timer
|
// Start timer
|
||||||
LL_TIM_SetCounter(TIM2, 0);
|
LL_TIM_SetCounter(TIM2, 0);
|
||||||
LL_TIM_EnableCounter(TIM2);
|
LL_TIM_EnableCounter(TIM2);
|
||||||
@ -919,6 +915,9 @@ bool furi_hal_subghz_start_async_tx(FuriHalSubGhzAsyncTxCallback callback, void*
|
|||||||
LL_TIM_DisableMasterSlaveMode(TIM2);
|
LL_TIM_DisableMasterSlaveMode(TIM2);
|
||||||
|
|
||||||
furi_hal_interrupt_set_timer_isr(TIM2, furi_hal_subghz_async_tx_timer_isr);
|
furi_hal_interrupt_set_timer_isr(TIM2, furi_hal_subghz_async_tx_timer_isr);
|
||||||
|
NVIC_SetPriority(TIM2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0));
|
||||||
|
NVIC_EnableIRQ(TIM2_IRQn);
|
||||||
|
|
||||||
LL_TIM_EnableIT_UPDATE(TIM2);
|
LL_TIM_EnableIT_UPDATE(TIM2);
|
||||||
LL_TIM_EnableDMAReq_UPDATE(TIM2);
|
LL_TIM_EnableDMAReq_UPDATE(TIM2);
|
||||||
LL_TIM_CC_EnableChannel(TIM2, LL_TIM_CHANNEL_CH2);
|
LL_TIM_CC_EnableChannel(TIM2, LL_TIM_CHANNEL_CH2);
|
||||||
@ -930,10 +929,6 @@ bool furi_hal_subghz_start_async_tx(FuriHalSubGhzAsyncTxCallback callback, void*
|
|||||||
#endif
|
#endif
|
||||||
furi_hal_subghz_tx();
|
furi_hal_subghz_tx();
|
||||||
|
|
||||||
// Enable NVIC
|
|
||||||
NVIC_SetPriority(TIM2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0));
|
|
||||||
NVIC_EnableIRQ(TIM2_IRQn);
|
|
||||||
|
|
||||||
LL_TIM_SetCounter(TIM2, 0);
|
LL_TIM_SetCounter(TIM2, 0);
|
||||||
LL_TIM_EnableCounter(TIM2);
|
LL_TIM_EnableCounter(TIM2);
|
||||||
return true;
|
return true;
|
||||||
|
Loading…
Reference in New Issue
Block a user