STM32F401 UART

For general Flowcode discussion that does not belong in the other sections.
Alan_37
Posts: 125
http://meble-kuchenne.info.pl
Joined: Thu Dec 03, 2020 7:23 pm
Has thanked: 37 times
Been thanked: 17 times

STM32F401 UART

Post by Alan_37 »

Hi , I am working with Flowcode V9 Target STM32f401 and i have this problem where sometimes UART stops responding
and only an MCU restart can bring it back .

After some investigation I found out that this happens if i try to transmit data and at the same time Data is recived .

So to investigate further I added the following C-code and send GLOBAL_STR out from Uart 2
it resulted in the UART being RX Busy all the time even when there is no data on RX , RX voltage is 3.3V and the
Interrupt is not begin triggered , it only change to READY if I disable the RX interrupt I don't know if this is normal behavior .


Code: Select all

// Check UART status
        switch (HAL_UART_GetState(&MX_UART_NUMBER_1)) {
            case HAL_UART_STATE_RESET:
                sprintf(FCV_GLOBAL_STR, "UART State: RESET\r\n");
                break;

            case HAL_UART_STATE_READY:
                sprintf(FCV_GLOBAL_STR, "UART State: READY\r\n");
                break;

            case HAL_UART_STATE_BUSY:
                sprintf(FCV_GLOBAL_STR, "UART State: BUSY\r\n");
                break;

            case HAL_UART_STATE_BUSY_TX:
                sprintf(FCV_GLOBAL_STR, "UART State: BUSY TX\r\n");
                break;

            case HAL_UART_STATE_BUSY_RX:
                sprintf(FCV_GLOBAL_STR, "UART State: BUSY RX\r\n");
                break;

            case HAL_UART_STATE_BUSY_TX_RX:
                sprintf(FCV_GLOBAL_STR, "UART State: BUSY TX RX\r\n");
                break;

            case HAL_UART_STATE_TIMEOUT:
                sprintf(FCV_GLOBAL_STR, "UART State: TIMEOUT\r\n");
                break;

            case HAL_UART_STATE_ERROR:
                sprintf(FCV_GLOBAL_STR, "UART State: ERROR\r\n");
                break;

            default:
                sprintf(FCV_GLOBAL_STR, "UART State: Unknown\r\n");
                break;
        }


Also would like to point out that the UART in software mode will not work , ( will only transmit data but the RX interrupt will not get
triggered .


Anyone had the same issues ?

Alan_37
Posts: 125
Joined: Thu Dec 03, 2020 7:23 pm
Has thanked: 37 times
Been thanked: 17 times

Re: STM32F401 UART

Post by Alan_37 »

hello again ,

Are these problems fixed in V10 ? cos I was considering to upgrade

Steve-Matrix
Matrix Staff
Posts: 1253
Joined: Sat Dec 05, 2020 10:32 am
Has thanked: 167 times
Been thanked: 277 times

Re: STM32F401 UART

Post by Steve-Matrix »

If you want me to check, PM your V9 project to me and I will recompile it using Flowcode V10. I'll send you back the compiled file and you can load that into your hardware to see if it works ok.

Alan_37
Posts: 125
Joined: Thu Dec 03, 2020 7:23 pm
Has thanked: 37 times
Been thanked: 17 times

Re: STM32F401 UART

Post by Alan_37 »

Hi Steve ,

Thanks for your reply ,

It's been a wile since V9 get any updates or fixes so I presume that the resources are concentrated
on V10 only . if that's the case will end up upgrading again anyways :)

I don't think that a 1 time compile will do much for me , I have V10 already installed on my pc
and logged in with my account , how about a trial period I think 15 days would be enough for me to decide .

Steve-Matrix
Matrix Staff
Posts: 1253
Joined: Sat Dec 05, 2020 10:32 am
Has thanked: 167 times
Been thanked: 277 times

Re: STM32F401 UART

Post by Steve-Matrix »

We no longer offer a trial. Instead, we have made most features of Flowcode v10 free to use (for hobbyists and for evaluation). It is limited to produce code for certain devices though. But all the newer features since v9 are available to use.

Alan_37
Posts: 125
Joined: Thu Dec 03, 2020 7:23 pm
Has thanked: 37 times
Been thanked: 17 times

Re: STM32F401 UART

Post by Alan_37 »

OK

I have upgraded to V10 just now will see :)

Alan_37
Posts: 125
Joined: Thu Dec 03, 2020 7:23 pm
Has thanked: 37 times
Been thanked: 17 times

Re: STM32F401 UART

Post by Alan_37 »

Hello Again ,

So is the same thing on V10 and interrupt in software mode also will not trigger .

But was thinking that the problem might be that the project I am building is using both
Uarts and the MCU has only 1 core so something is going wrong when for example
the 2 Uarts trigger the Interrupt at the same time .

So what I would need help on is to use the UART in a different way ( polling approach) .

I need that the UART will store the data in a buffer without triggering any
interrupts , then when the MCU is ready to process the Uart Data will go check if
there is Data in the buffer and if yes process it .

I believe this will require a different init and will most likely need to be done with a C block

the following is what I could find but I don't know how adopt for Flowcode

Code: Select all

#include "stm32f4xx_hal.h"

#define BUFFER_SIZE 128

UART_HandleTypeDef huart2;
uint8_t rx_buffer[BUFFER_SIZE];
volatile uint8_t rx_buffer_head = 0;
volatile uint8_t rx_buffer_tail = 0;

void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART2_UART_Init(void);

int main(void) {
    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();
    MX_USART2_UART_Init();

    while (1) {
        // Check if there is data in the UART receive buffer
        if (rx_buffer_head != rx_buffer_tail) {
            // Process the data
            uint8_t data = rx_buffer[rx_buffer_tail];
            // Your processing logic here
          
            // Move the buffer tail pointer to the next position
            rx_buffer_tail = (rx_buffer_tail + 1) % BUFFER_SIZE;
        }
    }
}

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
    // This callback will be called when a byte is received
    // You can leave it empty as we are not using interrupts for UART

    // Instead, handle the received data in the main loop
    if (rx_buffer_head != ((rx_buffer_tail - 1 + BUFFER_SIZE) % BUFFER_SIZE)) {
        // Buffer not full, store the received byte
        rx_buffer[rx_buffer_head] = huart->Instance->DR;
        // Move the buffer head pointer to the next position
        rx_buffer_head = (rx_buffer_head + 1) % BUFFER_SIZE;
    }
}

// USART2 Initialization Function
static void MX_USART2_UART_Init(void) {
    huart2.Instance = USART2;
    huart2.Init.BaudRate = 9600;
    huart2.Init.WordLength = UART_WORDLENGTH_8B;
    huart2.Init.StopBits = UART_STOPBITS_1;
    huart2.Init.Parity = UART_PARITY_NONE;
    huart2.Init.Mode = UART_MODE_RX;
    huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
    huart2.Init.OverSampling = UART_OVERSAMPLING_16;
    if (HAL_UART_Init(&huart2) != HAL_OK) {
        Error_Handler();
    }
}
What i Would need is a C block that initializes the Uart and another one that check the buffer
and writes to a variable how many bytes there is in the buffer so can decide if process it or not

Any one can help with this please ?

LeighM
Valued Contributor
Posts: 401
Joined: Mon Dec 07, 2020 1:00 pm
Has thanked: 71 times
Been thanked: 217 times

Re: STM32F401 UART

Post by LeighM »

Hi,

What you are requesting there is the equivalent of using the Flowcode circular buffer component, which is the best way of handling UART reception.
Interrupt handlers always need to be as short as possible, therefore best to save the received character into a buffer and then process later in the main loop. How this is done depends upon the protocol. e.g. you might have a start of data marker, then receive a known number of characters, then process the string once all have been received (using the GetNumberBytes of the circular buffer).

Here is a skeleton example.
STM32F401_DUAL_UART.fcfx
(18.85 KiB) Downloaded 116 times

nb. when using a UART interrupt you need to limit use of the UART component macros to simple ReceiveChar only, do not attempt to use such as ReceiveString, ReceiveNumber etc (as these use the poll/wait method).

btw. A software UART cannot use interrupt, as this is generated by the device's UART peripheral hardware.

Hope that helps,
Leigh

Alan_37
Posts: 125
Joined: Thu Dec 03, 2020 7:23 pm
Has thanked: 37 times
Been thanked: 17 times

Re: STM32F401 UART

Post by Alan_37 »

Hi Leigh ,

Thanks for you replay , this is exactly what I have in my project
with the only difference that I use an array of bytes Variable to store data ,
Cos circular buffer deletes the data when I read from it the first time.

Uart_1 is receiving data every 500ms on a baud rate of 1200 this leaves
very small time in-between to process other tasks , and that is why
I don't want to use Interrupts anymore cos the MCU is constantly being interrupted

resulting in the loss of data on the other Uart RX , among other problems


So instead I need the Uart to store like 256 bytes in a buffer, that will be like 10 seconds of data from Uart_1
then data will be processed all at once this will drastically reduce the load and amount of interrupts
on the MCU .

I know this might be a bit challenging , but it should be more then possible to accomplish

Alan

LeighM
Valued Contributor
Posts: 401
Joined: Mon Dec 07, 2020 1:00 pm
Has thanked: 71 times
Been thanked: 217 times

Re: STM32F401 UART

Post by LeighM »

Uart_1 is receiving data every 500ms on a baud rate of 1200
That should leave plenty of processing time to do other tasks.
As long as the interrupt code is just reading the UART char and storing in a buffer, then immediately returning from the interrupt routine.
The buffer/array can be as big as you like, then, as you say, occasionally process the array data from within the foreground main loop.
You probably need some state machine code to synchronize loading and resetting the data array.

Are you handling the UART 2 received data in the same way? i.e. short interrupt routine to grab the char and buffer it?
Running with UART interrupts like this is much better than polling and waiting in delay loops.

Are you transmitting much data?
Are you using SendString functions that are blocking? i.e. character sends with wait delays between.
A transmitted string at 1200 baud is going to block the main task for a while.
Could this be the holdup?

Maybe I need to see your program to offer any more help.

Post Reply