diff --git a/targets/f7/api_symbols.csv b/targets/f7/api_symbols.csv index 1168a6eea53..aeca775198b 100644 --- a/targets/f7/api_symbols.csv +++ b/targets/f7/api_symbols.csv @@ -1628,6 +1628,7 @@ Function,+,furi_hal_serial_async_rx,uint8_t,FuriHalSerialHandle* Function,+,furi_hal_serial_async_rx_available,_Bool,FuriHalSerialHandle* Function,+,furi_hal_serial_async_rx_start,void,"FuriHalSerialHandle*, FuriHalSerialAsyncRxCallback, void*, _Bool" Function,+,furi_hal_serial_async_rx_stop,void,FuriHalSerialHandle* +Function,+,furi_hal_serial_configure_flow_control,void,"FuriHalSerialHandle*, _Bool, _Bool" Function,+,furi_hal_serial_configure_framing,void,"FuriHalSerialHandle*, FuriHalSerialDataBits, FuriHalSerialParity, FuriHalSerialStopBits" Function,+,furi_hal_serial_control_acquire,FuriHalSerialHandle*,FuriHalSerialId Function,+,furi_hal_serial_control_deinit,void, diff --git a/targets/f7/furi_hal/furi_hal_serial.c b/targets/f7/furi_hal/furi_hal_serial.c index 8ad9794a850..adad1ad9af9 100644 --- a/targets/f7/furi_hal/furi_hal_serial.c +++ b/targets/f7/furi_hal/furi_hal_serial.c @@ -691,6 +691,58 @@ void furi_hal_serial_configure_framing( } } +static void furi_hal_serial_usart_configure_flow_control(bool rts, bool cts) { + uint32_t flow_control; + if(rts && cts) { + flow_control = LL_USART_HWCONTROL_RTS_CTS; + } else if(rts) { + flow_control = LL_USART_HWCONTROL_RTS; + } else if(cts) { + flow_control = LL_USART_HWCONTROL_CTS; + } else { + flow_control = LL_USART_HWCONTROL_NONE; + } + LL_USART_SetHWFlowCtrl(USART1, flow_control); +} + +static void furi_hal_serial_lpuart_configure_flow_control(bool rts, bool cts) { + uint32_t flow_control; + if(rts && cts) { + flow_control = LL_LPUART_HWCONTROL_RTS_CTS; + } else if(rts) { + flow_control = LL_LPUART_HWCONTROL_RTS; + } else if(cts) { + flow_control = LL_LPUART_HWCONTROL_CTS; + } else { + flow_control = LL_LPUART_HWCONTROL_NONE; + } + LL_USART_SetHWFlowCtrl(LPUART1, flow_control); +} + +void furi_hal_serial_configure_flow_control(FuriHalSerialHandle* handle, bool rts, bool cts) { + furi_check(handle); + + if(handle->id == FuriHalSerialIdUsart) { + if(LL_USART_IsEnabled(USART1)) { + // Wait for transfer complete flag + while(!LL_USART_IsActiveFlag_TC(USART1)) + ; + LL_USART_Disable(USART1); + furi_hal_serial_usart_configure_flow_control(rts, cts); + LL_USART_Enable(USART1); + } + } else if(handle->id == FuriHalSerialIdLpuart) { + if(LL_LPUART_IsEnabled(LPUART1)) { + // Wait for transfer complete flag + while(!LL_LPUART_IsActiveFlag_TC(LPUART1)) + ; + LL_LPUART_Disable(LPUART1); + furi_hal_serial_lpuart_configure_flow_control(rts, cts); + LL_LPUART_Enable(LPUART1); + } + } +} + void furi_hal_serial_deinit(FuriHalSerialHandle* handle) { furi_check(handle); furi_hal_serial_async_rx_configure(handle, NULL, NULL); diff --git a/targets/f7/furi_hal/furi_hal_serial.h b/targets/f7/furi_hal/furi_hal_serial.h index ca8860a60fc..1deee017b83 100644 --- a/targets/f7/furi_hal/furi_hal_serial.h +++ b/targets/f7/furi_hal/furi_hal_serial.h @@ -80,6 +80,15 @@ void furi_hal_serial_configure_framing( FuriHalSerialParity parity, FuriHalSerialStopBits stop_bits); +/** + * @brief Configures hardware flow control of a serial interface + * + * @param handle Serial handle + * @param rts Whether to enable RTS (Request To Send) + * @param cts Whether to enable CTS (Clear To Send) + */ +void furi_hal_serial_configure_flow_control(FuriHalSerialHandle* handle, bool rts, bool cts); + /** Transmits data in semi-blocking mode * * Fills transmission pipe with data, returns as soon as all bytes from buffer