I'm trying to learn about DMA and its use in the STM32L4S9VI platform. One thing I'm confused about is what binds the DMA transfer to any one specific interrupt? In the below example, I'm curious which UART interrupt triggers the transfer of the next byte into the transmit data register, as well as how the DMA determines which interrupt from UART was called. As I understand it, there is actually only 1 general USART2 interrupt line that goes to the DMA, so how does the DMA actually know that the interrupt is the one that signals that it's ready to have another byte put into the transmit data register? Does
HAL_UART_IRQHandler(&huart2);
take care of it?
Example:
/* Private variables ---------------------------------------------------------*/
extern UART_HandleTypeDef huart2;
DMA_HandleTypeDef hdma_usart2_tx;
char *msg = "Hello STM32 Lovers! This message is transferred in DMA Mode.\r\n";
/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void DMATransferComplete(DMA_HandleTypeDef *hdma);
/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/
/* USER CODE END PFP */
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
int main(void) {
HAL_Init();
Nucleo_BSP_Init();
hdma_usart2_tx.Instance = DMA1_Channel7;
hdma_usart2_tx.Init.Request = DMA_REQUEST_2;
hdma_usart2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_usart2_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart2_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart2_tx.Init.Mode = DMA_NORMAL;
hdma_usart2_tx.Init.Priority = DMA_PRIORITY_LOW;
hdma_usart2_tx.XferCpltCallback = &DMATransferComplete;
HAL_DMA_Init(&hdma_usart2_tx);
/* DMA interrupt init */
HAL_NVIC_SetPriority(DMA1_Channel7_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel7_IRQn);
HAL_DMA_Start_IT(&hdma_usart2_tx, (uint32_t)msg, (uint32_t)&huart2.Instance->TDR, strlen(msg));
//Enable UART in DMA mode
huart2.Instance->CR3 |= USART_CR3_DMAT;
/* Infinite loop */
while (1);
}
void DMATransferComplete(DMA_HandleTypeDef *hdma) {
if(hdma->Instance == DMA1_Channel7) {
//Disable UART DMA mode
huart2.Instance->CR3 &= ~USART_CR3_DMAT;
//Turn LD2 ON
HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_SET);
}
}