BeRTOS
|
00001 00047 #include "adc_lm3s.h" 00048 00049 #include <cpu/irq.h> 00050 00051 #include "cfg/cfg_adc.h" 00052 #include "cfg/cfg_proc.h" 00053 #include "cfg/cfg_signal.h" 00054 00055 #include <cfg/macros.h> 00056 #include <cfg/compiler.h> 00057 #include <cfg/debug.h> 00058 00059 // Define log settings for cfg/log.h. 00060 #define LOG_LEVEL ADC_LOG_LEVEL 00061 #define LOG_FORMAT ADC_LOG_FORMAT 00062 #include <cfg/log.h> 00063 00064 #include <drv/adc.h> 00065 #include <drv/timer.h> 00066 #include <drv/clock_lm3s.h> 00067 00068 #include <io/lm3s.h> 00069 00070 /* Select witch ADC use */ 00071 #if CPU_CM3_LM3S1968 || CPU_CM3_LM3S8962 00072 #define ADC_BASE ADC0_BASE 00073 #define SYSCTL_RCGC_R SYSCTL_RCGC0_R 00074 #define SYSCTL_RCGC_ADC SYSCTL_RCGC0_ADC0 00075 #else 00076 #error Unknow ADC register for select cpu core 00077 #endif 00078 00079 00080 #if CONFIG_KERN 00081 #include <cfg/module.h> 00082 00083 #include <kern/proc.h> 00084 #include <kern/signal.h> 00085 00086 #include <drv/irq_cm3.h> 00087 00088 00089 #if !CONFIG_KERN_SIGNALS 00090 #error Signals must be active to use ADC with kernel 00091 #endif 00092 00093 /* Signal adc convertion end */ 00094 #define SIG_ADC_COMPLETE SIG_USER0 00095 00096 /* ADC waiting process */ 00097 static struct Process *adc_process; 00098 00103 static DECLARE_ISR(adc_conversion_end_irq) 00104 { 00105 sig_post(adc_process, SIG_ADC_COMPLETE); 00106 00107 /* Clear the status bit */ 00108 HWREG(ADC_BASE + ADC_O_ISC) |= ADC_ISC_IN3; 00109 00110 } 00111 00112 static void adc_enable_irq(void) 00113 { 00114 /* Clear all pending irq */ 00115 HWREG(ADC_BASE + ADC_O_ISC) = 0; 00116 /* Register the IRQ handler */ 00117 sysirq_setHandler(INT_ADC3, adc_conversion_end_irq); 00118 /* Enable IRQ */ 00119 HWREG(ADC_BASE + ADC_O_SSCTL3) |= ADC_SSCTL3_IE0; 00120 HWREG(ADC_BASE + ADC_O_IM) |= ADC_IM_MASK3; 00121 } 00122 00123 #endif /* CONFIG_KERN */ 00124 00132 void adc_hw_select_ch(uint8_t ch) 00133 { 00134 /* Select channel that we want read */ 00135 HWREG(ADC_BASE + ADC_O_SSMUX3) = ch; 00136 /* Make single acquisition */ 00137 HWREG(ADC_BASE + ADC_O_SSCTL3) |= ADC_SSCTL3_END0; 00138 /* Enable sequence S03 (single sample on select channel) */ 00139 HWREG(ADC_BASE + ADC_O_ACTSS) |= ADC_ACTSS_ASEN3; 00140 } 00141 00147 uint16_t adc_hw_read(void) 00148 { 00149 #if CONFIG_KERN 00150 /* Ensure ADC is not already in use by another process */ 00151 ASSERT(adc_process == NULL); 00152 adc_process = proc_current(); 00153 #endif 00154 00155 /* Start convertion */ 00156 HWREG(ADC0_BASE + ADC_O_PSSI) |= ADC_PSSI_SS3; 00157 00158 #if CONFIG_KERN 00159 /* Ensure IRQs enabled. */ 00160 IRQ_ASSERT_ENABLED(); 00161 sig_wait(SIG_ADC_COMPLETE); 00162 00163 /* Prevent race condition in case of preemptive kernel */ 00164 uint16_t ret = (uint16_t)HWREG(ADC_BASE + ADC_O_SSFIFO3); 00165 MEMORY_BARRIER; 00166 adc_process = NULL; 00167 return ret; 00168 #else 00169 /* Wait in polling until conversion is done */ 00170 while (!(HWREG(ADC_BASE + ADC_O_SSFSTAT3) & ADC_SSFSTAT3_FULL)); 00171 00172 /* Return the last converted data */ 00173 return (uint16_t)HWREG(ADC_BASE + ADC_O_SSFIFO3); 00174 #endif 00175 } 00176 00180 void adc_hw_init(void) 00181 { 00182 /* Enable ADC0 clock */ 00183 SYSCTL_RCGC_R |= SYSCTL_RCGC_ADC; 00184 00185 /* 00186 * We wait some time because the clock is istable 00187 * and that could cause system hardfault 00188 */ 00189 lm3s_busyWait(10); 00190 00191 /* Disable all sequence */ 00192 HWREG(ADC_BASE + ADC_O_ACTSS) = 0; 00193 /* Set trigger event to programmed (for all sequence) */ 00194 HWREG(ADC_BASE + ADC_O_EMUX) = 0; 00195 00196 #if CONFIG_KERN 00197 adc_enable_irq(); 00198 #endif 00199 }