[FL-1506, FL-2197] Power, USB, LED driver improvements (#966)
* Power, USB, LED driver improvements * u2f hid descriptor fix * variable_item_list: value alignment fix * InputTypeRepeat handling in menu/submenu/var_item_list * lp5562: fix bugs on 400khz i2c * Scripts: lint in parallel. * FuriHal: rename some USB structure to match naming convention. Drivers: update magic values in LP5562. Co-authored-by: Aleksandr Kutuzov <alleteam@gmail.com>
This commit is contained in:
		| @@ -71,7 +71,7 @@ void bad_usb_app_free(BadUsbApp* app) { | ||||
| } | ||||
|  | ||||
| int32_t bad_usb_app(void* p) { | ||||
|     UsbInterface* usb_mode_prev = furi_hal_usb_get_config(); | ||||
|     FuriHalUsbInterface* usb_mode_prev = furi_hal_usb_get_config(); | ||||
|     furi_hal_usb_set_config(&usb_hid); | ||||
|  | ||||
|     BadUsbApp* bad_usb_app = bad_usb_app_alloc(); | ||||
|   | ||||
| @@ -41,7 +41,7 @@ int32_t usb_mouse_app(void* p) { | ||||
|     furi_check(event_queue); | ||||
|     ViewPort* view_port = view_port_alloc(); | ||||
|  | ||||
|     UsbInterface* usb_mode_prev = furi_hal_usb_get_config(); | ||||
|     FuriHalUsbInterface* usb_mode_prev = furi_hal_usb_get_config(); | ||||
|     furi_hal_usb_set_config(&usb_hid); | ||||
|  | ||||
|     view_port_draw_callback_set(view_port, usb_mouse_render_callback, NULL); | ||||
|   | ||||
| @@ -15,6 +15,7 @@ typedef struct { | ||||
| typedef enum { | ||||
|     UsbTestSubmenuIndexEnable, | ||||
|     UsbTestSubmenuIndexDisable, | ||||
|     UsbTestSubmenuIndexRestart, | ||||
|     UsbTestSubmenuIndexVcpSingle, | ||||
|     UsbTestSubmenuIndexVcpDual, | ||||
|     UsbTestSubmenuIndexHid, | ||||
| @@ -28,6 +29,8 @@ void usb_test_submenu_callback(void* context, uint32_t index) { | ||||
|         furi_hal_usb_enable(); | ||||
|     } else if(index == UsbTestSubmenuIndexDisable) { | ||||
|         furi_hal_usb_disable(); | ||||
|     } else if(index == UsbTestSubmenuIndexRestart) { | ||||
|         furi_hal_usb_reinit(); | ||||
|     } else if(index == UsbTestSubmenuIndexVcpSingle) { | ||||
|         furi_hal_usb_set_config(&usb_cdc_single); | ||||
|     } else if(index == UsbTestSubmenuIndexVcpDual) { | ||||
| @@ -60,6 +63,8 @@ UsbTestApp* usb_test_app_alloc() { | ||||
|         app->submenu, "Enable", UsbTestSubmenuIndexEnable, usb_test_submenu_callback, app); | ||||
|     submenu_add_item( | ||||
|         app->submenu, "Disable", UsbTestSubmenuIndexDisable, usb_test_submenu_callback, app); | ||||
|     submenu_add_item( | ||||
|         app->submenu, "Restart", UsbTestSubmenuIndexRestart, usb_test_submenu_callback, app); | ||||
|     submenu_add_item( | ||||
|         app->submenu, "Single VCP", UsbTestSubmenuIndexVcpSingle, usb_test_submenu_callback, app); | ||||
|     submenu_add_item( | ||||
|   | ||||
| @@ -154,7 +154,7 @@ static int32_t usb_uart_worker(void* context) { | ||||
|     furi_thread_set_context(usb_uart->tx_thread, usb_uart); | ||||
|     furi_thread_set_callback(usb_uart->tx_thread, usb_uart_tx_thread); | ||||
|  | ||||
|     UsbInterface* usb_mode_prev = furi_hal_usb_get_config(); | ||||
|     FuriHalUsbInterface* usb_mode_prev = furi_hal_usb_get_config(); | ||||
|     usb_uart_vcp_init(usb_uart, usb_uart->cfg.vcp_ch); | ||||
|     usb_uart_serial_init(usb_uart, usb_uart->cfg.uart_ch); | ||||
|     usb_uart_set_baudrate(usb_uart, usb_uart->cfg.baudrate); | ||||
|   | ||||
| @@ -77,7 +77,7 @@ static bool file_select_input_callback(InputEvent* event, void* context) { | ||||
|     FileSelect* file_select = (FileSelect*)context; | ||||
|     bool consumed = false; | ||||
|  | ||||
|     if(event->type == InputTypeShort) { | ||||
|     if((event->type == InputTypeShort) | (event->type == InputTypeRepeat)) { | ||||
|         if(!file_select->init_completed) { | ||||
|             if(!file_select_init_inner(file_select)) { | ||||
|                 file_select->callback(false, file_select->context); | ||||
|   | ||||
| @@ -87,6 +87,14 @@ static bool menu_input_callback(InputEvent* event, void* context) { | ||||
|             consumed = true; | ||||
|             menu_process_ok(menu); | ||||
|         } | ||||
|     } else if(event->type == InputTypeRepeat) { | ||||
|         if(event->key == InputKeyUp) { | ||||
|             consumed = true; | ||||
|             menu_process_up(menu); | ||||
|         } else if(event->key == InputKeyDown) { | ||||
|             consumed = true; | ||||
|             menu_process_down(menu); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     return consumed; | ||||
|   | ||||
| @@ -106,6 +106,14 @@ static bool submenu_view_input_callback(InputEvent* event, void* context) { | ||||
|         default: | ||||
|             break; | ||||
|         } | ||||
|     } else if(event->type == InputTypeRepeat) { | ||||
|         if(event->key == InputKeyUp) { | ||||
|             consumed = true; | ||||
|             submenu_process_up(submenu); | ||||
|         } else if(event->key == InputKeyDown) { | ||||
|             consumed = true; | ||||
|             submenu_process_down(submenu); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     return consumed; | ||||
|   | ||||
| @@ -71,7 +71,13 @@ static void variable_item_list_draw_callback(Canvas* canvas, void* _model) { | ||||
|                 canvas_draw_str(canvas, 73, item_text_y, "<"); | ||||
|             } | ||||
|  | ||||
|             canvas_draw_str(canvas, 80, item_text_y, string_get_cstr(item->current_value_text)); | ||||
|             canvas_draw_str_aligned( | ||||
|                 canvas, | ||||
|                 (115 + 73) / 2 + 1, | ||||
|                 item_text_y, | ||||
|                 AlignCenter, | ||||
|                 AlignBottom, | ||||
|                 string_get_cstr(item->current_value_text)); | ||||
|  | ||||
|             if(item->current_value_index < (item->values_count - 1)) { | ||||
|                 canvas_draw_str(canvas, 115, item_text_y, ">"); | ||||
| @@ -147,6 +153,27 @@ static bool variable_item_list_input_callback(InputEvent* event, void* context) | ||||
|         default: | ||||
|             break; | ||||
|         } | ||||
|     } else if(event->type == InputTypeRepeat) { | ||||
|         switch(event->key) { | ||||
|         case InputKeyUp: | ||||
|             consumed = true; | ||||
|             variable_item_list_process_up(variable_item_list); | ||||
|             break; | ||||
|         case InputKeyDown: | ||||
|             consumed = true; | ||||
|             variable_item_list_process_down(variable_item_list); | ||||
|             break; | ||||
|         case InputKeyLeft: | ||||
|             consumed = true; | ||||
|             variable_item_list_process_left(variable_item_list); | ||||
|             break; | ||||
|         case InputKeyRight: | ||||
|             consumed = true; | ||||
|             variable_item_list_process_right(variable_item_list); | ||||
|             break; | ||||
|         default: | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     return consumed; | ||||
|   | ||||
| @@ -2,6 +2,11 @@ | ||||
| #include <furi_hal.h> | ||||
| #include <notification/notification_messages.h> | ||||
|  | ||||
| typedef struct { | ||||
|     osThreadId_t thread; | ||||
|  | ||||
| } PowerObserverSrv; | ||||
|  | ||||
| const NotificationMessage message_green_110 = { | ||||
|     .type = NotificationMessageTypeLedGreen, | ||||
|     .data.led.value = 110, | ||||
| @@ -14,20 +19,58 @@ static const NotificationSequence sequence_overconsumption = { | ||||
|     NULL, | ||||
| }; | ||||
|  | ||||
| typedef enum { | ||||
|     EventReset = (1 << 0), | ||||
|     EventRequest = (1 << 1), | ||||
| } UsbEvent; | ||||
|  | ||||
| static void usb_state_callback(FuriHalUsbStateEvent state, void* context) { | ||||
|     PowerObserverSrv* srv = (PowerObserverSrv*)(context); | ||||
|     if(state == FuriHalUsbStateEventReset) { | ||||
|         osThreadFlagsSet(srv->thread, EventReset); | ||||
|     } else if(state == FuriHalUsbStateEventDescriptorRequest) { | ||||
|         osThreadFlagsSet(srv->thread, EventRequest); | ||||
|     } | ||||
| } | ||||
|  | ||||
| int32_t power_observer_srv(void* p) { | ||||
|     NotificationApp* notifications = furi_record_open("notification"); | ||||
|     PowerObserverSrv* srv = furi_alloc(sizeof(PowerObserverSrv)); | ||||
|     srv->thread = osThreadGetId(); | ||||
|  | ||||
|     const float overconsumption_limit = 0.03f; | ||||
|     bool usb_request_pending = false; | ||||
|     uint8_t usb_wait_time = 0; | ||||
|  | ||||
|     furi_hal_usb_set_state_callback(usb_state_callback, srv); | ||||
|  | ||||
|     while(true) { | ||||
|         float current = -furi_hal_power_get_battery_current(FuriHalPowerICFuelGauge); | ||||
|  | ||||
|         if(current >= overconsumption_limit) { | ||||
|             notification_message_block(notifications, &sequence_overconsumption); | ||||
|         uint32_t flags = osThreadFlagsWait(EventReset | EventRequest, osFlagsWaitAny, 500); | ||||
|         if((flags & osFlagsError) == 0) { | ||||
|             if(flags & EventReset) { | ||||
|                 usb_request_pending = true; | ||||
|                 usb_wait_time = 0; | ||||
|             } | ||||
|             if(flags & EventRequest) { | ||||
|                 usb_request_pending = false; | ||||
|             } | ||||
|         } else if(usb_request_pending) { | ||||
|             usb_wait_time++; | ||||
|             if(usb_wait_time > 4) { | ||||
|                 furi_hal_usb_reinit(); | ||||
|                 usb_request_pending = false; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         delay(1000); | ||||
|         float current = -furi_hal_power_get_battery_current(FuriHalPowerICFuelGauge); | ||||
|         if(current > overconsumption_limit) { | ||||
|             notification_message_block(notifications, &sequence_overconsumption); | ||||
|         } | ||||
|         if(furi_hal_power_is_otg_enabled()) { | ||||
|             furi_hal_power_check_otg_status(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     free(srv); | ||||
|     return 0; | ||||
| } | ||||
| } | ||||
|   | ||||
| @@ -190,7 +190,7 @@ static int32_t u2f_hid_worker(void* context) { | ||||
|  | ||||
|     FURI_LOG_D(WORKER_TAG, "Init"); | ||||
|  | ||||
|     UsbInterface* usb_mode_prev = furi_hal_usb_get_config(); | ||||
|     FuriHalUsbInterface* usb_mode_prev = furi_hal_usb_get_config(); | ||||
|     furi_hal_usb_set_config(&usb_hid_u2f); | ||||
|  | ||||
|     u2f_hid->lock_timer = osTimerNew(u2f_hid_lock_timeout_callback, osTimerOnce, u2f_hid, NULL); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user