blob: f87a1694f299aed8e3abb44bfc8836a1fe03f691 [file] [log] [blame]
Rob Purchase47ea0302008-01-14 22:04:48 +00001/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2007 by Dave Chapman
11 *
Daniel Stenberg2acc0ac2008-06-28 18:10:04 +000012 * 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.
Rob Purchase47ea0302008-01-14 22:04:48 +000016 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include "config.h"
22#include "cpu.h"
23#include "system.h"
24#include "kernel.h"
25#include "thread.h"
26#include "string.h"
27#include "adc.h"
28
Rob Purchase47ea0302008-01-14 22:04:48 +000029static unsigned short adcdata[8];
30
Rob Purchase36f8fba2008-04-04 23:43:31 +000031#ifndef BOOTLOADER
32
33/* Tick task */
34static void adc_tick(void)
Rob Purchase47ea0302008-01-14 22:04:48 +000035{
36 int i;
Rob Purchase36f8fba2008-04-04 23:43:31 +000037
38 PCLK_ADC |= PCK_EN; /* Enable ADC clock */
39
40 /* Start converting the first 4 channels */
41 for (i = 0; i < 4; i++)
42 ADCCON = i;
43
44}
45
46/* IRQ handler */
47void ADC(void)
48{
49 int num;
50 uint32_t adc_status;
51
52 do
53 {
54 adc_status = ADCSTATUS;
55 num = (adc_status>>24) & 7;
56 if (num) adcdata[(adc_status >> 16) & 0x7] = adc_status & 0x3ff;
57 } while (num);
58
59 PCLK_ADC &= ~PCK_EN; /* Disable ADC clock */
60}
61#endif /* BOOTLOADER */
62
63
64unsigned short adc_read(int channel)
65{
66#ifdef BOOTLOADER
67 /* IRQs aren't enabled in the bootloader - just do the read directly */
Rob Purchased7411742008-04-07 22:48:19 +000068 int i;
Rob Purchase47ea0302008-01-14 22:04:48 +000069 uint32_t adc_status;
70
71 PCLK_ADC |= PCK_EN; /* Enable ADC clock */
72
73 /* Start converting the first 4 channels */
74 for (i = 0; i < 4; i++)
75 ADCCON = i;
76
Rob Purchased7411742008-04-07 22:48:19 +000077 /* Now read the values back */
78 for (i=0; i < 4; i++)
Rob Purchase36f8fba2008-04-04 23:43:31 +000079 {
Rob Purchased7411742008-04-07 22:48:19 +000080 /* Wait for data to become stable */
81 while ((ADCDATA & 0x1) == 0);
82
Rob Purchase47ea0302008-01-14 22:04:48 +000083 adc_status = ADCSTATUS;
Rob Purchased7411742008-04-07 22:48:19 +000084 adcdata[(adc_status >> 16) & 0x7] = adc_status & 0x3ff;
85 }
Rob Purchase47ea0302008-01-14 22:04:48 +000086
87 PCLK_ADC &= ~PCK_EN; /* Disable ADC clock */
Rob Purchase36f8fba2008-04-04 23:43:31 +000088#endif
Rob Purchase47ea0302008-01-14 22:04:48 +000089
90 return adcdata[channel];
91}
92
93void adc_init(void)
94{
95 /* consider configuring PCK_ADC source here */
96
Rob Purchase36f8fba2008-04-04 23:43:31 +000097 ADCCON = (1<<4); /* Enter standby mode */
Rob Purchased7411742008-04-07 22:48:19 +000098 ADCCFG |= 0x00000003; /* Single-mode, auto power-down */
Rob Purchase36f8fba2008-04-04 23:43:31 +000099
100#ifndef BOOTLOADER
Rob Purchased7411742008-04-07 22:48:19 +0000101 ADCCFG |= (1<<3); /* Request IRQ on ADC completion */
102 IEN |= ADC_IRQ_MASK; /* Unmask ADC IRQs */
Rob Purchase36f8fba2008-04-04 23:43:31 +0000103
104 tick_add_task(adc_tick);
105
106 sleep(2); /* Ensure valid readings when adc_init returns */
107#endif
Rob Purchase47ea0302008-01-14 22:04:48 +0000108}