summaryrefslogtreecommitdiff
path: root/firmware/drivers/adc.c
diff options
context:
space:
mode:
authorBrandon Low <lostlogic@rockbox.org>2006-03-09 19:47:12 +0000
committerBrandon Low <lostlogic@rockbox.org>2006-03-09 19:47:12 +0000
commit19f4c2a093698940482aad6df0bd8478a82f2a9d (patch)
tree66de55749bcaaf45d95b828423ffca8c715b7112 /firmware/drivers/adc.c
parent5ecac908a2738e7a83dc0227daef3aaf16787dbc (diff)
downloadrockbox-19f4c2a093698940482aad6df0bd8478a82f2a9d.tar.gz
rockbox-19f4c2a093698940482aad6df0bd8478a82f2a9d.zip
Improve ipod i2c driver somewhat by at least taking advantage of the in-device addressing in the pcf50605, also switch to a 10bit resistive divider for the ipod battery reading, this is easily configurable if it needs changing, or even to become a user/runtime setting
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@8980 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/drivers/adc.c')
-rw-r--r--firmware/drivers/adc.c67
1 files changed, 32 insertions, 35 deletions
diff --git a/firmware/drivers/adc.c b/firmware/drivers/adc.c
index a75f788417..4a99a49753 100644
--- a/firmware/drivers/adc.c
+++ b/firmware/drivers/adc.c
@@ -286,60 +286,57 @@ void adc_init(void)
286#elif CONFIG_CPU == PP5020 || (CONFIG_CPU == PP5002) 286#elif CONFIG_CPU == PP5020 || (CONFIG_CPU == PP5002)
287 287
288struct adc_struct { 288struct adc_struct {
289 long last_read; 289 long timeout;
290 unsigned short (*conversion)(unsigned short data); 290 void (*conversion)(unsigned short *data);
291 short channelnum; 291 short channelnum;
292 unsigned short data; 292 unsigned short data;
293}; 293};
294 294
295static struct adc_struct adcdata[NUM_ADC_CHANNELS] IDATA_ATTR; 295static struct adc_struct adcdata[NUM_ADC_CHANNELS] IDATA_ATTR;
296 296
297/* This takes 10 bit ADC data from the subtractor circuit and scales it to 297static unsigned short _adc_read(struct adc_struct *adc)
298 * a 13 bit value corresponding to 0-5.4v, the resulting range is 13FB-17FA,
299 * representing 3.1-5.4v */
300static unsigned short ten_bit_subtractor(unsigned short data) {
301 return (data<<2)+0x4FB;
302}
303
304static unsigned short _adc_scan(struct adc_struct *adc)
305{ 298{
306 unsigned short data; 299 if (adc->timeout < current_tick) {
307 300 unsigned char data[2];
308 /* ADCC1, 8 bit, start */ 301 unsigned short value;
309 pcf50605_write(0x2f, 0x80 | (adc->channelnum << 1) | 0x1); 302 /* 5x per 2 seconds */
310 data = pcf50605_read(0x30); /* ADCS1 */ 303 adc->timeout = current_tick + (HZ * 2 / 5);
311 304
312 if (adc->conversion) { 305 /* ADCC1, 10 bit, start */
313 data = adc->conversion(data); 306 pcf50605_write(0x2f, (adc->channelnum << 1) | 0x1);
307 pcf50605_read_multiple(0x30, data, 2); /* ADCS1, ADCS2 */
308 value = data[0];
309 value <<= 2;
310 value |= data[1] & 0x3;
311
312 if (adc->conversion) {
313 adc->conversion(&value);
314 }
315 adc->data = value;
316 return value;
317 } else {
318 return adc->data;
314 } 319 }
315 adc->data = data;
316 return data;
317} 320}
318 321
319/* Force an ADC scan _now_ */ 322/* Force an ADC scan _now_ */
320unsigned short adc_scan(int channel) { 323unsigned short adc_scan(int channel) {
321 return _adc_scan(&adcdata[channel]); 324 struct adc_struct *adc = &adcdata[channel];
325 adc->timeout = 0;
326 return _adc_read(adc);
322} 327}
323 328
324/* Retrieve the ADC value, only does a scan once per second or less */ 329/* Retrieve the ADC value, only does a scan periodically */
325unsigned short adc_read(int channel) 330unsigned short adc_read(int channel) {
326{ 331 return _adc_read(&adcdata[channel]);
327 struct adc_struct *adc = &adcdata[channel];
328 if (adc->last_read + HZ < current_tick) {
329 adc->last_read = current_tick;
330 return _adc_scan(adc);
331 } else {
332 return adc->data;
333 }
334} 332}
335 333
336void adc_init(void) 334void adc_init(void)
337{ 335{
338 struct adc_struct *adc_battery = &adcdata[ADC_BATTERY]; 336 struct adc_struct *adc_battery = &adcdata[ADC_BATTERY];
339 adc_battery->channelnum = 0x3; /* ADCVIN1, subtractor */ 337 adc_battery->channelnum = 0x2; /* ADCVIN1, resistive divider */
340 adc_battery->conversion = ten_bit_subtractor; 338 adc_battery->timeout = 0;
341 adc_battery->last_read = current_tick; 339 _adc_read(adc_battery);
342 _adc_scan(adc_battery);
343} 340}
344 341
345#elif CONFIG_CPU == PNX0101 342#elif CONFIG_CPU == PNX0101