1 /*-------------------------------------------------------------------------
2 adc.c - A/D conversion module library header
4 Copyright (C) 2004, Vangelis Rokas <vrokas AT otenet.gr>
6 This library is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This library 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 library; see the file COPYING. If not, write to the
18 Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
21 As a special exception, if you link this library with other files,
22 some of which are compiled with SDCC, to produce an executable,
23 this library does not by itself cause the resulting executable to
24 be covered by the GNU General Public License. This exception does
25 not however invalidate any other reasons why the executable file
26 might be covered by the GNU General Public License.
27 -------------------------------------------------------------------------*/
29 * Devices implemented:
37 /* link I/O libarary */
41 * adc_open's `channel' argument:
46 /* channel selection (CHS field in ADCON0) */
47 #define ADC_CHN_0 0x00
48 #define ADC_CHN_1 0x01
49 #define ADC_CHN_2 0x02
50 #define ADC_CHN_3 0x03
51 #define ADC_CHN_4 0x04
52 #define ADC_CHN_5 0x05
53 #define ADC_CHN_6 0x06
54 #define ADC_CHN_7 0x07
55 #define ADC_CHN_8 0x08
56 #define ADC_CHN_9 0x09
57 #define ADC_CHN_10 0x0a
58 #define ADC_CHN_11 0x0b
59 #define ADC_CHN_12 0x0c
60 #define ADC_CHN_13 0x0d
61 #define ADC_CHN_14 0x0e
62 #define ADC_CHN_DAC 0x0e /* 13k50-style */
63 #define ADC_CHN_15 0x0f
64 #define ADC_CHN_FVR 0x0f /* 13k50-style */
65 /* more channels: 23k22-style */
66 #define ADC_CHN_16 0x10
67 #define ADC_CHN_17 0x11
68 #define ADC_CHN_18 0x12
69 #define ADC_CHN_19 0x13
70 #define ADC_CHN_20 0x14
71 #define ADC_CHN_21 0x15
72 #define ADC_CHN_22 0x16
73 #define ADC_CHN_23 0x17
74 #define ADC_CHN_24 0x18
75 #define ADC_CHN_25 0x19
76 #define ADC_CHN_26 0x1a
77 #define ADC_CHN_27 0x1b
78 #define ADC_CHN_K_CTMU 0x1d
79 #define ADC_CHN_K_DAC 0x1e
80 #define ADC_CHN_K_FVR 0x1f
84 * adc_open's `fosc' argument:
86 * ADC_FOSC_* | ADC_ACQT_* | ADC_CAL | ADC_TRIGSEL_*
89 * +-----+-----+-----+-----+-----+-----+-----+-----+
90 * | TRG | CAL | ACQT | FOSC/ADCS |
91 * +-----+-----+-----+-----+-----+-----+-----+-----+
94 /* oscillator frequency (ADCS field) */
95 #define ADC_FOSC_2 0x00
96 #define ADC_FOSC_4 0x04
97 #define ADC_FOSC_8 0x01
98 #define ADC_FOSC_16 0x05
99 #define ADC_FOSC_32 0x02
100 #define ADC_FOSC_64 0x06
101 #define ADC_FOSC_RC 0x07
103 /* acquisition time (13k50/2220/24j50/65j50-styles only) */
104 #define ADC_ACQT_0 (0x00 << 3)
105 #define ADC_ACQT_2 (0x01 << 3)
106 #define ADC_ACQT_4 (0x02 << 3)
107 #define ADC_ACQT_6 (0x03 << 3)
108 #define ADC_ACQT_8 (0x04 << 3)
109 #define ADC_ACQT_12 (0x05 << 3)
110 #define ADC_ACQT_16 (0x06 << 3)
111 #define ADC_ACQT_20 (0x07 << 3)
113 /* calibration enable (24j50/65j50-style only) */
116 /* trigger selection (23k22-style only) */
117 #define ADC_TRIGGER 0x80
121 * adc_open's `pcfg' argment:
123 * ADC_CFG_* (see below, style-specific)
128 * adc_open's `config' argument:
130 * ADC_FRM_* | ADC_INT_* | ADC_VCFG_* | ADC_NVCFG_* | ADC_PVCFG_*
133 * +-----+-----+-----+-----+-----+-----+-----+-----+
134 * | FRM | INT | VCFG | PVCFG | NVCFG |
135 * +-----+-----+-----+-----+-----+-----+-----+-----+
139 #define ADC_FRM_LJUST 0x00
140 #define ADC_FRM_RJUST 0x80
142 /* interrupt on/off flag */
143 #define ADC_INT_OFF 0x00
144 #define ADC_INT_ON 0x40
146 /* reference voltage configuration (not for 18f242-style ADC) */
147 #define ADC_VCFG_VDD_VSS 0x00
148 #define ADC_VCFG_AN3_VSS 0x10
149 #define ADC_VCFG_VDD_AN2 0x20
150 #define ADC_VCFG_AN3_AN2 0x30
152 /* reference voltage configuration (13k50-style) */
153 #define ADC_NVCFG_VSS 0x00
154 #define ADC_NVCFG_AN5 0x01
156 #define ADC_PVCFG_VDD (0x00 << 2)
157 #define ADC_PVCFG_AN4 (0x01 << 2)
158 #define ADC_PVCFG_FVR (0x02 << 2)
160 /* reference voltage configuration (23k22-style) */
161 #define ADC_NVCFG_AN2 0x01
162 #define ADC_PVCFG_AN3 (0x01 << 2)
163 #define ADC_TRIGSEL_CCP5 (0x00 << 7)
164 #define ADC_TRIGSEL_CTMU (0x01 << 7)
168 * Distinguishing between ADC-styles:
169 * - 18f24j50-style devices have separate ANCON0/ANCON1
170 * registers for A/D port pin configuration, whereas
171 * 18f65j50-style devices multiplex ANCONx and ADCONx
174 * bit 18f242 18f1220 18f1230 18f13k50 18f2220 18f24j50 18f65j50 18f23k22
175 * 0 ADON ADON ADON ADON ADON ADON ADON ADON
176 * 1 - GO GO GO GO GO GO GO
177 * 2 GO CHS0 CHS0 CHS0 CHS0 CHS0 CHS0 CHS0
178 * 3 CHS0 CHS1 CHS1 CHS1 CHS1 CHS1 CHS1 CHS1
179 * 4 CHS1 CHS2 - CHS2 CHS2 CHS2 CHS2 CHS2
180 * 5 CHS2 - - CHS3 CHS3 CHS3 CHS3 CHS3
181 * 6 ADCS0 VCFG0 - - - VCFG0 VCFG0 CHS4
182 * 7 ADCS1 VCFG1 SEVTEN - (ADCAL) VCFG1 VCFG1 -
185 * bit 18f242 18f1220 18f1230 18f13k50 18f2220 18f24j50 18f65j50 18f23k22
186 * 0 PCFG0 PCFG0 PCFG0 NVCFG0 PCFG0 ADCS0 ADCS0 NVCFG0
187 * 1 PCFG1 PCFG1 PCFG1 NVCFG1 PCFG1 ADCS1 ADCS1 NVCFG1
188 * 2 PCFG2 PCFG2 PCFG2 PVCFG0 PCFG2 ADCS2 ADCS2 PVCFG0
189 * 3 PCFG3 PCFG3 PCFG3 PVCFG1 PCFG3 ACQT0 ACQT0 PVCFG1
190 * 4 - PCFG4 VCFG0 - VCFG0 ACQT1 ACQT1 -
191 * 5 - PCFG5 - VCFG1 ACQT2 ACQT2 -
192 * 6 ADCS2 PCFG6 - - ADCAL ADCAL -
193 * 7 ADFM - - - ADFM ADFM TRIGSEL
196 * bit 18f242 18f1220 18f1230 18f13k50 18f2220 18f24j50 18f65j50 18f23k22
197 * 0 ADCS0 ADCS0 ADCS0 ADCS0
198 * 1 ADCS1 ADCS1 ADCS1 ADCS1
199 * 2 ADCS2 ADCS2 ADCS2 ADCS2
200 * 3 ACQT0 ACQT0 ADQT0 ACQT0
201 * 4 ACQT1 ACQT1 ADQT1 ACQT1
202 * 5 ACQT2 ACQT2 ADQT2 ACQT2
204 * 7 ADFM ADFM ADFM ADFM
206 #include "pic18fam.h"
210 /* Port configuration (PCFG (and VCFG) field(s) in ADCON1) */
211 #if (__SDCC_ADC_STYLE == 0)
213 #warning The target device is not supported by the SDCC PIC16 ADC library.
215 #elif (__SDCC_ADC_STYLE == 1802420)
217 #define ADC_CFG_8A_0R 0x00
218 #define ADC_CFG_7A_1R 0x01
219 #define ADC_CFG_5A_0R 0x02
220 #define ADC_CFG_4A_1R 0x03
221 #define ADC_CFG_3A_0R 0x04
222 #define ADC_CFG_2A_1R 0x05
223 #define ADC_CFG_0A_0R 0x06
224 #define ADC_CFG_6A_2R 0x08
225 #define ADC_CFG_6A_0R 0x09
226 #define ADC_CFG_5A_1R 0x0a
227 #define ADC_CFG_4A_2R 0x0b
228 #define ADC_CFG_3A_2R 0x0c
229 #define ADC_CFG_2A_2R 0x0d
230 #define ADC_CFG_1A_0R 0x0e
231 #define ADC_CFG_1A_2R 0x0f
233 #elif (__SDCC_ADC_STYLE == 1812200)
236 * These devices use a bitmask in ADCON1 to configure AN0..AN6
237 * as digital ports (bit set) or analog input (bit clear).
239 * These settings are selected based on their similarity with
240 * the 2220-style settings; 1220-style is more flexible, though.
242 * Reference voltages are configured via adc_open's config parameter
246 #define ADC_CFG_6A 0x00
247 #define ADC_CFG_5A 0x20
248 #define ADC_CFG_4A 0x30
249 #define ADC_CFG_3A 0x38
250 #define ADC_CFG_2A 0x3c
251 #define ADC_CFG_1A 0x3e
252 #define ADC_CFG_0A 0x3f
254 #elif (__SDCC_ADC_STYLE == 1812300)
257 * These devices use a bitmask in ADCON1 to configure AN0..AN3
258 * as digital ports (bit set) or analog input (bit clear).
260 * These settings are selected based on their similarity with
261 * the 2220-style settings; 1230-style is more flexible, though.
263 * Reference voltages are configured via adc_open's config parameter
267 #define ADC_CFG_4A 0x00
268 #define ADC_CFG_3A 0x08
269 #define ADC_CFG_2A 0x0c
270 #define ADC_CFG_1A 0x0e
271 #define ADC_CFG_0A 0x0f
273 #define ADC_VCFG_AVDD 0x00 /* AVdd */
274 #define ADC_VCFG_VREF 0x10 /* Vref+ */
276 #elif (__SDCC_ADC_STYLE == 1813502)
279 * These devices use a bitmask in ANSEL/H to configure
280 * AN7..0/AN15..8 as digital ports (bit clear) or analog
283 * These settings are selected based on their similarity with
284 * the 2220-style settings; 13k50-style is more flexible, though.
286 * Reference voltages are configured via adc_open's config parameter
287 * using ADC_PVCFG_* and ADC_NVCFG_*.
290 #define ADC_CFG_16A 0xFFFF
291 #define ADC_CFG_15A 0x7FFF
292 #define ADC_CFG_14A 0x3FFF
293 #define ADC_CFG_13A 0x1FFF
294 #define ADC_CFG_12A 0x0FFF
295 #define ADC_CFG_11A 0x07FF
296 #define ADC_CFG_10A 0x03FF
297 #define ADC_CFG_9A 0x01FF
298 #define ADC_CFG_8A 0x00FF
299 #define ADC_CFG_7A 0x007F
300 #define ADC_CFG_6A 0x003F
301 #define ADC_CFG_5A 0x001F
302 #define ADC_CFG_4A 0x000F
303 #define ADC_CFG_3A 0x0007
304 #define ADC_CFG_2A 0x0003
305 #define ADC_CFG_1A 0x0001
306 #define ADC_CFG_0A 0x0000
308 #elif (__SDCC_ADC_STYLE == 1822200)
311 * The reference voltage configuration should be factored out into
312 * the config argument (ADC_VCFG_*) to adc_open to facilitate a
313 * merger with the 1220-style ADC.
316 #define ADC_CFG_16A 0x00
317 /* 15 analog ports cannot be configured! */
318 #define ADC_CFG_14A 0x01
319 #define ADC_CFG_13A 0x02
320 #define ADC_CFG_12A 0x03
321 #define ADC_CFG_11A 0x04
322 #define ADC_CFG_10A 0x05
323 #define ADC_CFG_9A 0x06
324 #define ADC_CFG_8A 0x07
325 #define ADC_CFG_7A 0x08
326 #define ADC_CFG_6A 0x09
327 #define ADC_CFG_5A 0x0a
328 #define ADC_CFG_4A 0x0b
329 #define ADC_CFG_3A 0x0c
330 #define ADC_CFG_2A 0x0d
331 #define ADC_CFG_1A 0x0e
332 #define ADC_CFG_0A 0x0f
335 * For compatibility only: Combined port and reference voltage selection.
336 * Consider using ADC_CFG_nA and a separate ADC_VCFG_* instead!
339 #define ADC_CFG_16A_0R 0x00
340 #define ADC_CFG_16A_1R 0x10
341 #define ADC_CFG_16A_2R 0x30
343 /* Can only select 14 or 16 analog ports ... */
344 #define ADC_CFG_15A_0R 0x00
345 #define ADC_CFG_15A_1R 0x10
346 #define ADC_CFG_15A_2R 0x30
348 #define ADC_CFG_14A_0R 0x01
349 #define ADC_CFG_14A_1R 0x11
350 #define ADC_CFG_14A_2R 0x31
351 #define ADC_CFG_13A_0R 0x02
352 #define ADC_CFG_13A_1R 0x12
353 #define ADC_CFG_13A_2R 0x32
354 #define ADC_CFG_12A_0R 0x03
355 #define ADC_CFG_12A_1R 0x13
356 #define ADC_CFG_12A_2R 0x33
357 #define ADC_CFG_11A_0R 0x04
358 #define ADC_CFG_11A_1R 0x14
359 #define ADC_CFG_11A_2R 0x34
360 #define ADC_CFG_10A_0R 0x05
361 #define ADC_CFG_10A_1R 0x15
362 #define ADC_CFG_10A_2R 0x35
363 #define ADC_CFG_09A_0R 0x06
364 #define ADC_CFG_09A_1R 0x16
365 #define ADC_CFG_09A_2R 0x36
366 #define ADC_CFG_08A_0R 0x07
367 #define ADC_CFG_08A_1R 0x17
368 #define ADC_CFG_08A_2R 0x37
369 #define ADC_CFG_07A_0R 0x08
370 #define ADC_CFG_07A_1R 0x18
371 #define ADC_CFG_07A_2R 0x38
372 #define ADC_CFG_06A_0R 0x09
373 #define ADC_CFG_06A_1R 0x19
374 #define ADC_CFG_06A_2R 0x39
375 #define ADC_CFG_05A_0R 0x0a
376 #define ADC_CFG_05A_1R 0x1a
377 #define ADC_CFG_05A_2R 0x3a
378 #define ADC_CFG_04A_0R 0x0b
379 #define ADC_CFG_04A_1R 0x1b
380 #define ADC_CFG_04A_2R 0x3b
381 #define ADC_CFG_03A_0R 0x0c
382 #define ADC_CFG_03A_1R 0x1c
383 #define ADC_CFG_03A_2R 0x3c
384 #define ADC_CFG_02A_0R 0x0d
385 #define ADC_CFG_02A_1R 0x1d
386 #define ADC_CFG_02A_2R 0x3d
387 #define ADC_CFG_01A_0R 0x0e
388 #define ADC_CFG_01A_1R 0x1e
389 #define ADC_CFG_01A_2R 0x3e
390 #define ADC_CFG_00A_0R 0x0f
392 #elif (__SDCC_ADC_STYLE == 1823222)
394 /* use ANSELA, ANSELB, ANSELC, ANSELD, ANSELE registers and
395 * TRISA, TRISB, TRISC, TRISD, TRISE registers to set
396 * corresponding port to analog mode
397 * Note: 46k22 supports up to 28 ADC ports */
400 #elif (__SDCC_ADC_STYLE == 1824501) || (__SDCC_ADC_STYLE == 1865501)
403 * These devices use a bitmask in ANCON0/1 to configure
404 * AN7..0/AN15..8 as digital ports (bit set) or analog
405 * inputs (bit clear).
407 * These settings are selected based on their similarity with
408 * the 2220-style settings; 24j50/65j50-style is more flexible, though.
410 * Reference voltages are configured via adc_open's config parameter
414 #define ADC_CFG_16A 0x0000
415 #define ADC_CFG_15A 0x8000
416 #define ADC_CFG_14A 0xC000
417 #define ADC_CFG_13A 0xE000
418 #define ADC_CFG_12A 0xF000
419 #define ADC_CFG_11A 0xF800
420 #define ADC_CFG_10A 0xFC00
421 #define ADC_CFG_9A 0xFE00
422 #define ADC_CFG_8A 0xFF00
423 #define ADC_CFG_7A 0xFF80
424 #define ADC_CFG_6A 0xFFC0
425 #define ADC_CFG_5A 0xFFE0
426 #define ADC_CFG_4A 0xFFF0
427 #define ADC_CFG_3A 0xFFF8
428 #define ADC_CFG_2A 0xFFFC
429 #define ADC_CFG_1A 0xFFFE
430 #define ADC_CFG_0A 0xFFFF
432 #else /* unhandled ADC style */
434 #error No supported ADC style selected.
436 #endif /* __SDCC_ADC_STYLE */
440 #if (__SDCC_ADC_STYLE == 1813502) \
441 || (__SDCC_ADC_STYLE == 1824501) \
442 || (__SDCC_ADC_STYLE == 1865501)
443 typedef unsigned int sdcc_pcfg_t
;
444 #else /* other styles */
445 typedef unsigned char sdcc_pcfg_t
;
448 /* initialize AD module */
449 void adc_open (unsigned char channel
, unsigned char fosc
, sdcc_pcfg_t pcfg
, unsigned char config
);
451 /* shutdown AD module */
452 void adc_close (void);
454 /* begin a conversion */
455 void adc_conv (void);
457 /* return 1 if AD is performing a conversion, 0 if done */
458 char adc_busy (void) __naked
;
460 /* get value of conversion */
461 int adc_read (void) __naked
;
463 /* setup conversion channel */
464 void adc_setchannel (unsigned char channel
);