2024-11-28 02:11 PM - last edited on 2024-11-29 07:45 AM by SofLit
I am supposed to be receiving 8-bit data with even parity. The blocks are defined with a header of 'F0', this is S.Bus data if anyone knows that that is. I setup a simple program that just does receive data. I get data but nowhere does it show an 'F0'. Am I supposed to use 'LL_USART_ReceiveData8' or 'LL_USART_ReceiveData9' to read this data? Is the parity supposed to be read with the data and discarded? It's not at all clear how the parity is handled.
2024-11-28 11:56 PM - edited 2024-11-28 11:57 PM
Hello,
You posted your thread in STM32CubeIDE (MCUs) which is not the right forum board. I moved it to STM32 MCUs Products.
Could you please also provide the MCU part number you are using?
2024-11-29 07:36 AM - edited 2024-11-29 07:38 AM
Sorry. I am using STM32G030C6. My code is
while (1)
{
int i = 0;
while(i < 500)
{
if(LL_USART_IsActiveFlag_FE(USART2))
{
LL_USART_ClearFlag_FE(USART2);
FE++;
}
if(LL_USART_IsActiveFlag_PE(USART2))
{
LL_USART_ClearFlag_PE(USART2);
PE++;
}
if(LL_USART_IsActiveFlag_NE(USART2))
{
LL_USART_ClearFlag_NE(USART2);
NE++;
}
if(LL_USART_IsActiveFlag_ORE(USART2))
{
LL_USART_ClearFlag_ORE(USART2);
ORE++;
}
if(LL_USART_IsActiveFlag_IDLE(USART2))
{
LL_USART_ClearFlag_IDLE(USART2);
IDLE++;
}
if(LL_USART_IsActiveFlag_RXNE_RXFNE(USART2))
{
// array[i] = LL_USART_ReceiveData8(USART2);
array[i] = LL_USART_ReceiveData9(USART2);
i++;
}
}
while(1) {};
}
2024-11-29 08:04 AM
> I get data but nowhere does it show an 'F0'.
I had to read it up, to be honest.
But yes, you should read the header value. Although the first hit I found suggests it is "0x0F", and not "0xF0".
Additionally, S.Bus requires 2 stop bits, and the uncommon baudrate of 100.000 bps.
Perhaps you can share the UART init code.
> Is the parity supposed to be read with the data and discarded? It's not at all clear how the parity is handled.
If the received parity value doesn't match, the PE error should trigger -> a.k.a. "parity error". In this case, the RD register values is usually not updated, and invalid.
2024-11-29 09:57 AM - edited 2024-11-29 10:09 AM
Here is the init code. The funny thing is that I do not see any 'IDLE"s. I should use these to delimit the blocks.
LL_USART_InitTypeDef USART_InitStruct = {0};
LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
/* Peripheral clock enable */
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_USART2);
LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOA);
/**USART2 GPIO Configuration
PA2 ------> USART2_TX
*/
GPIO_InitStruct.Pin = LL_GPIO_PIN_2;
GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_OPENDRAIN;
GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
GPIO_InitStruct.Alternate = LL_GPIO_AF_1;
LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* USER CODE BEGIN USART2_Init 1 */
/* USER CODE END USART2_Init 1 */
USART_InitStruct.PrescalerValue = LL_USART_PRESCALER_DIV1;
USART_InitStruct.BaudRate = 100000;
USART_InitStruct.DataWidth = LL_USART_DATAWIDTH_9B;
USART_InitStruct.StopBits = LL_USART_STOPBITS_2;
USART_InitStruct.Parity = LL_USART_PARITY_EVEN;
USART_InitStruct.TransferDirection = LL_USART_DIRECTION_RX;
USART_InitStruct.OverSampling = LL_USART_OVERSAMPLING_16;
LL_USART_Init(USART2, &USART_InitStruct);
LL_USART_DisableDMADeactOnRxErr(USART2);
LL_USART_ConfigHalfDuplexMode(USART2);
/* USER CODE BEGIN WKUPType USART2 */
/* USER CODE END WKUPType USART2 */
LL_USART_Enable(USART2);
/* Polling USART2 initialisation */
while((!(LL_USART_IsActiveFlag_TEACK(USART2))) || (!(LL_USART_IsActiveFlag_REACK(USART2))))
{
}
Also, I enable the receive bit just before entering the loop. I should point out that I am getting a lot of parity errors (250) and framing errors (147). These are pretty consistent run to run.
2024-12-01 06:39 AM
Is this all the init code ?
Being accustomed to either SPL code or direct access, the init for PA2 looks strange. What alternate function (many pins of F3/F4 MCUs I frequently use have 7 alternate functions). And pull-up & OD at the same time ?
But most important, is there no Rx pin initialisation ?
If in doubt, I always check the respective reference manual section, and observe the peripheral register settings in a debugger.
2024-12-01 10:04 AM
Yes, this is all init code as generated by MX. For some reason, MX treats alternate function inputs as outputs. I don't know what you mean by Rx pin initialization. If you look at the code, the last entry to GPIO init function is the alternate function code of 1.
2024-12-02 12:23 AM
> I get data but nowhere does it show an 'F0'.
And what does it show?
Is there any external pullup? The internal is nominally 40kOhm, it may not be enough to produce clean edges.
The UART is here set to HalfDuplex, and in that case it uses the Tx pin as the single IO pin.
JW
2024-12-02 05:27 AM
> The UART is here set to HalfDuplex, and in that case it uses the Tx pin as the single IO pin.
I suspected that much.
But I have never used such half-duplex UART mode, especially not on the C0 devices.
2024-12-02 05:32 AM
> I am using STM32G030C6. My code is ...
If you debug the code, can you see any of the error counters go up ?
And on a related note ...
Serial communication, including the UART, can be tricky to debug.
The debugger might clear receive flags, and thus change the code execution path.