cancel
Showing results for 
Search instead for 
Did you mean: 

TIM2 TRGO not triggering ADC1

gtoonstra
Associate
Posted on November 12, 2014 at 12:49

Hello,

I've been trying to trigger ADC1 conversions for transfer through DMA afterwards, but unsuccessful so far. I searched and verified examples, verified all code and registers and cannot figure it out so far. I'm using a new STM32F042C6 chip on a custom made board, so some hardware issue cannot be eliminated. Hopefully, someone can point out what I may be doing wrong. I'm using libopencm3 as an abstraction.

Configuration code to enable clocks:

static void config_clock( void )

{

    rcc_clock_setup_in_hse_8mhz_out_48mhz();

    rcc_periph_clock_enable(RCC_GPIOA);

    rcc_periph_clock_enable(RCC_GPIOB);

    rcc_periph_clock_enable(RCC_DMA);

    rcc_periph_clock_enable(RCC_SPI1);

    rcc_periph_clock_enable(RCC_ADC);

    rcc_periph_clock_enable(RCC_CAN);

    rcc_periph_clock_enable(RCC_USART1);

    rcc_periph_clock_enable(RCC_TIM1);

    rcc_periph_clock_enable(RCC_TIM2);

    rcc_periph_clock_enable(RCC_TIM3);

    rcc_periph_clock_enable(RCC_TIM14);

}

Code to configure timer2:

void config_tim2( void )

{

    uint32_t timer = TIM2;

    /* Time Base configuration */

    timer_reset(timer);

    timer_set_mode(timer, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);

    timer_set_period(timer, 1000);

    timer_set_prescaler(timer, 47);

    /* Generate TRGO on every update. */

    timer_set_master_mode(timer, TIM_CR2_MMS_UPDATE);

    timer_enable_counter(timer);

}

Code to configure adc:

static uint8_t channel_array[] = { ADC_CHANNEL3, ADC_CHANNEL4, ADC_CHANNEL5 };

void config_adc( void )

{

    // Enable ADC interrupt for checking.

    nvic_enable_irq(NVIC_ADC_COMP_IRQ);

    nvic_set_priority(NVIC_ADC_COMP_IRQ, 0);

    adc_power_off(ADC1);

    adc_set_clk_source(ADC1, ADC_CLKSOURCE_ADC);

    adc_calibrate_start(ADC1);

    adc_calibrate_wait_finish(ADC1);

    adc_set_operation_mode(ADC1, ADC_MODE_SCAN);

    // this selects TIM2-TRGO

    adc_enable_external_trigger_regular(ADC1, ADC_CFGR1_EXTSEL_VAL(0b010), ADC_CFGR1_EXTEN_RISING );

    adc_set_right_aligned(ADC1);

    adc_set_sample_time_on_all_channels(ADC1, ADC_SMPR_SMP_239DOT5);

    adc_set_regular_sequence(ADC1, NUM_CHANNELS, channel_array);

    adc_set_resolution(ADC1, ADC_RESOLUTION_12BIT);

    adc_disable_analog_watchdog(ADC1);

    adc_power_on(ADC1);

    /* Wait for ADC starting up. */

    int i;

    for (i = 0; i < 800000; i++) {    /* Wait a bit. */

        __asm__(''nop'');

    }

    adc_enable_overrun_interrupt( ADC1 );

    adc_enable_eoc_sequence_interrupt( ADC1 );

    adc_enable_eoc_interrupt( ADC1 );

    adc_enable_dma( ADC1 );

    dma_channel_reset(DMA1, DMA_CHANNEL1);

    // DMA1_Channel1->CPAR = (uint32_t) (&(ADC1->DR));

    dma_set_peripheral_address(DMA1, DMA_CHANNEL1, (uint32_t) &ADC1_DR );

    //DMA1_Channel1->CMAR = (uint32_t)(ADC_array);

    dma_set_memory_address(DMA1, DMA_CHANNEL1, (uint32_t)ADC_array);

    

    //DMA1_Channel1->CNDTR = NUMBER_OF_ADC_CHANNEL;

    dma_set_number_of_data(DMA1, DMA_CHANNEL1, NUM_CHANNELS);

    dma_set_read_from_memory(DMA1, DMA_CHANNEL1);

    // DMA1_Channel1->CCR |= DMA_CCR_MINC | DMA_CCR_MSIZE_0 | DMA_CCR_PSIZE_0

    //                | DMA_CCR_TEIE | DMA_CCR_TCIE ;

    dma_enable_memory_increment_mode(DMA1, DMA_CHANNEL1);

    dma_set_memory_size(DMA1, DMA_CHANNEL1, DMA_CCR_MSIZE_16BIT);

    dma_set_peripheral_size(DMA1, DMA_CHANNEL1, DMA_CCR_MSIZE_16BIT);

    dma_enable_transfer_error_interrupt(DMA1, DMA_CHANNEL1);

    dma_enable_transfer_complete_interrupt(DMA1, DMA_CHANNEL1);

    dma_set_priority(DMA1, DMA_CHANNEL1, DMA_CCR_PL_HIGH);

    // Enable DMA interrupt.

    nvic_enable_irq(NVIC_DMA1_CHANNEL1_IRQ);

    nvic_set_priority(NVIC_DMA1_CHANNEL1_IRQ, 0);

    //DMA1_Channel1->CCR |= DMA_CCR_EN;

    dma_enable_channel(DMA1, DMA_CHANNEL1);

    //ADC_CR(ADC1) |= ADC_CR_ADSTART;

    //adc_start_conversion_regular( ADC1 );

}

Timer2 registers:

(gdb) x/20x 0x40000000

0x40000000:    0x00000001    0x00000020    0x00000000    0x00000000

0x40000010:    0x0000001f    0x00000000    0x00000000    0x00000000

0x40000020:    0x00000000    0x00000235    0x0000002f    0x000003e8

ADC1 registers:

(gdb) x/20x 0x40012400

0x40012400:    0x00000001    0x0000001c    0x00000001    0x00000481

0x40012410:    0x00001000    0x00000007    0x00000000    0x00000000

0x40012420:    0x0fff0000    0x00000000    0x00000038    0x00000000

I found this code, which indicates that I can't be too far off with my code.

How can I verify that TRGO actually gets generated? 

When I change the timer2 to generate an interrupt together with an isr, the isr does get called. This is on the UIE (UG) event and it is continuously called.

The errata for this chip only indicated a legal disclaimer update, so I couldn't find anything.

When I enable the ''ADC_CR_ADSTART'', the ADC kicks off and performs a conversion, but only once.

#stm32 #tim2 #trgo
1 REPLY 1
robertnoble9
Associate III
Posted on May 28, 2017 at 20:54

Hi,

Sorry to dig up an old thread, but I have a similar problem. Did you ever solve this?