From 17b122990f35998d412bf2769467e5cd4b192311 Mon Sep 17 00:00:00 2001 From: Skorpionm <85568270+Skorpionm@users.noreply.github.com> Date: Tue, 19 Dec 2023 18:13:37 +0400 Subject: [PATCH] USART Bridge: added support for software control of DE/RE pins (#3280) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * USART Bridge: added support for software control of DE/RE pins * USART Bridge: fix syntax * UsbUsartBridge: add TODO ticket * UsbUsartBridge: add second TODO ticket * GpioUartBridge: human readable configuration * GpioUartBridge: rename `Soft DE/RE` to `DE/RE Pin` * GpioUartBridge: push pull for DE/RE pin Co-authored-by: あく --- .../gpio/scenes/gpio_scene_usb_uart_config.c | 17 +++++++++ applications/main/gpio/usb_uart_bridge.c | 35 +++++++++++++++++++ applications/main/gpio/usb_uart_bridge.h | 1 + 3 files changed, 53 insertions(+) diff --git a/applications/main/gpio/scenes/gpio_scene_usb_uart_config.c b/applications/main/gpio/scenes/gpio_scene_usb_uart_config.c index e2ab662644..8fcacd4039 100644 --- a/applications/main/gpio/scenes/gpio_scene_usb_uart_config.c +++ b/applications/main/gpio/scenes/gpio_scene_usb_uart_config.c @@ -27,6 +27,7 @@ static const uint32_t baudrate_list[] = { 460800, 921600, }; +static const char* software_de_re[] = {"None", "4"}; bool gpio_scene_usb_uart_cfg_on_event(void* context, SceneManagerEvent event) { GpioApp* app = context; @@ -84,6 +85,17 @@ static void line_port_cb(VariableItem* item) { view_dispatcher_send_custom_event(app->view_dispatcher, GpioUsbUartEventConfigSet); } +static void line_software_de_re_cb(VariableItem* item) { + GpioApp* app = variable_item_get_context(item); + furi_assert(app); + uint8_t index = variable_item_get_current_value_index(item); + + variable_item_set_current_value_text(item, software_de_re[index]); + + app->usb_uart_cfg->software_de_re = index; + view_dispatcher_send_custom_event(app->view_dispatcher, GpioUsbUartEventConfigSet); +} + static void line_flow_cb(VariableItem* item) { GpioApp* app = variable_item_get_context(item); furi_assert(app); @@ -155,6 +167,11 @@ void gpio_scene_usb_uart_cfg_on_enter(void* context) { app->var_item_flow = item; line_ensure_flow_invariant(app); + item = variable_item_list_add( + var_item_list, "DE/RE Pin", COUNT_OF(software_de_re), line_software_de_re_cb, app); + variable_item_set_current_value_index(item, app->usb_uart_cfg->software_de_re); + variable_item_set_current_value_text(item, software_de_re[app->usb_uart_cfg->software_de_re]); + variable_item_list_set_selected_item( var_item_list, scene_manager_get_scene_state(app->scene_manager, GpioAppViewUsbUartCfg)); diff --git a/applications/main/gpio/usb_uart_bridge.c b/applications/main/gpio/usb_uart_bridge.c index 9bc759dc89..366c5cdc4e 100644 --- a/applications/main/gpio/usb_uart_bridge.c +++ b/applications/main/gpio/usb_uart_bridge.c @@ -6,11 +6,16 @@ #include #include +//TODO: FL-3276 port to new USART API +#include +#include + #define USB_CDC_PKT_LEN CDC_DATA_SZ #define USB_UART_RX_BUF_SIZE (USB_CDC_PKT_LEN * 5) #define USB_CDC_BIT_DTR (1 << 0) #define USB_CDC_BIT_RTS (1 << 1) +#define USB_USART_DE_RE_PIN &gpio_ext_pa4 static const GpioPin* flow_pins[][2] = { {&gpio_ext_pa7, &gpio_ext_pa6}, // 2, 3 @@ -247,6 +252,17 @@ static int32_t usb_uart_worker(void* context) { usb_uart->cfg.flow_pins = usb_uart->cfg_new.flow_pins; events |= WorkerEvtCtrlLineSet; } + if(usb_uart->cfg.software_de_re != usb_uart->cfg_new.software_de_re) { + usb_uart->cfg.software_de_re = usb_uart->cfg_new.software_de_re; + if(usb_uart->cfg.software_de_re != 0) { + furi_hal_gpio_write(USB_USART_DE_RE_PIN, true); + furi_hal_gpio_init( + USB_USART_DE_RE_PIN, GpioModeOutputPushPull, GpioPullNo, GpioSpeedMedium); + } else { + furi_hal_gpio_init( + USB_USART_DE_RE_PIN, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + } + } api_lock_unlock(usb_uart->cfg_lock); } if(events & WorkerEvtLineCfgSet) { @@ -260,6 +276,8 @@ static int32_t usb_uart_worker(void* context) { usb_uart_vcp_deinit(usb_uart, usb_uart->cfg.vcp_ch); usb_uart_serial_deinit(usb_uart, usb_uart->cfg.uart_ch); + furi_hal_gpio_init(USB_USART_DE_RE_PIN, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + if(usb_uart->cfg.flow_pins != 0) { furi_hal_gpio_init_simple(flow_pins[usb_uart->cfg.flow_pins - 1][0], GpioModeAnalog); furi_hal_gpio_init_simple(flow_pins[usb_uart->cfg.flow_pins - 1][1], GpioModeAnalog); @@ -298,7 +316,24 @@ static int32_t usb_uart_tx_thread(void* context) { if(len > 0) { usb_uart->st.tx_cnt += len; + + if(usb_uart->cfg.software_de_re != 0) + furi_hal_gpio_write(USB_USART_DE_RE_PIN, false); + furi_hal_uart_tx(usb_uart->cfg.uart_ch, data, len); + + if(usb_uart->cfg.software_de_re != 0) { + //TODO: FL-3276 port to new USART API + if(usb_uart->cfg.uart_ch == FuriHalUartIdUSART1) { + while(!LL_USART_IsActiveFlag_TC(USART1)) + ; + } else if(usb_uart->cfg.uart_ch == FuriHalUartIdLPUART1) { + while(!LL_LPUART_IsActiveFlag_TC(LPUART1)) + ; + } + + furi_hal_gpio_write(USB_USART_DE_RE_PIN, true); + } } } } diff --git a/applications/main/gpio/usb_uart_bridge.h b/applications/main/gpio/usb_uart_bridge.h index b456c3cc4e..ebb103f548 100644 --- a/applications/main/gpio/usb_uart_bridge.h +++ b/applications/main/gpio/usb_uart_bridge.h @@ -11,6 +11,7 @@ typedef struct { uint8_t flow_pins; uint8_t baudrate_mode; uint32_t baudrate; + uint8_t software_de_re; } UsbUartConfig; typedef struct {