@@ -9,7 +9,8 @@
# Framebuffer support, board specific drivers
#
-FB_OBJS=fb/framebuffer.o fb/font.o fb/helvR08.o fb/helvB14.o fb/c64.o
+FB_OBJS=fb/framebuffer.o fb/font.o fb/helvR08.o fb/helvB14.o fb/c64.o \
+ fb/symbols.o
FB_e88_OBJS=$(FB_OBJS) fb/fb_bw8.o fb/fb_st7558.o
FB_e99_OBJS=$(FB_OBJS) fb/fb_rgb332.o fb/fb_ssd1783.o
@@ -24,12 +25,14 @@
# OpenMoko GTA0x
-gta0x_OBJS=$(calypso_COMMON_OBJS) board/gta0x/rffe_gta0x_triband.o board/gta0x/init.o board/gta0x/rf_power.o $(FB_dummy_OBJS)
+gta0x_OBJS=$(calypso_COMMON_OBJS) board/gta0x/rffe_gta0x_triband.o board/gta0x/init.o \
+ board/gta0x/rf_power.o battery/dummy.o $(FB_dummy_OBJS)
gta0x_ENVIRONMENTS=highram
# Pirelli DP-L10
-pirelli_dpl10_OBJS=$(calypso_COMMON_OBJS) board/pirelli_dpl10/rffe_dpl10_triband.o board/pirelli_dpl10/init.o board/pirelli_dpl10/rf_power.o $(FB_dpl10_OBJS)
+pirelli_dpl10_OBJS=$(calypso_COMMON_OBJS) board/pirelli_dpl10/rffe_dpl10_triband.o board/pirelli_dpl10/init.o \
+ board/pirelli_dpl10/rf_power.o battery/dummy.o $(FB_dpl10_OBJS)
pirelli_dpl10_ENVIRONMENTS=highram
# Compal Generic
@@ -45,7 +48,7 @@
# Compal E88
-compal_e88_OBJS=$(compal_COMMON_OBJS) board/compal_e88/init.o $(FB_e88_OBJS)
+compal_e88_OBJS=$(compal_COMMON_OBJS) board/compal_e88/init.o battery/compal_e88.o $(FB_e88_OBJS)
compal_e88_ENVIRONMENTS=$(compal_COMMON_ENVIRONMENTS) e88loader e88flash
e88loader_LDS=board/compal_e88/loader.lds
@@ -56,12 +59,13 @@
# Compal E86 (has a different RFFE configuration)
-compal_e86_OBJS=$(calypso_COMMON_OBJS) board/compal_e86/rffe_dualband_e86.o board/compal/rf_power.o board/compal_e86/init.o $(FB_e86_OBJS)
+compal_e86_OBJS=$(calypso_COMMON_OBJS) board/compal_e86/rffe_dualband_e86.o board/compal/rf_power.o \
+ board/compal_e86/init.o battery/dummy.o $(FB_e86_OBJS)
compal_e86_ENVIRONMENTS=$(compal_COMMON_ENVIRONMENTS)
# Compal E99
-compal_e99_OBJS=$(compal_COMMON_OBJS) board/compal_e99/init.o $(FB_e99_OBJS)
+compal_e99_OBJS=$(compal_COMMON_OBJS) board/compal_e99/init.o battery/dummy.o $(FB_e99_OBJS)
compal_e99_ENVIRONMENTS=$(compal_COMMON_ENVIRONMENTS)
e99loader_LDS=board/compal_e99/loader.lds
@@ -70,7 +74,7 @@
# Sony Ericsson J100 (made by Compal)
-se_j100_OBJS=$(compal_COMMON_OBJS) board/se_j100/init.o $(FB_j100_OBJS)
+se_j100_OBJS=$(compal_COMMON_OBJS) board/se_j100/init.o battery/dummy.o $(FB_j100_OBJS)
se_j100_ENVIRONMENTS=$(compal_COMMON_ENVIRONMENTS)
# Global include path
@@ -41,6 +41,7 @@
#include <comm/sercomm.h>
#include <comm/timer.h>
#include <fb/framebuffer.h>
+#include <battery/battery.h>
/* Main Program */
const char *hr = "======================================================================\n";
@@ -67,6 +68,36 @@
puts("\n");
}
+void
+write_battery_info(void *p){
+ char buf[128];
+
+ fb_setfg(FB_COLOR_WHITE);
+ fb_setfont(FB_FONT_C64);
+
+ snprintf(buf,sizeof(buf),"B: %04d mV",battery_info.bat_volt_mV);
+ fb_gotoxy(8,41);
+ fb_putstr(buf,framebuffer->width-8);
+
+ snprintf(buf,sizeof(buf),"C: %04d mV",battery_info.charger_volt_mV);
+ fb_gotoxy(8,49);
+ fb_putstr(buf,framebuffer->width-8);
+
+ snprintf(buf,sizeof(buf),"F: %08x",battery_info.flags);
+ fb_gotoxy(8,57);
+ fb_putstr(buf,framebuffer->width-8);
+
+ fb_flush();
+ osmo_timer_schedule((struct osmo_timer_list*)p,100);
+
+}
+
+/* timer that fires the charging loop regularly */
+static struct osmo_timer_list write_battery_info_timer = {
+ .cb = &write_battery_info,
+ .data = &write_battery_info_timer
+};
+
int main(void)
{
board_init();
@@ -123,6 +154,8 @@
sercomm_register_rx_cb(SC_DLCI_CONSOLE, console_rx_cb);
sercomm_register_rx_cb(SC_DLCI_L1A_L23, l1a_l23_rx_cb);
+ osmo_timer_schedule(&write_battery_info_timer,100);
+
/* beyond this point we only react to interrupts */
puts("entering interrupt loop\n");
while (1) {
@@ -50,6 +50,7 @@
#include <osmocom/gsm/rsl.h>
#include <osmocom/gsm/protocol/gsm_04_08.h>
#include <osmocom/gsm/gsm48_ie.h>
+#include <battery/battery.h>
enum key_codes key_code = KEY_INV;
int key_pressed = 0;
@@ -170,6 +171,7 @@
static void refresh_display(void)
{
char text[16];
+ int bat = battery_info.battery_percent;
fb_clear();
@@ -179,9 +181,25 @@
fb_setfg(FB_COLOR_BLUE);
fb_setfont(FB_FONT_HELVR08);
fb_gotoxy(0, 7);
- fb_putstr("Osmocom Monitor Tool", -1);
- fb_gotoxy(0, 10);
+ fb_putstr("Osmocom RSSI", -1);
+ fb_setfg(FB_COLOR_RGB(0xc0, 0xc0, 0x00));
+ fb_setfont(FB_FONT_SYMBOLS);
+ fb_gotoxy(framebuffer->width - 15, 8);
+ if (bat >= 100 && (battery_info.flags & BATTERY_CHG_ENABLED)
+ && !(battery_info.flags & BATTERY_CHARGING))
+ fb_putstr("@HHBC", framebuffer->width);
+ else {
+ sprintf(text, "@%c%c%cC", (bat >= 30) ? 'B':'A',
+ (bat >= 60) ? 'B':'A', (bat >= 90) ? 'B':'A');
+ fb_putstr(text, framebuffer->width);
+ }
+ fb_gotoxy(0, 8);
+ sprintf(text, "%c%cE%c%c", (power >= 40) ? 'D':'G',
+ (power >= 10) ? 'D':'G', (power >= 10) ? 'F':'G',
+ (power >= 40) ? 'F':'G');
+ fb_putstr(text, framebuffer->width);
fb_setfg(FB_COLOR_GREEN);
+ fb_gotoxy(0, 10);
fb_boxto(framebuffer->width - 1, 10);
}
fb_setfg(FB_COLOR_BLACK);
@@ -0,0 +1,384 @@
+/* Battery management for compal_e88 */
+
+/* (C) 2010 by Christian Vogel <vogelchr@vogel.cx>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+/*
+ * ___C123 (compal e88) very simplified diagram of charging circuitry___
+ *
+ * ICTL
+ * |
+ * v
+ * Charger -> OVP -------> P-Mosfet --->[0.15 Ohm]---> Battery
+ * (NCP345, | | |
+ * 6.85V) v v v
+ * VCHG VCCS VBAT &
+ * VBATS
+ *
+ * Inputs to IOTA:
+ * VCHG: senses voltage on the charger input
+ * VCSS/VBATS: to difference amplifier, to measure charge current
+ * VBAT: senses voltage on the battery terminal
+ * Outputs from IOTA:
+ * ICTL: Control signal for the switching mosfet
+ *
+ */
+
+#include <battery/battery.h>
+#include <battery/compal_e88.h>
+
+#include <stdint.h>
+#include <abb/twl3025.h>
+#include <comm/timer.h>
+#include <stdio.h>
+
+/* ADC calibration, scale is LSB/uV or LSB/uA, physical unit is mV or mA */
+#define ADC_TO_PHYSICAL(adc,scale) (((adc)*(scale)+500)/1000)
+#define PHYSICAL_TO_ADC(phy,scale) (((phy)*1000+(scale)/2)/(scale))
+
+/* conversion factors for internal IOTA battery charging/sensing circuitry */
+#define VREF_LSB_uV 1709 /* VREF = 1.75V --> 1.709 mV/LSB */
+#define VBAT_LSB_uV 6836 /* VBAT = 7.0 V FS --> 6.836 mV/LSB */
+#define VCHG_LSB_uV 8545 /* VCHG = 8.75V FS --> 8.545 mV/LSB */
+#define ICHG_LSB_uA 854 /* ICHG = 875mA FS --> 0.854 mA/LSB */
+
+/* battery is considered full/empty at these thresholds... */
+#define VBAT_full PHYSICAL_TO_ADC(4000,VBAT_LSB_uV)
+#define VBAT_empty PHYSICAL_TO_ADC(3200,VBAT_LSB_uV)
+
+/* we declare overvoltage at this point... */
+#define VBAT_fail PHYSICAL_TO_ADC(4250,VBAT_LSB_uV)
+
+/* DAC to ADC offsets in CC mode with my C123
+ IMEI 358317015976471, P329431014
+
+ I/mA DAC ADC
+ ----------------
+ 100 117 108
+ 150 176 168
+ 200 234 227
+ 250 293 291
+ 300 351 349
+ 350 410 410
+*/
+
+#define CHGDAC_GAIN 967 /* times 0.001 */
+#define CHGDAC_OFFS 13
+
+/* convert ADC reading to DAC value, according to calibration values
+ given above */
+#define CHGDAC_ADJ(x) (CHGDAC_GAIN*(x)/1000+CHGDAC_OFFS)
+
+/* charging current in DAC LSBs, same ref. and # of bits, but keep
+ the correction specified above in mind! */
+
+#define ICHG_set CHGDAC_ADJ(PHYSICAL_TO_ADC(200,ICHG_LSB_uA))
+#define VCHG_set CHGDAC_ADJ(VBAT_full)
+
+struct battery_info battery_info; /* global battery info */
+uint16_t bat_compal_e88_madc[MADC_NUM_CHANNELS]; /* MADC measurements */
+
+static const int BATTERY_TIMER_DELAY=5000; /* 5000ms for control loop */
+static const int ADC_TIMER_DELAY=100; /* 100ms for ADC conversion */
+
+/* thermistor sense current, turn it up to eleven! */
+#define TH_SENS (THSENS0|THSENS1|THSENS2|THEN)
+#define BATTERY_ALL_SENSE (TH_SENS|MESBAT|TYPEN)
+
+/*
+ * charger modes state machine
+ *
+ * +------------------+-------------------+
+ * | | | lost AC power
+ * | ^ ^
+ * V on AC power | @VBAT_full |
+ * +-----+ +------------+ -----> +------------+
+ * | OFF | -----> | CONST_CURR | | CONST_VOLT |
+ * +-----+ +------------+ +------------+
+ * ^ ^ | |
+ * | /failure v v failure
+ * +---------+ / gone | | condition
+ * | FAILURE | <----------+-------------------+
+ * +---------+
+ *
+ * Failure modes currently detected:
+ * + high battery voltage
+ * Failure modes TODO:
+ * + high battery temperature
+ */
+enum bat_compal_e88_chg_state {
+ CHARG_OFF,
+ CHARG_CONST_CURR,
+ CHARG_CONST_VOLT,
+ CHARG_FAIL
+};
+static enum bat_compal_e88_chg_state bat_compal_e88_chg_state;
+
+static const char *bat_compal_e88_chg_state_names[]={
+ "Off",
+ "Constant Current",
+ "Constant Voltage",
+ "Battery Failure"
+};
+
+static void
+bat_compal_e88_goto_state(enum bat_compal_e88_chg_state newstate){
+
+ if(bat_compal_e88_chg_state == newstate) /* already there? */
+ return;
+
+ printf("\033[34;1mCHARGER: %s --> %s.\033[0m\n",
+ bat_compal_e88_chg_state_names[bat_compal_e88_chg_state],
+ bat_compal_e88_chg_state_names[newstate]);
+
+ /* update user visible flags, set registers */
+ switch(newstate){
+ case CHARG_CONST_CURR:
+ battery_info.flags &= ~BATTERY_FAILURE;
+ battery_info.flags |= (BATTERY_CHG_ENABLED|
+ BATTERY_CHARGING);
+ twl3025_reg_write(BCICTL2,0);
+ twl3025_reg_write(CHGREG,0);
+ twl3025_reg_write(BCICTL2,CHEN|LEDC|CHIV);
+ twl3025_reg_write(CHGREG,ICHG_set);
+
+ break;
+
+ case CHARG_CONST_VOLT:
+ battery_info.flags &= ~( BATTERY_CHARGING |
+ BATTERY_FAILURE );
+ battery_info.flags |= BATTERY_CHG_ENABLED;
+ twl3025_reg_write(BCICTL2,0);
+ twl3025_reg_write(CHGREG,0);
+ twl3025_reg_write(BCICTL2,CHEN|LEDC);
+ twl3025_reg_write(CHGREG,VCHG_set);
+ break;
+
+ case CHARG_FAIL:
+ case CHARG_OFF:
+ default:
+ battery_info.flags &= ~( BATTERY_CHG_ENABLED |
+ BATTERY_CHARGING | BATTERY_FAILURE );
+ twl3025_reg_write(BCICTL2,0); /* turn off charger */
+ twl3025_reg_write(CHGREG,0);
+ break;
+ }
+
+ printf("BCICTL2 is 0x%03x, CHGREG=%d\n",
+ twl3025_reg_read(BCICTL2),
+ twl3025_reg_read(CHGREG));
+
+ bat_compal_e88_chg_state = newstate;
+}
+
+static void
+bat_compal_e88_chg_control(){
+ /* with AC power disconnected, always go to off state */
+ if(!(battery_info.flags & BATTERY_CHG_CONNECTED)){
+ bat_compal_e88_goto_state(CHARG_OFF);
+ return;
+ }
+
+ /* if failure condition is detected, always goto failure state */
+ if(bat_compal_e88_madc[MADC_VBAT] > VBAT_fail){
+ bat_compal_e88_goto_state(CHARG_FAIL);
+ return;
+ }
+
+ /* now AC power is present and battery is not over failure
+ thresholds */
+ switch(bat_compal_e88_chg_state){
+ case CHARG_OFF:
+ if(bat_compal_e88_madc[MADC_VBAT] >= VBAT_full)
+ bat_compal_e88_goto_state(CHARG_CONST_VOLT);
+ else
+ bat_compal_e88_goto_state(CHARG_CONST_CURR);
+ break;
+ case CHARG_CONST_CURR:
+ if(bat_compal_e88_madc[MADC_VBAT] >= VBAT_full)
+ bat_compal_e88_goto_state(CHARG_CONST_VOLT);
+ break;
+ case CHARG_CONST_VOLT:
+ break;
+ default:
+ case CHARG_FAIL:
+ if(bat_compal_e88_madc[MADC_VBAT] < VBAT_full)
+ bat_compal_e88_goto_state(CHARG_CONST_CURR);
+ break;
+ }
+}
+
+/*
+ * Charging voltage connection - state machine, remembers
+ * state in battery_info.flags.
+ *
+ * VCHG > VCHG_thr_on
+ * +-----------------+ ------------------> +---------------+
+ * | ! CHG_CONNECTED | | CHG_CONNECTED |
+ * +-----------------+ <------------------ +---------------+
+ * VCHG < VCHG_thr_off
+ */
+static void
+bat_compal_e88_chk_ac_presence(){
+ int vrpcsts = twl3025_reg_read(VRPCSTS);
+
+ /* check for presence of charging voltage */
+ if(!(battery_info.flags & BATTERY_CHG_CONNECTED)){
+ if(vrpcsts & CHGPRES){
+ puts("\033[34;1mCHARGER: external voltage connected!\033[0m\n");
+ battery_info.flags |= BATTERY_CHG_CONNECTED;
+
+ /* always keep ADC, voltage dividers and bias voltages on */
+ twl3025_unit_enable(TWL3025_UNIT_MAD,1);
+ twl3025_reg_write(BCICTL1,BATTERY_ALL_SENSE);
+ }
+ } else {
+ if(!(vrpcsts & CHGPRES)){
+ /* we'll only run ADC on demand */
+ twl3025_unit_enable(TWL3025_UNIT_MAD,0);
+ twl3025_reg_write(BCICTL1,0);
+
+ battery_info.flags &= ~ BATTERY_CHG_CONNECTED;
+ puts("\033[34;1mCHARGER: external voltage disconnected!\033[0m\n");
+ }
+ }
+}
+
+/* ---- update voltages visible to the user ---- */
+static void
+bat_compal_e88_upd_measurements(){
+ int adc,i;
+
+ battery_info.charger_volt_mV=
+ ADC_TO_PHYSICAL(bat_compal_e88_madc[MADC_VCHG],VCHG_LSB_uV);
+ battery_info.bat_volt_mV=
+ ADC_TO_PHYSICAL(bat_compal_e88_madc[MADC_VBAT],VBAT_LSB_uV);
+ battery_info.bat_chg_curr_mA=
+ ADC_TO_PHYSICAL(bat_compal_e88_madc[MADC_ICHG],ICHG_LSB_uA);
+
+ adc = bat_compal_e88_madc[MADC_VBAT];
+ if(adc <= VBAT_empty){ /* battery 0..100% */
+ battery_info.battery_percent = 0;
+ } else if (adc >= VBAT_full){
+ battery_info.battery_percent = 100;
+ } else {
+ battery_info.battery_percent =
+ (50+100*(adc-VBAT_empty))/(VBAT_full-VBAT_empty);
+ }
+
+ /* DEBUG */
+ printf("BAT-ADC: ");
+ for(i=0;i<MADC_NUM_CHANNELS;i++)
+ printf("%3d ",bat_compal_e88_madc[i]);
+ printf("%c\n",32);
+ printf("\tCharger at %u mV.\n",battery_info.charger_volt_mV);
+ printf("\tBattery at %u mV.\n",battery_info.bat_volt_mV);
+ printf("\tCharging at %u mA.\n",battery_info.bat_chg_curr_mA);
+ printf("\tBattery capacity is %u%%.\n",battery_info.battery_percent);
+ printf("\tBattery range is %d..%d mV.\n",
+ ADC_TO_PHYSICAL(VBAT_empty,VBAT_LSB_uV),
+ ADC_TO_PHYSICAL(VBAT_full,VBAT_LSB_uV));
+ printf("\tBattery full at %d LSB .. full at %d LSB\n",VBAT_empty,VBAT_full);
+ printf("\tCharging at %d LSB (%d mA).\n",ICHG_set,
+ ADC_TO_PHYSICAL(ICHG_set,ICHG_LSB_uA));
+ i = twl3025_reg_read(BCICTL2);
+ printf("\tBCICTL2=0x%03x\n",i);
+ printf("\tbattery-info.flags=0x%08x\n",battery_info.flags);
+ printf("\tbat_compal_e88_chg_state=%d\n",bat_compal_e88_chg_state);
+}
+
+/* bat_compal_e88_adc_read() :
+ *
+ * Schedule a ADC conversion or read values from ADC. If we are
+ * running on battery, bias currents/voltage dividers are turned
+ * on on demand.
+ *
+ * Return 0 if new ADC values have been acquired, 1 if ADC
+ * has been scheduled for a new conversion or is not yet finished.
+ *
+ */
+
+enum bat_compal_e88_madc_stat {
+ ADC_CONVERSION = 1 << 0
+};
+static uint32_t bat_compal_e88_madc_stat=0;
+
+static int
+bat_compal_e88_adc_read(){
+ int i;
+
+ if(bat_compal_e88_madc_stat & ADC_CONVERSION){
+ i = twl3025_reg_read(MADCSTAT);
+ if(i & ADCBUSY)
+ return 1;
+ for(i=0;i<MADC_NUM_CHANNELS;i++)
+ bat_compal_e88_madc[i]=twl3025_reg_read(VBATREG+i);
+ /* if charger is connected, we keep the ADC and BIAS on
+ continuously, if running on battery, we try to save power */
+ if(!(battery_info.flags & BATTERY_CHG_CONNECTED)){
+ twl3025_reg_write(BCICTL1,0x00); /* turn off bias */
+ twl3025_unit_enable(TWL3025_UNIT_MAD,0); /* & ADC */
+ }
+ bat_compal_e88_madc_stat &= ~ ADC_CONVERSION;
+ return 0;
+ } else {
+ /* if running on battery, turn on ADC & BIAS on demand */
+ if(!(battery_info.flags & BATTERY_CHG_CONNECTED)){
+ twl3025_unit_enable(TWL3025_UNIT_MAD,1);
+ twl3025_reg_write(BCICTL1,BATTERY_ALL_SENSE);
+ }
+
+ twl3025_reg_write(MADCTRL,0xff); /* convert all channels */
+ twl3025_reg_write(VBATREG,0); /* trigger conversion */
+
+ bat_compal_e88_madc_stat |= ADC_CONVERSION;
+ return 1;
+ }
+}
+
+static void
+battery_compal_e88_timer_cb(void *p){
+ struct osmo_timer_list *tmr = (struct osmo_timer_list*)p;
+ int i;
+
+ if(bat_compal_e88_adc_read()){ /* read back ADCs after a brief delay */
+ osmo_timer_schedule(tmr,ADC_TIMER_DELAY);
+ return;
+ }
+
+ bat_compal_e88_upd_measurements(); /* convert user-accessible information */
+ bat_compal_e88_chk_ac_presence(); /* detect AC charger presence */
+ bat_compal_e88_chg_control(); /* battery charger state machine */
+
+ osmo_timer_schedule(tmr,BATTERY_TIMER_DELAY);
+}
+
+/* timer that fires the charging loop regularly */
+static struct osmo_timer_list battery_compal88_timer = {
+ .cb = &battery_compal_e88_timer_cb,
+ .data = &battery_compal88_timer
+};
+
+void
+battery_compal_e88_init(){
+ printf("%s: starting up\n",__FUNCTION__);
+ osmo_timer_schedule(&battery_compal88_timer,BATTERY_TIMER_DELAY);
+}
+
@@ -0,0 +1,9 @@
+#include <battery/battery.h>
+
+/* Battery Management: Dummy file when no charging logic exists. */
+struct battery_info battery_info;
+
+void battery_dummy_init(){
+ battery_info.flags = BATTERY_FAILURE; /* not implemented */
+}
+
@@ -45,6 +45,7 @@
#include <abb/twl3025.h>
#include <rf/trf6151.h>
#include <fb/framebuffer.h>
+#include <battery/compal_e88.h>
#define ARMIO_LATCH_OUT 0xfffe4802
#define IO_CNTL_REG 0xfffe4804
@@ -133,4 +134,7 @@
/* Initialize ABB driver (uses SPI) */
twl3025_init();
+
+ /* Initialize the charging controller */
+ battery_compal_e88_init();
}
@@ -32,6 +32,7 @@
extern const struct fb_font font_helvB14;
// extern const struct fb_font font_helvB24;
extern const struct fb_font font_c64;
+extern const struct fb_font font_symbols;
const struct fb_font *fb_fonts[]={
// &font_4x6,
@@ -43,6 +44,7 @@
&font_helvB14,
// &font_helvB24,
&font_c64,
+ &font_symbols,
};
const struct fb_char *
@@ -0,0 +1,113 @@
+#include <fb/font.h>
+static const uint8_t font_symbols_data[] = {
+/* @ battery - */
+ /*0000:*/ 3, 3, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0005:*/ 0x60, /* .##..... */
+ /*0006:*/ 0x40, /* .#...... */
+ /*0007:*/ 0x40, /* .#...... */
+ /*0008:*/ 0x40, /* .#...... */
+ /*0009:*/ 0x40, /* .#...... */
+ /*000a:*/ 0x40, /* .#...... */
+ /*000b:*/ 0x40, /* .#...... */
+ /*000c:*/ 0x60, /* .##..... */
+/* A battery empty */
+ /*000d:*/ 3, 3, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0012:*/ 0xe0, /* ###..... */
+ /*0013:*/ 0x00, /* ........ */
+ /*0014:*/ 0x00, /* ........ */
+ /*0015:*/ 0x00, /* ........ */
+ /*0016:*/ 0x00, /* ........ */
+ /*0017:*/ 0x00, /* ........ */
+ /*0018:*/ 0x00, /* ........ */
+ /*0019:*/ 0xe0, /* ###..... */
+/* B battery full */
+ /*001a:*/ 3, 3, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*001f:*/ 0xe0, /* ###..... */
+ /*0020:*/ 0x00, /* ........ */
+ /*0021:*/ 0xc0, /* ##...... */
+ /*0022:*/ 0xc0, /* ##...... */
+ /*0023:*/ 0xc0, /* ##...... */
+ /*0024:*/ 0xc0, /* ##...... */
+ /*0025:*/ 0x00, /* ........ */
+ /*0026:*/ 0xe0, /* ###..... */
+/* C battery + */
+ /*0027:*/ 3, 3, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*002c:*/ 0x80, /* #....... */
+ /*002d:*/ 0x80, /* #....... */
+ /*002e:*/ 0xc0, /* ##...... */
+ /*002f:*/ 0xc0, /* ##...... */
+ /*0030:*/ 0xc0, /* ##...... */
+ /*0031:*/ 0xc0, /* ##...... */
+ /*0032:*/ 0x80, /* #....... */
+ /*0033:*/ 0x80, /* #....... */
+/* D radiation left */
+ /*0034:*/ 3, 3, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0039:*/ 0x20, /* ..#..... */
+ /*003a:*/ 0x40, /* .#...... */
+ /*003b:*/ 0x20, /* ..#..... */
+ /*003c:*/ 0x00, /* ........ */
+ /*003d:*/ 0x00, /* ........ */
+ /*003e:*/ 0x00, /* ........ */
+ /*003f:*/ 0x00, /* ........ */
+ /*0040:*/ 0x00, /* ........ */
+/* E tower */
+ /*0041:*/ 5, 5, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0046:*/ 0x20, /* ..#..... */
+ /*0047:*/ 0x50, /* .#.#.... */
+ /*0048:*/ 0x20, /* ..#..... */
+ /*0049:*/ 0x20, /* ..#..... */
+ /*004a:*/ 0x50, /* .#.#.... */
+ /*004b:*/ 0x50, /* .#.#.... */
+ /*004c:*/ 0x88, /* #...#... */
+ /*004d:*/ 0xf8, /* #####... */
+/* F radiation right */
+ /*004e:*/ 3, 3, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0053:*/ 0x80, /* #....... */
+ /*0054:*/ 0x40, /* .#...... */
+ /*0055:*/ 0x80, /* #....... */
+ /*0056:*/ 0x00, /* ........ */
+ /*0057:*/ 0x00, /* ........ */
+ /*0058:*/ 0x00, /* ........ */
+ /*0059:*/ 0x00, /* ........ */
+ /*005a:*/ 0x00, /* ........ */
+/* G no radiation */
+ /*005b:*/ 3, 3, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0060:*/ 0x00, /* ........ */
+ /*0061:*/ 0x00, /* ........ */
+ /*0062:*/ 0x00, /* ........ */
+ /*0063:*/ 0x00, /* ........ */
+ /*0064:*/ 0x00, /* ........ */
+ /*0065:*/ 0x00, /* ........ */
+ /*0066:*/ 0x00, /* ........ */
+ /*0067:*/ 0x00, /* ........ */
+/* H battery loaded */
+ /*0068:*/ 3, 3, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*006d:*/ 0xe0, /* ###..... */
+ /*006e:*/ 0x00, /* ........ */
+ /*006f:*/ 0xe0, /* ###..... */
+ /*0070:*/ 0xe0, /* ###..... */
+ /*0071:*/ 0xe0, /* ###..... */
+ /*0072:*/ 0xe0, /* ###..... */
+ /*0073:*/ 0x00, /* ........ */
+ /*0074:*/ 0xe0, /* ###..... */
+};
+static const uint16_t font_symbols_offsets[] = {
+ 0x0000 /* '@' */,
+ 0x000d /* 'A' */,
+ 0x001a /* 'B' */,
+ 0x0027 /* 'C' */,
+ 0x0034 /* 'D' */,
+ 0x0041 /* 'E' */,
+ 0x004e /* 'F' */,
+ 0x005b /* 'G' */,
+ 0x0068 /* 'H' */,
+};
+const struct fb_font font_symbols = {
+ .height = 8,
+ .ascent = 8,
+ .firstchar = 64, /* '@' */
+ .lastchar = 72,
+ .chardata = font_symbols_data,
+ .charoffs = font_symbols_offsets,
+};
+
@@ -69,6 +69,56 @@
};
#define BULDATA2 BULDATA1
+/* available ADC inputs on IOTA */
+enum twl3025_dac_inputs {/* === Signal ============================= */
+ MADC_VBAT=0, /* battery voltage / 4 */
+ MADC_VCHG=1, /* charger voltage / 5 */
+ MADC_ICHG=2, /* I-sense amp or CHGREG DAC output */
+ MADC_VBKP=3, /* backup battery voltage / 4 */
+ MADC_ADIN1=4, /* VADCID, sense battery type, not used */
+ MADC_ADIN2=5, /* Temperature sensor in Battery */
+ MADC_ADIN3=6, /* Mode_detect: sense 2.5mm jack insertion */
+ MADC_ADIN4=7, /* RITA: TEMP_SEN */
+ MADC_NUM_CHANNELS=8
+};
+
+enum madcstat_reg_bits { /* monitoring ADC status register */
+ ADCBUSY = 0x01 /* if set, a conversion is currently going on */
+};
+
+/* BCICTL1 register bits */
+enum bcictl1_reg_bits {
+ MESBAT = 1<<0, /* connect resistive divider for bat voltage */
+ DACNBUF = 1<<1, /* bypass DAC buffer */
+ THSENS0 = 1<<3, /* thermal sensor bias current (ADIN2), bit 0 */
+ THSENS1 = 1<<4, /* "" bit 1 */
+ THSENS2 = 1<<5, /* "" bit 2 */
+ THEN = 1<<6, /* enable thermal sensor bias current (ADIN1) */
+ TYPEN = 1<<7 /* enable bias current for battery type reading */
+};
+
+/* BCICTL1 register bits */
+enum bcictl2_reg_bits {
+ CHEN = 1<<0, /* enable charger */
+ CHIV = 1<<1, /* 1=constant current, 0=constant voltage */
+ CHBPASSPA=1<<2, /* full charging of the battery during pulse radio */
+ CLIB = 1<<3, /* calibrate I-to-V amp (short input pins) */
+ CHDISPA = 1<<4, /* disabel charging during pulse radio (???) */
+ LEDC = 1<<5, /* enable LED during charge */
+ CGAIN4 = 1<<6, /* if set, I-to-V amp gain is reduced from 10 to 4 */
+ PREOFF = 1<<7 /* disable battery precharge */
+};
+
+enum vrpcsts_reg_bits {
+ ONBSTS = 1<<0, /* button push switched on the mobile */
+ ONRSTS = 1<<1, /* RPWON terminal switched on the mobile */
+ ITWSTS = 1<<2, /* ITWAKEUP terminal switched on the mobile */
+ CHGSTS = 1<<3, /* plugging in charger has switched on the mobile */
+ ONREFLT= 1<<4, /* state of PWON terminal after debouncing */
+ ONMRFLT= 1<<5, /* state of RPWON terminal after debouncing */
+ CHGPRES= 1<<6 /* charger is connected */
+};
+
enum togbr2_bits {
TOGBR2_KEEPR = (1 << 0), /* Clear KEEPON bit */
TOGBR2_KEEPS = (1 << 1), /* Set KEEPON bit */
@@ -0,0 +1,37 @@
+#ifndef _BATTERY_BATTERY_H
+#define _BATTERY_BATTERY_H
+
+/* User-visible state of the battery charger.
+ *
+ * If CHG_CONNECTED, power is externally supplied to the mobile.
+ *
+ * If CHG_ENABLED, the charger will try to provide charge
+ * to the battery if needed, but this state might be switchable?
+ *
+ * BATTERY_CHARGING: Battery is not full, so a significant charging
+ * current (not trickle charge) is supplied.
+ *
+ * BATTERY_FAILURE: Overtemperature, overvoltage, ... if this bit
+ * is set, charging should be inhibited.
+ */
+
+
+enum battery_flags {
+ BATTERY_CHG_CONNECTED = 1 << 0, /* AC adapter is connected */
+ BATTERY_CHG_ENABLED = 1 << 1, /* if needed charger could charge */
+ BATTERY_CHARGING = 1 << 2, /* charger is actively charging */
+ BATTERY_FAILURE = 1 << 3, /* problem exists preventing charge */
+};
+
+struct battery_info {
+ enum battery_flags flags;
+ int charger_volt_mV; /* charger connection voltage */
+ int bat_volt_mV; /* battery terminal voltage */
+ int bat_chg_curr_mA; /* battery charging current */
+ int battery_percent; /* 0(empty) .. 100(full) */
+};
+
+extern struct battery_info
+battery_info;
+
+#endif
@@ -0,0 +1,15 @@
+#ifndef _BATTERY_COMPAL_E88_H
+#define _BATTERY_COMPAL_E88_H
+
+#include <stdint.h>
+#include <abb/twl3025.h>
+
+/* initialize the charger control loop on C123 */
+
+extern void
+battery_compal_e88_init();
+
+extern uint16_t
+compal_e88_madc[MADC_NUM_CHANNELS];
+
+#endif
@@ -70,6 +70,7 @@
FB_FONT_HELVB14,
// FB_FONT_HELVB24,
FB_FONT_C64,
+ FB_FONT_SYMBOLS,
};
extern const struct fb_font *fb_fonts[]; // note: has to match fb_font_id enum!