lpc2387-adc.c
4.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/*
* Copyright 2008, Freie Universitaet Berlin (FUB). All rights reserved.
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @file
* @ingroup lpc2387_adc
* @brief LPC2387 ADC
*
* @author Thomas Hillebrandt <hillebra@inf.fu-berlin.de>
* @version $Revision: 3250 $
*
* @note $Id: lpc2387-adc.c 3250 2011-03-11 09:45:44Z schmittb $
*/
// cpu
#include "lpc2387.h"
#include "lpc23xx.h"
#include "lpc2387-adc.h"
#define ENABLE_DEBUG (0)
#include "debug.h"
#if ENABLE_DEBUG
#include "xtimer.h"
#endif
/*---------------------------------------------------------------------------*/
void
adc_init(void)
{
// enable clock /Power for ADC
PCONP |= BIT12;
// peripheral Clock Selection for ADC
PCLKSEL0 |= 0x03000000; // pclock = cclock/8
// set A/D control register AD0CR
AD0CR = (0x01 << 0) | /* SEL=1, select channel 0~7 on ADC0 */
(0xff << 8) | /* CLKDIV = 1, ADC_CLK = PCLK/10 = 0.45 MHz */
(0 << 16) | /* BURST = 0, no BURST, software controlled */
(0 << 17) | /* CLKS = 0, 11 clocks/10 bits */
(1 << 21) | /* PDN = 1, normal operation */
(0 << 22) | /* TEST1:0 = 00 */
(0 << 24) | /* START = 0 A/D conversion stops */
(0 << 27); /* EDGE = 0 (CAP/MAT signal falling,trigger A/D conversion) */
}
/*---------------------------------------------------------------------------*/
void
adc_init_1(void)
{
// enable clock /Power for ADC
PCONP |= BIT12;
//PIN0.24 function select AD0.1
PINSEL1 |= BIT16;
// peripheral Clock Selection for ADC
PCLKSEL0 |= 0x03000000; // pclock = cclock/8
// set A/D control register AD0CR
AD0CR = (0x01 << 0) | /* SEL=1, select channel 0~7 on ADC0 */
(0x00 << 8) | /* CLKDIV = 1, ADC_CLK = PCLK/1 = 4.5 MHz */
(0 << 16) | /* BURST = 0, no BURST, software controlled */
(0 << 17) | /* CLKS = 0, 11 clocks/10 bits */
(1 << 21) | /* PDN = 1, normal operation */
(0 << 22) | /* TEST1:0 = 00 */
(0 << 24) | /* START = 0 A/D conversion stops */
(0 << 27); /* EDGE = 0 (CAP/MAT signal falling,trigger A/D conversion) */
}
/*---------------------------------------------------------------------------*/
void adc_init_2(void)
{
// enable clock /Power for ADC
PCONP |= BIT12;
// PIN0.23 function select to AD0.0
PINSEL1 |= BIT14;
// peripheral Clock Selection for ADC
PCLKSEL0 |= 0x03000000; // pclock = cclock/8
// set A/D control register AD0CR
AD0CR = (0x01 << 0) | /* SEL=1, select channel 0 on ADC0 */
(0x00 << 8) | /* CLKDIV = 1, ADC_CLK = PCLK/1 = 4.5 MHz */
(0 << 16) | /* BURST = 0, no BURST */
(0 << 17) | /* CLKS = 0, 11 clocks/10 bits */
(1 << 21) | /* PDN = 1, normal operation */
(0 << 22) | /* TEST1:0 = 00 */
(0 << 24) | /* START = 0 A/D conversion stops */
(0 << 27); /* EDGE = 0 (CAP/MAT signal falling,trigger A/D conversion) */
}
/*---------------------------------------------------------------------------*/
uint16_t adc_read(uint8_t channel)
{
#if ENABLE_DEBUG
uint32_t t1, t2;
#endif
uint32_t regVal, adc_data;
/* channel number is 0 through 7 */
if (channel >= ADC_NUM) {
channel = 0; /* reset channel number to 0 */
}
/* switch channel, start A/D convert */
AD0CR &= 0xFFFFFF00;
#if ENABLE_DEBUG
t1 = _xtimer_now();
#endif
AD0CR |= (1 << 24) | (1 << channel);
#if ENABLE_DEBUG
t2 = _xtimer_now();
#endif
while (1) {
/* read result of A/D conversion */
regVal = *(volatile unsigned long *)(AD0_BASE_ADDR + ADC_OFFSET + ADC_INDEX * channel);
/* wait until end of A/D convert */
if (regVal & ADC_DONE) {
break;
}
}
AD0CR &= 0xF8FFFFFF; /* stop ADC now */
if (regVal & ADC_OVERRUN) { /* save data when it's not overrun, otherwise, return zero */
return 0;
}
adc_data = (regVal >> 6) & 0x3FF;
DEBUG("%s, %d: %lu\n", RIOT_FILE_RELATIVE, __LINE__, t1);
DEBUG("%s, %d: %lu\n", RIOT_FILE_RELATIVE, __LINE__, t2);
return (uint16_t) adc_data; /* return A/D conversion value */
}