예제 #1
0
파일: root_menu.c 프로젝트: ntj/rockbox
static int do_shutdown(void)
{
#if CONFIG_CHARGING
    if (charger_inserted())
        charging_splash();
    else
#endif
        sys_poweroff();
    return 0;
}
예제 #2
0
void EXT3(void)
{
    if (get_pmu_type() == PCF50606)
    {
    unsigned char data[3]; /* 0 = INT1, 1 = INT2, 2 = INT3 */

    /* Clear pending interrupts from pcf50606 */
    pcf50606_read_multiple(0x02, data, 3);

    if (data[0] & 0x04)
    {
        /* ONKEY1S */
        if (!charger_inserted())
            sys_poweroff();
        else
            pcf50606_reset_timeout();
    }

    if (data[2] & 0x08)
    {
        /* Touchscreen event, do something about it */
        touchscreen_handle_device_irq();
    }
    }
    else
    {
        unsigned char data[5]; /* 0 = INT1, 1 = INT2, 2 = INT3, ... 4 = INT5 */

        /* Clear pending interrupts from pcf50635 */
        pcf50635_read_multiple(PCF5063X_REG_INT1, data, 5);

        if (data[2] & PCF5063X_INT3_ONKEY1S)
        {
           
            if (!charger_inserted())
                sys_poweroff();
        }
    }
}
예제 #3
0
static void charging_screen(void)
{
    unsigned int button;
    const char* msg;

    ide_power_enable(false); /* power down the disk, else would be spinning */

    lcd_clear_display();

    do
    {
#ifdef ARCHOS_RECORDER
        if (charge_state == CHARGING)
            msg = "charging";
        else if (charge_state == TOPOFF)
            msg = "topoff charge";
        else if (charge_state == TRICKLE)
            msg = "trickle charge";
        else
            msg = "not charging";
#else
        msg = "charging";
#endif
        lcd_puts(0, 0, msg);
        {
            char buf[32];
            int battv = battery_voltage();
            snprintf(buf, sizeof(buf), "%d.%02dV %d%%",
                battv / 1000, (battv % 1000) / 10, battery_level());
            lcd_puts(0, 1, buf);
        }
        lcd_update();

        button = button_get_w_tmo(HZ/2);
#ifdef BUTTON_ON
        if (button == (BUTTON_ON | BUTTON_REL))
#else
        if (button == (BUTTON_RIGHT | BUTTON_REL))
#endif
            break; /* start */
        else
        {
            if (usb_detect() == USB_INSERTED)
                break;
            else if (!charger_inserted())
                power_off(); /* charger removed: power down */
        }
    } while (1);
}
예제 #4
0
static void init_battery_percent(void)
{
#if CONFIG_CHARGING
    if (charger_inserted()) {
        battery_percent = voltage_to_percent(battery_millivolts,
                            percent_to_volt_charge);
    }
    else
#endif
    {
        battery_percent = voltage_to_percent(battery_millivolts,
                            percent_to_volt_discharge[battery_type]);
        battery_percent += battery_percent < 100;
    }

}
예제 #5
0
static void average_init(void)
{
    /* initialize the voltages for the exponential filter */
    avgbat = _battery_voltage() + 15;

#ifdef HAVE_DISK_STORAGE /* this adjustment is only needed for HD based */
    /* The battery voltage is usually a little lower directly after
       turning on, because the disk was used heavily. Raise it by 5% */
#if CONFIG_CHARGING
    if (!charger_inserted()) /* only if charger not connected */
#endif
    {
        avgbat += (percent_to_volt_discharge[battery_type][6] -
                   percent_to_volt_discharge[battery_type][5]) / 2;
    }
#endif /* HAVE_DISK_STORAGE */

    avgbat = avgbat * BATT_AVE_SAMPLES;
    battery_millivolts = power_history[0] = avgbat / BATT_AVE_SAMPLES;
}
예제 #6
0
파일: button.c 프로젝트: 4nykey/rockbox
static void button_tick(void)
{
    static int count = 0;
    static int repeat_speed = REPEAT_INTERVAL_START;
    static int repeat_count = 0;
    static bool repeat = false;
    static bool post = false;
#ifdef HAVE_BACKLIGHT
    static bool skip_release = false;
#ifdef HAVE_REMOTE_LCD
    static bool skip_remote_release = false;
#endif
#endif
    int diff;
    int btn;
#ifdef HAVE_BUTTON_DATA
    int data = 0;
#else
    const int data = 0;
#endif

#if defined(HAS_SERIAL_REMOTE) && !defined(SIMULATOR)
    /* Post events for the remote control */
    btn = remote_control_rx();
    if(btn)
        button_try_post(btn, 0);
#endif

#ifdef HAVE_BUTTON_DATA
    btn = button_read(&data);
#else
    btn = button_read();
#endif
#if defined(HAVE_HEADPHONE_DETECTION)
    if (headphones_inserted() != phones_present)
    {
        /* Use the autoresetting oneshot to debounce the detection signal */
        phones_present = !phones_present;
        timeout_register(&hp_detect_timeout, btn_detect_callback,
                         HZ/2, phones_present);
    }
#endif

    /* Find out if a key has been released */
    diff = btn ^ lastbtn;
    if(diff && (btn & diff) == 0)
    {
#ifdef HAVE_BACKLIGHT
#ifdef HAVE_REMOTE_LCD
        if(diff & BUTTON_REMOTE)
            if(!skip_remote_release)
                button_try_post(BUTTON_REL | diff, data);
            else
                skip_remote_release = false;
        else
#endif
            if(!skip_release)
                button_try_post(BUTTON_REL | diff, data);
            else
                skip_release = false;
#else
        button_try_post(BUTTON_REL | diff, data);
#endif
    }
    else
    {
        if ( btn )
        {
            /* normal keypress */
            if ( btn != lastbtn )
            {
                post = true;
                repeat = false;
                repeat_speed = REPEAT_INTERVAL_START;
            }
            else /* repeat? */
            {
                if ( repeat )
                {
                    if (!post)
                        count--;
                    if (count == 0) {
                        post = true;
                        /* yes we have repeat */
                        if (repeat_speed > REPEAT_INTERVAL_FINISH)
                            repeat_speed--;
                        count = repeat_speed;

                        repeat_count++;

                        /* Send a SYS_POWEROFF event if we have a device
                           which doesn't shut down easily with the OFF
                           key */
#ifdef HAVE_SW_POWEROFF
                        if ((btn & POWEROFF_BUTTON
#ifdef RC_POWEROFF_BUTTON
                                    || btn == RC_POWEROFF_BUTTON
#endif
                                    ) &&
#if CONFIG_CHARGING && !defined(HAVE_POWEROFF_WHILE_CHARGING)
                                !charger_inserted() &&
#endif
                                repeat_count > POWEROFF_COUNT)
                        {
                            /* Tell the main thread that it's time to
                               power off */
                            sys_poweroff();

                            /* Safety net for players without hardware
                               poweroff */
#if (CONFIG_PLATFORM & PLATFORM_NATIVE)
                            if(repeat_count > POWEROFF_COUNT * 10)
                                power_off();
#endif
                        }
#endif
                    }
                }
                else
                {
                    if (count++ > REPEAT_START)
                    {
                        post = true;
                        repeat = true;
                        repeat_count = 0;
                        /* initial repeat */
                        count = REPEAT_INTERVAL_START;
                    }
#ifdef HAVE_TOUCHSCREEN
                    else if (lastdata != data && btn == lastbtn)
                    {   /* only coordinates changed, post anyway */
                        if (touchscreen_get_mode() == TOUCHSCREEN_POINT)
                            post = true;
                    }
#endif
                }
            }
            if ( post )
            {
                if (repeat)
                {
                    /* Only post repeat events if the queue is empty,
                     * to avoid afterscroll effects. */
                    if (button_try_post(BUTTON_REPEAT | btn, data))
                    {
#ifdef HAVE_BACKLIGHT
#ifdef HAVE_REMOTE_LCD
                        skip_remote_release = false;
#endif
                        skip_release = false;
#endif
                        post = false;
                    }
                }
                else
                {
#ifdef HAVE_BACKLIGHT
#ifdef HAVE_REMOTE_LCD
                    if (btn & BUTTON_REMOTE) {
                        if (!remote_filter_first_keypress 
                            || is_remote_backlight_on(false)
#if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES)
                            || (remote_type()==REMOTETYPE_H300_NONLCD)
#endif
                            )
                            button_try_post(btn, data);
                        else
                            skip_remote_release = true;
                    }
                    else
#endif
                        if (!filter_first_keypress || is_backlight_on(false)
#if BUTTON_REMOTE
                                || (btn & BUTTON_REMOTE)
#endif
                           )
                            button_try_post(btn, data);
                        else
                            skip_release = true;
#else /* no backlight, nothing to skip */
                    button_try_post(btn, data);
#endif
                    post = false;
                }
#ifdef HAVE_REMOTE_LCD
                if(btn & BUTTON_REMOTE)
                    remote_backlight_on();
                else
#endif
                {
                    backlight_on();
#ifdef HAVE_BUTTON_LIGHT
                    buttonlight_on();
#endif
                }

                reset_poweroff_timer();
            }
        }
        else
        {
            repeat = false;
            count = 0;
        }
    }
    lastbtn = btn & ~(BUTTON_REL | BUTTON_REPEAT);
#ifdef HAVE_BUTTON_DATA
    lastdata = data;
#endif
}
static void power_thread(void)
{
    long next_power_hist;

    /* Delay reading the first battery level */
#ifdef MROBE_100
    while (battery_adc_voltage() > 4200) /* gives false readings initially */
#endif
    {
        sleep(HZ/100);
    }

#if CONFIG_CHARGING
    /* Initialize power input status before calling other routines. */
    power_thread_inputs = power_input_status();
#endif

    /* initialize the voltages for the exponential filter */
    avgbat = battery_adc_voltage() + 15;

#ifdef HAVE_DISK_STORAGE /* this adjustment is only needed for HD based */
    /* The battery voltage is usually a little lower directly after
       turning on, because the disk was used heavily. Raise it by 5% */
#if CONFIG_CHARGING
    if (!charger_inserted()) /* only if charger not connected */
#endif
    {
        avgbat += (percent_to_volt_discharge[battery_type][6] -
                   percent_to_volt_discharge[battery_type][5]) / 2;
    }
#endif /* HAVE_DISK_STORAGE */

    avgbat = avgbat * BATT_AVE_SAMPLES;
    battery_millivolts = avgbat / BATT_AVE_SAMPLES;
    power_history[0] = battery_millivolts;

#if CONFIG_CHARGING
    if (charger_inserted()) {
        battery_percent = voltage_to_percent(battery_millivolts,
                                             percent_to_volt_charge);
    }
    else
#endif
    {
        battery_percent = voltage_to_percent(battery_millivolts,
                                             percent_to_volt_discharge[battery_type]);
        battery_percent += battery_percent < 100;
    }

    powermgmt_init_target();

    next_power_hist = current_tick + HZ*60;

    while (1)
    {
#if CONFIG_CHARGING
        unsigned int pwr = power_input_status();
#ifdef HAVE_BATTERY_SWITCH
        if ((pwr ^ power_thread_inputs) & POWER_INPUT_BATTERY) {
            sleep(HZ/10);
            reset_battery_filter(battery_adc_voltage());
        }
#endif
        power_thread_inputs = pwr;

        if (!detect_charger(pwr))
#endif /* CONFIG_CHARGING */
        {
            /* Steady state */
            sleep(POWER_THREAD_STEP_TICKS);

            /* Do common power tasks */
            power_thread_step();
        }

        /* Perform target tasks */
        charging_algorithm_step();

        if (TIME_BEFORE(current_tick, next_power_hist))
            continue;

        /* increment to ensure there is a record for every minute
         * rather than go forward from the current tick */
        next_power_hist += HZ*60;

        /* rotate the power history */
        memmove(&power_history[1], &power_history[0],
                sizeof(power_history) - sizeof(power_history[0]));

        /* insert new value at the start, in millivolts 8-) */
        power_history[0] = battery_millivolts;

        handle_auto_poweroff();
    }
} /* power_thread */
예제 #8
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
}
예제 #9
0
static bool clean_shutdown(void (*callback)(void *), void *parameter)
{
#ifdef SIMULATOR
    (void)callback;
    (void)parameter;
    bookmark_autobookmark();
    call_storage_idle_notifys(true);
    exit(0);
#else
    long msg_id = -1;
    int i;

    scrobbler_poweroff();

#if CONFIG_CHARGING && !defined(HAVE_POWEROFF_WHILE_CHARGING)
    if(!charger_inserted())
#endif
    {
        bool batt_safe = battery_level_safe();
        int audio_stat = audio_status();

        FOR_NB_SCREENS(i)
        {
            screens[i].clear_display();
            screens[i].update();
        }

        if (batt_safe)
        {
#ifdef HAVE_TAGCACHE
            if (!tagcache_prepare_shutdown())
            {
                cancel_shutdown();
                splash(HZ, ID2P(LANG_TAGCACHE_BUSY));
                return false;
            }
#endif
            if (battery_level() > 10)
                splash(0, str(LANG_SHUTTINGDOWN));
            else
            {
                msg_id = LANG_WARNING_BATTERY_LOW;
                splashf(0, "%s %s", str(LANG_WARNING_BATTERY_LOW),
                                    str(LANG_SHUTTINGDOWN));
            }
        }
        else
        {
            msg_id = LANG_WARNING_BATTERY_EMPTY;
            splashf(0, "%s %s", str(LANG_WARNING_BATTERY_EMPTY),
                                str(LANG_SHUTTINGDOWN));
        }

        if (global_settings.fade_on_stop
            && (audio_stat & AUDIO_STATUS_PLAY))
        {
            fade(false, false);
        }

        if (batt_safe) /* do not save on critical battery */
        {
#if defined(HAVE_RECORDING) && CONFIG_CODEC == SWCODEC
            if (audio_stat & AUDIO_STATUS_RECORD)
            {
                rec_command(RECORDING_CMD_STOP);
                /* wait for stop to complete */
                while (audio_status() & AUDIO_STATUS_RECORD)
                    sleep(1);
            }
#endif
            bookmark_autobookmark();

            /* audio_stop_recording == audio_stop for HWCODEC */
            audio_stop();

            if (callback != NULL)
                callback(parameter);

#if CONFIG_CODEC != SWCODEC
            /* wait for audio_stop or audio_stop_recording to complete */
            while (audio_status())
                sleep(1);
#endif

#if defined(HAVE_RECORDING) && CONFIG_CODEC == SWCODEC
            audio_close_recording();
#endif

            if(global_settings.talk_menu)
            {
                bool enqueue = false;
                if(msg_id != -1)
                {
                    talk_id(msg_id, enqueue);
                    enqueue = true;
                }
                talk_id(LANG_SHUTTINGDOWN, enqueue);
#if CONFIG_CODEC == SWCODEC
                voice_wait();
#endif
            }

            system_flush();
#ifdef HAVE_EEPROM_SETTINGS
            if (firmware_settings.initialized)
            {
                firmware_settings.disk_clean = true;
                firmware_settings.bl_version = 0;
                eeprom_settings_store();
            }
#endif
        }
#ifdef HAVE_DIRCACHE
        else
            dircache_disable();
#endif

        shutdown_hw();
    }
예제 #10
0
void main(void)
{
    int rc;

    power_init();
    system_init();
    kernel_init();
    lcd_init();
    show_logo();
    enable_irq();
    adc_init();
    usb_init();
    button_init();
    powermgmt_init();

#if CONFIG_CHARGING && (CONFIG_CPU == SH7034)
    if (charger_inserted()
#ifdef ATA_POWER_PLAYERSTYLE
        && !ide_powered() /* relies on probing result from bootloader */
#endif
        )
    {
        charging_screen(); /* display a "charging" screen */
        show_logo();  /* again, to provide better visual feedback */
    }
#endif

    rc = storage_init();
    if(rc)
    {
#ifdef HAVE_LCD_BITMAP
        char str[32];
        lcd_clear_display();
        snprintf(str, 31, "ATA error: %d", rc);
        lcd_puts(0, 1, str);
        lcd_update();
        while(!(button_get(true) & BUTTON_REL));
#endif
        panicf("storage: %d", rc);
    }

    usb_start_monitoring();
    while (usb_detect() == USB_INSERTED)
    {   /* enter USB mode early, before trying to mount */
        if (button_get_w_tmo(HZ/10) == SYS_USB_CONNECTED)
        {
            usb_screen();
        }
    }

    rc = disk_mount_all();
    if (rc<=0)
    {
        prompt_usb("No partition", "found.");
    }

    {   // rolo the firmware
        static const char filename[] = "/" BOOTFILE;
        rolo_load((char*)filename); /* won't return if started */

        prompt_usb("No firmware", filename);
    }


}
예제 #11
0
int do_shortcut_menu(void *ignored)
{
    (void)ignored;
    struct simplelist_info list;
    struct shortcut *sc;
    int done = GO_TO_PREVIOUS;
    if (first_handle == 0)
        shortcuts_init();
    simplelist_info_init(&list, P2STR(ID2P(LANG_SHORTCUTS)), shortcut_count, NULL);
    list.get_name = shortcut_menu_get_name;
    list.action_callback = shortcut_menu_get_action;
    if (global_settings.show_icons)
        list.get_icon = shortcut_menu_get_icon;
    list.title_icon = Icon_Bookmark;
    if (global_settings.talk_menu)
        list.get_talk = shortcut_menu_speak_item;

    push_current_activity(ACTIVITY_SHORTCUTSMENU);

    while (done == GO_TO_PREVIOUS)
    {
        if (simplelist_show_list(&list))
            break; /* some error happened?! */
        if (list.selection == -1)
            break;
        else
        {
            sc = get_shortcut(list.selection);
            if (!sc)
                continue;
            switch (sc->type)
            {
                case SHORTCUT_PLAYLISTMENU:
                    if (!file_exists(sc->u.path))
                    {
                        splash(HZ, ID2P(LANG_NO_FILES));
                        break;
                    }
                    else
                    {
                        onplay_show_playlist_menu(sc->u.path);
                    }
                    break;
                case SHORTCUT_FILE:
                    if (!file_exists(sc->u.path))
                    {
                        splash(HZ, ID2P(LANG_NO_FILES));
                        break;
                    }
                    /* else fall through */
                case SHORTCUT_BROWSER:
                {
                    struct browse_context browse;
                    browse_context_init(&browse, global_settings.dirfilter, 0,
                            NULL, NOICON, sc->u.path, NULL);
                    if (sc->type == SHORTCUT_FILE)
                        browse.flags |= BROWSE_RUNFILE;
                    done = rockbox_browse(&browse);
                }
                break;
                case SHORTCUT_SETTING:
                    do_setting_screen(sc->u.setting,
                            sc->name[0] ? sc->name : P2STR(ID2P(sc->u.setting->lang_id)),NULL);
                    break;
                case SHORTCUT_DEBUGITEM:
                    run_debug_screen(sc->u.path);
                    break;
                case SHORTCUT_SHUTDOWN:
#if CONFIG_CHARGING
                    if (charger_inserted())
                        charging_splash();
                    else
#endif
                        sys_poweroff();
                    break;
                case SHORTCUT_TIME:
#if CONFIG_RTC
                  if (sc->u.timedata.talktime) {
                        talk_timedate();
                        talk_force_enqueue_next();
                  } else
#endif
                    {
                        char timer_buf[10];
                        set_sleep_timer(sc->u.timedata.sleep_timeout * 60);
                        splashf(HZ, "%s (%s)", str(LANG_SLEEP_TIMER), 
                                sleep_timer_formatter(timer_buf, sizeof(timer_buf),
                                                      sc->u.timedata.sleep_timeout, NULL));
                    }
                    break;
                case SHORTCUT_UNDEFINED:
                default:
                    break;
            }
        }
    }
    pop_current_activity();
    return done;
}
예제 #12
0
int usb_detect(void)
{
    if (charger_inserted())
        return USB_INSERTED;
    return USB_EXTRACTED;
}