D2: Use a common function for reading ADC values from the PMU

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@23007 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Rob Purchase 2009-10-08 15:47:43 +00:00
parent 5a435e62d0
commit 292a53da4b
5 changed files with 54 additions and 31 deletions

View File

@ -62,3 +62,26 @@ void pcf50606_reset_timeout(void)
pcf50606_write(PCF5060X_OOCC1, pcf50606_read(PCF5060X_OOCC1) | TOTRST);
restore_irq(level);
}
void pcf50606_read_adc(int adc, short* res1, short* res2)
{
int adcs1 = 0, adcs2 = 0, adcs3 = 0;
int level = disable_irq_save();
pcf50606_write(PCF5060X_ADCC2, (adc<<1) | 1); /* ADC start */
do {
adcs2 = pcf50606_read(PCF5060X_ADCS2);
} while (!(adcs2 & 0x80)); /* Busy wait on ADCRDY flag */
adcs1 = pcf50606_read(PCF5060X_ADCS1);
if (res2 != NULL) adcs3 = pcf50606_read(PCF5060X_ADCS3);
pcf50606_write(PCF5060X_ADCC2, 0); /* ADC stop */
restore_interrupt(level);
if (res1 != NULL) *res1 = (adcs1 << 2) | (adcs2 & 3);
if (res2 != NULL) *res2 = (adcs3 << 2) | ((adcs2 & 0xC) >> 2);
}

View File

@ -52,4 +52,6 @@ unsigned char pcf50606_i2c_inb(bool ack);
void pcf50606_reset_timeout(void);
#endif
void pcf50606_read_adc(int adc, short* res1, short* res2);
#endif /* PCF50606_H */

View File

@ -92,4 +92,21 @@
#define PCF5060X_GPOC4 0x3b
#define PCF5060X_GPOC5 0x3c
/* ADCC2 mux values */
#define PCF5060X_ADC_BATVOLT_RES 0x0
#define PCF5060X_ADC_BATVOLT_SUBTR 0x1
#define PCF5060X_ADC_ADCIN1_RES 0x2
#define PCF5060X_ADC_ADCIN1_SUBTR 0x3
#define PCF5060X_ADC_BATTEMP 0x4
#define PCF5060X_ADC_ADCIN2 0x5
#define PCF5060X_ADC_ADCIN3 0x6
#define PCF5060X_ADC_ADCIN3_RATIO 0x7
#define PCF5060X_ADC_TSC_X 0x8
#define PCF5060X_ADC_TSC_Y 0x9
#define PCF5060X_ADC_TSC_P1 0xa
#define PCF5060X_ADC_TSC_P2 0xb
#define PCF5060X_ADC_BATVOLT_ADCIN1 0xc
#define PCF5060X_ADC_TSC_XY 0xe
#define PCF5060X_ADC_TSC_P1P2 0xf
#endif /* PCF5060X_H */

View File

@ -41,35 +41,22 @@ static int short_cmp(const void *a, const void *b)
void button_read_touch()
{
unsigned char buf[3];
static long last_touch_interrupt = 0;
static int touch_data_index = 0;
/* put the touchscreen into idle mode */
pcf50606_write(PCF5060X_ADCC1, 0);
/* here the touch coordinates are read 5 times */
/* they will be sorted and the middle one will be used */
pcf50606_write(PCF5060X_ADCC2, (0xE<<1) | 1); /* ADC start X+Y */
do {
buf[1] = pcf50606_read(PCF5060X_ADCS2);
} while (!(buf[1] & 0x80)); /* Busy wait on ADCRDY flag */
buf[0] = pcf50606_read(PCF5060X_ADCS1);
buf[2] = pcf50606_read(PCF5060X_ADCS3);
pcf50606_write(PCF5060X_ADCC2, 0); /* ADC stop */
if (TIME_AFTER(current_tick, last_touch_interrupt + 1))
{
/* resets the index if the last touch could not be read 5 times */
touch_data_index = 0;
}
x[touch_data_index] = (buf[0] << 2) | (buf[1] & 3);
y[touch_data_index] = (buf[2] << 2) | ((buf[1] & 0xC) >> 2);
/* here the touch coordinates are read 5 times */
/* they will be sorted and the middle one will be used */
pcf50606_read_adc(PCF5060X_ADC_TSC_XY,
&x[touch_data_index], &y[touch_data_index]);
touch_data_index++;
@ -126,7 +113,7 @@ void button_init_device(void)
{
/* Configure GPIOA 4 (POWER) and 8 (HOLD) for input */
GPIOA_DIR &= ~0x110;
/* Configure GPIOB 4 (button pressed) for input */
GPIOB_DIR &= ~0x10;
@ -229,12 +216,12 @@ int button_read_device(int *data)
touch_hold = false;
pcf50606_write(PCF5060X_ADCC1, 1);
}
if (!(GPIOA & 0x4))
btn |= BUTTON_POWER;
if (btn & BUTTON_TOUCHSCREEN && !is_backlight_on(true))
old_data = *data = 0;
return btn;
}

View File

@ -26,7 +26,7 @@
#include "pcf50606.h"
unsigned short current_voltage = 3910;
const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] =
{
3380
@ -42,7 +42,7 @@ const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] =
{
/* Standard D2 internal battery */
{ 3370, 3690, 3750, 3775, 3790, 3820, 3880, 3940, 3980, 4090, 4170 }
/* TODO: DIY replacements eg. Nokia BP-4L ? */
};
@ -65,15 +65,9 @@ unsigned int battery_adc_voltage(void)
if (TIME_BEFORE(last_tick+HZ, current_tick))
{
int adc_val, irq_status;
unsigned char buf[2];
short adc_val;
pcf50606_read_adc(PCF5060X_ADC_BATVOLT_RES, &adc_val, NULL);
irq_status = disable_irq_save();
pcf50606_write(PCF5060X_ADCC2, 0x1);
pcf50606_read_multiple(PCF5060X_ADCS1, buf, 2);
restore_interrupt(irq_status);
adc_val = (buf[0]<<2) | (buf[1] & 3); //ADCDAT1H+ADCDAT1L
current_voltage = (adc_val * BATTERY_SCALE_FACTOR) >> 10;
last_tick = current_tick;