cancel
Showing results for 
Search instead for 
Did you mean: 

USART DMA IDLE State for STM32F401RETx

Rashedul Islam
Associate III

Posted on November 24, 2017 at 15:19

Hi All,

I was working on getting user input via keyboard over uart. The input could be varible length. To handle this issue I use HAL uart receive DMA (circualr mode). To get input and and tranfer it over uart, i got an example which actually serves my purpose fine. The example is by

pasztora

 and link is given below: <LINK NO LONGER ACTIVE>

Now I implement my task in STM32L476RG Nucelo board and it was absolutely fine

In the example mentioned above, there is code block,

if((USART2->ISR & USART_ISR_IDLE) != RESET)

{

    USART2->ICR = UART_CLEAR_IDLEF;

    /* Start DMA timer */

    dma_uart_rx.timer = DMA_TIMEOUT_MS;

 }

Well, for my client project I got a board which has STM32F401RETx. But for the 

STM32F401RETx board I dont get defined the below:

USART2->ISR

USART2->ICR

USART_ISR_IDLE

UART_CLEAR_IDLEF

My question is why those above mentioned are not defined? and what is alternative for that ?

what modiftion needs to be done for the above mentioned code block? 

For STM32L476RG

the type is defined as belwo:

/**

* @brief Universal Synchronous Asynchronous Receiver Transmitter

*/

typedef struct

{

__IO uint32_t CR1; /*!< USART Control register 1, Address offset: 0x00 */

__IO uint32_t CR2; /*!< USART Control register 2, Address offset: 0x04 */

__IO uint32_t CR3; /*!< USART Control register 3, Address offset: 0x08 */

__IO uint32_t BRR; /*!< USART Baud rate register, Address offset: 0x0C */

__IO uint16_t GTPR; /*!< USART Guard time and prescaler register, Address offset: 0x10 */

uint16_t RESERVED2; /*!< Reserved, 0x12 */

__IO uint32_t RTOR; /*!< USART Receiver Time Out register, Address offset: 0x14 */

__IO uint16_t RQR; /*!< USART Request register, Address offset: 0x18 */

uint16_t RESERVED3; /*!< Reserved, 0x1A */

__IO uint32_t

ISR

; /*!< USART Interrupt and status register, Address offset: 0x1C */

__IO uint32_t

ICR

; /*!< USART Interrupt flag Clear register, Address offset: 0x20 */

__IO uint16_t RDR; /*!< USART Receive Data register, Address offset: 0x24 */

uint16_t RESERVED4; /*!< Reserved, 0x26 */

__IO uint16_t TDR; /*!< USART Transmit Data register, Address offset: 0x28 */

uint16_t RESERVED5; /*!< Reserved, 0x2A */

} USART_TypeDef;

And for STM32F401RETx the type is defined as,

/**

* @brief Universal Synchronous Asynchronous Receiver Transmitter

*/

typedef struct

{

__IO uint32_t SR; /*!< USART Status register, Address offset: 0x00 */

__IO uint32_t DR; /*!< USART Data register, Address offset: 0x04 */

__IO uint32_t BRR; /*!< USART Baud rate register, Address offset: 0x08 */

__IO uint32_t CR1; /*!< USART Control register 1, Address offset: 0x0C */

__IO uint32_t CR2; /*!< USART Control register 2, Address offset: 0x10 */

__IO uint32_t CR3; /*!< USART Control register 3, Address offset: 0x14 */

__IO uint32_t GTPR; /*!< USART Guard time and prescaler register, Address offset: 0x18 */

} USART_TypeDef;

1 ACCEPTED SOLUTION

Accepted Solutions
Posted on November 27, 2017 at 13:47

Ok I have figure it out and its working now.

I used as below, 

__HAL_UART_CLEAR_IDLEFLAG(&huart1);  instead of  

//

USART1->ICR = UART_CLEAR_IDLEF;

View solution in original post

5 REPLIES 5
Posted on November 24, 2017 at 15:35

The F4 has an earlier USART design. The status bits would be in USART->SR, USART_FLAG_IDLE

For user input DMA is probably overkill

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on November 24, 2017 at 15:55

Turvey.Clive.002

Thanks for you quick response.

As I am a newbi, I did not understand what you meant by '

For user input DMA is probably overkill

'.

Also

USART_FLAG_IDLE is not available. I simply made search to the whole project. Do I need any changes/modification to the cubeMX project configuration, which can add the required flags in the library??

I also edited my main post. You can check the highlighted code block which I want to use in STM32F4.

Posted on November 24, 2017 at 18:14

I've yet to meet a human that can type 1000 characters a second. I think this could be more trivially handled in an IRQ.

The F4 uses a different USART with different flagging and clearing methods, you should review the Reference Manual (RM0090) to understand the differences and whether your algorithm will port cleanly.

USART_FLAG_IDLE should be in stm32f4xx_hal_usart.h, you should check what modules are being flagged for inclusion in the stm32f4xx_hal_conf.h for your project.

Sorry not looking to port HAL code.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on November 27, 2017 at 10:28

Hello

Turvey.Clive.002

‌ and

pasztora

I have manually uncomment the section

#define HAL_USART_MODULE_ENABLED

in the file stm32f4xx_hal_conf.h file.

Now I have the USART_FLAG_IDLE.

I am using USART1, so my code looks like

void USART1_IRQHandler(void)

{

/* USER CODE BEGIN USART1_IRQn 0 */

/* USER CODE END USART1_IRQn 0 */

HAL_UART_IRQHandler(&huart1);

/* USER CODE BEGIN USART1_IRQn 1 */

/* UART IDLE Interrupt */

if((USART1->SR & USART_FLAG_IDLE ) != RESET)

{

//

USART1->ICR = UART_CLEAR_IDLEF;

/* Start DMA timer */

dma_uart_rx.timer = DMA_TIMEOUT_MS;

}

/* USER CODE END USART1_IRQn 1 */

}

But it is still not working as expected. It transmits data once the input buffer reaches to the defined size But in the example project it transmit data immidately after any size data is transferred.

I am still confused with the blue colored line.

Sorry I am doing any silly mistake, as I am very new to this platform.

Posted on November 27, 2017 at 13:47

Ok I have figure it out and its working now.

I used as below, 

__HAL_UART_CLEAR_IDLEFLAG(&huart1);  instead of  

//

USART1->ICR = UART_CLEAR_IDLEF;