1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2006 by Wade Brown
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
24 #include "adc-target.h"
28 #include "touchscreen-target.h"
31 static unsigned short adc_readings
[NUM_ADC_CHANNELS
];
34 static unsigned short __adc_read(int channel
);
35 static void adc_tick(void);
41 /* Turn on the ADC PCLK */
42 s3c_regset32(&CLKCON
, 1<<15);
44 /* Set channel 0, normal mode, disable "start by read" */
47 /* No start delay. Use normal conversion mode. */
50 /* Set and enable the prescaler */
51 ADCCON
= (ADCCON
& ~(0xff<<6)) | (0x19<<6);
54 /* prefill the adc channels */
55 for (i
= 0; i
< NUM_ADC_CHANNELS
; i
++)
57 adc_readings
[i
] = __adc_read(i
);
60 /* start at zero so when the tick starts it is at zero */
61 adc_readings
[0] = __adc_read(0);
63 /* attach the adc reading to the tick */
64 tick_add_task(adc_tick
);
67 /* Called to get the recent ADC reading */
68 inline unsigned short adc_read(int channel
)
70 return adc_readings
[channel
];
74 * Read the ADC by polling
75 * @param channel The ADC channel to read
76 * @return 10bit reading from ADC channel or ADC_READ_ERROR if timeout
78 static unsigned short __adc_read(int channel
)
83 ADCCON
= (ADCCON
& ~(0x7<<3)) | (channel
<<3);
85 /* Start the conversion process */
88 /* Wait for a low Enable_start */
91 if(0 == (ADCCON
& 0x1))
100 /* Ran out of time */
101 return ADC_READ_ERROR
;
106 /* Wait for high End_of_Conversion */
118 /* Ran out of time */
119 return ADC_READ_ERROR
;
123 return (ADCDAT0
& 0x3ff);
126 /* add this to the tick so that the ADC converts are done in the background */
127 static void adc_tick(void)
129 static unsigned channel
=0;
131 /* Check if the End Of Conversion is set */
132 if (ADCCON
& (1<<15))
134 adc_readings
[channel
] = (ADCDAT0
& 0x3FF);
135 if (++channel
>= NUM_ADC_CHANNELS
)
140 /* interleave a touchscreen read if neccessary */
141 touchscreen_scan_device();
143 /* setup the next conversion and start it*/
144 ADCCON
= (ADCCON
& ~(0x7<<3)) | (channel
<<3) | 0x01;