How use two periphrals with DMA which are in same DMA stream but in diffrent DMA channel?
Hi, I have a problem in DMA with stm32f4XX. I need to use two peripherals i2c3 for IMU and UART4 for gps, I setup the base code and its working fine when one of the peripheral DMA initialisation is disable.
Here is my code:-
void GPIO_I2C3_Init(void)
{
GPIO_InitTypeDef GPIO_Init;
static DMA_HandleTypeDef hdma2_tx;
static DMA_HandleTypeDef hdma2_rx;
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_I2C3_CLK_ENABLE();
__HAL_RCC_I2C3_FORCE_RESET();
HAL_Delay(10);
__HAL_RCC_I2C3_RELEASE_RESET();
__HAL_RCC_DMA1_CLK_ENABLE();
GPIO_Init.Pin = GPIO_PIN_8;
GPIO_Init.Mode = GPIO_MODE_AF_OD;
GPIO_Init.Pull = GPIO_PULLUP;
GPIO_Init.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_Init.Alternate = GPIO_AF4_I2C3;
HAL_GPIO_Init(GPIOA,&GPIO_Init);
GPIO_Init.Pin = GPIO_PIN_9;
GPIO_Init.Mode = GPIO_MODE_AF_OD;
GPIO_Init.Pull = GPIO_PULLUP;
GPIO_Init.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_Init.Alternate = GPIO_AF4_I2C3;
HAL_GPIO_Init(GPIOC,&GPIO_Init);
i2c3_cfg.Instance = I2C3;
i2c3_cfg.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
i2c3_cfg.Init.ClockSpeed = 400000;
i2c3_cfg.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
i2c3_cfg.Init.DutyCycle = I2C_DUTYCYCLE_2;
i2c3_cfg.Init.GeneralCallMode = I2C_GENERALCALL_ENABLE;
i2c3_cfg.Init.OwnAddress1 = 0;
i2c3_cfg.Init.OwnAddress2 = 0;
i2c3_cfg.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
hdma2_tx.Instance = DMA1_Stream4;
hdma2_tx.Init.Channel = DMA_CHANNEL_3;
hdma2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma2_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma2_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma2_tx.Init.Mode = DMA_NORMAL;
hdma2_tx.Init.Priority = DMA_PRIORITY_LOW;
hdma2_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
hdma2_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
hdma2_tx.Init.MemBurst = DMA_MBURST_INC8;
hdma2_tx.Init.PeriphBurst = DMA_PBURST_INC8;
HAL_DMA_Init(&hdma2_tx);
__HAL_LINKDMA(&i2c3_cfg, hdmatx, hdma2_tx);
hdma2_rx.Instance = DMA1_Stream2;
hdma2_rx.Init.Channel = DMA_CHANNEL_3;
hdma2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma2_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma2_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma2_rx.Init.Mode = DMA_NORMAL;
hdma2_rx.Init.Priority = DMA_PRIORITY_HIGH;
hdma2_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
hdma2_rx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
hdma2_rx.Init.MemBurst = DMA_MBURST_INC8;
hdma2_rx.Init.PeriphBurst = DMA_PBURST_INC8;
HAL_DMA_Init(&hdma2_rx);
__HAL_LINKDMA(&i2c3_cfg, hdmarx, hdma2_rx);
HAL_NVIC_SetPriority(DMA1_Stream2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream2_IRQn);
HAL_NVIC_SetPriority(DMA1_Stream4_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream4_IRQn);
HAL_NVIC_SetPriority(I2C3_ER_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(I2C3_ER_IRQn);
HAL_NVIC_SetPriority(I2C3_EV_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(I2C3_EV_IRQn);
HAL_I2C_Init(&i2c3_cfg);
}
void GPIO_UART4_Init(void)
{
GPIO_InitTypeDef GPIO_Init;
static DMA_HandleTypeDef hdma1_rx;
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_UART4_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();
GPIO_Init.Pin = GPIO_PIN_0|GPIO_PIN_1;
GPIO_Init.Pull = GPIO_PULLUP;
GPIO_Init.Mode = GPIO_MODE_AF_PP; //uart4 tx pin as pushpull
GPIO_Init.Alternate = GPIO_AF8_UART4;
GPIO_Init.Speed = GPIO_SPEED_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_Init);
GPS_Uart.Instance = UART4;
GPS_Uart.Init.BaudRate = 9600;
GPS_Uart.Init.StopBits = UART_STOPBITS_1;
GPS_Uart.Init.WordLength = UART_WORDLENGTH_8B;
GPS_Uart.Init.Mode = UART_MODE_TX_RX;
GPS_Uart.Init.Parity = UART_PARITY_NONE;
GPS_Uart.Init.HwFlowCtl = UART_HWCONTROL_NONE;
GPS_Uart.Init.OverSampling = UART_OVERSAMPLING_16;
HAL_UART_Init(&GPS_Uart);
hdma1_rx.Instance = DMA1_Stream2;
hdma1_rx.Init.Channel = DMA_CHANNEL_4;
hdma1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma1_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma1_rx.Init.Mode = DMA_CIRCULAR;
hdma1_rx.Init.Priority = DMA_PRIORITY_HIGH;
hdma1_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
hdma1_rx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
hdma1_rx.Init.MemBurst = DMA_MBURST_INC8;
hdma1_rx.Init.PeriphBurst = DMA_PBURST_INC8;
HAL_DMA_Init(&hdma1_rx);
__HAL_LINKDMA(&GPS_Uart, hdmarx, hdma1_rx);
HAL_NVIC_SetPriority(DMA1_Stream2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream2_IRQn);
HAL_NVIC_SetPriority(UART4_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(UART4_IRQn);
__HAL_UART_ENABLE_IT(&GPS_Uart,UART_IT_IDLE);
__HAL_DMA_ENABLE_IT(&hdma1_rx,DMA_IT_TC);
}
and IRQs :-
void DMA1_Stream2_IRQHandler(void)
{
flag_g=~flag_g;
if(flag_g)
HAL_DMA_IRQHandler(i2c3_cfg.hdmarx);
else
HAL_DMA_IRQHandler(GPS_Uart.hdmarx); //UART4
}
void DMA1_Stream4_IRQHandler(void)
{
HAL_DMA_IRQHandler(i2c3_cfg.hdmatx);
}
void UART4_IRQHandler(void)
{
HAL_UART_IRQHandler(&GPS_Uart);
}
void I2C3_EV_IRQHandler(void)
{
HAL_I2C_EV_IRQHandler(&i2c3_cfg);
}
void I2C3_ER_IRQHandler(void)
{
HAL_I2C_ER_IRQHandler(&i2c3_cfg);
}
The main probleam is i2c3 and uart4 is in same dma stream-> dma_stream2, but in diffrent channel. So is there any way use two periphral with DMA which are in same stream?
