Przeglądaj źródła

Allow pins 0 and 1 as RTS/DTR for USB UART Bridge (#1864)

* Allow pins 0 and 1 as RTS/DTR for USB UART Bridge
* add logic to gpio_scene_usb_uart_config, fix flow_pins
* fixing count of pins
* disable PC0,PC1 RTS/DTR when using LPUART
* add logic to ensure flow pins dont overlap with uart lines

Co-authored-by: あく <alleteam@gmail.com>
Kevin Kwok 3 lat temu
rodzic
commit
72713d6f4e

+ 1 - 0
applications/main/gpio/gpio_app_i.h

@@ -24,6 +24,7 @@ struct GpioApp {
     Widget* widget;
     Widget* widget;
 
 
     VariableItemList* var_item_list;
     VariableItemList* var_item_list;
+    VariableItem* var_item_flow;
     GpioTest* gpio_test;
     GpioTest* gpio_test;
     GpioUsbUart* gpio_usb_uart;
     GpioUsbUart* gpio_usb_uart;
     UsbUartBridge* usb_uart_bridge;
     UsbUartBridge* usb_uart_bridge;

+ 24 - 2
applications/main/gpio/scenes/gpio_scene_usb_uart_config.c

@@ -13,7 +13,7 @@ static UsbUartConfig* cfg_set;
 
 
 static const char* vcp_ch[] = {"0 (CLI)", "1"};
 static const char* vcp_ch[] = {"0 (CLI)", "1"};
 static const char* uart_ch[] = {"13,14", "15,16"};
 static const char* uart_ch[] = {"13,14", "15,16"};
-static const char* flow_pins[] = {"None", "2,3", "6,7"};
+static const char* flow_pins[] = {"None", "2,3", "6,7", "16,15"};
 static const char* baudrate_mode[] = {"Host"};
 static const char* baudrate_mode[] = {"Host"};
 static const uint32_t baudrate_list[] = {
 static const uint32_t baudrate_list[] = {
     2400,
     2400,
@@ -33,6 +33,24 @@ bool gpio_scene_usb_uart_cfg_on_event(void* context, SceneManagerEvent event) {
     return false;
     return false;
 }
 }
 
 
+void line_ensure_flow_invariant(GpioApp* app) {
+    // GPIO pins PC0, PC1 (16,15) are unavailable for RTS/DTR when LPUART is
+    // selected. This function enforces that invariant by resetting flow_pins
+    // to None if it is configured to 16,15 when LPUART is selected.
+
+    uint8_t available_flow_pins = cfg_set->uart_ch == FuriHalUartIdLPUART1 ? 3 : 4;
+    VariableItem* item = app->var_item_flow;
+    variable_item_set_values_count(item, available_flow_pins);
+
+    if(cfg_set->flow_pins >= available_flow_pins) {
+        cfg_set->flow_pins = 0;
+        usb_uart_set_config(app->usb_uart_bridge, cfg_set);
+
+        variable_item_set_current_value_index(item, cfg_set->flow_pins);
+        variable_item_set_current_value_text(item, flow_pins[cfg_set->flow_pins]);
+    }
+}
+
 static void line_vcp_cb(VariableItem* item) {
 static void line_vcp_cb(VariableItem* item) {
     GpioApp* app = variable_item_get_context(item);
     GpioApp* app = variable_item_get_context(item);
     uint8_t index = variable_item_get_current_value_index(item);
     uint8_t index = variable_item_get_current_value_index(item);
@@ -54,6 +72,7 @@ static void line_port_cb(VariableItem* item) {
     else if(index == 1)
     else if(index == 1)
         cfg_set->uart_ch = FuriHalUartIdLPUART1;
         cfg_set->uart_ch = FuriHalUartIdLPUART1;
     usb_uart_set_config(app->usb_uart_bridge, cfg_set);
     usb_uart_set_config(app->usb_uart_bridge, cfg_set);
+    line_ensure_flow_invariant(app);
 }
 }
 
 
 static void line_flow_cb(VariableItem* item) {
 static void line_flow_cb(VariableItem* item) {
@@ -116,9 +135,12 @@ void gpio_scene_usb_uart_cfg_on_enter(void* context) {
     variable_item_set_current_value_index(item, cfg_set->uart_ch);
     variable_item_set_current_value_index(item, cfg_set->uart_ch);
     variable_item_set_current_value_text(item, uart_ch[cfg_set->uart_ch]);
     variable_item_set_current_value_text(item, uart_ch[cfg_set->uart_ch]);
 
 
-    item = variable_item_list_add(var_item_list, "RTS/DTR Pins", 3, line_flow_cb, app);
+    item = variable_item_list_add(
+        var_item_list, "RTS/DTR Pins", COUNT_OF(flow_pins), line_flow_cb, app);
     variable_item_set_current_value_index(item, cfg_set->flow_pins);
     variable_item_set_current_value_index(item, cfg_set->flow_pins);
     variable_item_set_current_value_text(item, flow_pins[cfg_set->flow_pins]);
     variable_item_set_current_value_text(item, flow_pins[cfg_set->flow_pins]);
+    app->var_item_flow = item;
+    line_ensure_flow_invariant(app);
 
 
     variable_item_list_set_selected_item(
     variable_item_list_set_selected_item(
         var_item_list, scene_manager_get_scene_state(app->scene_manager, GpioAppViewUsbUartCfg));
         var_item_list, scene_manager_get_scene_state(app->scene_manager, GpioAppViewUsbUartCfg));

+ 1 - 0
applications/main/gpio/usb_uart_bridge.c

@@ -14,6 +14,7 @@
 static const GpioPin* flow_pins[][2] = {
 static const GpioPin* flow_pins[][2] = {
     {&gpio_ext_pa7, &gpio_ext_pa6}, // 2, 3
     {&gpio_ext_pa7, &gpio_ext_pa6}, // 2, 3
     {&gpio_ext_pb2, &gpio_ext_pc3}, // 6, 7
     {&gpio_ext_pb2, &gpio_ext_pc3}, // 6, 7
+    {&gpio_ext_pc0, &gpio_ext_pc1}, // 16, 15
 };
 };
 
 
 typedef enum {
 typedef enum {

+ 4 - 0
applications/services/gui/modules/variable_item_list.c

@@ -396,6 +396,10 @@ void variable_item_set_current_value_index(VariableItem* item, uint8_t current_v
     item->current_value_index = current_value_index;
     item->current_value_index = current_value_index;
 }
 }
 
 
+void variable_item_set_values_count(VariableItem* item, uint8_t values_count) {
+    item->values_count = values_count;
+}
+
 void variable_item_set_current_value_text(VariableItem* item, const char* current_value_text) {
 void variable_item_set_current_value_text(VariableItem* item, const char* current_value_text) {
     furi_string_set(item->current_value_text, current_value_text);
     furi_string_set(item->current_value_text, current_value_text);
 }
 }

+ 7 - 0
applications/services/gui/modules/variable_item_list.h

@@ -81,6 +81,13 @@ uint8_t variable_item_list_get_selected_item_index(VariableItemList* variable_it
  */
  */
 void variable_item_set_current_value_index(VariableItem* item, uint8_t current_value_index);
 void variable_item_set_current_value_index(VariableItem* item, uint8_t current_value_index);
 
 
+/** Set number of values for item
+ *
+ * @param      item                 VariableItem* instance
+ * @param      values_count         The new values count
+ */
+void variable_item_set_values_count(VariableItem* item, uint8_t values_count);
+
 /** Set item current selected text
 /** Set item current selected text
  *
  *
  * @param      item                VariableItem* instance
  * @param      item                VariableItem* instance