BeRTOS
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 data_ready;
00063 /* The last converted data */
00064 static uint32_t data;
00065 
00077 static DECLARE_ISR(adc_conversion_end_irq)
00078 {
00079     data = 0;
00080     if (ADC_ISR & BV(ADC_DRDY))
00081     {
00082         data = ADC_LDATA;
00083         event_do(&data_ready);
00084     }
00085 }
00086 
00090 void adc_hw_select_ch(uint8_t ch)
00091 {
00092     /* Disable all channels */
00093     ADC_CHDR = ADC_CH_MASK;
00094     /* Enable select channel */
00095     ADC_CHER = BV(ch);
00096 }
00097 
00101 uint16_t adc_hw_read(void)
00102 {
00103     ADC_CR = BV(ADC_START);
00104     event_wait(&data_ready);
00105     return(data);
00106 }
00107 
00111 void adc_hw_init(void)
00112 {
00113     /* Make sure that interrupt are enabled */
00114     IRQ_ASSERT_ENABLED();
00115 
00116     /* Initialize the dataready event */
00117     event_initGeneric(&data_ready);
00118 
00119     /* Clock ADC peripheral */
00120     pmc_periphEnable(ADC_ID);
00121 
00122      /* Reset adc controller */
00123     ADC_CR = ADC_SWRST;
00124 
00125     /*
00126      * Set adc mode register:
00127      * - Disable hardware trigger and enable software trigger.
00128      * - Select normal mode.
00129      */
00130     ADC_MR = 0;
00131 
00132     /* Set ADC_BITS bit convertion resolution. */
00133     #if ADC_BITS == 12
00134         ADC_MR &= ~BV(ADC_LOWRES);
00135     #elif ADC_BITS == 10
00136         ADC_MR |= BV(ADC_LOWRES);
00137     #else
00138         #error No select bit resolution is supported to this CPU
00139     #endif
00140 
00141     /* Setup ADC */
00142     LOG_INFO("Computed ADC_CLOCK %ld\n", ADC_CLOCK);
00143     ADC_MR |= ((ADC_PRESCALER << ADC_PRESCALER_SHIFT) & ADC_PRESCALER_MASK);
00144     LOG_INFO("prescaler[%ld]\n", ADC_PRESCALER);
00145     ADC_MR |= ((CONFIG_ADC_SUT << ADC_STARTUP_SHIFT) & ADC_STARTUP_MASK);
00146     LOG_INFO("starup[%d]\n", CONFIG_ADC_SUT);
00147     ADC_MR |= ((CONFIG_ADC_STTLING << ADC_SETTLING_SHIFT) & ADC_SETTLING_MASK);
00148     LOG_INFO("sttime[%d]\n", CONFIG_ADC_STTLING);
00149     ADC_MR |= ((CONFIG_ADC_TRACKTIM << ADC_TRACKTIM_SHIFT) & ADC_TRACKTIM_MASK);
00150     LOG_INFO("tracking[%d]\n", CONFIG_ADC_TRACKTIM);
00151     ADC_MR |= ((CONFIG_ADC_TRANSFER << ADC_TRANSFER_SHIFT) & ADC_TRANSFER_MASK);
00152     LOG_INFO("tranfer[%d]\n", CONFIG_ADC_TRANSFER);
00153 
00154     /* Register and enable irq for adc. */
00155     sysirq_setHandler(INT_ADC, adc_conversion_end_irq);
00156     ADC_IER = BV(ADC_DRDY);
00157 }