2016-12-29 05:05 PM
2016-12-30 12:43 AM
Isn't the underlying problem that ADC1 and ADC2 pair, the logic doesn't permit a void where ADC2 is idle.
Consider Triple mode and throw away ADC2 data.
2017-01-02 05:33 PM
Hi,
Thanks for your answer.
I have tried to change the mode to Triple Mode but nothing change.
multimode.Mode = ADC_TRIPLEMODE_REGSIMULT;
The IRQ are never called and the array adc1Array[] is never updated.
As said previously, when I use them independently, both ADC1 and ADC3 are working.
2017-01-02 07:23 PM
hadc3.Init.ContinuousConvMode = ENABLE; // NO
Double and Triple mode you set up one DMA, for ADC1, and the read is of the Common Data Register. The ADC are tied together, all share a common configuration, if you are triggering, it is not continuous
2017-01-03 12:14 PM
2017-01-03 01:51 PM
,
,
Not a Cube/HAL guy
Suggest you review Dual and Triple examples
STM32Cube_FW_F7_V1.3.0\Projects\STM32756G_EVAL\Examples\ADC\ADC_DualModeInterleaved
STM32Cube_FW_F7_V1.3.0\Projects\STM32756G_EVAL\Examples\ADC\ADC_TripleModeInterleaved
Mechanics of Dual Simultaneous on F4 using SPL,
,2017-01-05 12:31 PM
Jeremy,
if you run in triple mode you must configured ADC2 also otherwise it will not works.
But if we return to your first desired configuration, as Clive1 said the dual mode configuration requires to use ADC1 and ADC2 not ADC1 and ADC3. ADC3 is used only in triple mode or in single mode.
Here is my functions to initialize the ADCs in dual mode...
void InitADCs (void)
{
ADC_ChannelConfTypeDef ChannelConfig;
ADC_MultiModeTypeDef MultiMode;
hADC1.Instance = ADC1;
hADC1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;
hADC1.Init.Resolution = ADC_RESOLUTION12b;
hADC1.Init.ScanConvMode = DISABLE;
hADC1.Init.ContinuousConvMode = DISABLE;
hADC1.Init.DiscontinuousConvMode = DISABLE;
hADC1.Init.NbrOfDiscConversion = 0;
hADC1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;
hADC1.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T3_CC4;
hADC1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hADC1.Init.NbrOfConversion = 1;
hADC1.Init.DMAContinuousRequests = ENABLE;
hADC1.Init.EOCSelection = DISABLE;
HAL_ADC_Init(&hADC1);
//Channel Configuration
ChannelConfig.Channel = ADC_CHANNEL_13;
ChannelConfig.Rank = 1;
ChannelConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
ChannelConfig.Offset = 0;
HAL_ADC_ConfigChannel(&hADC1, &ChannelConfig);
//ADC2
hADC2.Instance = ADC2;
hADC2.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;
hADC2.Init.Resolution = ADC_RESOLUTION12b;
hADC2.Init.ScanConvMode = DISABLE;
hADC2.Init.ContinuousConvMode = DISABLE;
hADC2.Init.DiscontinuousConvMode = DISABLE;
hADC2.Init.NbrOfDiscConversion = 0;
hADC2.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hADC2.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T3_CC4;
hADC2.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hADC2.Init.NbrOfConversion = 1;
hADC2.Init.DMAContinuousRequests = ENABLE;
hADC2.Init.EOCSelection = DISABLE;
HAL_ADC_Init(&hADC2);
//Use same channel configuration of ADC1
HAL_ADC_ConfigChannel(&hADC2, &ChannelConfig);
//Configure Dual Mode Interleaved
MultiMode.Mode = ADC_DUALMODE_INTERL;
MultiMode.DMAAccessMode = ADC_DMAACCESSMODE_2;
MultiMode.TwoSamplingDelay = ADC_TWOSAMPLINGDELAY_8CYCLES;
HAL_ADCEx_MultiModeConfigChannel(&hADC1, &MultiMode);
//Enable ADC2
HAL_ADC_Start(&hADC2);
//Enable ADC1 dual interleaved DMA with double buffering
HAL_ADC_MultiModeStart_DMA_MultiBuffer(&hADC1, (uint32_t)&OddFramePixels[0], (uint32_t)&EvenFramePixels[0], CCD_NUMBER_OF_PIXELS/2);
return;
}
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
GPIO_InitTypeDef GPIO_InitStructure;
if(hadc->Instance == ADC1)
{
//##-1- Enable peripherals and GPIO Clocks #################################
__GPIOC_CLK_ENABLE();
__ADC1_CLK_ENABLE();
__DMA2_CLK_ENABLE();
//##-2- Configure peripheral GPIO ##########################################
//Configure PC3 as analog input for ADC1/2 Channel13
GPIO_InitStructure.Pin = GPIO_PIN_3;
GPIO_InitStructure.Mode = GPIO_MODE_ANALOG;
GPIO_InitStructure.Speed = GPIO_SPEED_LOW;
GPIO_InitStructure.Pull = GPIO_NOPULL ;
//GPIO_InitStructure.Alternate = GPIO_AF0_RTC_50Hz; //DONT CARE
HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);
//##-3- Configure the DMA streams ##########################################
//DMA2 Stream 0 Channel 0 ADC1 fixed length transfer of 2140
hDMA2_ADC.Instance = DMA2_Stream0;
hDMA2_ADC.Init.Channel = DMA_CHANNEL_0;
hDMA2_ADC.Init.Direction = DMA_PERIPH_TO_MEMORY;
hDMA2_ADC.Init.PeriphInc = DMA_PINC_DISABLE;
hDMA2_ADC.Init.MemInc = DMA_MINC_ENABLE;
if(Global_db.p_sysMeasRate_db->ui16SysSamplingRate==SYS_MEAS_RATE_1000HZ)// (ADC->CCR & ADC_CCR_MULTI)!=0)
{
hDMA2_ADC.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
hDMA2_ADC.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
}
else
{
hDMA2_ADC.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
hDMA2_ADC.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;//DMA_MDATAALIGN_WORD;
}
hDMA2_ADC.Init.Mode = DMA_CIRCULAR;
hDMA2_ADC.Init.Priority = DMA_PRIORITY_HIGH;
hDMA2_ADC.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
hDMA2_ADC.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_1QUARTERFULL;
hDMA2_ADC.Init.MemBurst = DMA_MBURST_SINGLE;
hDMA2_ADC.Init.PeriphBurst = DMA_PBURST_SINGLE;
HAL_DMA_Init(&hDMA2_ADC);
// Associate the initialized DMA handle to the the ADC handle
__HAL_LINKDMA(hadc, DMA_Handle, hDMA2_ADC);
//##-4- Configure the NVIC for DMA #########################################
//Add interrupt handling for DMA2 linked to ADC
HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 0x0F, 0x0F);
HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);
}
//Nothing Special because of Dual Mode
if(hadc->Instance == ADC2)
{
//##-1- Enable peripherals and GPIO Clocks #################################
__ADC2_CLK_ENABLE();
}
}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?