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 | #define BLINK_COLOR_COUNT 7 | ||||||
| 
 | 
 | ||||||
| typedef enum { | typedef enum { | ||||||
|     EventTypeTick, |     BlinkEventTypeTick, | ||||||
|     EventTypeKey, |     BlinkEventTypeInput, | ||||||
| } EventType; | } BlinkEventType; | ||||||
| 
 | 
 | ||||||
| typedef struct { | typedef struct { | ||||||
|     EventType type; |     BlinkEventType type; | ||||||
|     InputEvent input; |     InputEvent input; | ||||||
| } BlinkEvent; | } BlinkEvent; | ||||||
| 
 | 
 | ||||||
| static void blink_test_update(void* ctx) { | static void blink_test_update(void* ctx) { | ||||||
|     furi_assert(ctx); |     furi_assert(ctx); | ||||||
|     osMessageQueueId_t event_queue = ctx; |     osMessageQueueId_t event_queue = ctx; | ||||||
| 
 |     BlinkEvent event = {.type = BlinkEventTypeTick}; | ||||||
|     BlinkEvent event = {.type = EventTypeTick}; |     // It's OK to loose this event if system overloaded
 | ||||||
|     osMessageQueuePut(event_queue, &event, 0, 0); |     osMessageQueuePut(event_queue, &event, 0, 0); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -36,8 +36,8 @@ static void blink_test_input_callback(InputEvent* input_event, void* ctx) { | |||||||
|     furi_assert(ctx); |     furi_assert(ctx); | ||||||
|     osMessageQueueId_t event_queue = ctx; |     osMessageQueueId_t event_queue = ctx; | ||||||
| 
 | 
 | ||||||
|     BlinkEvent event = {.type = EventTypeKey, .input = *input_event}; |     BlinkEvent event = {.type = BlinkEventTypeInput, .input = *input_event}; | ||||||
|     osMessageQueuePut(event_queue, &event, 0, 0); |     osMessageQueuePut(event_queue, &event, 0, osWaitForever); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int32_t blink_test_app(void* p) { | int32_t blink_test_app(void* p) { | ||||||
| @ -45,7 +45,6 @@ int32_t blink_test_app(void* p) { | |||||||
| 
 | 
 | ||||||
|     // Configure view port
 |     // Configure view port
 | ||||||
|     ViewPort* view_port = view_port_alloc(); |     ViewPort* view_port = view_port_alloc(); | ||||||
|     furi_check(view_port); |  | ||||||
|     view_port_draw_callback_set(view_port, blink_test_draw_callback, NULL); |     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); |     view_port_input_callback_set(view_port, blink_test_input_callback, event_queue); | ||||||
|     osTimerId_t timer = osTimerNew(blink_test_update, osTimerPeriodic, event_queue, NULL); |     osTimerId_t timer = osTimerNew(blink_test_update, osTimerPeriodic, event_queue, NULL); | ||||||
| @ -72,20 +71,12 @@ int32_t blink_test_app(void* p) { | |||||||
| 
 | 
 | ||||||
|     while(1) { |     while(1) { | ||||||
|         furi_check(osMessageQueueGet(event_queue, &event, NULL, osWaitForever) == osOK); |         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)) { |             if((event.input.type == InputTypeShort) && (event.input.key == InputKeyBack)) { | ||||||
|                 furi_record_close("notification"); |                 break; | ||||||
|                 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; |  | ||||||
|             } |             } | ||||||
|         } else { |         } else { | ||||||
|             notification_message(notifications, colors[state]); |             notification_message(notifications, colors[state]); | ||||||
| 
 |  | ||||||
|             state++; |             state++; | ||||||
|             if(state >= BLINK_COLOR_COUNT) { |             if(state >= BLINK_COLOR_COUNT) { | ||||||
|                 state = 0; |                 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; |     return 0; | ||||||
| } | } | ||||||
| @ -13,17 +13,6 @@ typedef struct { | |||||||
|     uint16_t ok; |     uint16_t ok; | ||||||
| } KeypadTestState; | } KeypadTestState; | ||||||
| 
 | 
 | ||||||
| typedef enum { |  | ||||||
|     EventTypeInput, |  | ||||||
| } EventType; |  | ||||||
| 
 |  | ||||||
| typedef struct { |  | ||||||
|     union { |  | ||||||
|         InputEvent input; |  | ||||||
|     }; |  | ||||||
|     EventType type; |  | ||||||
| } KeypadTestEvent; |  | ||||||
| 
 |  | ||||||
| static void keypad_test_reset_state(KeypadTestState* state) { | static void keypad_test_reset_state(KeypadTestState* state) { | ||||||
|     state->left = 0; |     state->left = 0; | ||||||
|     state->right = 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) { | static void keypad_test_input_callback(InputEvent* input_event, void* ctx) { | ||||||
|     osMessageQueueId_t event_queue = ctx; |     osMessageQueueId_t event_queue = ctx; | ||||||
| 
 |     osMessageQueuePut(event_queue, input_event, 0, osWaitForever); | ||||||
|     KeypadTestEvent event; |  | ||||||
|     event.type = EventTypeInput; |  | ||||||
|     event.input = *input_event; |  | ||||||
|     osMessageQueuePut(event_queue, &event, 0, osWaitForever); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int32_t keypad_test_app(void* p) { | 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); |     furi_check(event_queue); | ||||||
| 
 | 
 | ||||||
|     KeypadTestState _state = {{false, false, false, false, false}, 0, 0, 0, 0, 0}; |     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* gui = furi_record_open("gui"); | ||||||
|     gui_add_view_port(gui, view_port, GuiLayerFullscreen); |     gui_add_view_port(gui, view_port, GuiLayerFullscreen); | ||||||
| 
 | 
 | ||||||
|     KeypadTestEvent event; |     InputEvent event; | ||||||
|     while(1) { |     while(osMessageQueueGet(event_queue, &event, NULL, osWaitForever) == osOK) { | ||||||
|         osStatus_t event_status = osMessageQueueGet(event_queue, &event, NULL, osWaitForever); |  | ||||||
|         KeypadTestState* state = (KeypadTestState*)acquire_mutex_block(&state_mutex); |         KeypadTestState* state = (KeypadTestState*)acquire_mutex_block(&state_mutex); | ||||||
| 
 |  | ||||||
|         if(event_status == osOK) { |  | ||||||
|             if(event.type == EventTypeInput) { |  | ||||||
|         FURI_LOG_I( |         FURI_LOG_I( | ||||||
|             TAG, |             TAG, | ||||||
|             "key: %s type: %s", |             "key: %s type: %s", | ||||||
|                     input_get_key_name(event.input.key), |             input_get_key_name(event.key), | ||||||
|                     input_get_type_name(event.input.type)); |             input_get_type_name(event.type)); | ||||||
| 
 | 
 | ||||||
|                 if(event.input.type == InputTypeLong && event.input.key == InputKeyBack) { |         if(event.key == InputKeyRight) { | ||||||
|                     release_mutex(&state_mutex, state); |             if(event.type == InputTypePress) { | ||||||
|                     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) { |  | ||||||
|                 state->press[0] = true; |                 state->press[0] = true; | ||||||
|                     } else if(event.input.type == InputTypeRelease) { |             } else if(event.type == InputTypeRelease) { | ||||||
|                 state->press[0] = false; |                 state->press[0] = false; | ||||||
|                     } |             } else if(event.type == InputTypeShort) { | ||||||
| 
 |  | ||||||
|                     if(event.input.type == InputTypeShort) { |  | ||||||
|                 ++state->right; |                 ++state->right; | ||||||
|             } |             } | ||||||
|                 } |         } else if(event.key == InputKeyLeft) { | ||||||
| 
 |             if(event.type == InputTypePress) { | ||||||
|                 if(event.input.key == InputKeyLeft) { |  | ||||||
|                     if(event.input.type == InputTypePress) { |  | ||||||
|                 state->press[1] = true; |                 state->press[1] = true; | ||||||
|                     } else if(event.input.type == InputTypeRelease) { |             } else if(event.type == InputTypeRelease) { | ||||||
|                 state->press[1] = false; |                 state->press[1] = false; | ||||||
|                     } |             } else if(event.type == InputTypeShort) { | ||||||
| 
 |  | ||||||
|                     if(event.input.type == InputTypeShort) { |  | ||||||
|                 ++state->left; |                 ++state->left; | ||||||
|             } |             } | ||||||
|                 } |         } else if(event.key == InputKeyUp) { | ||||||
| 
 |             if(event.type == InputTypePress) { | ||||||
|                 if(event.input.key == InputKeyUp) { |  | ||||||
|                     if(event.input.type == InputTypePress) { |  | ||||||
|                 state->press[2] = true; |                 state->press[2] = true; | ||||||
|                     } else if(event.input.type == InputTypeRelease) { |             } else if(event.type == InputTypeRelease) { | ||||||
|                 state->press[2] = false; |                 state->press[2] = false; | ||||||
|                     } |             } else if(event.type == InputTypeShort) { | ||||||
| 
 |  | ||||||
|                     if(event.input.type == InputTypeShort) { |  | ||||||
|                 ++state->up; |                 ++state->up; | ||||||
|             } |             } | ||||||
|                 } |         } else if(event.key == InputKeyDown) { | ||||||
| 
 |             if(event.type == InputTypePress) { | ||||||
|                 if(event.input.key == InputKeyDown) { |  | ||||||
|                     if(event.input.type == InputTypePress) { |  | ||||||
|                 state->press[3] = true; |                 state->press[3] = true; | ||||||
|                     } else if(event.input.type == InputTypeRelease) { |             } else if(event.type == InputTypeRelease) { | ||||||
|                 state->press[3] = false; |                 state->press[3] = false; | ||||||
|                     } |             } else if(event.type == InputTypeShort) { | ||||||
| 
 |  | ||||||
|                     if(event.input.type == InputTypeShort) { |  | ||||||
|                 ++state->down; |                 ++state->down; | ||||||
|             } |             } | ||||||
|                 } |         } else if(event.key == InputKeyOk) { | ||||||
| 
 |             if(event.type == InputTypePress) { | ||||||
|                 if(event.input.key == InputKeyOk) { |  | ||||||
|                     if(event.input.type == InputTypePress) { |  | ||||||
|                 state->press[4] = true; |                 state->press[4] = true; | ||||||
|                     } else if(event.input.type == InputTypeRelease) { |             } else if(event.type == InputTypeRelease) { | ||||||
|                 state->press[4] = false; |                 state->press[4] = false; | ||||||
|                     } |             } else if(event.type == InputTypeShort) { | ||||||
| 
 |  | ||||||
|                     if(event.input.type == InputTypeShort) { |  | ||||||
|                 ++state->ok; |                 ++state->ok; | ||||||
|             } |             } | ||||||
|                 } |         } else if(event.key == InputKeyBack) { | ||||||
|             } |             if(event.type == InputTypeLong) { | ||||||
|         } |  | ||||||
|         view_port_update(view_port); |  | ||||||
|                 release_mutex(&state_mutex, state); |                 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
 |     // remove & free all stuff created by app
 | ||||||
|     gui_remove_view_port(gui, view_port); |     gui_remove_view_port(gui, view_port); | ||||||
|     view_port_free(view_port); |     view_port_free(view_port); | ||||||
|     osMessageQueueDelete(event_queue); |     osMessageQueueDelete(event_queue); | ||||||
|     delete_mutex(&state_mutex); |     delete_mutex(&state_mutex); | ||||||
| 
 | 
 | ||||||
|  |     furi_record_close("gui"); | ||||||
|  | 
 | ||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
|  | |||||||
| @ -5,10 +5,6 @@ | |||||||
| #include <input/input.h> | #include <input/input.h> | ||||||
| #include <notification/notification-messages.h> | #include <notification/notification-messages.h> | ||||||
| 
 | 
 | ||||||
| typedef struct { |  | ||||||
|     InputEvent input; |  | ||||||
| } VibroEvent; |  | ||||||
| 
 |  | ||||||
| void vibro_test_draw_callback(Canvas* canvas, void* ctx) { | void vibro_test_draw_callback(Canvas* canvas, void* ctx) { | ||||||
|     canvas_clear(canvas); |     canvas_clear(canvas); | ||||||
|     canvas_set_font(canvas, FontPrimary); |     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) { | void vibro_test_input_callback(InputEvent* input_event, void* ctx) { | ||||||
|     furi_assert(ctx); |     furi_assert(ctx); | ||||||
|     osMessageQueueId_t event_queue = ctx; |     osMessageQueueId_t event_queue = ctx; | ||||||
| 
 |     osMessageQueuePut(event_queue, input_event, 0, osWaitForever); | ||||||
|     VibroEvent event = {.input = *input_event}; |  | ||||||
|     osMessageQueuePut(event_queue, &event, 0, 0); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int32_t vibro_test_app(void* p) { | 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
 |     // Configure view port
 | ||||||
|     ViewPort* view_port = view_port_alloc(); |     ViewPort* view_port = view_port_alloc(); | ||||||
|     furi_check(view_port); |  | ||||||
|     view_port_draw_callback_set(view_port, vibro_test_draw_callback, NULL); |     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); |     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"); |     NotificationApp* notification = furi_record_open("notification"); | ||||||
| 
 | 
 | ||||||
|     VibroEvent event; |     InputEvent event; | ||||||
| 
 | 
 | ||||||
|     while(1) { |     while(osMessageQueueGet(event_queue, &event, NULL, osWaitForever) == osOK) { | ||||||
|         furi_check(osMessageQueueGet(event_queue, &event, NULL, osWaitForever) == osOK); |         if(event.type == InputTypeShort && event.key == InputKeyBack) { | ||||||
|         if(event.input.type == InputTypeShort && event.input.key == InputKeyBack) { |  | ||||||
|             notification_message(notification, &sequence_reset_vibro); |             notification_message(notification, &sequence_reset_vibro); | ||||||
|             notification_message(notification, &sequence_reset_green); |             notification_message(notification, &sequence_reset_green); | ||||||
|             furi_record_close("notification"); |             break; | ||||||
|             view_port_enabled_set(view_port, false); |         } | ||||||
|  |         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); |     gui_remove_view_port(gui, view_port); | ||||||
|     view_port_free(view_port); |     view_port_free(view_port); | ||||||
|     osMessageQueueDelete(event_queue); |     osMessageQueueDelete(event_queue); | ||||||
| 
 | 
 | ||||||
|             return 0; |     furi_record_close("notification"); | ||||||
|         } |     furi_record_close("gui"); | ||||||
|         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); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
| @ -18,6 +18,8 @@ typedef struct { | |||||||
| 
 | 
 | ||||||
| ARRAY_DEF(MenuItemArray, MenuItem, M_POD_OPLIST); | ARRAY_DEF(MenuItemArray, MenuItem, M_POD_OPLIST); | ||||||
| 
 | 
 | ||||||
|  | #define M_OPL_MenuItemArray_t() ARRAY_OPLIST(MenuItemArray, M_POD_OPLIST) | ||||||
|  | 
 | ||||||
| typedef struct { | typedef struct { | ||||||
|     MenuItemArray_t items; |     MenuItemArray_t items; | ||||||
|     size_t position; |     size_t position; | ||||||
| @ -136,11 +138,7 @@ Menu* menu_alloc() { | |||||||
| 
 | 
 | ||||||
| void menu_free(Menu* menu) { | void menu_free(Menu* menu) { | ||||||
|     furi_assert(menu); |     furi_assert(menu); | ||||||
|     with_view_model( |     menu_clean(menu); | ||||||
|         menu->view, (MenuModel * model) { |  | ||||||
|             MenuItemArray_clear(model->items); |  | ||||||
|             return true; |  | ||||||
|         }); |  | ||||||
|     view_free(menu->view); |     view_free(menu->view); | ||||||
|     free(menu); |     free(menu); | ||||||
| } | } | ||||||
| @ -153,7 +151,7 @@ View* menu_get_view(Menu* menu) { | |||||||
| void menu_add_item( | void menu_add_item( | ||||||
|     Menu* menu, |     Menu* menu, | ||||||
|     const char* label, |     const char* label, | ||||||
|     IconAnimation* icon, |     const Icon* icon, | ||||||
|     uint32_t index, |     uint32_t index, | ||||||
|     MenuItemCallback callback, |     MenuItemCallback callback, | ||||||
|     void* context) { |     void* context) { | ||||||
| @ -165,7 +163,7 @@ void menu_add_item( | |||||||
|         menu->view, (MenuModel * model) { |         menu->view, (MenuModel * model) { | ||||||
|             item = MenuItemArray_push_new(model->items); |             item = MenuItemArray_push_new(model->items); | ||||||
|             item->label = label; |             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); |             view_tie_icon_animation(menu->view, item->icon); | ||||||
|             item->index = index; |             item->index = index; | ||||||
|             item->callback = callback; |             item->callback = callback; | ||||||
| @ -178,6 +176,12 @@ void menu_clean(Menu* menu) { | |||||||
|     furi_assert(menu); |     furi_assert(menu); | ||||||
|     with_view_model( |     with_view_model( | ||||||
|         menu->view, (MenuModel * 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); |             MenuItemArray_reset(model->items); | ||||||
|             model->position = 0; |             model->position = 0; | ||||||
|             return true; |             return true; | ||||||
|  | |||||||
| @ -49,7 +49,7 @@ View* menu_get_view(Menu* menu); | |||||||
| void menu_add_item( | void menu_add_item( | ||||||
|     Menu* menu, |     Menu* menu, | ||||||
|     const char* label, |     const char* label, | ||||||
|     IconAnimation* icon, |     const Icon* icon, | ||||||
|     uint32_t index, |     uint32_t index, | ||||||
|     MenuItemCallback callback, |     MenuItemCallback callback, | ||||||
|     void* context); |     void* context); | ||||||
|  | |||||||
| @ -279,7 +279,7 @@ static void loader_build_menu() { | |||||||
|         menu_add_item( |         menu_add_item( | ||||||
|             loader_instance->primary_menu, |             loader_instance->primary_menu, | ||||||
|             FLIPPER_APPS[i].name, |             FLIPPER_APPS[i].name, | ||||||
|             FLIPPER_APPS[i].icon ? icon_animation_alloc(FLIPPER_APPS[i].icon) : NULL, |             FLIPPER_APPS[i].icon, | ||||||
|             i, |             i, | ||||||
|             loader_menu_callback, |             loader_menu_callback, | ||||||
|             (void*)&FLIPPER_APPS[i]); |             (void*)&FLIPPER_APPS[i]); | ||||||
| @ -287,26 +287,31 @@ static void loader_build_menu() { | |||||||
|     menu_add_item( |     menu_add_item( | ||||||
|         loader_instance->primary_menu, |         loader_instance->primary_menu, | ||||||
|         "Plugins", |         "Plugins", | ||||||
|         icon_animation_alloc(&A_Plugins_14), |         &A_Plugins_14, | ||||||
|         i++, |         i++, | ||||||
|         loader_submenu_callback, |         loader_submenu_callback, | ||||||
|         (void*)LoaderMenuViewPlugins); |         (void*)LoaderMenuViewPlugins); | ||||||
|  |     if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) { | ||||||
|         menu_add_item( |         menu_add_item( | ||||||
|             loader_instance->primary_menu, |             loader_instance->primary_menu, | ||||||
|             "Debug tools", |             "Debug tools", | ||||||
|         icon_animation_alloc(&A_Debug_14), |             &A_Debug_14, | ||||||
|             i++, |             i++, | ||||||
|             loader_submenu_callback, |             loader_submenu_callback, | ||||||
|             (void*)LoaderMenuViewDebug); |             (void*)LoaderMenuViewDebug); | ||||||
|  |     } | ||||||
|     menu_add_item( |     menu_add_item( | ||||||
|         loader_instance->primary_menu, |         loader_instance->primary_menu, | ||||||
|         "Settings", |         "Settings", | ||||||
|         icon_animation_alloc(&A_Settings_14), |         &A_Settings_14, | ||||||
|         i++, |         i++, | ||||||
|         loader_submenu_callback, |         loader_submenu_callback, | ||||||
|         (void*)LoaderMenuViewSettings); |         (void*)LoaderMenuViewSettings); | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
|  | static void loader_build_submenu() { | ||||||
|     FURI_LOG_I(TAG, "Building plugins menu"); |     FURI_LOG_I(TAG, "Building plugins menu"); | ||||||
|  |     size_t i; | ||||||
|     for(i = 0; i < FLIPPER_PLUGINS_COUNT; i++) { |     for(i = 0; i < FLIPPER_PLUGINS_COUNT; i++) { | ||||||
|         loader_add_cli_command((FlipperApplication*)&FLIPPER_PLUGINS[i]); |         loader_add_cli_command((FlipperApplication*)&FLIPPER_PLUGINS[i]); | ||||||
|         submenu_add_item( |         submenu_add_item( | ||||||
| @ -344,12 +349,18 @@ void loader_show_menu() { | |||||||
|     osThreadFlagsSet(loader_instance->loader_thread, LOADER_THREAD_FLAG_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) { | int32_t loader_srv(void* p) { | ||||||
|     FURI_LOG_I(TAG, "Starting"); |     FURI_LOG_I(TAG, "Starting"); | ||||||
| 
 | 
 | ||||||
|     loader_instance = loader_alloc(); |     loader_instance = loader_alloc(); | ||||||
| 
 | 
 | ||||||
|     loader_build_menu(); |     loader_build_menu(); | ||||||
|  |     loader_build_submenu(); | ||||||
| 
 | 
 | ||||||
|     // Call on start hooks
 |     // Call on start hooks
 | ||||||
|     for(size_t i = 0; i < FLIPPER_ON_SYSTEM_START_COUNT; i++) { |     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 */ | /** Show primary loader */ | ||||||
| void loader_show_menu(); | void loader_show_menu(); | ||||||
|  | 
 | ||||||
|  | /** Show primary loader */ | ||||||
|  | void loader_update_menu(); | ||||||
|  | |||||||
| @ -1,4 +1,5 @@ | |||||||
| #include "system_settings.h" | #include "system_settings.h" | ||||||
|  | #include <loader/loader.h> | ||||||
| 
 | 
 | ||||||
| static uint8_t | static uint8_t | ||||||
|     uint32_value_index(const uint32_t value, const uint32_t values[], uint8_t values_count) { |     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 { |     } else { | ||||||
|         furi_hal_rtc_reset_flag(FuriHalRtcFlagDebug); |         furi_hal_rtc_reset_flag(FuriHalRtcFlagDebug); | ||||||
|     } |     } | ||||||
|  |     loader_update_menu(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static uint32_t system_settings_exit(void* context) { | static uint32_t system_settings_exit(void* context) { | ||||||
|  | |||||||
| @ -10,6 +10,9 @@ | |||||||
| #include <cc1101.h> | #include <cc1101.h> | ||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
| 
 | 
 | ||||||
|  | #define __STDC_FORMAT_MACROS | ||||||
|  | #include <inttypes.h> | ||||||
|  | 
 | ||||||
| #define TAG "FuriHalSubGhz" | #define TAG "FuriHalSubGhz" | ||||||
| 
 | 
 | ||||||
| static volatile SubGhzState furi_hal_subghz_state = SubGhzStateInit; | static volatile SubGhzState furi_hal_subghz_state = SubGhzStateInit; | ||||||
| @ -808,6 +811,8 @@ typedef struct { | |||||||
|     bool flip_flop; |     bool flip_flop; | ||||||
|     FuriHalSubGhzAsyncTxCallback callback; |     FuriHalSubGhzAsyncTxCallback callback; | ||||||
|     void* callback_context; |     void* callback_context; | ||||||
|  |     uint64_t duty_high; | ||||||
|  |     uint64_t duty_low; | ||||||
| } FuriHalSubGhzAsyncTx; | } FuriHalSubGhzAsyncTx; | ||||||
| 
 | 
 | ||||||
| static FuriHalSubGhzAsyncTx furi_hal_subghz_async_tx = {0}; | 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; |         bool is_odd = samples % 2; | ||||||
|         LevelDuration ld = |         LevelDuration ld = | ||||||
|             furi_hal_subghz_async_tx.callback(furi_hal_subghz_async_tx.callback_context); |             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
 |             // One more even sample required to end at low level
 | ||||||
|             if(is_odd) { |             if(is_odd) { | ||||||
|                 *buffer = API_HAL_SUBGHZ_ASYNC_TX_GUARD_TIME; |                 *buffer = API_HAL_SUBGHZ_ASYNC_TX_GUARD_TIME; | ||||||
|                 buffer++; |                 buffer++; | ||||||
|                 samples--; |                 samples--; | ||||||
|  |                 furi_hal_subghz_async_tx.duty_low += API_HAL_SUBGHZ_ASYNC_TX_GUARD_TIME; | ||||||
|             } |             } | ||||||
|             break; |             break; | ||||||
|         } else { |         } else { | ||||||
|             // Inject guard time if level is incorrect
 |             // 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 = API_HAL_SUBGHZ_ASYNC_TX_GUARD_TIME; | ||||||
|                 buffer++; |                 buffer++; | ||||||
|                 samples--; |                 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); |             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 = duration; | ||||||
|             buffer++; |             buffer++; | ||||||
|             samples--; |             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_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_hal_subghz_async_tx.buffer = | ||||||
|         furi_alloc(API_HAL_SUBGHZ_ASYNC_TX_BUFFER_FULL * sizeof(uint32_t)); |         furi_alloc(API_HAL_SUBGHZ_ASYNC_TX_BUFFER_FULL * sizeof(uint32_t)); | ||||||
|     furi_hal_subghz_async_tx_refill( |     furi_hal_subghz_async_tx_refill( | ||||||
| @ -994,5 +1017,8 @@ void furi_hal_subghz_stop_async_tx() { | |||||||
| 
 | 
 | ||||||
|     free(furi_hal_subghz_async_tx.buffer); |     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; |     furi_hal_subghz_state = SubGhzStateIdle; | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 あく
						あく