Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions targets/f7/api_symbols.csv
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
52 changes: 52 additions & 0 deletions targets/f7/furi_hal/furi_hal_serial.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
9 changes: 9 additions & 0 deletions targets/f7/furi_hal/furi_hal_serial.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down