1 /****************************************************************************
4 * Copyright 2012 Nathael Pajani <nathael.pajani@ed3l.fr>
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 *************************************************************************** */
25 #include "lib/stdint.h"
26 #include "core/lpc_regs.h"
28 /***************************************************************************** */
29 /* Analog to Digital Converter (ADC) */
30 /***************************************************************************** */
32 /* ADC driver for the integrated ADC module of the LPC82x.
33 * Refer to LPC82x documentation (UM10800.pdf) for more information.
36 #define NB_ADC_CHANNELS 12
37 #define NB_ADC_SEQUENCES 2
39 #define LPC_ADC_SEQ(x) (x)
40 #define LPC_ADC_SEQA 0
41 #define LPC_ADC_SEQB 1
43 /* Read the conversion from the given channel
44 * This function reads the conversion value directly in the data register and
45 * always returns a value.
46 * Return 0 if the value is a new one and no overrun occured.
47 * Return -EINVAL if channel does not exist
48 * Return 1 if the value is an old one.
49 * Return 2 if an overrun occured
51 int adc_get_value(uint16_t * val, uint8_t channel);
53 /* Start a conversion on the given channel
54 * Unsupported yet : Set use_int to 1 to have your interrupt callback called upon conversion done.
56 void adc_start_convertion_once(uint8_t channel, uint8_t seq_num, uint8_t use_int);
58 /* Start burst conversions.
59 * channels is a bit mask of requested channels.
60 * Use ADC_MCH(x) (x = 0 .. 11) for channels selection.
62 void adc_start_burst_conversion(uint16_t channels, uint8_t seq_num);
63 void adc_stop_burst_conversion(uint8_t seq_num);
66 enum lpc_adc_start_conv_events {
67 LPC_ADC_START_CONV_SOFT = 0,
68 LPC_ADC_START_CONV_ADC_PINTRIG_0,
69 LPC_ADC_START_CONV_ADC_PINTRIG_1,
70 LPC_ADC_START_CONV_SCT0_OUT3,
71 LPC_ADC_START_CONV_ACMP_OUT,
72 LPC_ADC_START_CONV_ARM_TXEV,
74 /* This should be used to configure conversion start on falling or rising edges of
75 * some signals, or on timer for burst conversions.
77 void adc_prepare_conversion_on_event(uint16_t channels, uint8_t seq_num, uint8_t event,
78 uint8_t use_int, uint32_t mode);
80 /* Software trigger of the given configured sequence */
81 void adc_trigger_sequence_conversion(uint8_t seq_num);
83 /***************************************************************************** */
86 /* When lowpower_en is not 0 the ADC low power mode is selected, which adds a 15ADC clock delay
87 * before each set of consecutive conversions (but not between consecutive conversions)
89 void adc_set_low_power(int lowpower_en);
91 /* Power on/off the ADC block */
92 void adc_on(void (*adc_callback)(uint32_t));
98 /***************************************************************************** */
99 /* Analog-to-Digital Converter */
100 /***************************************************************************** */
101 /* Analog-to-Digital Converter (ADC) */
104 volatile uint32_t ctrl; /* 0x000 : A/D Control Register (R/W) */
106 volatile uint32_t seqctrl[2]; /* 0x008 - 0x00C : A/D Conversion sequence A and B control register (R/W) */
107 volatile uint32_t global_data[2]; /* 0x010 - 0x014 : A/D sequence A and B Global Data Register (R/W) */
108 uint32_t reserved_1[2];
109 volatile uint32_t data[NB_ADC_CHANNELS]; /* Offset: 0x020-0x04C A/D Channel 0..11 Data Register (R/-) */
110 volatile uint32_t threshold_low[2]; /* 0x050 - 0x054 : A/D Low Compare Threshold Register 0 and 1 (R/W) */
111 volatile uint32_t threshold_high[2]; /* 0x058 - 0x05C : A/D High Compare Threshold Register 0 and 1 (R/W) */
112 volatile uint32_t chan_threshold_sel; /* 0x060 : A/D Channel Threshold select Register (R/W) */
113 volatile uint32_t int_en; /* 0x064 : A/D Interrupt Enable Register (R/W) */
114 volatile const uint32_t flags; /* 0x068 : A/D Flags Register (R/ ) */
115 volatile uint32_t trim; /* 0x06C : A/D Trim Register (R/W) */
117 #define LPC_ADC_REGS ((struct lpc_adc *) LPC_ADC_BASE)
119 /* ADC Control register bits */
120 #define LPC_ADC_CLK_MASK 0x0FF
121 #define LPC_ADC_CLK_DIV(x) ((x) & LPC_ADC_CLK_MASK)
122 #define LPC_ADC_LOW_POWER_EN (0x01 << 10)
123 #define LPC_ADC_CALIBRATION (0x01 << 30)
125 /* ADC_MCH_* are also used for interrupt register */
126 #define ADC_MCH_MASK (0xFFF << 0)
127 #define ADC_MCH(x) (0x01 << (x))
128 #define LPC_ADC_START_CONV_EVENT(x) (((x) & 0x7) << 12)
129 #define LPC_ADC_START_EDGE_FALLING (0x0 << 18)
130 #define LPC_ADC_START_EDGE_RISING (0x1 << 18)
131 #define LPC_ADC_SYNC_TRIG_BYPASS (0x1 << 19)
132 #define LPC_ADC_START_CONV_NOW (0x01 << 26)
133 #define LPC_ADC_BURST (0x01 << 27)
134 #define LPC_ADC_SINGLESTEP (0x01 << 28)
135 #define LPC_ADC_LOW_PRIORITY (0x01 << 29)
136 #define LPC_ADC_INT_MODE_END_OF_SEQ (0x01 << 30)
137 #define LPC_ADC_SEQ_EN (0x01 << 31)
138 #define LPC_ADC_ADDITIONAL_MODE_MASK ((0x0 << 18) | (0x1 << 19) | (0x01 << 28) | (0x01 << 29) | (0x01 << 30))
141 /* ADC Data register bits */
142 #define LPC_ADC_RESULT_MASK 0xFFF
143 #define LPC_ADC_RESULT_SHIFT 4
144 #define LPC_ADC_RESULT(x) (((x) & LPC_ADC_RESULT_MASK) >> LPC_ADC_RESULT_SHIFT)
145 #define LPC_ADC_THRESHOLD_CMP_RANGE(x) (((x) & 0x03) >> 16)
146 #define LPC_ADC_THRESHOLD_CMP_CROSS(x) (((x) & 0x03) >> 18)
147 #define LPC_ADC_RES_CHAN(x) (((x) & 0x0F) >> 26)
148 #define LPC_ADC_OVERRUN (0x01 << 30)
149 #define LPC_ADC_CONV_DONE (0x01 << 31)
151 /* ADC Threshold register bits */
152 #define LPC_ADC_THRESHOLD(x) (((x) & LPC_ADC_RESULT_MASK) << LPC_ADC_RESULT_SHIFT)
153 #define LPC_ADC_THRESHOLD_LEVEL_0 0
154 #define LPC_ADC_THRESHOLD_LEVEL_1 1
156 /* For more readability when selecting a channel number */
157 #define LPC_ADC(x) (x)
161 /* ADC Interrupt Register */
162 #define LPC_ADC_SEQA_INTEN (0x01 << 0)
163 #define LPC_ADC_SEQB_INTEN (0x01 << 1)
164 /* TODO : Define other bits */
168 #endif /* DRIVERS_ADC_H */