-
Notifications
You must be signed in to change notification settings - Fork 29
Description
Simplicity SDK version: 2024.12.2 but seems to be the case for sisdk-2025.6 as well.
We are trying to enable hardware flow control on the EUSART perihperal of a EFR32FG28 MCU. We have the flow control working but one of the UART devices we are using is a bit non-compliant in the sense that it sends a few more bytes before respecting the CTS/RTS line. This causes us to lose some bytes, because the internal EUSART FIFO is filled but the device sends more bytes.
I can see in the documentation (at least on the EFR32FG28 chips), the EUSART has a RTSRXFW value in the CFG1 register, that allows you to "preshoot" the RTS signal. This way, RTS gets asserted before the FIFO buffers is fully filled, which allows us to not lose bytes even if the device ignores the CTS signal for a few bytes.
The problem is that emlib provides no interface for configuring that register value, neither in EUSART_UartInit_TypeDef nor EUSART_AdvancedInit_TypeDef. Also, you can't set that value manually.
You can't write to the CFG1 register after initialization, as you're not allowed to edit the CFGx registers post-init. You also can't write to the CFG1 before initialization, since EUSART_UartInitHf() clears the CFGx registers before writing to them.
As a workaround, you can sneak the desired RTSRXFW value into TxFifoWatermark. This works because TxFifoWatermark is an enum, not a bitfield, so we have room for it. Also, the value in TxFifoWatermark gets directly written into CFG1 and it's right next to the desired RTSRXFW value. However, this is obviously a hack and realisitcally the option to configure RTSRXFW should be provided in the EUSART_AdvancedInit_TypeDef structure.
EUSART_AdvancedInit_TypeDef advancedC = EUSART_ADVANCED_INIT_DEFAULT;
advancedC.hwFlowControl = eusartHwFlowControlCtsAndRts;
// Evil hack to set the `RTSRXFW` bits in `TxFifoWatermark`
advancedC.TxFifoWatermark = static_cast<EUSART_TxFifoWatermark_TypeDef>
(advancedC.TxFifoWatermark | EUSART_CFG1_RTSRXFW_TENFRAMES);
EUSART_UartInit_TypeDef c = EUSART_UART_INIT_DEFAULT_HF;
c.baudrate = config.baudRate;
c.parity = eusartNoParity;
c.advancedSettings = &advancedC;
// We can't write to CFG1 here or before becuase EUSART_UartInitHf() clears CFG1
EUSART_UartInitHf(reinterpret_cast<EUSART_TypeDef *>(handle), &c);
// We can't write to CFG1 here because EUSART is now initialized and CFGx writes cause a hard fault