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