Xmega Application Note


asf_adc_example_interrupt.c

Go to the documentation of this file.
00001 #include <string.h>
00002 #include "adc.h"
00003 #include "pmic.h"
00004 
00006 #define SAMPLE_COUNT 100
00007 
00008 void adc_ch3_callback(ADC_t *adc, uint8_t ch, adc_result_t res);
00009 
00011 int16_t adcSamples[4][SAMPLE_COUNT];
00012 
00013 uint16_t interrupt_count = 0;
00014 int8_t offset;
00015 
00016 int main(void)
00017 {
00018         struct adc_config           adc_conf;
00019         struct adc_channel_config       adc_ch_conf_ch0;
00020         struct adc_channel_config       adc_ch_conf_ch1;
00021         struct adc_channel_config       adc_ch_conf_ch2;
00022         struct adc_channel_config       adc_ch_conf_ch3;
00023     uint16_t        ADCA_cal;
00024 
00025         /* Move stored calibration values to ADC A. */
00026     /* I can not find any function to insert this calibration data into the ADC */
00027     ADCA_cal = adc_get_calibration_data(ADC_CAL_ADCA);
00028 
00029         // Clear the configuration structures.
00030         memset(&adc_conf, 0, sizeof(struct adc_config));
00031         memset(&adc_ch_conf_ch0, 0, sizeof(struct adc_channel_config));
00032         memset(&adc_ch_conf_ch1, 0, sizeof(struct adc_channel_config));
00033         memset(&adc_ch_conf_ch2, 0, sizeof(struct adc_channel_config));
00034         memset(&adc_ch_conf_ch3, 0, sizeof(struct adc_channel_config));
00035 
00036         /* Set up ADC A to have signed conversion mode and 12 bit resolution. 
00037        and set ref to internal VCC/1.6 V.*/
00038         adc_set_conversion_parameters(&adc_conf, ADC_SIGN_ON, ADC_RES_12, ADC_REF_VCC);
00039 
00040         /* Set sample rate */
00041         adc_set_clock_rate(&adc_conf, 200000UL);
00042 
00043     /* Write ADC module configuration */
00044     adc_write_configuration(&ADCA, &adc_conf);
00045 
00046         /* Get offset value for ADC A. */
00047         adcch_set_input(&adc_ch_conf_ch0, ADCCH_POS_PIN1, ADCCH_NEG_PIN1, 1);
00048     adcch_write_configuration(&ADCA, 0, &adc_ch_conf_ch0);
00049 
00050         adc_enable(&ADCA);
00051 
00052         /* Wait until common mode voltage is stable which take exactly one conversion */
00053     adc_start_conversion(&ADCA, ADC_CH0);
00054     adc_wait_for_interrupt_flag(&ADCA, ADC_CH0);
00055 
00056     /* Get offset value */
00057     adc_start_conversion(&ADCA, ADC_CH0);
00058     adc_wait_for_interrupt_flag(&ADCA, ADC_CH0);
00059         offset = adcch_get_result(&ADCA, 0);
00060     adc_disable(&ADCA);
00061     
00062         /* Setup channel 0, 1, 2 and 3 to have single ended input.
00063            Set input to the channels in ADC A to be PIN 4, 5, 6 and 7. */
00064         adcch_set_input(&adc_ch_conf_ch0, ADCCH_POS_PIN4, ADCCH_NEG_NONE, 1);
00065         adcch_set_input(&adc_ch_conf_ch1, ADCCH_POS_PIN5, ADCCH_NEG_NONE, 1);
00066         adcch_set_input(&adc_ch_conf_ch2, ADCCH_POS_PIN6, ADCCH_NEG_NONE, 1);
00067         adcch_set_input(&adc_ch_conf_ch3, ADCCH_POS_PIN7, ADCCH_NEG_NONE, 1);
00068 
00069         /* Set interrupt mode to conversion complete on channel 3. */
00070     adcch_set_interrupt_mode(&adc_ch_conf_ch3, ADC_CH_INTMODE_COMPLETE_gc);
00071 
00072     /* Enable interrupt on channel 3, low level is default interrupt level */
00073     adcch_enable_interrupt(&adc_ch_conf_ch3);
00074 
00075     /* Write configuration to channels */
00076     adcch_write_configuration(&ADCA, 0, &adc_ch_conf_ch0);
00077     adcch_write_configuration(&ADCA, 1, &adc_ch_conf_ch1);
00078     adcch_write_configuration(&ADCA, 2, &adc_ch_conf_ch2);
00079     adcch_write_configuration(&ADCA, 3, &adc_ch_conf_ch3);
00080    
00081         /* Enable PMIC interrupt level low. */
00082     pmic_enable_level(PMIC_LVL_LOW);
00083     adc_set_callback(&ADCA, adc_ch3_callback);
00084 
00085         /* Enable global interrupts. */
00086         sei();
00087 
00088         /* Setup sweep of all four virtual channels.*/
00089         /* Enable free running mode. */
00090     adc_set_conversion_trigger(&adc_conf, ADC_TRIG_FREERUN_SWEEP, 4, 0);
00091     adc_write_configuration(&ADCA, &adc_conf);
00092 
00093         /* Enable ADC A with free running mode, VCC reference and signed conversion.*/
00094         adc_enable(&ADCA);
00095 
00096         /* Eternal loop to wait for the conversions and interrupts to finnish. */
00097         while(true){
00098         asm("nop");
00099         }
00100 }
00101 
00102 
00110 void adc_ch3_callback(ADC_t *adc, uint8_t ch, adc_result_t res)
00111 {
00112         /*  Read samples and clear interrupt flags. */
00113         adcSamples[0][interrupt_count] = adcch_get_signed_result(&ADCA, 0) - offset;
00114         adcSamples[1][interrupt_count] = adcch_get_signed_result(&ADCA, 1) - offset;
00115         adcSamples[2][interrupt_count] = adcch_get_signed_result(&ADCA, 2) - offset;
00116         adcSamples[3][interrupt_count] = res - offset;
00117 
00118         if(interrupt_count == SAMPLE_COUNT-1)
00119     {
00120         struct adc_channel_config       adc_ch_conf_ch3;
00121         struct adc_config           adc_conf;
00122 
00123         memset(&adc_ch_conf_ch3, 0, sizeof(struct adc_channel_config));
00124         memset(&adc_conf, 0, sizeof(struct adc_config));
00125 
00126         adc_set_conversion_trigger(&adc_conf, ADC_TRIG_MANUAL, 4, 0);
00127         adc_write_configuration(&ADCA, &adc_conf);
00128 
00129         adcch_disable_interrupt(&adc_ch_conf_ch3);
00130         adcch_write_configuration(&ADCA, 3, &adc_ch_conf_ch3);
00131                 adc_disable(&ADCA);
00132         }
00133 
00134         interrupt_count++;
00135 }
@DOC_TITLE@
Generated on Fri Oct 22 12:15:25 2010 for AVR1300 Using the Xmega ADC by doxygen 1.6.3