Question
UART Half Duplex: How to get DMA working for both RX and TX on STM32F303CC?
I am using UART1 in half duplex mode and DMA works for TX, but I cannot get it to work for RX (after calling HAL_HalfDuplex_EnableReceiver).
Here is my initialization code:
__HAL_RCC_GPIOA_CLK_ENABLE();
m_GPIO_InitStructTX.Pin = GPIO_PIN_9;
m_GPIO_InitStructTX.Mode = GPIO_MODE_AF_PP;
m_GPIO_InitStructTX.Pull = GPIO_NOPULL;
m_GPIO_InitStructTX.Speed = GPIO_SPEED_LOW;
m_GPIO_InitStructTX.Alternate = GPIO_AF7_USART1;
HAL_GPIO_Init(GPIOA, &m_GPIO_InitStructTX);
__HAL_RCC_USART1_FORCE_RESET();
__HAL_RCC_USART1_RELEASE_RESET();
__HAL_RCC_USART1_CLK_ENABLE();
m_uartHandle = UART_HandleTypeDef();
m_uartHandle.Instance = USART1;
m_uartHandle.Init.BaudRate = 9600;
m_uartHandle.Init.WordLength = UART_WORDLENGTH_8B;
m_uartHandle.Init.StopBits = UART_STOPBITS_2; // !!! 2 Stopbits
m_uartHandle.Init.Parity = UART_PARITY_NONE;
m_uartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
m_uartHandle.Init.Mode = UART_MODE_TX;
huart = &m_uartHandle;
HAL_HalfDuplex_Init(&m_uartHandle);
HAL_HalfDuplex_EnableTransmitter(&m_uartHandle);
HAL_NVIC_ClearPendingIRQ(USART1_IRQn);
HAL_NVIC_DisableIRQ(USART1_IRQn);
HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART1_IRQn);
__HAL_RCC_DMA1_CLK_ENABLE();
m_DMAHandleTX.Instance = DMA1_Channel4;
m_DMAHandleTX.Init.Direction = DMA_MEMORY_TO_PERIPH;
m_DMAHandleTX.Init.PeriphInc = DMA_PINC_DISABLE;
m_DMAHandleTX.Init.MemInc = DMA_MINC_ENABLE;
m_DMAHandleTX.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
m_DMAHandleTX.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
m_DMAHandleTX.Init.Priority = DMA_PRIORITY_MEDIUM;
m_DMAHandleTX.Init.Mode = DMA_NORMAL;
hdmaTX = &m_DMAHandleTX;
__HAL_LINKDMA(&m_uartHandle, hdmatx, m_DMAHandleTX);
__HAL_DMA_ENABLE_IT(&m_DMAHandleTX, DMA_IT_TC);
HAL_DMA_Init(&m_DMAHandleTX);
HAL_NVIC_SetPriority(DMA1_Channel4_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel4_IRQn);DMA works fine for TX, but when I switch to HAL_HalfDuplex_EnableReceiver it does not work anymore. I also tried to reconfigure the DMA and UART by calling:
m_uartHandle.Init.Mode = UART_MODE_RX;
HAL_HalfDuplex_Init(&m_uartHandle);
HAL_DMA_DeInit(&m_DMAHandleTX);
m_DMAHandleTX.Init.Direction = DMA_PERIPH_TO_MEMORY;
__HAL_LINKDMA(&m_uartHandle, hdmarx, m_DMAHandleTX);
HAL_DMA_Init(&m_DMAHandleTX);
HAL_HalfDuplex_EnableReceiver(&m_uartHandle);
HAL_UART_Receive_DMA(&m_uartHandle, buf, length);What am I missing?
