static void battery_status_update(void) { int level = voltage_to_battery_level(battery_millivolts); #ifdef CURRENT_NORMAL /*don't try to estimate run or charge time without normal current defined*/ /* calculate estimated remaining running time */ #if CONFIG_CHARGING >= CHARGING_MONITOR if (charging_state()) { /* charging: remaining charging time */ powermgmt_est_runningtime_min = (100 - level)*battery_capacity*60 / 100 / (CURRENT_MAX_CHG - runcurrent()); } else #endif /* discharging: remaining running time */ if (battery_millivolts > percent_to_volt_discharge[0][0]) { /* linear extrapolation */ powermgmt_est_runningtime_min = (level + battery_percent)*60 * battery_capacity / 200 / runcurrent(); } if (0 > powermgmt_est_runningtime_min) { powermgmt_est_runningtime_min = 0; } #else powermgmt_est_runningtime_min=-1; #endif battery_percent = level; send_battery_level_event(); }
/* update battery level and estimated runtime, called once per minute or * when battery capacity / type settings are changed */ static int voltage_to_battery_level(int battery_millivolts) { int level; if (battery_millivolts < 0) return -1; #if CONFIG_CHARGING >= CHARGING_MONITOR if (charging_state()) { /* battery level is defined to be < 100% until charging is finished */ level = voltage_to_percent(battery_millivolts, percent_to_volt_charge); if (level > 99) level = 99; } else #endif /* CONFIG_CHARGING >= CHARGING_MONITOR */ { /* DISCHARGING or error state */ level = voltage_to_percent(battery_millivolts, percent_to_volt_discharge[battery_type]); } return level; }
unsigned int power_input_status(void) { unsigned int status = POWER_INPUT_NONE; if (charging_state()) status |= POWER_INPUT_MAIN_CHARGER; return status; }
static inline void charging_algorithm_step(void) { switch (charger_input_state) { case CHARGER_PLUGGED: case CHARGER: if (charging_state()) { charge_state = CHARGING; break; } /* Fallthrough */ case CHARGER_UNPLUGGED: case NO_CHARGER: charge_state = DISCHARGING; break; } }
bool dbg_hw_info(void) { int line; int i; unsigned int state = 0; const unsigned int max_states=3; lcd_clear_display(); lcd_setfont(FONT_SYSFIXED); state=0; while(1) { lcd_clear_display(); line = 0; if(state == 0) { _DEBUG_PRINTF("CPU:"); _DEBUG_PRINTF("current_tick: %d", (unsigned int)current_tick); line++; _DEBUG_PRINTF("LCD type: %d", lcd_type); line++; } else if(state==1) { _DEBUG_PRINTF("PMU:"); for(i=0;i<7;i++) { char *device[] = {"(unknown)", "(unknown)", "(unknown)", "(unknown)", "(unknown)", "(unknown)", "(unknown)"}; _DEBUG_PRINTF("ldo%d %s: %dmV %s",i, pmu_read(0x2e + (i << 1))?" on":"off", 900 + pmu_read(0x2d + (i << 1))*100, device[i]); } _DEBUG_PRINTF("cpu voltage: %dmV",625 + pmu_read(0x1e)*25); _DEBUG_PRINTF("memory voltage: %dmV",625 + pmu_read(0x22)*25); line++; _DEBUG_PRINTF("charging: %s", charging_state() ? "true" : "false"); _DEBUG_PRINTF("backlight: %s", pmu_read(0x29) ? "on" : "off"); _DEBUG_PRINTF("brightness value: %d", pmu_read(0x28)); } else if(state==2) { _DEBUG_PRINTF("Audio DMA:"); _DEBUG_PRINTF(">%08X %08X %08X %08X %08X", DMAC0C0CONFIG, DMAC0C0SRCADDR, DMAC0C0DESTADDR, DMAC0C0NEXTLLI, DMAC0C0CONTROL); for(i = 0; i < PCM_LLICOUNT; i++) _DEBUG_PRINTF("%08X: %08X %08X %08X %08X", &pcm_lli[i], pcm_lli[i].srcaddr, pcm_lli[i].dstaddr, pcm_lli[i].nextlli, pcm_lli[i].control); _DEBUG_PRINTF("chunk: %08X %08X", pcm_chunksize, pcm_remaining); } else { state=0; } lcd_update(); switch(button_get_w_tmo(HZ/20)) { case BUTTON_SCROLL_BACK: if(state!=0) state--; break; case BUTTON_SCROLL_FWD: if(state!=max_states-1) { state++; } break; case DEBUG_CANCEL: case BUTTON_REL: lcd_setfont(FONT_UI); return false; } } lcd_setfont(FONT_UI); return false; }
void main(void) { unsigned char* loadbuffer; int buffer_size; int rc; int(*kernel_entry)(void); system_init(); kernel_init(); /* Need the kernel to sleep */ enable_interrupt(IRQ_FIQ_STATUS); lcd_init(); backlight_init(); button_init(); font_init(); adc_init(); lcd_setfont(FONT_SYSFIXED); /* These checks should only run if the bootloader is flashed */ if(GSTATUS3&0x02) { GSTATUS3&=0xFFFFFFFD; if(!(GPGDAT&BUTTON_POWER) && charger_inserted()) { while(!(GPGDAT&BUTTON_POWER) && charger_inserted()) { char msg[20]; if(charging_state()) { snprintf(msg,sizeof(msg),"Charging"); } else { snprintf(msg,sizeof(msg),"Charge Complete"); } reset_screen(); lcd_putsxy( (LCD_WIDTH - (SYSFONT_WIDTH * strlen(msg))) / 2, (LCD_HEIGHT - SYSFONT_HEIGHT) / 2, msg); lcd_update(); #if defined(HAVE_RTC_ALARM) /* Check if the alarm went off while charging */ if(rtc_check_alarm_flag()) { GSTATUS3=1; /* Normally this is set in crt0.s */ break; } #endif } if(!(GPGDAT&BUTTON_POWER) #if defined(HAVE_RTC_ALARM) && !GSTATUS3 #endif ) { shutdown(); } } if(button_hold()) { const char msg[] = "HOLD is enabled"; reset_screen(); lcd_putsxy( (LCD_WIDTH - (SYSFONT_WIDTH * strlen(msg))) / 2, (LCD_HEIGHT - SYSFONT_HEIGHT) / 2, msg); lcd_update(); sleep(2*HZ); shutdown(); } } power_init(); usb_init(); /* Enter USB mode without USB thread */ if(usb_detect() == USB_INSERTED) { const char msg[] = "Bootloader USB mode"; reset_screen(); lcd_putsxy( (LCD_WIDTH - (SYSFONT_WIDTH * strlen(msg))) / 2, (LCD_HEIGHT - SYSFONT_HEIGHT) / 2, msg); lcd_update(); storage_enable(false); sleep(HZ/20); usb_enable(true); while (usb_detect() == USB_INSERTED) sleep(HZ); usb_enable(false); reset_screen(); lcd_update(); } reset_screen(); /* Show debug messages if button is pressed */ if(button_read_device()&BUTTON_A) verbose = true; printf("Rockbox boot loader"); printf("Version %s", rbversion); sleep(50); /* ATA seems to error without this pause */ rc = storage_init(); if(rc) { reset_screen(); error(EATA, rc, true); } filesystem_init(); rc = disk_mount_all(); if (rc<=0) { error(EDISK, rc, true); } printf("Loading firmware"); /* Flush out anything pending first */ commit_discard_idcache(); loadbuffer = (unsigned char*) 0x31000000; buffer_size = (unsigned char*)0x31400000 - loadbuffer; rc = load_firmware(loadbuffer, BOOTFILE, buffer_size); if(rc <= EFILE_EMPTY) error(EBOOTFILE, rc, true); storage_close(); system_prepare_fw_start(); commit_discard_idcache(); kernel_entry = (void*) loadbuffer; rc = kernel_entry(); #if 0 /* Halt */ while (1) core_idle(); #else /* Return and restart */ #endif }
/* Returns battery voltage from ADC [millivolts] */ unsigned int battery_adc_voltage(void) { int compensation = (10 * (pmu_read_battery_current() - 7)) / 12; if (charging_state()) return pmu_read_battery_voltage() - compensation; return pmu_read_battery_voltage() + compensation; }