summaryrefslogtreecommitdiffstats
path: root/firmware/target/arm/s3c2440/adc-s3c2440.c
diff options
context:
space:
mode:
authorDominik Wenger <domonoky@googlemail.com>2009-10-26 18:16:58 +0000
committerDominik Wenger <domonoky@googlemail.com>2009-10-26 18:16:58 +0000
commit90b576f55ea6854a70c8ed77095b42e57b744723 (patch)
tree33b5a4d1b76b435ef6ec5138e7160d9d32c955c1 /firmware/target/arm/s3c2440/adc-s3c2440.c
parent6d20102a9c468135770f820a896dad3518c2093f (diff)
downloadrockbox-90b576f55ea6854a70c8ed77095b42e57b744723.tar.gz
rockbox-90b576f55ea6854a70c8ed77095b42e57b744723.zip
Many more drivers for mini2440. Now the main binary compiles and runs.
Flyspray: FS#10725 Author: Bob Cousins git-svn-id: svn://svn.rockbox.org/rockbox/trunk@23362 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/arm/s3c2440/adc-s3c2440.c')
-rw-r--r--firmware/target/arm/s3c2440/adc-s3c2440.c140
1 files changed, 140 insertions, 0 deletions
diff --git a/firmware/target/arm/s3c2440/adc-s3c2440.c b/firmware/target/arm/s3c2440/adc-s3c2440.c
new file mode 100644
index 0000000000..fd5151a3bf
--- /dev/null
+++ b/firmware/target/arm/s3c2440/adc-s3c2440.c
@@ -0,0 +1,140 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2006 by Wade Brown
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#include "cpu.h"
+#include "system.h"
+#include "adc.h"
+#include "adc-target.h"
+#include "kernel.h"
+
+static unsigned short adc_readings[NUM_ADC_CHANNELS];
+
+/* prototypes */
+static unsigned short __adc_read(int channel);
+static void adc_tick(void);
+
+void adc_init(void)
+{
+ int i;
+
+ /* Turn on the ADC PCLK */
+ s3c_regset32(&CLKCON, 1<<15);
+
+ /* Set channel 0, normal mode, disable "start by read" */
+ ADCCON &= ~(0x3F);
+
+ /* No start delay. Use normal conversion mode. */
+ ADCDLY = 0x1;
+
+ /* Set and enable the prescaler */
+ ADCCON = (ADCCON & ~(0xff<<6)) | (0x19<<6);
+ ADCCON |= (1<<14);
+
+ /* prefill the adc channels */
+ for (i = 0; i < NUM_ADC_CHANNELS; i++)
+ {
+ adc_readings[i] = __adc_read(i);
+ }
+
+ /* start at zero so when the tick starts it is at zero */
+ adc_readings[0] = __adc_read(0);
+
+ /* attach the adc reading to the tick */
+ tick_add_task(adc_tick);
+}
+
+/* Called to get the recent ADC reading */
+inline unsigned short adc_read(int channel)
+{
+ return adc_readings[channel];
+}
+
+/**
+ * Read the ADC by polling
+ * @param channel The ADC channel to read
+ * @return 10bit reading from ADC channel or ADC_READ_ERROR if timeout
+ */
+static unsigned short __adc_read(int channel)
+{
+ int i;
+
+ /* Set the channel */
+ ADCCON = (ADCCON & ~(0x7<<3)) | (channel<<3);
+
+ /* Start the conversion process */
+ ADCCON |= 0x1;
+
+ /* Wait for a low Enable_start */
+ for (i = 20000;;)
+ {
+ if(0 == (ADCCON & 0x1))
+ {
+ break;
+ }
+ else
+ {
+ i--;
+ if (0 == i)
+ {
+ /* Ran out of time */
+ return ADC_READ_ERROR;
+ }
+ }
+ }
+
+ /* Wait for high End_of_Conversion */
+ for(i = 20000;;)
+ {
+ if(ADCCON & (1<<15))
+ {
+ break;
+ }
+ else
+ {
+ i--;
+ if(0 == i)
+ {
+ /* Ran out of time */
+ return ADC_READ_ERROR;
+ }
+ }
+ }
+ return (ADCDAT0 & 0x3ff);
+}
+
+/* add this to the tick so that the ADC converts are done in the background */
+static void adc_tick(void)
+{
+ static unsigned channel;
+
+ /* Check if the End Of Conversion is set */
+ if (ADCCON & (1<<15))
+ {
+ adc_readings[channel] = (ADCDAT0 & 0x3FF);
+ if (++channel >= NUM_ADC_CHANNELS)
+ {
+ channel = 0;
+ }
+
+ /* setup the next conversion and start it*/
+ ADCCON = (ADCCON & ~(0x7<<3)) | (channel<<3) | 0x01;
+ }
+}
+