STM32-Peripheral’s-UART: DMA Mode

STM32-Peripheral’s-UART: DMA Mode

Figure 1: Source (All about circuit)

USART introduction


The universal synchronous asynchronous receiver transmitter (USART) offers a flexible
means of full-duplex data exchange with external equipment requiring an industry standard
NRZ asynchronous serial data format. The USART offers a very wide range of baud rates
using a fractional baud rate generator.
It supports synchronous one-way communication and half-duplex single wire
communication. It also supports the LIN (local interconnection network), Smartcard Protocol
and IrDA (infrared data association) SIR ENDEC specifications, and modem operations
(CTS/RTS). It allows multiprocessor communication.
High speed data communication is possible by using the DMA for multi buffer configuration.

USART main features

  • Full duplex, asynchronous communications
  • NRZ standard format (Mark/Space)
  • Configurable oversampling method by 16 or by 8 to give flexibility between speed and
  • clock tolerance
  • Fractional baud rate generator systems
  • – Common programmable transmit and receive baud rate (refer to the datasheets
  • for the value of the baud rate at the maximum APB frequency.
  • Programmable data word length (8 or 9 bits)
  • Configurable stop bits – support for 1 or 2 stop bits
  • LIN Master Synchronous Break send capability and LIN slave break detection
  • capability
  • – 13-bit break generation and 10/11 bit break detection when USART is hardware
  • configured for LIN
  • Transmitter clock output for synchronous transmission
  • IrDA SIR encoder decoder
  • – Support for 3/16 bit duration for normal mode
  • Smartcard emulation capability
  • – The Smartcard interface supports the asynchronous protocol Smartcards as
  • defined in the ISO 7816-3 standards
  • – 0.5, 1.5 stop bits for Smartcard operation
  • Single-wire half-duplex communication
  • Configurable multibuffer communication using DMA (direct memory access)

How to use this driver

The UART HAL driver can be used as follows:
1. Declare a UART_HandleTypeDef handle structure (eg. UART_HandleTypeDef huart)

2. Initialize the UART low level resources by implementing the HAL_UART_MspInit() API:
a. Enable the USARTx interface clock.
b. UART pins configuration:
◦ Enable the clock for the UART GPIOs.
◦ Configure these UART pins (TX as alternate function pull-up, RX as alternate function Input).
c. NVIC configuration if you need to use interrupt process (HAL_UART_Transmit_IT() and
HAL_UART_Receive_IT() APIs):
◦ Configure the USARTx interrupt priority.
◦ Enable the NVIC USART IRQ handle.
d. DMA Configuration if you need to use DMA process (HAL_UART_Transmit_DMA() and
HAL_UART_Receive_DMA() APIs):
◦ Declare a DMA handle structure for the Tx/Rx stream.
◦ Enable the DMAx interface clock.
◦ Configure the declared DMA handle structure with the required Tx/Rx parameters.
◦ Configure the DMA Tx/Rx stream.
◦ Associate the initialized DMA handle to the UART DMA Tx/Rx handle.
◦ Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx/Rx
stream.
◦ Configure the USARTx interrupt priority and enable the NVIC USART IRQ handle (used for last
byte sending completion detection in DMA non circular mode)

3. Program the Baud Rate, Word Length, Stop Bit, Parity, Hardware flow control and Mode(Receiver/
Transmitter) in the huart Init structure.
4. For the UART asynchronous mode, initialize the UART registers by calling the HAL_UART_Init() API.
5. For the UART Half duplex mode, initialize the UART registers by calling the HAL_HalfDuplex_Init() API.
6. For the LIN mode, initialize the UART registers by calling the HAL_LIN_Init() API.
7. For the Multi-Processor mode, initialize the UART registers by calling the HAL_MultiProcessor_Init() API

  • DMA mode IO operation
    • Send an amount of data in non blocking mode (DMA) using HAL_USART_Transmit_DMA()
    • At transmission end of half transfer HAL_USART_TxHalfCpltCallback is executed and user can add his own
    code by customization of function pointer HAL_USART_TxHalfCpltCallback
    • At transmission end of transfer HAL_USART_TxCpltCallback is executed and user can add his own code by
    customization of function pointer HAL_USART_TxCpltCallback
    • Receive an amount of data in non blocking mode (DMA) using HAL_USART_Receive_DMA()
  • At reception end of half transfer HAL_USART_RxHalfCpltCallback is executed and user can add his own
    code by customization of function pointer HAL_USART_RxHalfCpltCallback
    • At reception end of transfer HAL_USART_RxCpltCallback is executed and user can add his own code by
    customization of function pointer HAL_USART_RxCpltCallback
    • In case of transfer Error, HAL_USART_ErrorCallback() function is executed and user can add his own code
    by customization of function pointer HAL_USART_ErrorCallback
    • Pause the DMA Transfer using HAL_USART_DMAPause()
    • Resume the DMA Transfer using HAL_USART_DMAResume()
    • Stop the DMA Transfer using HAL_USART_DMAStop()

For this blog we are going to use UART DMA mode

Creating STM32 executable projects steps are available on this link , please follow steps 1 to 10 as per blog, here we will start from step 11. PA9 & PA10 Pin used for debugging purpose as UART Tx & UART Rx respectively. this blog is specially for UART configuration & its usage in DMA mode, output will be available in serial terminal

UART in Interrupt mode click here , UART in poling mode click here

11. Enable UART Configuration

Go to System mode > Connectivity > USART1 > Mode > Asynchronous

Go to System mode > Connectivity > USART1 > Parameter settings > Default

Figure 2: USART1 Enable

12. Enable the Interrupt

Go to System mode > Connectivity > USART1 > NVIC Settings > Enable

Figure 3: USART1 Interrupt Enable

13. Enable the DMA Settings for Tx & Rx

Go to System mode > Connectivity > USART1 > DMA Settings > ADD > Mode: Circular > Priority: Low

Figure 5: DMA Transmit mode settings
Figure 6: DMA Receive mode settings

14. PA9 : USART_Tx & PA10: USART_Rx

Figure 4: Pin Selection

15. Press below icon for code generation

Figure 7: Cube IDE Code Generation

16. Sample Code

/* USER CODE BEGIN PTD */
uint8_t temp_data[10];
uint8_t Rxflag = 0;
/* USER CODE END PTD */

/* USER CODE BEGIN PV */
 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
 {
	 if(huart1.Instance == USART1)
	 {
		 Rxflag = 1;
	 }
 }
/* USER CODE END PV */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  HAL_UART_Receive_DMA(&huart1, temp_data, 5);
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
	  HAL_Delay(1000);
	  if (Rxflag == 1)
	  {
		  HAL_UART_Transmit_DMA(&huart1, temp_data, 5);
		  HAL_UART_Receive_DMA(&huart1, temp_data, 5);
		  Rxflag = 0;
	  }
  }
  /* USER CODE END 3 */
Software Tools:
  1. STM32CubeIDE
  2. STM32CubeMx
  3. Teraterm
Hardware Setup:
  1. STM32F429IDISCOVERY board
  2. Mini USB Cable
  3. Jumper wire
Conclusion:

Successfully demonstrated UART functionality in DMA mode.

References:
  1. STM32 HAL Library
  2. STM32 UM1718 document
Similar topics:
  1. https://kalapiinfotech.in/stm32-cube-ide-freertos-code-generation-using-cubemx/
  2. STM32 Peripherals: GPIO
  3. STM32 Peripherals: DAC
  4. STM32 Peripherals: ADC using Polling Mode
  5. STM32 Peripherals: UART Polling Mode

Leave a Reply

Your email address will not be published. Required fields are marked *