2014-11-12 03:49 AM
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 #trgo2017-05-28 11:54 AM
Hi,
Sorry to dig up an old thread, but I have a similar problem. Did you ever solve this?