adc_sam3.c
Go to the documentation of this file.
00001
00039 #include "adc_sam3.h"
00040
00041 #include "cfg/cfg_adc.h"
00042
00043 #include <cfg/macros.h>
00044 #include <cfg/compiler.h>
00045
00046 // Define log settings for cfg/log.h.
00047 #define LOG_LEVEL         ADC_LOG_LEVEL
00048 #define LOG_FORMAT        ADC_LOG_FORMAT
00049 #include <cfg/log.h>
00050
00051 #include <drv/adc.h>
00052 #include <drv/irq_cm3.h>
00053
00054 #include <cpu/irq.h>
00055
00056 #include <mware/event.h>
00057
00058 #include <io/cm3.h>
00059
00060
00061 /* We use event to signal the end of conversion */
00062 static Event adc_data_ready;
00063 /* The last converted data */
00064 static uint32_t data;
00065
00077 static DECLARE_ISR(adc_conversion_end_irq)
00078 {
00079     if (ADC_ISR & BV(ADC_DRDY))
00080     {
00081         data = ADC_LDATA;
00082         event_do(&adc_data_ready);
00083     }
00084 }
00085
00089 void adc_hw_select_ch(uint8_t ch)
00090 {
00091     /* Disable all channels */
00092     ADC_CHDR = ADC_CH_MASK;
00093     /* Enable select channel */
00094     ADC_CHER = BV(ch);
00095 }
00096
00100 uint16_t adc_hw_read(void)
00101 {
00102     ADC_CR = BV(ADC_START);
00103     event_wait(&adc_data_ready);
00104     return(data);
00105 }
00106
00110 void adc_hw_init(void)
00111 {
00112     /* Make sure that interrupt are enabled */
00113     IRQ_ASSERT_ENABLED();
00114
00115     /* Initialize the dataready event */
00116     event_initGeneric(&adc_data_ready);
00117
00118     /* Clock ADC peripheral */
00119     pmc_periphEnable(ADC_ID);
00120
00121      /* Reset adc controller */
00122     ADC_CR |= BV(ADC_SWRST);
00123
00124     /*
00125      * Set adc mode register:
00126      * - Disable hardware trigger and enable software trigger.
00127      * - Select normal mode.
00128      */
00129     ADC_MR = 0;
00130
00131     /* Set ADC_BITS bit convertion resolution. */
00132     #if ADC_BITS == 12
00133         ADC_MR &= ~BV(ADC_LOWRES);
00134     #elif ADC_BITS == 10
00135         ADC_MR |= BV(ADC_LOWRES);
00136     #else
00137         #error No select bit resolution is supported to this CPU
00138     #endif
00139 
00140     /* Setup ADC */
00141     LOG_INFO("Computed ADC_CLOCK %ld\n", ADC_CLOCK);
00142     ADC_MR |= ((ADC_PRESCALER << ADC_PRESCALER_SHIFT) & ADC_PRESCALER_MASK);
00143     LOG_INFO("prescaler[%ld]\n", ADC_PRESCALER);
00144     ADC_MR |= ((CONFIG_ADC_SUT << ADC_STARTUP_SHIFT) & ADC_STARTUP_MASK);
00145     LOG_INFO("starup[%d]\n", CONFIG_ADC_SUT);
00146     ADC_MR |= ((CONFIG_ADC_STTLING << ADC_SETTLING_SHIFT) & ADC_SETTLING_MASK);
00147     LOG_INFO("sttime[%d]\n", CONFIG_ADC_STTLING);
00148     ADC_MR |= ((CONFIG_ADC_TRACKTIM << ADC_TRACKTIM_SHIFT) & ADC_TRACKTIM_MASK);
00149     LOG_INFO("tracking[%d]\n", CONFIG_ADC_TRACKTIM);
00150     ADC_MR |= ((CONFIG_ADC_TRANSFER << ADC_TRANSFER_SHIFT) & ADC_TRANSFER_MASK);
00151     LOG_INFO("tranfer[%d]\n", CONFIG_ADC_TRANSFER);
00152
00153     /* Register and enable irq for adc. */
00154     sysirq_setHandler(INT_ADC, adc_conversion_end_irq);
00155     ADC_IER = BV(ADC_DRDY);
00156 }