void adc_init( void ) { uint8_t x=0; // ADC channel mapping uint8_t adc_channel_map[4]; /* Init GPIO ports for ADC operation */ #if USE_ADC_1 PRINT_CONFIG_MSG("Info: Using ADC_1"); gpio_setup_pin_analog(ADC_1_GPIO_PORT, ADC_1_GPIO_PIN); #endif #if USE_ADC_2 PRINT_CONFIG_MSG("Info: Using ADC_2"); gpio_setup_pin_analog(ADC_2_GPIO_PORT, ADC_2_GPIO_PIN); #endif #if USE_ADC_3 PRINT_CONFIG_MSG("Info: Using ADC_3"); gpio_setup_pin_analog(ADC_3_GPIO_PORT, ADC_3_GPIO_PIN); #endif #if USE_ADC_4 PRINT_CONFIG_MSG("Info: Using ADC_4"); gpio_setup_pin_analog(ADC_4_GPIO_PORT, ADC_4_GPIO_PIN); #endif #if USE_ADC_5 PRINT_CONFIG_MSG("Info: Using ADC_5"); gpio_setup_pin_analog(ADC_5_GPIO_PORT, ADC_5_GPIO_PIN); #endif #if USE_ADC_6 PRINT_CONFIG_MSG("Info: Using ADC_6"); gpio_setup_pin_analog(ADC_6_GPIO_PORT, ADC_6_GPIO_PIN); #endif #if USE_ADC_7 PRINT_CONFIG_MSG("Info: Using ADC_7"); gpio_setup_pin_analog(ADC_7_GPIO_PORT, ADC_7_GPIO_PIN); #endif #if USE_ADC_8 PRINT_CONFIG_MSG("Info: Using ADC_8"); gpio_setup_pin_analog(ADC_8_GPIO_PORT, ADC_8_GPIO_PIN); #endif #if USE_ADC_9 PRINT_CONFIG_MSG("Info: Using ADC_9"); gpio_setup_pin_analog(ADC_9_GPIO_PORT, ADC_9_GPIO_PIN); #endif // Init clock and irq adc_init_rcc(); adc_init_irq(); /* If fewer than 4 channels are active, say 3, then they are placed in to * injection slots 2,3 and 4 because the stm32 architecture converts injected * slots 2,3 and 4 and skips slot 1 instead of logicaly converting slots 1,2 * and 3 and leave slot 4. * EXAMPLE OF ADC EXECUTION ORDER WHEN WE HAVE SAY 2 ADC INPUTS USED on ADC1 * The first board adc channel ADC1_1 is mapped to injected channel 3 and ADC1_2 * to injected channel 4 and because the conversions start from the lowest * injection channel used, 3 in our case, injected channel 3 data will be * located at JDR1 and 4 to JDR2 so JDR1 = ADC1_1 and JDR2 = ADC1_2. * That's why "adc_channel_map" has this descending order. */ nb_adc1_channels = NB_ADC1_CHANNELS; #if USE_AD1 #ifdef AD1_1_CHANNEL adc_channel_map[AD1_1] = AD1_1_CHANNEL; #endif #ifdef AD1_2_CHANNEL adc_channel_map[AD1_2] = AD1_2_CHANNEL; #endif #ifdef AD1_3_CHANNEL adc_channel_map[AD1_3] = AD1_3_CHANNEL; #endif #ifdef AD1_4_CHANNEL adc_channel_map[AD1_4] = AD1_4_CHANNEL; #endif // initialize buffer pointers with 0 (not set). Buffer null pointers will be ignored in interrupt // handler, which is important as there are no buffers registered at the time the ADC trigger // interrupt is enabled. for (x = 0; x < 4; x++) { adc1_buffers[x] = NULL; } adc_init_single(ADC1, nb_adc1_channels, adc_channel_map); #endif // USE_AD1 nb_adc2_channels = NB_ADC2_CHANNELS; #if USE_AD2 #ifdef AD2_1_CHANNEL adc_channel_map[AD2_1] = AD2_1_CHANNEL; #endif #ifdef AD2_2_CHANNEL adc_channel_map[AD2_2] = AD2_2_CHANNEL; #endif #ifdef AD2_3_CHANNEL adc_channel_map[AD2_3] = AD2_3_CHANNEL; #endif #ifdef AD2_4_CHANNEL adc_channel_map[AD2_4] = AD2_4_CHANNEL; #endif // initialize buffer pointers with 0 (not set). Buffer null pointers will be ignored in interrupt // handler, which is important as there are no buffers registered at the time the ADC trigger // interrupt is enabled. for (x = 0; x < 4; x++) { adc2_buffers[x] = NULL; } adc_init_single(ADC2, nb_adc2_channels, adc_channel_map); #endif // USE_AD2 nb_adc3_channels = NB_ADC3_CHANNELS; #if USE_AD3 #ifdef AD3_1_CHANNEL adc_channel_map[AD3_1] = AD3_1_CHANNEL; #endif #ifdef AD3_2_CHANNEL adc_channel_map[AD3_2] = AD3_2_CHANNEL; #endif #ifdef AD3_3_CHANNEL adc_channel_map[AD3_3] = AD3_3_CHANNEL; #endif #ifdef AD3_4_CHANNEL adc_channel_map[AD3_4] = AD3_4_CHANNEL; #endif // initialize buffer pointers with 0 (not set). Buffer null pointers will be ignored in interrupt // handler, which is important as there are no buffers registered at the time the ADC trigger // interrupt is enabled. for (x = 0; x < 4; x++) { adc3_buffers[x] = NULL; } adc_init_single(ADC3, nb_adc3_channels, adc_channel_map); #endif // USE_AD3 adc_new_data_trigger = FALSE; #if USE_ADC_WATCHDOG adc_watchdog.cb = NULL; adc_watchdog.timeStamp=0; #endif }
/** * Adc init * * Initialize ADC drivers, buffers and start conversion in the background */ void adc_init(void) { /* Init GPIO ports for ADC operation */ #if USE_ADC_1 PRINT_CONFIG_MSG("Info: Using ADC_1"); gpio_setup_pin_analog(ADC_1_GPIO_PORT, ADC_1_GPIO_PIN); #endif #if USE_ADC_2 PRINT_CONFIG_MSG("Info: Using ADC_2"); gpio_setup_pin_analog(ADC_2_GPIO_PORT, ADC_2_GPIO_PIN); #endif #if USE_ADC_3 PRINT_CONFIG_MSG("Info: Using ADC_3"); gpio_setup_pin_analog(ADC_3_GPIO_PORT, ADC_3_GPIO_PIN); #endif #if USE_ADC_4 PRINT_CONFIG_MSG("Info: Using ADC_4"); gpio_setup_pin_analog(ADC_4_GPIO_PORT, ADC_4_GPIO_PIN); #endif #if USE_ADC_5 PRINT_CONFIG_MSG("Info: Using ADC_5"); gpio_setup_pin_analog(ADC_5_GPIO_PORT, ADC_5_GPIO_PIN); #endif #if USE_ADC_6 PRINT_CONFIG_MSG("Info: Using ADC_6"); gpio_setup_pin_analog(ADC_6_GPIO_PORT, ADC_6_GPIO_PIN); #endif #if USE_ADC_7 PRINT_CONFIG_MSG("Info: Using ADC_7"); gpio_setup_pin_analog(ADC_7_GPIO_PORT, ADC_7_GPIO_PIN); #endif #if USE_ADC_8 PRINT_CONFIG_MSG("Info: Using ADC_8"); gpio_setup_pin_analog(ADC_8_GPIO_PORT, ADC_8_GPIO_PIN); #endif #if USE_ADC_9 PRINT_CONFIG_MSG("Info: Using ADC_9"); gpio_setup_pin_analog(ADC_9_GPIO_PORT, ADC_9_GPIO_PIN); #endif // Configurtion register uint32_t sqr1, sqr2, sqr3; adc_regular_sequence(&sqr1, &sqr2, &sqr3, ADC_NUM_CHANNELS, adc_channel_map); #ifdef __STM32F10x_H uint32_t smpr1, smpr2; adc_sample_time_on_all_channels(&smpr1, &smpr2, ADC_SAMPLE_41P5); adcgrpcfg.cr2 = ADC_CR2_TSVREFE; #elif defined(__STM32F4xx_H) uint32_t smpr1, smpr2; adc_sample_time_on_all_channels(&smpr1, &smpr2, ADC_SAMPLE_480); adcgrpcfg.cr2 = ADC_CR2_SWSTART; #endif #if USE_ADC_WATCHDOG adc_watchdog.adc = NULL; adc_watchdog.cb = NULL; adc_watchdog.channel = 0; adc_watchdog.vmin = (1<<12)-1; // max adc #endif adcgrpcfg.circular = TRUE; adcgrpcfg.num_channels = ADC_NUM_CHANNELS; adcgrpcfg.end_cb = adc1callback; adcgrpcfg.error_cb = adcerrorcallback; adcgrpcfg.cr1 = 0; adcgrpcfg.smpr1 = smpr1; adcgrpcfg.smpr2 = smpr2; adcgrpcfg.sqr1 = sqr1; adcgrpcfg.sqr2 = sqr2; adcgrpcfg.sqr3 = sqr3; // Start ADC in continious conversion mode adcStart(&ADCD1, NULL); adcStartConversion(&ADCD1, &adcgrpcfg, adc_samples, ADC_BUF_DEPTH); }