2017-11-06 08:03 AM
Hello,
In my custom design am using a STM32F767BITx. Am using an output compare at 5Mghz to trigger the DMA2 and get data from a gpio Port, in circular mode.Am using the DMA_Stream2 and channel 7, DMA_PERIPH_TO_MEMORY, for this particular stream.This works fine, i get correct datas.
However, i would like to use another in the same time to use another timer, channel and stream to send data to another GPIO using DMA2 at about 8Mghz
I read through the documentations and it's not clear for me if I can use another stream of DMA2 while the DMA2 if this one is use by another channel in circular mode.
So my question is simple can we use several stream of the same dma if one of them is in circular mode if the frequency of filling datas is less 10Mghz?
thanks for any advice
2017-11-06 08:14 AM
Each stream is independent so multiple can run concurrently until you run out of bandwidth.
2017-11-10 07:32 AM
Ok thanks you for your reply,
However it doesn't seem to work with my application. I think, I missed something, but I don't know what...
I have 2 streams for DMAs running in the same with the same frequency, they are both in circular modeI have TIM8 triggering the DMA2 in to read data at 5mghz onto two GPIO port GPIOG & GPIOF
1: DMA2_Stream2, DMA_CHANNEL_7 for GPIOG
1: DMA2_Stream3, DMA_CHANNEL_7 for GPIOF
PROBLEM:
If i start 2 streams the transfer last twice the time compare to the time if just one stream is enable.Here is my code TIMER 8 configuration:
/* Compute the prescaler value to have TIMx counter clock equal to 100 MHz */
uwPrescalerValue = ((SystemCoreClock) / (100000000)) - 1;htim8.Instance = TIM8;
htim8.Init.Period = 20+1;// 5MghZ htim8.Init.Prescaler = uwPrescalerValue; htim8.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim8.Init.CounterMode = TIM_COUNTERMODE_UP; htim8.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; if(HAL_TIM_OC_Init(&htim8) != HAL_OK) { /* Initialization Error */ Error_Handler(); } TIM_OC_InitTypeDef sConfig;/*##-2- Configure the Output Compare channels #########################################*/
/* Common configuration for all channels */ sConfig.OCMode = TIM_OCMODE_PWM1; sConfig.OCPolarity = TIM_OCPOLARITY_HIGH; sConfig.OCNPolarity = TIM_OCNPOLARITY_LOW; sConfig.OCFastMode = TIM_OCFAST_ENABLE; sConfig.OCNIdleState = TIM_OCNIDLESTATE_RESET; sConfig.OCIdleState = TIM_OCIDLESTATE_RESET; sConfig.Pulse = htim8.Init.Period /2; if(HAL_TIM_OC_ConfigChannel(&htim8, &sConfig, TIM_CHANNEL_1) != HAL_OK) {//Stream 2 channel 0 Error_Handler(); } sConfig.OCMode = TIM_OCMODE_TIMING;if(HAL_TIM_OC_ConfigChannel(&htim8, &sConfig, TIM_CHANNEL_2) != HAL_OK) {//Stream 3 channel 7
Error_Handler(); }Here is the DMA2 configuration
__HAL_RCC_DMA2_CLK_ENABLE();
hdma_adc1.Instance = DMA2_Stream2;
hdma_adc1.Init.Channel = DMA_CHANNEL_7; hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY; hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE; hdma_adc1.Init.MemInc = DMA_MINC_ENABLE; hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; hdma_adc1.Init.Mode = DMA_CIRCULAR; hdma_adc1.Init.Priority = DMA_PRIORITY_HIGH; hdma_adc1.Init.FIFOMode = DMA_FIFOMODE_ENABLE; hdma_adc1.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL; hdma_adc1.Init.MemBurst = DMA_MBURST_SINGLE; hdma_adc1.Init.PeriphBurst = DMA_PBURST_SINGLE;// /* Link hdma_adc1 to hdma[CC1] */
__HAL_LINKDMA (&htim8, hdma[TIM_DMA_ID_CC1], hdma_adc1);/* Initialize TIMx DMA handle */
if (HAL_DMA_Init(htim8.hdma[TIM_DMA_ID_CC1]) != HAL_OK){ _Error_Handler(__FILE__, __LINE__); } /* Select Callbacks functions called after Transfer complete and Transfer error */ HAL_DMA_RegisterCallback(&hdma_adc1, HAL_DMA_XFER_CPLT_CB_ID, Adc1TransferComplete); HAL_DMA_RegisterCallback(&hdma_adc1, HAL_DMA_XFER_ERROR_CB_ID, Adc1TransferError); HAL_DMA_RegisterCallback(&hdma_adc1, HAL_DMA_XFER_HALFCPLT_CB_ID, Adc1TransferHalfComplete);HAL_NVIC_SetPriority(DMA2_Stream2_IRQn, 3,1);
HAL_NVIC_EnableIRQ(DMA2_Stream2_IRQn); hdma_adc2.Instance = DMA2_Stream3; hdma_adc2.Init.Channel = DMA_CHANNEL_7; hdma_adc2.Init.Direction = DMA_PERIPH_TO_MEMORY; hdma_adc2.Init.PeriphInc = DMA_PINC_DISABLE; hdma_adc2.Init.MemInc = DMA_MINC_ENABLE; hdma_adc2.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; hdma_adc2.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; hdma_adc2.Init.Mode = DMA_CIRCULAR; hdma_adc2.Init.Priority = DMA_PRIORITY_HIGH; hdma_adc2.Init.FIFOMode = DMA_FIFOMODE_ENABLE; hdma_adc2.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL; hdma_adc2.Init.MemBurst = DMA_MBURST_SINGLE; hdma_adc2.Init.PeriphBurst = DMA_PBURST_SINGLE;/* Link hdma_adc1 to hdma[CC2] */
__HAL_LINKDMA (&htim8, hdma[TIM_DMA_ID_CC2], hdma_adc2);/* Initialize TIMx DMA handle */
HAL_DMA_Init(htim8.hdma[TIM_DMA_ID_CC2]); /* Select Callbacks functions called after Transfer complete and Transfer error */ HAL_DMA_RegisterCallback(&hdma_adc2, HAL_DMA_XFER_CPLT_CB_ID, Adc2TransferComplete); HAL_DMA_RegisterCallback(&hdma_adc2, HAL_DMA_XFER_ERROR_CB_ID, Adc2TransferError); HAL_DMA_RegisterCallback(&hdma_adc2, HAL_DMA_XFER_HALFCPLT_CB_ID, Adc2TransferHalfComplete);HAL_NVIC_SetPriority(DMA2_Stream3_IRQn, 3,2);
HAL_NVIC_EnableIRQ(DMA2_Stream3_IRQn);HERE IS WHERE I START DMAS
if (HAL_DMA_Start_IT(htim8.hdma[TIM_DMA_ID_CC1], (uint32_t)&GPIOG->IDR, (uint32_t)&ADCBuffer1, 50000) != HAL_OK){
Error_Handler(); } __HAL_TIM_ENABLE_DMA(&htim8, TIM_DMA_CC1);if (HAL_DMA_Start_IT(htim8.hdma[TIM_DMA_ID_CC2], (uint32_t)&GPIOF->IDR, (uint32_t)&ADCBuffer3, 50000) != HAL_OK){
Error_Handler(); } __HAL_TIM_ENABLE_DMA(&htim8, TIM_DMA_CC2);Duration is not ok, i don't understand.
Thanks for any input for this issue.
regards
2017-11-15 12:18 AM
My bad sorry, Code above is fine.