2015-08-05 02:54 PM
I would like to benefit of the alternate trigger of the injected conversion. I am using the DMA on my interleaved regular conversion.
I would like to know if it is possible to use the DMA controller for injected conversion also. I tried without success and cannot find information of it in the reference manual.Anyone knows?Thank you2015-08-05 04:26 PM
I don't think so. It doesn't have any specific DMA channel committed to such, and having it in the primary stream would just tend to cause all kinds of chaos in the data array. The point of injecting is to get some out-of-band conversions done.
If you pair ADC1+ADC2, you could use ADC3 independently.2015-08-06 09:38 AM
Ok, so you said that I can do a regular dual interleaved ADC1+ADC2 and use the ADC3 in regular mode? I tried but like in another post the status register was always busy
2015-08-06 01:13 PM
On paper it looks viable, I've done independent DMA on 3 ADC channels. I can't make a business case to prototype the solution here, and definitely not with the HAL.
2015-08-06 01:43 PM
I've used ADC1+ADC2 paired in DMA mode and ADC3 injected in interrupt mode, works fine. Since injected conversions are out of band you can't use DMA as it would trash your conversion buffers. All you have to do is set up ADC3 JEOC interrupt and read the injected conversion when the interrupt occurs.
Inside the ADC interrupt handler:// power supply injected conversion, open AWD windows for all ADCs after debounce
if(ADC_GetITStatus(ADC3, ADC_IT_JEOC) != RESET)
{ // ADC3 injected conversion ready
ADC_ClearITPendingBit(ADC3, ADC_IT_JEOC); // clear JEOC interrupt
ADC_ClearFlag(ADC3, ADC_FLAG_JSTRT | ADC_FLAG_JEOC);
adcInjects[ADC_IOB_MISC]++; // count ADC injections
adcSample[ADCDEV_CHAN_POWER] =
ADC_GetInjectedConversionValue(ADC3, ADC_InjectedChannel_1); // 24V power supply
Not sure what you mean by busy flag. All I test are interrupt status flags in interrupt handler.
Jack Peacock
2015-08-18 02:05 PM
I think I have found the problem. I am using the HAL STM32F4 Library. If you look at the function to start an injected conversion with interrupt you must use the ADC1 for the injection (last if block of the function).
So basically, I need to write another function to get start I guess.HAL_StatusTypeDef HAL_ADCEx_InjectedStart_IT(ADC_HandleTypeDef* hadc)
{
__IO uint32_t counter = 0;
uint32_t tmp1 = 0, tmp2 =0;
/* Process locked */
__HAL_LOCK(hadc);
/* Check if a regular conversion is ongoing */
if(hadc->State == HAL_ADC_STATE_BUSY_REG)
{
/* Change ADC state */
hadc->State = HAL_ADC_STATE_BUSY_INJ_REG;
}
else
{
/* Change ADC state */
hadc->State = HAL_ADC_STATE_BUSY_INJ;
}
/* Set ADC error code to none */
hadc->ErrorCode = HAL_ADC_ERROR_NONE;
/* Check if ADC peripheral is disabled in order to enable it and wait during
Tstab time the ADC's stabilization */
if((hadc->Instance->CR2 & ADC_CR2_ADON) != ADC_CR2_ADON)
{
/* Enable the Peripheral */
__HAL_ADC_ENABLE(hadc);
/* Delay for temperature sensor stabilization time */
/* Compute number of CPU cycles to wait for */
counter = (ADC_STAB_DELAY_US * (SystemCoreClock / 1000000));
while(counter != 0)
{
counter--;
}
}
/* Enable the ADC end of conversion interrupt for injected group */
__HAL_ADC_ENABLE_IT(hadc, ADC_IT_JEOC);
/* Enable the ADC overrun interrupt */
__HAL_ADC_ENABLE_IT(hadc, ADC_IT_OVR);
/* Check if Multimode enabled */
if(HAL_IS_BIT_CLR(ADC->CCR, ADC_CCR_MULTI))
{
tmp1 = HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_JEXTEN);
tmp2 = HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO);
if(tmp1 && tmp2)
{
/* Enable the selected ADC software conversion for injected group */
hadc->Instance->CR2 |= ADC_CR2_JSWSTART;
}
}
else
{
tmp1 = HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_JEXTEN);
tmp2 = HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO);
if((hadc->Instance == ADC1) && tmp1 && tmp2)
{
/* Enable the selected ADC software conversion for injected group */
hadc->Instance->CR2 |= ADC_CR2_JSWSTART;
}
}
/* Process unlocked */
__HAL_UNLOCK(hadc);
/* Return function status */
return HAL_OK;
}