Hide debug tools if debug is not enabled. Application: update debug tools code base. SubGhz: log duty cycle. (#903)
* Application: clean debug_tools code base. * SubGhz: add duty cycle logging. * Application: hide debug tools if not enabled. Gui: move icon_animation allocation to menu module.
This commit is contained in:
		
							parent
							
								
									f6db5dd2a8
								
							
						
					
					
						commit
						63642617ee
					
				| @ -9,20 +9,20 @@ | ||||
| #define BLINK_COLOR_COUNT 7 | ||||
| 
 | ||||
| typedef enum { | ||||
|     EventTypeTick, | ||||
|     EventTypeKey, | ||||
| } EventType; | ||||
|     BlinkEventTypeTick, | ||||
|     BlinkEventTypeInput, | ||||
| } BlinkEventType; | ||||
| 
 | ||||
| typedef struct { | ||||
|     EventType type; | ||||
|     BlinkEventType type; | ||||
|     InputEvent input; | ||||
| } BlinkEvent; | ||||
| 
 | ||||
| static void blink_test_update(void* ctx) { | ||||
|     furi_assert(ctx); | ||||
|     osMessageQueueId_t event_queue = ctx; | ||||
| 
 | ||||
|     BlinkEvent event = {.type = EventTypeTick}; | ||||
|     BlinkEvent event = {.type = BlinkEventTypeTick}; | ||||
|     // It's OK to loose this event if system overloaded
 | ||||
|     osMessageQueuePut(event_queue, &event, 0, 0); | ||||
| } | ||||
| 
 | ||||
| @ -36,8 +36,8 @@ static void blink_test_input_callback(InputEvent* input_event, void* ctx) { | ||||
|     furi_assert(ctx); | ||||
|     osMessageQueueId_t event_queue = ctx; | ||||
| 
 | ||||
|     BlinkEvent event = {.type = EventTypeKey, .input = *input_event}; | ||||
|     osMessageQueuePut(event_queue, &event, 0, 0); | ||||
|     BlinkEvent event = {.type = BlinkEventTypeInput, .input = *input_event}; | ||||
|     osMessageQueuePut(event_queue, &event, 0, osWaitForever); | ||||
| } | ||||
| 
 | ||||
| int32_t blink_test_app(void* p) { | ||||
| @ -45,7 +45,6 @@ int32_t blink_test_app(void* p) { | ||||
| 
 | ||||
|     // Configure view port
 | ||||
|     ViewPort* view_port = view_port_alloc(); | ||||
|     furi_check(view_port); | ||||
|     view_port_draw_callback_set(view_port, blink_test_draw_callback, NULL); | ||||
|     view_port_input_callback_set(view_port, blink_test_input_callback, event_queue); | ||||
|     osTimerId_t timer = osTimerNew(blink_test_update, osTimerPeriodic, event_queue, NULL); | ||||
| @ -72,20 +71,12 @@ int32_t blink_test_app(void* p) { | ||||
| 
 | ||||
|     while(1) { | ||||
|         furi_check(osMessageQueueGet(event_queue, &event, NULL, osWaitForever) == osOK); | ||||
|         if(event.type == EventTypeKey) { | ||||
|         if(event.type == BlinkEventTypeInput) { | ||||
|             if((event.input.type == InputTypeShort) && (event.input.key == InputKeyBack)) { | ||||
|                 furi_record_close("notification"); | ||||
|                 view_port_enabled_set(view_port, false); | ||||
|                 gui_remove_view_port(gui, view_port); | ||||
|                 view_port_free(view_port); | ||||
|                 osMessageQueueDelete(event_queue); | ||||
|                 osTimerDelete(timer); | ||||
| 
 | ||||
|                 return 0; | ||||
|                 break; | ||||
|             } | ||||
|         } else { | ||||
|             notification_message(notifications, colors[state]); | ||||
| 
 | ||||
|             state++; | ||||
|             if(state >= BLINK_COLOR_COUNT) { | ||||
|                 state = 0; | ||||
| @ -93,5 +84,14 @@ int32_t blink_test_app(void* p) { | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     osTimerDelete(timer); | ||||
| 
 | ||||
|     gui_remove_view_port(gui, view_port); | ||||
|     view_port_free(view_port); | ||||
|     osMessageQueueDelete(event_queue); | ||||
| 
 | ||||
|     furi_record_close("notification"); | ||||
|     furi_record_close("gui"); | ||||
| 
 | ||||
|     return 0; | ||||
| } | ||||
| @ -13,17 +13,6 @@ typedef struct { | ||||
|     uint16_t ok; | ||||
| } KeypadTestState; | ||||
| 
 | ||||
| typedef enum { | ||||
|     EventTypeInput, | ||||
| } EventType; | ||||
| 
 | ||||
| typedef struct { | ||||
|     union { | ||||
|         InputEvent input; | ||||
|     }; | ||||
|     EventType type; | ||||
| } KeypadTestEvent; | ||||
| 
 | ||||
| static void keypad_test_reset_state(KeypadTestState* state) { | ||||
|     state->left = 0; | ||||
|     state->right = 0; | ||||
| @ -67,15 +56,11 @@ static void keypad_test_render_callback(Canvas* canvas, void* ctx) { | ||||
| 
 | ||||
| static void keypad_test_input_callback(InputEvent* input_event, void* ctx) { | ||||
|     osMessageQueueId_t event_queue = ctx; | ||||
| 
 | ||||
|     KeypadTestEvent event; | ||||
|     event.type = EventTypeInput; | ||||
|     event.input = *input_event; | ||||
|     osMessageQueuePut(event_queue, &event, 0, osWaitForever); | ||||
|     osMessageQueuePut(event_queue, input_event, 0, osWaitForever); | ||||
| } | ||||
| 
 | ||||
| int32_t keypad_test_app(void* p) { | ||||
|     osMessageQueueId_t event_queue = osMessageQueueNew(32, sizeof(KeypadTestEvent), NULL); | ||||
|     osMessageQueueId_t event_queue = osMessageQueueNew(32, sizeof(InputEvent), NULL); | ||||
|     furi_check(event_queue); | ||||
| 
 | ||||
|     KeypadTestState _state = {{false, false, false, false, false}, 0, 0, 0, 0, 0}; | ||||
| @ -95,97 +80,75 @@ int32_t keypad_test_app(void* p) { | ||||
|     Gui* gui = furi_record_open("gui"); | ||||
|     gui_add_view_port(gui, view_port, GuiLayerFullscreen); | ||||
| 
 | ||||
|     KeypadTestEvent event; | ||||
|     while(1) { | ||||
|         osStatus_t event_status = osMessageQueueGet(event_queue, &event, NULL, osWaitForever); | ||||
|     InputEvent event; | ||||
|     while(osMessageQueueGet(event_queue, &event, NULL, osWaitForever) == osOK) { | ||||
|         KeypadTestState* state = (KeypadTestState*)acquire_mutex_block(&state_mutex); | ||||
| 
 | ||||
|         if(event_status == osOK) { | ||||
|             if(event.type == EventTypeInput) { | ||||
|         FURI_LOG_I( | ||||
|             TAG, | ||||
|             "key: %s type: %s", | ||||
|                     input_get_key_name(event.input.key), | ||||
|                     input_get_type_name(event.input.type)); | ||||
|             input_get_key_name(event.key), | ||||
|             input_get_type_name(event.type)); | ||||
| 
 | ||||
|                 if(event.input.type == InputTypeLong && event.input.key == InputKeyBack) { | ||||
|                     release_mutex(&state_mutex, state); | ||||
|                     break; | ||||
|                 } | ||||
| 
 | ||||
|                 if(event.input.type == InputTypeShort && event.input.key == InputKeyBack) { | ||||
|                     keypad_test_reset_state(state); | ||||
|                 } | ||||
| 
 | ||||
|                 if(event.input.key == InputKeyRight) { | ||||
|                     if(event.input.type == InputTypePress) { | ||||
|         if(event.key == InputKeyRight) { | ||||
|             if(event.type == InputTypePress) { | ||||
|                 state->press[0] = true; | ||||
|                     } else if(event.input.type == InputTypeRelease) { | ||||
|             } else if(event.type == InputTypeRelease) { | ||||
|                 state->press[0] = false; | ||||
|                     } | ||||
| 
 | ||||
|                     if(event.input.type == InputTypeShort) { | ||||
|             } else if(event.type == InputTypeShort) { | ||||
|                 ++state->right; | ||||
|             } | ||||
|                 } | ||||
| 
 | ||||
|                 if(event.input.key == InputKeyLeft) { | ||||
|                     if(event.input.type == InputTypePress) { | ||||
|         } else if(event.key == InputKeyLeft) { | ||||
|             if(event.type == InputTypePress) { | ||||
|                 state->press[1] = true; | ||||
|                     } else if(event.input.type == InputTypeRelease) { | ||||
|             } else if(event.type == InputTypeRelease) { | ||||
|                 state->press[1] = false; | ||||
|                     } | ||||
| 
 | ||||
|                     if(event.input.type == InputTypeShort) { | ||||
|             } else if(event.type == InputTypeShort) { | ||||
|                 ++state->left; | ||||
|             } | ||||
|                 } | ||||
| 
 | ||||
|                 if(event.input.key == InputKeyUp) { | ||||
|                     if(event.input.type == InputTypePress) { | ||||
|         } else if(event.key == InputKeyUp) { | ||||
|             if(event.type == InputTypePress) { | ||||
|                 state->press[2] = true; | ||||
|                     } else if(event.input.type == InputTypeRelease) { | ||||
|             } else if(event.type == InputTypeRelease) { | ||||
|                 state->press[2] = false; | ||||
|                     } | ||||
| 
 | ||||
|                     if(event.input.type == InputTypeShort) { | ||||
|             } else if(event.type == InputTypeShort) { | ||||
|                 ++state->up; | ||||
|             } | ||||
|                 } | ||||
| 
 | ||||
|                 if(event.input.key == InputKeyDown) { | ||||
|                     if(event.input.type == InputTypePress) { | ||||
|         } else if(event.key == InputKeyDown) { | ||||
|             if(event.type == InputTypePress) { | ||||
|                 state->press[3] = true; | ||||
|                     } else if(event.input.type == InputTypeRelease) { | ||||
|             } else if(event.type == InputTypeRelease) { | ||||
|                 state->press[3] = false; | ||||
|                     } | ||||
| 
 | ||||
|                     if(event.input.type == InputTypeShort) { | ||||
|             } else if(event.type == InputTypeShort) { | ||||
|                 ++state->down; | ||||
|             } | ||||
|                 } | ||||
| 
 | ||||
|                 if(event.input.key == InputKeyOk) { | ||||
|                     if(event.input.type == InputTypePress) { | ||||
|         } else if(event.key == InputKeyOk) { | ||||
|             if(event.type == InputTypePress) { | ||||
|                 state->press[4] = true; | ||||
|                     } else if(event.input.type == InputTypeRelease) { | ||||
|             } else if(event.type == InputTypeRelease) { | ||||
|                 state->press[4] = false; | ||||
|                     } | ||||
| 
 | ||||
|                     if(event.input.type == InputTypeShort) { | ||||
|             } else if(event.type == InputTypeShort) { | ||||
|                 ++state->ok; | ||||
|             } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         view_port_update(view_port); | ||||
|         } else if(event.key == InputKeyBack) { | ||||
|             if(event.type == InputTypeLong) { | ||||
|                 release_mutex(&state_mutex, state); | ||||
|                 break; | ||||
|             } else if(event.type == InputTypeShort) { | ||||
|                 keypad_test_reset_state(state); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         release_mutex(&state_mutex, state); | ||||
|         view_port_update(view_port); | ||||
|     } | ||||
| 
 | ||||
|     // remove & free all stuff created by app
 | ||||
|     gui_remove_view_port(gui, view_port); | ||||
|     view_port_free(view_port); | ||||
|     osMessageQueueDelete(event_queue); | ||||
|     delete_mutex(&state_mutex); | ||||
| 
 | ||||
|     furi_record_close("gui"); | ||||
| 
 | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| @ -5,10 +5,6 @@ | ||||
| #include <input/input.h> | ||||
| #include <notification/notification-messages.h> | ||||
| 
 | ||||
| typedef struct { | ||||
|     InputEvent input; | ||||
| } VibroEvent; | ||||
| 
 | ||||
| void vibro_test_draw_callback(Canvas* canvas, void* ctx) { | ||||
|     canvas_clear(canvas); | ||||
|     canvas_set_font(canvas, FontPrimary); | ||||
| @ -22,17 +18,14 @@ void vibro_test_draw_callback(Canvas* canvas, void* ctx) { | ||||
| void vibro_test_input_callback(InputEvent* input_event, void* ctx) { | ||||
|     furi_assert(ctx); | ||||
|     osMessageQueueId_t event_queue = ctx; | ||||
| 
 | ||||
|     VibroEvent event = {.input = *input_event}; | ||||
|     osMessageQueuePut(event_queue, &event, 0, 0); | ||||
|     osMessageQueuePut(event_queue, input_event, 0, osWaitForever); | ||||
| } | ||||
| 
 | ||||
| int32_t vibro_test_app(void* p) { | ||||
|     osMessageQueueId_t event_queue = osMessageQueueNew(8, sizeof(VibroEvent), NULL); | ||||
|     osMessageQueueId_t event_queue = osMessageQueueNew(8, sizeof(InputEvent), NULL); | ||||
| 
 | ||||
|     // Configure view port
 | ||||
|     ViewPort* view_port = view_port_alloc(); | ||||
|     furi_check(view_port); | ||||
|     view_port_draw_callback_set(view_port, vibro_test_draw_callback, NULL); | ||||
|     view_port_input_callback_set(view_port, vibro_test_input_callback, event_queue); | ||||
| 
 | ||||
| @ -42,31 +35,31 @@ int32_t vibro_test_app(void* p) { | ||||
| 
 | ||||
|     NotificationApp* notification = furi_record_open("notification"); | ||||
| 
 | ||||
|     VibroEvent event; | ||||
|     InputEvent event; | ||||
| 
 | ||||
|     while(1) { | ||||
|         furi_check(osMessageQueueGet(event_queue, &event, NULL, osWaitForever) == osOK); | ||||
|         if(event.input.type == InputTypeShort && event.input.key == InputKeyBack) { | ||||
|     while(osMessageQueueGet(event_queue, &event, NULL, osWaitForever) == osOK) { | ||||
|         if(event.type == InputTypeShort && event.key == InputKeyBack) { | ||||
|             notification_message(notification, &sequence_reset_vibro); | ||||
|             notification_message(notification, &sequence_reset_green); | ||||
|             furi_record_close("notification"); | ||||
|             view_port_enabled_set(view_port, false); | ||||
|             break; | ||||
|         } | ||||
|         if(event.key == InputKeyOk) { | ||||
|             if(event.type == InputTypePress) { | ||||
|                 notification_message(notification, &sequence_set_vibro_on); | ||||
|                 notification_message(notification, &sequence_set_green_255); | ||||
|             } else if(event.type == InputTypeRelease) { | ||||
|                 notification_message(notification, &sequence_reset_vibro); | ||||
|                 notification_message(notification, &sequence_reset_green); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     gui_remove_view_port(gui, view_port); | ||||
|     view_port_free(view_port); | ||||
|     osMessageQueueDelete(event_queue); | ||||
| 
 | ||||
|             return 0; | ||||
|         } | ||||
|         if(event.input.key == InputKeyOk) { | ||||
|             if(event.input.type == InputTypePress) { | ||||
|                 notification_message(notification, &sequence_set_vibro_on); | ||||
|                 notification_message(notification, &sequence_set_green_255); | ||||
|             } else if(event.input.type == InputTypeRelease) { | ||||
|                 notification_message(notification, &sequence_reset_vibro); | ||||
|                 notification_message(notification, &sequence_reset_green); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     furi_record_close("notification"); | ||||
|     furi_record_close("gui"); | ||||
| 
 | ||||
|     return 0; | ||||
| } | ||||
| @ -18,6 +18,8 @@ typedef struct { | ||||
| 
 | ||||
| ARRAY_DEF(MenuItemArray, MenuItem, M_POD_OPLIST); | ||||
| 
 | ||||
| #define M_OPL_MenuItemArray_t() ARRAY_OPLIST(MenuItemArray, M_POD_OPLIST) | ||||
| 
 | ||||
| typedef struct { | ||||
|     MenuItemArray_t items; | ||||
|     size_t position; | ||||
| @ -136,11 +138,7 @@ Menu* menu_alloc() { | ||||
| 
 | ||||
| void menu_free(Menu* menu) { | ||||
|     furi_assert(menu); | ||||
|     with_view_model( | ||||
|         menu->view, (MenuModel * model) { | ||||
|             MenuItemArray_clear(model->items); | ||||
|             return true; | ||||
|         }); | ||||
|     menu_clean(menu); | ||||
|     view_free(menu->view); | ||||
|     free(menu); | ||||
| } | ||||
| @ -153,7 +151,7 @@ View* menu_get_view(Menu* menu) { | ||||
| void menu_add_item( | ||||
|     Menu* menu, | ||||
|     const char* label, | ||||
|     IconAnimation* icon, | ||||
|     const Icon* icon, | ||||
|     uint32_t index, | ||||
|     MenuItemCallback callback, | ||||
|     void* context) { | ||||
| @ -165,7 +163,7 @@ void menu_add_item( | ||||
|         menu->view, (MenuModel * model) { | ||||
|             item = MenuItemArray_push_new(model->items); | ||||
|             item->label = label; | ||||
|             item->icon = icon; | ||||
|             item->icon = icon ? icon_animation_alloc(icon) : icon_animation_alloc(&A_Plugins_14); | ||||
|             view_tie_icon_animation(menu->view, item->icon); | ||||
|             item->index = index; | ||||
|             item->callback = callback; | ||||
| @ -178,6 +176,12 @@ void menu_clean(Menu* menu) { | ||||
|     furi_assert(menu); | ||||
|     with_view_model( | ||||
|         menu->view, (MenuModel * model) { | ||||
|             for | ||||
|                 M_EACH(item, model->items, MenuItemArray_t) { | ||||
|                     icon_animation_stop(item->icon); | ||||
|                     icon_animation_free(item->icon); | ||||
|                 } | ||||
| 
 | ||||
|             MenuItemArray_reset(model->items); | ||||
|             model->position = 0; | ||||
|             return true; | ||||
|  | ||||
| @ -49,7 +49,7 @@ View* menu_get_view(Menu* menu); | ||||
| void menu_add_item( | ||||
|     Menu* menu, | ||||
|     const char* label, | ||||
|     IconAnimation* icon, | ||||
|     const Icon* icon, | ||||
|     uint32_t index, | ||||
|     MenuItemCallback callback, | ||||
|     void* context); | ||||
|  | ||||
| @ -279,7 +279,7 @@ static void loader_build_menu() { | ||||
|         menu_add_item( | ||||
|             loader_instance->primary_menu, | ||||
|             FLIPPER_APPS[i].name, | ||||
|             FLIPPER_APPS[i].icon ? icon_animation_alloc(FLIPPER_APPS[i].icon) : NULL, | ||||
|             FLIPPER_APPS[i].icon, | ||||
|             i, | ||||
|             loader_menu_callback, | ||||
|             (void*)&FLIPPER_APPS[i]); | ||||
| @ -287,26 +287,31 @@ static void loader_build_menu() { | ||||
|     menu_add_item( | ||||
|         loader_instance->primary_menu, | ||||
|         "Plugins", | ||||
|         icon_animation_alloc(&A_Plugins_14), | ||||
|         &A_Plugins_14, | ||||
|         i++, | ||||
|         loader_submenu_callback, | ||||
|         (void*)LoaderMenuViewPlugins); | ||||
|     if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) { | ||||
|         menu_add_item( | ||||
|             loader_instance->primary_menu, | ||||
|             "Debug tools", | ||||
|         icon_animation_alloc(&A_Debug_14), | ||||
|             &A_Debug_14, | ||||
|             i++, | ||||
|             loader_submenu_callback, | ||||
|             (void*)LoaderMenuViewDebug); | ||||
|     } | ||||
|     menu_add_item( | ||||
|         loader_instance->primary_menu, | ||||
|         "Settings", | ||||
|         icon_animation_alloc(&A_Settings_14), | ||||
|         &A_Settings_14, | ||||
|         i++, | ||||
|         loader_submenu_callback, | ||||
|         (void*)LoaderMenuViewSettings); | ||||
| } | ||||
| 
 | ||||
| static void loader_build_submenu() { | ||||
|     FURI_LOG_I(TAG, "Building plugins menu"); | ||||
|     size_t i; | ||||
|     for(i = 0; i < FLIPPER_PLUGINS_COUNT; i++) { | ||||
|         loader_add_cli_command((FlipperApplication*)&FLIPPER_PLUGINS[i]); | ||||
|         submenu_add_item( | ||||
| @ -344,12 +349,18 @@ void loader_show_menu() { | ||||
|     osThreadFlagsSet(loader_instance->loader_thread, LOADER_THREAD_FLAG_SHOW_MENU); | ||||
| } | ||||
| 
 | ||||
| void loader_update_menu() { | ||||
|     menu_clean(loader_instance->primary_menu); | ||||
|     loader_build_menu(); | ||||
| } | ||||
| 
 | ||||
| int32_t loader_srv(void* p) { | ||||
|     FURI_LOG_I(TAG, "Starting"); | ||||
| 
 | ||||
|     loader_instance = loader_alloc(); | ||||
| 
 | ||||
|     loader_build_menu(); | ||||
|     loader_build_submenu(); | ||||
| 
 | ||||
|     // Call on start hooks
 | ||||
|     for(size_t i = 0; i < FLIPPER_ON_SYSTEM_START_COUNT; i++) { | ||||
|  | ||||
| @ -31,3 +31,6 @@ bool loader_is_locked(Loader* instance); | ||||
| 
 | ||||
| /** Show primary loader */ | ||||
| void loader_show_menu(); | ||||
| 
 | ||||
| /** Show primary loader */ | ||||
| void loader_update_menu(); | ||||
|  | ||||
| @ -1,4 +1,5 @@ | ||||
| #include "system_settings.h" | ||||
| #include <loader/loader.h> | ||||
| 
 | ||||
| static uint8_t | ||||
|     uint32_value_index(const uint32_t value, const uint32_t values[], uint8_t values_count) { | ||||
| @ -54,6 +55,7 @@ static void debug_changed(VariableItem* item) { | ||||
|     } else { | ||||
|         furi_hal_rtc_reset_flag(FuriHalRtcFlagDebug); | ||||
|     } | ||||
|     loader_update_menu(); | ||||
| } | ||||
| 
 | ||||
| static uint32_t system_settings_exit(void* context) { | ||||
|  | ||||
| @ -10,6 +10,9 @@ | ||||
| #include <cc1101.h> | ||||
| #include <stdio.h> | ||||
| 
 | ||||
| #define __STDC_FORMAT_MACROS | ||||
| #include <inttypes.h> | ||||
| 
 | ||||
| #define TAG "FuriHalSubGhz" | ||||
| 
 | ||||
| static volatile SubGhzState furi_hal_subghz_state = SubGhzStateInit; | ||||
| @ -808,6 +811,8 @@ typedef struct { | ||||
|     bool flip_flop; | ||||
|     FuriHalSubGhzAsyncTxCallback callback; | ||||
|     void* callback_context; | ||||
|     uint64_t duty_high; | ||||
|     uint64_t duty_low; | ||||
| } FuriHalSubGhzAsyncTx; | ||||
| 
 | ||||
| static FuriHalSubGhzAsyncTx furi_hal_subghz_async_tx = {0}; | ||||
| @ -817,21 +822,30 @@ static void furi_hal_subghz_async_tx_refill(uint32_t* buffer, size_t samples) { | ||||
|         bool is_odd = samples % 2; | ||||
|         LevelDuration ld = | ||||
|             furi_hal_subghz_async_tx.callback(furi_hal_subghz_async_tx.callback_context); | ||||
|         if(level_duration_is_wait(ld)) return; | ||||
|         if(level_duration_is_reset(ld)) { | ||||
| 
 | ||||
|         if(level_duration_is_wait(ld)) { | ||||
|             return; | ||||
|         } else if(level_duration_is_reset(ld)) { | ||||
|             // One more even sample required to end at low level
 | ||||
|             if(is_odd) { | ||||
|                 *buffer = API_HAL_SUBGHZ_ASYNC_TX_GUARD_TIME; | ||||
|                 buffer++; | ||||
|                 samples--; | ||||
|                 furi_hal_subghz_async_tx.duty_low += API_HAL_SUBGHZ_ASYNC_TX_GUARD_TIME; | ||||
|             } | ||||
|             break; | ||||
|         } else { | ||||
|             // Inject guard time if level is incorrect
 | ||||
|             if(is_odd == level_duration_get_level(ld)) { | ||||
|             bool level = level_duration_get_level(ld); | ||||
|             if(is_odd == level) { | ||||
|                 *buffer = API_HAL_SUBGHZ_ASYNC_TX_GUARD_TIME; | ||||
|                 buffer++; | ||||
|                 samples--; | ||||
|                 if (!level) { | ||||
|                     furi_hal_subghz_async_tx.duty_high += API_HAL_SUBGHZ_ASYNC_TX_GUARD_TIME; | ||||
|                 } else { | ||||
|                     furi_hal_subghz_async_tx.duty_low += API_HAL_SUBGHZ_ASYNC_TX_GUARD_TIME; | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             uint32_t duration = level_duration_get_duration(ld); | ||||
| @ -839,6 +853,12 @@ static void furi_hal_subghz_async_tx_refill(uint32_t* buffer, size_t samples) { | ||||
|             *buffer = duration; | ||||
|             buffer++; | ||||
|             samples--; | ||||
| 
 | ||||
|             if (level) { | ||||
|                 furi_hal_subghz_async_tx.duty_high += duration; | ||||
|             } else { | ||||
|                 furi_hal_subghz_async_tx.duty_low += duration; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| @ -888,6 +908,9 @@ bool furi_hal_subghz_start_async_tx(FuriHalSubGhzAsyncTxCallback callback, void* | ||||
| 
 | ||||
|     furi_hal_subghz_state = SubGhzStateAsyncTx; | ||||
| 
 | ||||
|     furi_hal_subghz_async_tx.duty_low = 0; | ||||
|     furi_hal_subghz_async_tx.duty_high = 0; | ||||
| 
 | ||||
|     furi_hal_subghz_async_tx.buffer = | ||||
|         furi_alloc(API_HAL_SUBGHZ_ASYNC_TX_BUFFER_FULL * sizeof(uint32_t)); | ||||
|     furi_hal_subghz_async_tx_refill( | ||||
| @ -994,5 +1017,8 @@ void furi_hal_subghz_stop_async_tx() { | ||||
| 
 | ||||
|     free(furi_hal_subghz_async_tx.buffer); | ||||
| 
 | ||||
|     float duty_cycle = 100.0f * (float)furi_hal_subghz_async_tx.duty_high / ((float)furi_hal_subghz_async_tx.duty_low + (float)furi_hal_subghz_async_tx.duty_high); | ||||
|     FURI_LOG_D(TAG, "Async TX Radio stats: on %0.0fus, off %0.0fus, DutyCycle: %0.0f%%", (float)furi_hal_subghz_async_tx.duty_high, (float)furi_hal_subghz_async_tx.duty_low, duty_cycle); | ||||
| 
 | ||||
|     furi_hal_subghz_state = SubGhzStateIdle; | ||||
| } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 あく
						あく