cancel
Showing results for 
Search instead for 
Did you mean: 

DMA UART TX single transfer

Vertinhol
Associate III

Hello, I have an stm32F103, I would like to start using DMA to transfer data from memory to TX pin, in circular mode it works fine but when I switch to normal mode it works only once, I cannot use the debug function since I'm not using a ST-Link, so here is the main code:

int main(void)
{
    /* USER CODE BEGIN 1 */
    uint8_t TX[4] = { 97, 98, 99, 10 };
    /* USER CODE END 1 */
 
    /* MCU Configuration--------------------------------------------------------*/
 
    /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
    HAL_Init();
 
    /* USER CODE BEGIN Init */
 
    /* USER CODE END Init */
 
    /* Configure the system clock */
    SystemClock_Config();
 
    /* USER CODE BEGIN SysInit */
 
    /* USER CODE END SysInit */
 
    /* Initialize all configured peripherals */
    MX_GPIO_Init();
    MX_DMA_Init();
    MX_I2C1_Init();
    MX_USART1_UART_Init();
    MX_SPI2_Init();
    MX_FATFS_Init();
    /* USER CODE BEGIN 2 */
    HAL_UART_Transmit_DMA(&huart1, TX, 4);
    /* USER CODE END 2 */
 
    /* Infinite loop */
    /* USER CODE BEGIN WHILE */
    while (1)
    {
 
        HAL_UART_Transmit_DMA(&huart1, TX, 4);
        /* USER CODE END WHILE */
 
        /* USER CODE BEGIN 3 */
    }
    /* USER CODE END 3 */
}
 
static void MX_DMA_Init(void)
{
 
    /* DMA controller clock enable */
    __HAL_RCC_DMA1_CLK_ENABLE();
 
    /* DMA interrupt init */
    /* DMA1_Channel4_IRQn interrupt configuration */
    HAL_NVIC_SetPriority(DMA1_Channel4_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(DMA1_Channel4_IRQn);
    /* DMA1_Channel5_IRQn interrupt configuration */
    HAL_NVIC_SetPriority(DMA1_Channel5_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(DMA1_Channel5_IRQn);
 
}

I tried every crazy combination, clearing directly registers, using different callback functions, refilling the buffer... the result is the same I only receive the information only at startup then nothing.

Help please :'(

2 REPLIES 2

hello

This is the difference between circular and non circular mode. In circular more the DMA req continues automatically, In normal mode after finish, the DMA the request stops.

In non circular mode DMA need to be reprogrammed again and (disabled-enabled) enabled. (HAL_UART_Transmit_DMA)

I tried to reinitiate the DMA but it didn't work, maybe I'm doing something wrong, and is it worth to use the CPU resources to reinitiate the DMA every WHILE(1) cycle? instead of using directly HAL_UART_Transmit() ?

while(1)
{
    MX_DMA_Init();
    uint8_t TX[4] = {97, 98, 99, 10};
    HAL_UART_Transmit_DMA(&huart1, TX, 4);
}

Also if I try to modify the buffer in circular mode I get wrong data

while(1)
{
    for(uint8_t i=0; i<3; i++)
    {
  	  for(uint8_t j=33; j<126; j++)
  	  {
  		  TX[i] = j;
  	   }
     }
}