1 #define ADC_PAGE 0x80900000
2 #define ADCRESULT_OFFSET 0x0008
3 #define SDR_MASK 0x80000000
4 #define DATA_OFFSET 0x0008
5 #define DATA_MASK 0xFFFF
6 #define ADCSWITCH_OFFSET 0x0018
7 #define ADC_CH0 0x0608
8 #define ADC_CH1 0x0680
9 #define ADC_CH2 0x0640
10 #define ADC_CH3 0x0620
11 #define ADC_CH4 0x0610
12 #define ADCSWLOCK_OFFSET 0x0020
13 #define UNLOCK_VAL 0xAA
14
15 #define SYSCON_PAGE 0x80930000
16 #define ADCCLKDIV_OFFSET 0x0090
17 #define SYSCON_UNLOCK 0x00C0
18 #define TSEN_MASK 0x80000000
19 #define DEVICECFG_OFFSET 0x0080
20 #define ADCPD_MASK 0x04
21 #define ADCEN_MASK 0x20000
22
23 /* prototypes */
24 void init_ADC(unsigned long adc_page, unsigned long syscon_page);
25 int read_channel(unsigned long adc_page, unsigned short channel);
26 static char is_ADC_busy(unsigned long adc_page);
27
init_ADC(unsigned long adc_page,unsigned long syscon_page)28 void init_ADC(unsigned long adc_page, unsigned long syscon_page)
29 {
30 unsigned long val;
31
32 /* set TSEN bit */
33 val = PEEK32(syscon_page + ADCCLKDIV_OFFSET);
34 //unlock the software lock
35 POKE32(syscon_page + SYSCON_UNLOCK, UNLOCK_VAL);
36 POKE32(syscon_page + ADCCLKDIV_OFFSET, TSEN_MASK | val);
37
38 /* set ADCEN bit */
39 val = PEEK32(syscon_page + DEVICECFG_OFFSET);
40 POKE32(syscon_page + SYSCON_UNLOCK, UNLOCK_VAL); //unlock the soft lock
41 POKE32(syscon_page + DEVICECFG_OFFSET, val | ADCEN_MASK);
42
43 /* clear ADCPD bit */
44 val = PEEK32(syscon_page + DEVICECFG_OFFSET);
45 POKE32(adc_page + SYSCON_UNLOCK, UNLOCK_VAL); //unlock the soft lock
46 POKE32(syscon_page + DEVICECFG_OFFSET, val & ~ADCPD_MASK);
47 }
48
read_channel(unsigned long adc_page,unsigned short channel)49 int read_channel(unsigned long adc_page, unsigned short channel)
50 {
51 unsigned long val;
52
53 POKE32(adc_page + ADCSWLOCK_OFFSET, UNLOCK_VAL); //unlock the soft lock
54
55 //write ADCSwitch reg to select channel
56 POKE32(adc_page + ADCSWITCH_OFFSET, channel);
57
58 while(is_ADC_busy(adc_page)); //poll ADCResult
59
60 //read result from data regisyyter
61 val = PEEK32(adc_page + DATA_OFFSET) ;
62
63 val = val & DATA_MASK;
64
65 return val;
66 }
67
is_ADC_busy(unsigned long adc_page)68 static char is_ADC_busy(unsigned long adc_page)
69 {
70 unsigned long val;
71
72 val = PEEK32(adc_page + ADCRESULT_OFFSET);
73
74 if((val & SDR_MASK) == SDR_MASK)
75 return TRUE;
76
77 return FALSE;
78 }
79