Skip to main content
Jakub B
Associate II
October 5, 2017
Solved

How to speed up usart communication?

  • October 5, 2017
  • 5 replies
  • 1589 views
Posted on October 05, 2017 at 13:39

The original post was too long to process during our migration. Please click on the attachment to read the original post.
    This topic has been closed for replies.
    Best answer by Jakub B
    Posted on October 06, 2017 at 15:09

    After 3 days i found a solution (or walkabout) for future reference.

    /* Infinite loop */

      /* USER CODE BEGIN WHILE */

      while (1)

      {

            HAL_UART_Receive_DMA(&huart1, Received, 8); //start of listening

    HAL_Delay(1);

       

            if (ramka==1){

                //przekierowanie rozkazu do funkcji

                switch(bufor[1]){

                    case 4:{

                    stany(); break;

                    }

            }

        }

        ramka=0;

      /* USER CODE END WHILE */

    i found out that when i send every 1 second order by hand it sometimes miss one or more answers, but if i send it quicker for example 5 times a sec it works perfectly. I figured that maybe there is some problem with time of creating answer so if i put a delay just outside of interrupt it might work..

    And it did

    5 replies

    Tesla DeLorean
    Guru
    October 5, 2017
    Posted on October 05, 2017 at 13:59

    Wouldn't call HAL_UART_Receive_DMA() blindly in a tight loop

    ramka should be a volatile variable, also you don't clear it in the loop after processing the packet

    Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
    AvaTar
    Senior III
    October 5, 2017
    Posted on October 05, 2017 at 14:02

    I would use a less EMI-prone standard, like RS485 or RS422.

    Your communication is package/message based, isn't it ?

    Why do you call the CRC2 function on every byte, from an interrupt context ?

    I have my problems understanding polish comments, though ...

    Jakub B
    Jakub BAuthor
    Associate II
    October 5, 2017
    Posted on October 05, 2017 at 14:12

    1. ramka is cleared in mail loop after checking packet. so i wait for order, check its crc if i should process it farther, then checking what it wants me to do and then clear.

    2. crc is calculated on 15/17 of final answer. last 2/17 are crc. I calculate it before sending answer in 2 parts. i copy part1 and move it to copy part2. Should i make a function for it outside of interrupt?

    Tesla DeLorean
    Guru
    October 5, 2017
    Posted on October 05, 2017 at 16:44

    >>ramka is cleared in mail loop after checking packet

    The placement seems to create a race condition, variable should be volatile.

    Enabling of DMA also seems problematic, and prone to synchronization issues.

    Try implementing with a simple USART IRQ method.

    Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
    Jakub B
    Jakub BAuthor
    Associate II
    October 6, 2017
    Posted on October 06, 2017 at 08:08

    >>The placement seems to create a race condition, variable should be volatile

    i'll try it

    >>Enabling of DMA also seems problematic, and prone to synchronization issues.

    with DMA i'm missing less  then without it, but issue is probably something else. I'll try changing it

    Jakub B
    Jakub BAuthor
    Associate II
    October 5, 2017
    Posted on October 05, 2017 at 14:29

    Can you tell me how to clear buffer with this:

    void

    TM_USART_ClearBuffer

    (

    USART_TypeDef

    *

    USARTx

    )

    ;

    maybe if i clear it after each recieve it will be enough?

    Jakub B
    Jakub BAuthorBest answer
    Associate II
    October 6, 2017
    Posted on October 06, 2017 at 15:09

    After 3 days i found a solution (or walkabout) for future reference.

    /* Infinite loop */

      /* USER CODE BEGIN WHILE */

      while (1)

      {

            HAL_UART_Receive_DMA(&huart1, Received, 8); //start of listening

    HAL_Delay(1);

       

            if (ramka==1){

                //przekierowanie rozkazu do funkcji

                switch(bufor[1]){

                    case 4:{

                    stany(); break;

                    }

            }

        }

        ramka=0;

      /* USER CODE END WHILE */

    i found out that when i send every 1 second order by hand it sometimes miss one or more answers, but if i send it quicker for example 5 times a sec it works perfectly. I figured that maybe there is some problem with time of creating answer so if i put a delay just outside of interrupt it might work..

    And it did

    AvaTar
    Senior III
    October 6, 2017
    Posted on October 06, 2017 at 15:38

    Polling with delay is possibly a workaround for Cube/HAL code, but still a bad solution.

    I would drop the Cube straitjacket alltogether and go for a clear interrupt-based solution, but it's not my project.

    I stopped commenting on Cube code a while ago ...