Page 2 of 3

Re: ADCv2

Posted: Fri Aug 26, 2016 9:41 am
by Giovanni
Hi,

Changes implemented in trunk.

Giovanni

Re: ADCv2

Posted: Fri Aug 26, 2016 1:22 pm
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.

Re: ADCv2

Posted: Fri Aug 26, 2016 1:35 pm
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

Re: ADCv2

Posted: Fri Aug 26, 2016 1:51 pm
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;
}

Re: ADCv2

Posted: Fri Aug 26, 2016 1:55 pm
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

Re: ADCv2

Posted: Fri Sep 09, 2016 3:11 pm
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

Re: ADCv2

Posted: Fri Sep 09, 2016 3:54 pm
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

Re: ADCv2

Posted: Mon Sep 12, 2016 9:44 am
by neums
Hi,
thanks. You are right. My fault... :-)

Re: ADCv2

Posted: Mon Sep 12, 2016 4:46 pm
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

Re: ADCv2

Posted: Fri Sep 16, 2016 2:12 pm
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.