1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2008 by Michael Sevakis
12 * 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.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
25 #include "adc-target.h"
28 /* Do this so we may read all channels in a single SPI message */
29 static const unsigned char reg_array
[4] =
37 static uint32_t channels
[2][4];
38 static struct wakeup adc_wake
;
39 static struct mutex adc_mtx
;
40 static long last_adc_read
[2]; /* One for each input group */
42 /* Read 10-bit ADC channel */
43 unsigned short adc_read(int channel
)
48 if ((unsigned)channel
>= NUM_ADC_CHANNELS
)
49 return ADC_READ_ERROR
;
51 input_select
= channel
>> 3;
55 /* Limit the traffic through here */
56 if (current_tick
!= last_adc_read
[input_select
])
58 /* Keep enable, start conversion, increment from channel 0,
59 * increment from channel 4 */
60 uint32_t adc1
= MC13783_ADEN
| MC13783_ASC
|
61 (0 << MC13783_ADA1_POS
) | (4 << MC13783_ADA2_POS
);
63 if (input_select
== 1)
64 adc1
|= MC13783_ADSEL
; /* 2nd set of inputs */
66 /* Start conversion */
67 mc13783_write(MC13783_ADC1
, adc1
);
69 /* Wait for done signal */
70 wakeup_wait(&adc_wake
, TIMEOUT_BLOCK
);
72 /* Read all 8 channels that are converted - two channels in each
74 mc13783_read_regset(reg_array
, channels
[input_select
], 4);
76 last_adc_read
[input_select
] = current_tick
;
79 data
= channels
[input_select
][channel
& 3];
81 mutex_unlock(&adc_mtx
);
83 /* Channels 0-3/8-11 in ADD1, 4-7/12-15 in ADD2 */
84 return (channel
& 4) ?
85 ((data
& MC13783_ADD2
) >> MC13783_ADD2_POS
) :
86 ((data
& MC13783_ADD1
) >> MC13783_ADD1_POS
);
89 bool adc_enable_channel(int channel
, bool enable
)
95 case ADC_CHARGER_CURRENT
:
96 mask
= MC13783_CHRGICON
;
99 case ADC_BATTERY_TEMP
:
100 mask
= MC13783_RTHEN
;
107 bit
= enable
? mask
: 0;
109 return mc13783_write_masked(MC13783_ADC0
, bit
, mask
)
110 != MC13783_DATA_ERROR
;
113 /* Called by mc13783 interrupt thread when conversion is complete */
116 wakeup_signal(&adc_wake
);
121 wakeup_init(&adc_wake
);
122 mutex_init(&adc_mtx
);
124 /* Init so first reads get data */
125 last_adc_read
[0] = last_adc_read
[1] = current_tick
-1;
127 /* Enable increment-by-read, turn off extra conversions. */
128 mc13783_write(MC13783_ADC0
, MC13783_ADINC2
| MC13783_ADINC1
);
130 /* Enable ADC, set multi-channel mode */
131 mc13783_write(MC13783_ADC1
, MC13783_ADEN
);
133 /* Enable ADCDONE event */
134 mc13783_write(MC13783_INTERRUPT_STATUS0
, MC13783_ADCDONEI
);
135 mc13783_enable_event(MC13783_ADCDONE_EVENT
);