Page 1 of 1

STM32F405RG ADC injected sequence length of 2 only converts first channel

Posted: Mon Aug 21, 2017 5:07 pm
by bxh
Hello all,

I'm using the triple ADC injected simultaneous only mode, and am trying to convert 2 channels on each ADC. The conversion is triggered by Timer 1 TRGO, and I've enabled the injected end of conversion (JEOC) interrupt successfully on ADC1.

The ISR checks ADC1's status register for the JEOC flag, which should mean the entire group of injected channels has been converted (both configured channels). However, while JDR1 contains the expected value, JDR2 to JDR4 always remain at 0.

I've checked the register settings in debug mode with the very helpful EmbSys Registers tool, and can confirm the injected sequence length is set to 1 (for 2 conversions) in the JSQR register, and the channels are set in the JSQ3 and JSQ4 bits as directed by the reference manual.

However, only the channel in JSQ3 is converted and stored in the JDR registers. Changing the channel in JSQ3 gives the correct ADC reading, so it's unlikely to be an issue with the channel configuration.

It almost appears that the JEOC interrupt is firing after the first conversion, does anybody know if this is actually the expected behaviour?

Thank you in advance.

Here's the relevant ADC configuration snippet:

Code: Select all

//Enable clocks for ADCs
rccEnableADC1(FALSE);
rccEnableADC2(FALSE);
rccEnableADC3(FALSE);

//ADC1 (Master)
memset(ADC1, 0, sizeof(ADC_TypeDef));
ADC1->CR1 |= ADC_CR1_JEOCIE; //Enable interrupt for injected channels
ADC1->CR2 |= ADC_CR2_JEXTEN_1; //Falling edge
ADC1->CR2 |= ADC_CR2_JEXTSEL_0; //Timer 1 TRGO
ADC1->CR2 |= ADC_CR2_ADON; //Enable ADC1
ADC1->JSQR |= ADC_JSQR_JL_0; //2 conversions
ADC1->JSQR |= 3 << 10; //JSQ3: ADC channel 3
ADC1->JSQR |= 15 << 15; //JSQ4: ADC channel 15

//ADC2 (Slave)
memset(ADC2, 0, sizeof(ADC_TypeDef));
ADC2->CR2 |= ADC_CR2_ADON; //Enable ADC2
ADC2->JSQR |= ADC_JSQR_JL_0; //2 conversions
ADC2->JSQR |= 2 << 10; //JSQ3: ADC channel 2
ADC2->JSQR |= 14 << 15; //JSQ4: ADC channel 14

//ADC3 (Slave)
memset(ADC3, 0, sizeof(ADC_TypeDef));
ADC3->CR2 |= ADC_CR2_ADON; //Enable ADC3
ADC3->JSQR |= ADC_JSQR_JL_0; //2 conversions
ADC3->JSQR |= 1 << 10; //JSQ3: ADC channel 1
ADC3->JSQR |= 0 << 15; //JSQ4: ADC channel 0

//ADC Common (Triple ADC injected simultaneous only)
memset(ADC, 0, sizeof(ADC_Common_TypeDef));
ADC->CCR |= ADC_CCR_ADCPRE_0; //PCLK2 divided by 4
ADC->CCR |= ADC_CCR_MULTI_4 | ADC_CCR_MULTI_2 | ADC_CCR_MULTI_0;

nvicEnableVector(ADC_IRQn, STM32_ADC_IRQ_PRIORITY);

Re: STM32F405RG ADC injected sequence length of 2 only converts first channel

Posted: Wed Aug 23, 2017 12:15 pm
by bxh
Solved. The ADCs need to have SCAN mode enabled.

Re: STM32F405RG ADC injected sequence length of 2 only converts first channel

Posted: Tue Aug 29, 2017 8:27 am
by alex31
Hello, I will have to manage both injected and regular sampling on three ADC with stm32f4, so you experience is welcome for me.

In your example, you enable ISR, but Chibios adc isr does not deal with injected sequence, so have you patched low level chibios adc driver ?

Alexandre