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();
}
예제 #2
0
/* 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;
}
예제 #3
0
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;
    }
}
예제 #5
0
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;
}
예제 #6
0
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
}
예제 #7
0
/* 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;
}