static void rtouch_start_read(uint32_t channel) { #ifdef AVR32_ADCIFA volatile avr32_adcifa_t *adcifa = &RTOUCH_ADC; s_current_channel = channel; if (channel < 8) { adcifa_sequence_conversion_opt[0].channel_p = channel; adcifa_sequence_conversion_opt[0].channel_n = AVR32_ADCIFA_INN_GNDANA; adcifa_sequence_conversion_opt[0].gain = ADCIFA_SHG_1; } else { adcifa_sequence_conversion_opt[0].channel_p = AVR32_ADCIFA_INP_GNDANA; adcifa_sequence_conversion_opt[0].channel_n = channel; adcifa_sequence_conversion_opt[0].gain = ADCIFA_SHG_1; } adcifa_configure_sequencer(adcifa, 0, &adcifa_sequence_opt, adcifa_sequence_conversion_opt); adcifa_start_sequencer(adcifa, 0); #else volatile avr32_adc_t *adc = &RTOUCH_ADC; /* disable all touch channels */ adc->chdr = RTOUCH_ADC_XL_CHANNEL | RTOUCH_ADC_YL_CHANNEL | RTOUCH_ADC_XH_CHANNEL | RTOUCH_ADC_YH_CHANNEL; /* enable current touch channel */ adc->cher = channel; adc_start(adc); #endif }
void adcifa_calibrate_offset(volatile avr32_adcifa_t *adcifa, adcifa_opt_t *p_adcifa_opt, uint32_t pb_hz){ /* Sequencer Configuration */ adcifa_sequencer_opt_t adcifa_sequence_opt; adcifa_sequencer_conversion_opt_t adcifa_sequence_conversion_opt[CALIBRATION_ADCIFA_NUMBER_OF_SEQUENCE]; /* Configure the ADC */ p_adcifa_opt->sample_and_hold_disable = true; p_adcifa_opt->single_sequencer_mode = true; p_adcifa_opt->free_running_mode_enable = false; p_adcifa_opt->sleep_mode_enable = false; p_adcifa_opt->mux_settle_more_time = false; /* Clear offset calibration value before starting calibration */ p_adcifa_opt->offset_calibration_value = 0; /* Configure ADCIFA core */ adcifa_configure(&AVR32_ADCIFA, p_adcifa_opt, pb_hz); /* ADCIFA sequencer 0 configuration structure*/ adcifa_sequence_opt.convnb = CALIBRATION_ADCIFA_NUMBER_OF_SEQUENCE; adcifa_sequence_opt.resolution = ADCIFA_SRES_12B; adcifa_sequence_opt.trigger_selection = ADCIFA_TRGSEL_SOFT; adcifa_sequence_opt.start_of_conversion = ADCIFA_SOCB_ALLSEQ; adcifa_sequence_opt.sh_mode = ADCIFA_SH_MODE_OVERSAMP; adcifa_sequence_opt.half_word_adjustment = ADCIFA_HWLA_NOADJ; adcifa_sequence_opt.software_acknowledge = ADCIFA_SA_NO_EOS_SOFTACK; /* ADCIFA conversions for sequencer 0*/ for (uint8_t i=0; i<CALIBRATION_ADCIFA_NUMBER_OF_SEQUENCE; i++){ adcifa_sequence_conversion_opt[i].channel_p = AVR32_ADCIFA_INP_GNDANA; adcifa_sequence_conversion_opt[i].channel_n = AVR32_ADCIFA_INN_GNDANA; adcifa_sequence_conversion_opt[i].gain = ADCIFA_SHG_1; } /* Configure ADCIFA sequencer 0 */ adcifa_configure_sequencer(&AVR32_ADCIFA, 0, &adcifa_sequence_opt, adcifa_sequence_conversion_opt); /* Start ADCIFA sequencer 0 */ adcifa_start_sequencer(&AVR32_ADCIFA, 0); /* Wait end of ADCIFA sequencer 0*/ while(!ADCIFA_is_eos_sequencer_0()); /* The last converted value is the offset value */ p_adcifa_opt->offset_calibration_value = - ADCIFA_read_resx_sequencer_0(CALIBRATION_ADCIFA_NUMBER_OF_SEQUENCE-1); }
///< starts sampling, captures one buffer length and then stops void adc_int_start_sampling(int32_t length, int32_t samplingrate, int32_t set_oversampling, int32_t set_oversampling_divider, bool continuous) { ///< Configure ADCIFA sequencer 0 adcifa_sequence_opt.convnb = sequencer_item_count; adcifa_configure_sequencer(adcifa, 0, (adcifa_sequencer_opt_t *)&adcifa_sequence_opt, (adcifa_sequencer_conversion_opt_t *)&adcifa_sequencer0_conversion_opt); oversampling = set_oversampling; oversampling_divider = set_oversampling_divider; volatile int32_t period_us = adc_config_options.frequency / (samplingrate*oversampling); oversampling_counter = 0; sample_counter = -10; number_of_samples = length; continuous_mode = continuous; channel_count = sequencer_item_count; adcifa_enable_interrupt(adcifa, ADC_INT_SEOS0); //adcifa_enable_interrupt(adcifa, ADC_INT_SEOS1); adcifa_start_itimer(adcifa, period_us); }
/** \brief Main function to initialize the system and loop to display ADC values * */ int main( void ) { int16_t adc_values[EXAMPLE_ADCIFA_NUMBER_OF_SEQUENCE]; adcifa_sequencer_opt_t adcifa_sequence_opt ; adcifa_sequencer_conversion_opt_t adcifa_sequence_conversion_opt[EXAMPLE_ADCIFA_NUMBER_OF_SEQUENCE]; adcifa_opt_t adc_config_t ; adcifa_window_monitor_opt_t adcifa_window_monitor_0_opt; adcifa_window_monitor_opt_t adcifa_window_monitor_1_opt; /* GPIO pin/adc-function map. */ const gpio_map_t ADCIFA_GPIO_MAP = { {AVR32_ADCREF0_PIN, AVR32_ADCREF0_FUNCTION}, {AVR32_ADCREFP_PIN, AVR32_ADCREFP_FUNCTION}, {AVR32_ADCREFN_PIN, AVR32_ADCREFN_FUNCTION}, {EXAMPLE_ADC_POTENTIOMETER_PIN, EXAMPLE_ADC_POTENTIOMETER_FUNCTION}, {EXAMPLE_ADC_MIC_PIN, EXAMPLE_ADC_MIC_FUNCTION} }; /* Init system clocks */ sysclk_init(); /* Init debug serial line */ init_dbg_rs232(sysclk_get_cpu_hz()); /* Assign and enable GPIO pins to the ADC function. */ gpio_enable_module(ADCIFA_GPIO_MAP, sizeof(ADCIFA_GPIO_MAP) / sizeof(ADCIFA_GPIO_MAP[0])); /* Configure the ADC for the application*/ adc_config_t.frequency = 1000000; adc_config_t.reference_source = ADCIFA_ADCREF0; adc_config_t.sample_and_hold_disable = false; adc_config_t.single_sequencer_mode = false; adc_config_t.free_running_mode_enable = false; adc_config_t.sleep_mode_enable = false; adc_config_t.mux_settle_more_time = false; /* Get ADCIFA Factory Configuration */ adcifa_get_calibration_data(&AVR32_ADCIFA, &adc_config_t); /* Calibrate offset first*/ adcifa_calibrate_offset(&AVR32_ADCIFA, &adc_config_t, sysclk_get_cpu_hz()); /* Configure ADCIFA core */ adcifa_configure(&AVR32_ADCIFA, &adc_config_t, sysclk_get_cpu_hz()); /* ADCIFA sequencer 0 configuration structure*/ adcifa_sequence_opt.convnb = EXAMPLE_ADCIFA_NUMBER_OF_SEQUENCE; adcifa_sequence_opt.resolution = ADCIFA_SRES_12B; adcifa_sequence_opt.trigger_selection = ADCIFA_TRGSEL_SOFT; adcifa_sequence_opt.start_of_conversion = ADCIFA_SOCB_ALLSEQ; adcifa_sequence_opt.sh_mode = ADCIFA_SH_MODE_OVERSAMP; adcifa_sequence_opt.half_word_adjustment= ADCIFA_HWLA_NOADJ; adcifa_sequence_opt.software_acknowledge= ADCIFA_SA_NO_EOS_SOFTACK; /* ADCIFA conversions for sequencer 0*/ adcifa_sequence_conversion_opt[0].channel_p = EXAMPLE_ADC_POTENTIOMETER_INP; adcifa_sequence_conversion_opt[0].channel_n = EXAMPLE_ADC_POTENTIOMETER_INN; adcifa_sequence_conversion_opt[0].gain = ADCIFA_SHG_1; adcifa_sequence_conversion_opt[1].channel_p = EXAMPLE_ADC_MIC_INP; adcifa_sequence_conversion_opt[1].channel_n = EXAMPLE_ADC_MIC_INN; adcifa_sequence_conversion_opt[1].gain = ADCIFA_SHG_8; /* Window Monitor 0 Configuration */ /* Window Mode 2 -> Active (If Result Register > Low Threshold) */ adcifa_window_monitor_0_opt.mode = ADCIFA_WINDOW_MODE_ABOVE; /* First channel in the configured sequence */ adcifa_window_monitor_0_opt.source_index = 0; /* Low Threshold Equivalent ADC counts */ adcifa_window_monitor_0_opt.low_threshold = 0x1FF; /* High Threshold Equivalent ADC counts */ adcifa_window_monitor_0_opt.high_threshold = 0; /* Window Monitor 1 Configuration */ /* Window Mode 2 -> Active (If Result Register > Low Threshold) */ adcifa_window_monitor_1_opt.mode = ADCIFA_WINDOW_MODE_ABOVE; /* Second channel in the configured sequence */ adcifa_window_monitor_1_opt.source_index = 1; /* Low Threshold Equivalent ADC counts */ adcifa_window_monitor_1_opt.low_threshold = 0x1FF; /* High Threshold Equivalent ADC counts */ adcifa_window_monitor_1_opt.high_threshold = 0; /* * Initialize the interrupt vectors * Note: This function adds nothing for IAR as the interrupts are * handled by the IAR compiler itself. It provides an abstraction * between GCC & IAR compiler to use interrupts. * Refer function implementation in interrupt_avr32.h */ irq_initialize_vectors(); /* * Register the ADCIFA interrupt handler * Note: This function adds nothing for IAR as the interrupts are * handled by the IAR compiler itself. It provides an abstraction * between GCC & IAR compiler to use interrupts. * Refer function implementation in interrupt_avr32.h */ irq_register_handler(&ADCIFA_interrupt_handler, AVR32_ADCIFA_WINDOW_IRQ, ADC_INTERRUPT_PRIORITY); /* Enable global Interrupts */ Enable_global_interrupt(); /* Configure ADCIFA Window Monitor 0 */ adcifa_configure_window_monitor(&AVR32_ADCIFA, 0 , &adcifa_window_monitor_0_opt); /* Configure ADCIFA Window Monitor 1 */ adcifa_configure_window_monitor(&AVR32_ADCIFA, 1 , &adcifa_window_monitor_1_opt); /* Enable the Window Monitor 0 Interrupt */ adcifa_enable_interrupt(&AVR32_ADCIFA,AVR32_ADCIFA_IDR_WM0_MASK); /* Enable the Window Monitor 1 Interrupt */ adcifa_enable_interrupt(&AVR32_ADCIFA,AVR32_ADCIFA_IDR_WM1_MASK); /* Configure ADCIFA sequencer 0 */ adcifa_configure_sequencer(&AVR32_ADCIFA, 0, &adcifa_sequence_opt, adcifa_sequence_conversion_opt); /* Start ADCIFA sequencer 0 */ adcifa_start_sequencer(&AVR32_ADCIFA, 0); while (true) { /* Get Values from sequencer 0 */ if (adcifa_get_values_from_sequencer(&AVR32_ADCIFA, 0, &adcifa_sequence_opt, adc_values) == ADCIFA_STATUS_COMPLETED) { /* Display values to user */ /* Display header */ print_dbg("\x1B[2J\x1B[H\r\nADCIFA Example\r\n"); print_dbg("HEX Value for Channel potentiometer: 0x"); print_dbg_hex(adc_values[0]); print_dbg("\r\n"); if(window1) { /* Out of Range -> Action */ print_dbg(" Window 1 : Out of Range\r\n"); window1=false; adcifa_enable_interrupt(&AVR32_ADCIFA,AVR32_ADCIFA_IDR_WM0_MASK); } else { print_dbg(" Window 1 : Inside Range\r\n"); } print_dbg("HEX Value for Channel microphone: 0x"); print_dbg_hex(~adc_values[1]); print_dbg("\r\n"); if(window2) { /* Out of Range -> Action */ print_dbg(" Window 2 : Out of Range\r\n"); window2=false; adcifa_enable_interrupt(&AVR32_ADCIFA,AVR32_ADCIFA_IDR_WM1_MASK); } else { print_dbg(" Window 2 : Inside Range\r\n"); } /* * Clear end-of-sequence for sequencer 0, * ready for next conversion. */ ADCIFA_clear_eos_sequencer_0(); /* Start new ADCIFA sequencer 0 */ adcifa_start_sequencer(&AVR32_ADCIFA, 0); } /* Slow down display of converted values */ delay_ms(100); } }