cancel
Showing results for 
Search instead for 
Did you mean: 

ADC / ADC Watchdog Triggered by Timer

janosch
Associate II
Posted on November 04, 2008 at 11:11

ADC / ADC Watchdog Triggered by Timer

5 REPLIES 5
janosch
Associate II
Posted on May 17, 2011 at 12:47

Hi,

I'm trying to get an ADC conversation, triggered by TIM1 CC2 to work

here is my code for ADC conversation:

Code:

<BR> ADC_InitSingleShot.ADC_Mode = ADC_Mode_Independent; <BR> ADC_InitSingleShot.ADC_ScanConvMode = DISABLE; <BR> ADC_InitSingleShot.ADC_ContinuousConvMode = DISABLE; <BR> ADC_InitSingleShot.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC2; <BR> ADC_InitSingleShot.ADC_DataAlign = ADC_DataAlign_Right; <BR> ADC_InitSingleShot.ADC_NbrOfChannel = USED_REGULAR_ADC_CHANNELS; <BR> ADC_Init(ADC1, &ADC_InitSingleShot); <BR> <BR> // ADC1 regular channel14 configuration <BR> ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 1, ADC_SampleTime_1Cycles5); <BR> //ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 2, ADC_SampleTime_1Cycles5); <BR> <BR> // Set injected sequencer length <BR> ADC_InjectedSequencerLengthConfig(ADC1, 1); <BR> <BR> // ADC1 injected channel Configuration <BR> ADC_InjectedChannelConfig(ADC1, ADC_Channel_8, 1, ADC_SampleTime_1Cycles5); <BR> <BR> // ADC1 injected external trigger configuration <BR> ADC_ExternalTrigInjectedConvConfig(ADC1, ADC_ExternalTrigInjecConv_None); <BR> <BR> // Disable automatic injected conversion start after regular one <BR> ADC_AutoInjectedConvCmd(ADC1, DISABLE); <BR> <BR> /* Enable ADC1 external trigger */ <BR> ADC_ExternalTrigConvCmd(ADC1, ENABLE); <BR> <BR> /* Enable EOC interupt */ <BR> ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE); <BR> <BR> // Enable ADC1 <BR> ADC_Cmd(ADC1, ENABLE); <BR> <BR> // Enable ADC1 reset calibaration register <BR> ADC_ResetCalibration(ADC1); <BR> // Check the end of ADC1 reset calibration register <BR> while(ADC_GetResetCalibrationStatus(ADC1)); <BR> <BR> // Start ADC1 calibaration <BR> ADC_StartCalibration(ADC1); <BR> // Check the end of ADC1 calibration <BR> while(ADC_GetCalibrationStatus(ADC1)); <BR> <BR>

And this is the code for the ADC Watchdog part.

At this point I made the assumption, that the Watchdog would not fire, as

long as the ADC conversation is not running. So my goal is to set up

the ADC conversation in continious mode, trigger it via an timer and stop

the conversation later in the AWD_IT.

Code:

<BR> // Enable ADC2 clock <BR> RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2, ENABLE); <BR> <BR> //ADC2 configuration <BR> ADC_InitWatchdog.ADC_Mode = ADC_Mode_Independent; <BR> ADC_InitWatchdog.ADC_ScanConvMode = DISABLE; <BR> ADC_InitWatchdog.ADC_ContinuousConvMode = ENABLE; <BR> ADC_InitWatchdog.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC3; <BR> ADC_InitWatchdog.ADC_DataAlign = ADC_DataAlign_Right; <BR> ADC_InitWatchdog.ADC_NbrOfChannel = 1; <BR> ADC_Init(ADC2, &ADC_InitWatchdog); <BR> <BR> // ADC2 regular channel14 configuration <BR> ADC_RegularChannelConfig(ADC2, ADC_Channel_4, 1, ADC_SampleTime_1Cycles5); <BR> <BR> // Configure high and low analog watchdog thresholds <BR> ADC_AnalogWatchdogThresholdsConfig(ADC2, 505, 500); <BR> <BR> // Configure channel4 as the single analog watchdog guarded channel <BR> ADC_AnalogWatchdogSingleChannelConfig(ADC2, ADC_Channel_4); <BR> <BR> // Enable analog watchdog on one regular channel <BR> ADC_AnalogWatchdogCmd(ADC2, ADC_AnalogWatchdog_SingleRegEnable); <BR> <BR> // Disable automatic injected conversion start after regular one <BR> ADC_AutoInjectedConvCmd(ADC2, DISABLE); <BR> <BR> // Disable EOC interupt <BR> ADC_ITConfig(ADC2, ADC_IT_EOC, DISABLE); <BR> <BR> // Enable ADC1 external trigger <BR> //ADC_ExternalTrigConvCmd(ADC2, ENABLE); <BR> <BR> // Enable ADC2 <BR> ADC_Cmd(ADC2, ENABLE); <BR> <BR> // Enable ADC2 reset calibaration register <BR> ADC_ResetCalibration(ADC2); <BR> // Check the end of ADC2 reset calibration register <BR> while(ADC_GetResetCalibrationStatus(ADC2)); <BR> <BR> // Start ADC2 calibaration <BR> ADC_StartCalibration(ADC2); <BR> // Check the end of ADC2 calibration <BR> while(ADC_GetCalibrationStatus(ADC2)); <BR>

I enabled TIM1 and set the CCs, and enabled the ADC1_2_IRQChannel in the

NVIC. But for some reason I never get an EOC or AWD interrupt.

I confirmed, that this code works, If I set TrigerConvetion to None,

and use ADC_SoftwareStartConvCmd to start the conversation

Thanks in Advance

Janosch

[ This message was edited by: janosch.machowinski on 09-10-2008 17:34 ]

janosch
Associate II
Posted on May 17, 2011 at 12:47

I looked further into this issue and discovered the following :

As far as I can see, the timer, that should trigger the ADC

needs to be configured as PWM Output.

As I use TIM1 only as an internal timer,

I remapped TIM1 pins to the nirvana (PE) and configured it as

PWM output. Anyway, PLEASE INCLUDE THIS IN THE DOCUMENTATION.

I spend 3 days on this, and it could all have been avoided by

the little sentence ''ADC CC Triggering only works if configured

as PWM''.

janosch
Associate II
Posted on May 17, 2011 at 12:47

Just to clarify this, Everything works, if I set

ADC_InitWatchdog.ADC_ExternalTrigConv = ADC_ExternalTrigConvNone

ADC_InitWatchdog.ADC_ExternalTrigConv = ADC_ExternalTrigConvNone

and use

ADC_SoftwareStartConvCmd(ADC1, ENABLE);

ADC_SoftwareStartConvCmd(ADC2, ENABLE);

to trigger the whole thing. But as I do some high speed

H-Bridge Control I rely on starting ADC Conversion, and

Watchdog functionality at a certain small time window.

That's why I chose to use the whole trigger thing.

And this is the point where it stops working. I watch the

Timer1 over USART and can see that it runs into CC2 and CC3,

but my ADC doesn't start to do anything.

So my main question is why dosen't the CC2 or CC3 event start

my ADC conversation ?

csiusa
Associate II
Posted on May 17, 2011 at 12:47

I've been trying to do much the same thing see my earlier

post with subject [example: 3ADCs_DMA]. Just run the

3ADCs_DMA example in the Firmware Library examples (\FWLib\examples\ADC\3ADCs_DMA), and try to set a breakpoint inside of the

interrupt service routine (ADC1_2_IRQHandler()). Though I

haven't yet put any signal on the (ISR converted) channel13,

I have run the example and GET NO BREAK when a breakpoint is

set inside the ADC1_2_IRQHandler().

What the example does is it throws an HardFaultException().

I had a look at the assembly listing (see my post

here:

http://www.st.com/mcu/forums-cat-7436-23.html

) and I

halted the code just before it entered the HardFaultException()

Just before it entered the HardFaultException() the PC was

zero (would make sense that it threw a HardFaultException())

with that, but what puzzles me is this:

0x00000000 ; PADDING

353: ADC2ConvertedValue = ADC_GetConversionValue(ADC2);

This is where the PC points to just before the exception.

It appears to be the data location for where the ISR is

supposed to put the ADCs result (am I right?)

Wierd hu? Did anybody test this piece of code before

it went out?

From what I've seen ADC works fine as long as you use DMA

to transfer the result. Unfortunately there are precious few

examples that do NOT use DMA (this the only one I've seen and

it doesn't work.)

Just in case its my tools, I'm using Ride7/GCC to compile/link,

and Signum's JTagJet/Cortex3M with their Chameleon debugger. I

do NOT think it's the tools but who knows.

CC

gareth
Associate II
Posted on May 17, 2011 at 12:47

Hi Janosch,

I am trying to do a similar task to yourself with no luck. The documentation was not clear about needing to use the pwm mode. Would it be possible to see yours/a sample solution to this using the PWM feature as i am struggling to get the adc to start even using it. the CC2 interupt is being set but no further action is occuring.

thankyou in advance

Gareth