ADCv2 Topic is solved

Report here problems in any of ChibiOS components. This forum is NOT for support.
User avatar
Giovanni
Site Admin
Posts: 14893
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 997 times

Re: ADCv2

Post by Giovanni »

Hi,

Changes implemented in trunk.

Giovanni
neums
Posts: 137
Joined: Fri May 08, 2015 1:09 pm
Has thanked: 10 times
Been thanked: 5 times

Re: ADCv2

Post by neums »

Hi,
thank you for implemenating!
Is it possible to add the injected sequence register (ADC_JSQR) to the config structure to make the injected conversion available? To read the data of the converted injected channels it is also sufficient the have access to the injected data register because this data is not transferred via DMA isn't it? I think the data has to be saved when the new ADC ISR hook is called.
User avatar
Giovanni
Site Admin
Posts: 14893
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 997 times

Re: ADCv2

Post by Giovanni »

You would still need to start the conversion manually.

That register does not belong there anyway, it is part of a different conversion process. A specific API would be a better option to start an injected conversion.

Giovanni
neums
Posts: 137
Joined: Fri May 08, 2015 1:09 pm
Has thanked: 10 times
Been thanked: 5 times

Re: ADCv2

Post by neums »

Something like that?

Code: Select all

/**
 * @brief   Enables the TSVREFE bit.
 * @details The TSVREFE bit is required in order to sample the internal
 *          temperature sensor and internal reference voltage.
 * @note    This is an STM32-only functionality.
 */
void adcSTM32EnableTSVREFE(void) {
  ADC->CCR |= ADC_CCR_TSVREFE;
}

/**
 * @brief   Disables the TSVREFE bit.
 * @details The TSVREFE bit is required in order to sample the internal
 *          temperature sensor and internal reference voltage.
 * @note    This is an STM32-only functionality.
 */
void adcSTM32DisableTSVREFE(void) {
  ADC->CCR &= ~ADC_CCR_TSVREFE;
}
User avatar
Giovanni
Site Admin
Posts: 14893
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 997 times

Re: ADCv2

Post by Giovanni »

Yes, create an adcSTM32StartInjectedConversion().

Initialize the register from a parameter and start the conversion, from ISR you could call a callback. There is no need to mix the two conversion functions.

Giovanni
neums
Posts: 137
Joined: Fri May 08, 2015 1:09 pm
Has thanked: 10 times
Been thanked: 5 times

Re: ADCv2

Post by neums »

Hi,
the only one reason to mix this two conversion functions is the Auto-injection functionality of the STM32F4. With this function you can convert the regular channel sequence followed by the injected channels. So you can extend the sequence length from 16 up to 20 channels. The only one problem is the DMA transfer.

A separate function needs to set the JEXTSEL in CR2 of the ADC. Do i have to call the adcStartConversion() after setting the ADC_JSQR? Because then JEXTSEL of CR2 will be overwritten by adcStartConversion if the injected channels are not in the ADCConversionGroup:

Code: Select all

  /* Enforcing the mandatory bits in CR2.*/
  cr2 = grpp->cr2 | ADC_CR2_DMA | ADC_CR2_DDS | ADC_CR2_ADON;


You wrote that the adcSTM32StartInjectedConversion() function should be like adcSTM32EnableTSVREFE(). But these STM specific functions are meant to be called after adcStart(). 2 options:
1: modify the adc_lld_start_conversion to not overwrite the CR2 at JEXTSEL and call adcSTM32StartInjectedConversion() after adcStart()
2: add the injected channels to the ADCConversionGroup. Maybe with an precompiler option definition in halconf.h.

I think that it would not be cool to hack the injected convertion after starting the reqular conversion sequence with adcStartConversion () or not?

Thanks
User avatar
Giovanni
Site Admin
Posts: 14893
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 997 times

Re: ADCv2

Post by Giovanni »

Hi,

I am a bit confused by adcStart() and adcStartConversion(), the latter should not affect anything related to injected conversion but the former could, it is a global initialization.

The driver was not designed for injected conversions support in mind so probably even more changes are required.

Giovanni
neums
Posts: 137
Joined: Fri May 08, 2015 1:09 pm
Has thanked: 10 times
Been thanked: 5 times

Re: ADCv2

Post by neums »

Hi,
thanks. You are right. My fault... :-)
neums
Posts: 137
Joined: Fri May 08, 2015 1:09 pm
Has thanked: 10 times
Been thanked: 5 times

Re: ADCv2

Post by neums »

Hi,
there is a dependency between regular und injected conversions. For both of them you have to initialize the sample time register. Due to the fact that the sample time register content belong to a channel and not to a rank in the conversion sequence it makes sense that the injected sequence register are configurable in the ADCConversionGroup. The JEOCIE could be activated via STM specifc API in the lld like adcSTM32EnableTSVREFE().

Sorry for spamming this thread but i think this is an essential feature of the STM32's ADC and the implementation is fully low level implementable via ADCConversionGroup.

Thanks
neums
Posts: 137
Joined: Fri May 08, 2015 1:09 pm
Has thanked: 10 times
Been thanked: 5 times

Re: ADCv2

Post by neums »

Hi,
i whould be very useful if the ADCDriver pointer is proceeded to the STM32_ADC_ADCx_IRQ_HOOK by evaluating the JEOC of the SR in the OSAL_IRQ_HANDLER(STM32_ADC_HANDLER) defined in hal_adc_lld.c:

Code: Select all

#if defined(STM32_ADC_ADC1_IRQ_HOOK)
#if STM32_ADC_USE_ADC1
  sr = ADC1->SR;
  ADC1->SR = 0;
  /* Note, an overflow may occur after the conversion ended before the driver
     is able to stop the ADC, this is why the DMA channel is checked too.*/
  if ((sr & ADC_SR_OVR) && (dmaStreamGetTransactionSize(ADCD1.dmastp) > 0)) {
    /* ADC overflow condition, this could happen only if the DMA is unable
       to read data fast enough.*/
    if (ADCD1.grpp != NULL)
      _adc_isr_error_code(&ADCD1, ADC_ERR_OVERFLOW);
  }
  /* TODO: Add here analog watchdog handling.*/
#if defined(STM32_ADC_ADC1_IRQ_HOOK)
  if(sr & ADC_SR_JEOC)
    STM32_ADC_ADC1_IRQ_HOOK(&ADC1)
#endif
#endif /* STM


In this implementation the hook is only called if the ADC module really is the source of the interrupt. E.g: if ADC2 throws the interrupt the ADC1 hook whould not be called this way.
Post Reply