Skip to main content
janosch
Associate II
November 4, 2008
Question

ADC / ADC Watchdog Triggered by Timer

  • November 4, 2008
  • 5 replies
  • 1398 views
Posted on November 04, 2008 at 11:11

ADC / ADC Watchdog Triggered by Timer

    This topic has been closed for replies.

    5 replies

    janosch
    janoschAuthor
    Associate II
    May 17, 2011
    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 ]

    csiusa
    Associate
    May 17, 2011
    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

    janosch
    janoschAuthor
    Associate II
    May 17, 2011
    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 ?

    janosch
    janoschAuthor
    Associate II
    May 17, 2011
    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''.

    gareth
    Associate II
    May 17, 2011
    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