Exemple #1
0
static void mpr121_thread(void)
{
    struct queue_event ev;

    while(1)
    {
        queue_wait(&mpr121_queue, &ev);
        /* handle usb connect and ignore all messages except rmi interrupts */
        if(ev.id == SYS_USB_CONNECTED)
        {
            usb_acknowledge(SYS_USB_CONNECTED_ACK);
            continue;
        }
        else if(ev.id != MPR121_INTERRUPT)
            continue;
        /* clear interrupt and get status */
        unsigned status;
        touchpad_btns = 0;
        if(!mpr121_get_touch_status(&status))
        {
            /* ELE3: up
             * ELE4: back
             * ELE5: menu
             * ELE6: down
             * ELE7: play */
            if(status & 0x8) touchpad_btns |= BUTTON_UP;
            if(status & 0x10) touchpad_btns |= BUTTON_BACK;
            if(status & 0x20) touchpad_btns |= BUTTON_MENU;
            if(status & 0x40) touchpad_btns |= BUTTON_DOWN;
            if(status & 0x80) touchpad_btns |= BUTTON_PLAY;
        }
        /* enable interrupt */
        imx233_pinctrl_setup_irq(0, 18, true, true, false, &mpr121_irq_cb, 0);
    }
}
Exemple #2
0
static void usb_mode(void)
{
    int button;

    /* Init USB */
    usb_init();
    usb_start_monitoring();

    /* Wait for threads to connect */
    show_splash(HZ/2, "Waiting for USB");

    while (1)
    {
        button = button_get_w_tmo(HZ/2);

        if (button == SYS_USB_CONNECTED)
            break; /* Hit */
    }

    if (button == SYS_USB_CONNECTED)
    {
        /* Got the message - wait for disconnect */
        show_splash(0, "Bootloader USB mode");

        usb_acknowledge(SYS_USB_CONNECTED_ACK);

        while (1)
        {
            button = button_get(true);
            if (button == SYS_USB_DISCONNECTED)
                break;
        }
    }
}
Exemple #3
0
static bool scroll_process_message(int delay)
{
    struct queue_event ev;

    do
    {
        long tick = current_tick;
        queue_wait_w_tmo(&scroll_queue, &ev, delay);

        switch (ev.id)
        {
        case SYS_TIMEOUT:
            return false;
        case SYS_USB_CONNECTED:
            usb_acknowledge(SYS_USB_CONNECTED_ACK);
            usb_wait_for_disconnect(&scroll_queue);
            sync_display_ticks();
            return true;
#if (CONFIG_PLATFORM & PLATFORM_NATIVE)
        case SYS_REMOTE_PLUGGED:
            if (!remote_initialized)
                sync_display_ticks();
#endif
        }

        delay -= current_tick - tick;
    }
    while (delay > 0);

    return false;
}
Exemple #4
0
/* Return USB_HANDLED if session took place else return USB_EXTRACTED */
static int handle_usb(int connect_timeout)
{
    static struct event_queue q SHAREDBSS_ATTR;
    struct queue_event ev;
    int usb = USB_EXTRACTED;
    long end_tick = 0;
    
    if (!usb_plugged())
        return USB_EXTRACTED;

    queue_init(&q, true);
    usb_init();
    usb_start_monitoring();

    printf("USB: Connecting");

    if (connect_timeout != TIMEOUT_BLOCK)
        end_tick = current_tick + connect_timeout;

    while (1)
    {
        /* Sleep no longer than 1/2s */
        queue_wait_w_tmo(&q, &ev, HZ/2);

        if (ev.id == SYS_USB_CONNECTED)
        {
            /* Switch to verbose mode if not in it so that the status updates
             * are shown */
            verbose = true;
            /* Got the message - wait for disconnect */
            printf("Bootloader USB mode");

            usb = USB_HANDLED;
            usb_acknowledge(SYS_USB_CONNECTED_ACK);
            usb_wait_for_disconnect(&q);
            break;
        }

        if (connect_timeout != TIMEOUT_BLOCK &&
            TIME_AFTER(current_tick, end_tick))
        {
            /* Timed out waiting for the connect - will happen when connected
             * to a charger instead of a host port and the charging pin is
             * the same as the USB pin */
            printf("USB: Timed out");
            break;
        }

        if (!usb_plugged())
            break; /* Cable pulled */
    }

    usb_close();
    queue_delete(&q);

    return usb;
}
Exemple #5
0
static int handle_usb_events(void)
{
#if (CONFIG_STORAGE & STORAGE_MMC)
    int next_update=0;
#endif /* STORAGE_MMC */

    /* Don't return until we get SYS_USB_DISCONNECTED or SYS_TIMEOUT */
    while(1)
    {
        int button;
#ifdef USB_ENABLE_HID
        if (usb_hid)
        {
            button = get_hid_usb_action();

            /* On mode change, we need to refresh the screen */
            if (button == ACTION_USB_HID_MODE_SWITCH_NEXT ||
                    button == ACTION_USB_HID_MODE_SWITCH_PREV)
            {
                break;
            }
        }
        else
#endif
        {
            button = button_get_w_tmo(HZ/2);
            /* hid emits the event in get_action */
            send_event(GUI_EVENT_ACTIONUPDATE, NULL);
        }

        switch(button)
        {
            case SYS_USB_DISCONNECTED:
                usb_acknowledge(SYS_USB_DISCONNECTED_ACK);
                return 1;
            case SYS_CHARGER_DISCONNECTED:
                /*reset rockbox battery runtime*/
                global_status.runtime = 0;
                break;
            case SYS_TIMEOUT:
                break;
        }

#if (CONFIG_STORAGE & STORAGE_MMC) /* USB-MMC bridge can report activity */
        if(TIME_AFTER(current_tick,next_update))
        {
            if(usb_inserted()) {
                led(mmc_usb_active(HZ));
            }
            next_update=current_tick+HZ/2;
        }
#endif /* STORAGE_MMC */
    }

    return 0;
}
static void usb_screen(void)
{
    lcd_clear_display();
    lcd_puts(0, 0, "USB mode");
    lcd_update();

    usb_acknowledge(SYS_USB_CONNECTED_ACK);
    while(usb_wait_for_disconnect_w_tmo(&button_queue, HZ)) {
    }
}
static void usb_mode(int connect_timeout)
{
    int button;
    
    usb_init();
    usb_start_monitoring();

    /* Wait for threads to connect or cable is pulled */
    printf("USB: Connecting");

    long end_tick = current_tick + connect_timeout;

    while(1)
    {
        button = button_get_w_tmo(HZ/10);

        if(button == SYS_USB_CONNECTED)
            break; /* Hit */

        if(TIME_AFTER(current_tick, end_tick))
        {
            /* Timed out waiting for the connect - will happen when connected
             * to a charger through the USB port */
            printf("USB: Timed out");
            break;
        }

        if(usb_detect() == USB_EXTRACTED)
            break; /* Cable pulled */
    }

    if(button == SYS_USB_CONNECTED)
    {
        /* Got the message - wait for disconnect */
        printf("Bootloader USB mode");

        usb_acknowledge(SYS_USB_CONNECTED_ACK);

        while(1)
        {
            button = button_get_w_tmo(HZ/2);
            if(button == SYS_USB_DISCONNECTED)
                break;
        }
    }

    /* Put drivers initialized for USB connection into a known state */
    usb_close();
}
Exemple #8
0
static void NORETURN_ATTR audio_thread(void)
{
    struct queue_event ev;
    ev.id = Q_NULL; /* something not in switch below */

    pcm_postinit();

    while (1)
    {
        switch (ev.id)
        {
        /* Starts the playback engine branch */
        case Q_AUDIO_PLAY:
            LOGFQUEUE("audio < Q_AUDIO_PLAY");
            audio_playback_handler(&ev);
            continue;

        /* Playback has to handle these, even if not playing */
        case Q_AUDIO_REMAKE_AUDIO_BUFFER:
#ifdef HAVE_DISK_STORAGE
        case Q_AUDIO_UPDATE_WATERMARK:
#endif
            audio_playback_handler(&ev);
            break;

#ifdef AUDIO_HAVE_RECORDING
        /* Starts the recording engine branch */
        case Q_AUDIO_INIT_RECORDING:
            LOGFQUEUE("audio < Q_AUDIO_INIT_RECORDING");
            audio_recording_handler(&ev);
            continue;
#endif

        /* All return upon USB */
        case SYS_USB_CONNECTED:
            LOGFQUEUE("audio < SYS_USB_CONNECTED");
            voice_stop();
            usb_acknowledge(SYS_USB_CONNECTED_ACK);
            usb_wait_for_disconnect(&audio_queue);
            break;
        }

        queue_wait(&audio_queue, &ev);
    }
}
Exemple #9
0
void usb_wait_for_disconnect(struct event_queue *q)
{
#ifdef USB_FULL_INIT
    struct queue_event ev;

    /* Don't return until we get SYS_USB_DISCONNECTED */
    while(1)
    {
        queue_wait(q, &ev);
        if(ev.id == SYS_USB_DISCONNECTED)
        {
            usb_acknowledge(SYS_USB_DISCONNECTED_ACK);
            return;
        }
    }
#else
    (void)q;
#endif /* USB_FULL_INIT */
}
Exemple #10
0
int usb_wait_for_disconnect_w_tmo(struct event_queue *q, int ticks)
{
#ifdef USB_FULL_INIT
    struct queue_event ev;

    /* Don't return until we get SYS_USB_DISCONNECTED or SYS_TIMEOUT */
    while(1)
    {
        queue_wait_w_tmo(q, &ev, ticks);
        switch(ev.id)
        {
            case SYS_USB_DISCONNECTED:
                usb_acknowledge(SYS_USB_DISCONNECTED_ACK);
                return 0;
            case SYS_TIMEOUT:
                return 1;
        }
    }
#else
    (void)q; (void)ticks;
    return 0;
#endif /* USB_FULL_INIT */
}
Exemple #11
0
void display_logf(void) /* Doesn't return! */
{
    int i, index, button, user_index=0;
#ifdef HAVE_TOUCHSCREEN
    int touch, prev_y=0;
#endif
    char buffer[COLUMNS+1];
    
    while(1)
    {
        index = logfindex + user_index;
        
        lcd_clear_display();
        for(i = LINES-1; i>=0; i--)
        {
            if(--index < 0)
            {
                if(logfwrap)
                    index = MAX_LOGF_LINES-1;
                else
                    break; /* done */
            }
            
            memcpy(buffer, logfbuffer[index], COLUMNS);
            
            if (logfbuffer[index][MAX_LOGF_ENTRY] == LOGF_TERMINATE_CONTINUE_LINE)
                buffer[MAX_LOGF_ENTRY-1] = '>';
            else if (logfbuffer[index][MAX_LOGF_ENTRY] == LOGF_TERMINATE_MULTI_LINE)
                buffer[MAX_LOGF_ENTRY-1] = '\0';
            
            buffer[COLUMNS] = '\0';
            
            lcd_puts(0, i, buffer);
        }
        
        button = button_get(false);
        if(button == SYS_USB_CONNECTED)
            usb_acknowledge(SYS_USB_CONNECTED_ACK);
        else if(button == SYS_USB_DISCONNECTED)
            ;
        else if(button & LOGF_UP)
            user_index++;
        else if(button & LOGF_DOWN)
            user_index--;
        else if(button & LOGF_CLEAR)
            user_index = 0;
#ifdef HAVE_TOUCHSCREEN
        else if(button & BUTTON_TOUCHSCREEN)
        {
            touch = button_get_data();
            
            if(button & BUTTON_REL)
                prev_y = 0;
            
            if(prev_y != 0)
                user_index += (prev_y - (touch & 0xFFFF)) / SYSFONT_HEIGHT;
            prev_y = touch & 0xFFFF;
        }
#endif
        
        lcd_update();
        sleep(HZ/16);
    }
}
Exemple #12
0
void gui_usb_screen_run(bool early_usb)
{
    (void) early_usb;
    struct usb_screen_vps_t usb_screen_vps_ar[NB_SCREENS];
#if defined HAVE_TOUCHSCREEN
    enum touchscreen_mode old_mode = touchscreen_get_mode();

    /* TODO: Paint buttons on screens OR switch to point mode and use
     * touchscreen as a touchpad to move the host's mouse cursor */
    touchscreen_set_mode(TOUCHSCREEN_BUTTON);
#endif

    push_current_activity(ACTIVITY_USBSCREEN);

#ifdef USB_ENABLE_HID
    usb_hid = global_settings.usb_hid;
    usb_keypad_mode = global_settings.usb_keypad_mode;
#endif

    FOR_NB_SCREENS(i)
    {
        struct screen *screen = &screens[i];

        screen->set_viewport(NULL);
#ifdef HAVE_LCD_CHARCELLS
        /* Quick fix. Viewports should really be enabled proper for charcell */
        viewport_set_defaults(&usb_screen_vps_ar[i].parent, i);
#else
        usb_screen_fix_viewports(screen, &usb_screen_vps_ar[i]);
#endif
    }

    /* update the UI before disabling fonts, this maximizes the propability
     * that font cache lookups succeed during USB */
    send_event(GUI_EVENT_ACTIONUPDATE, NULL);
#ifdef HAVE_LCD_BITMAP
    if(!early_usb)
    {
        /* The font system leaves the .fnt fd's open, so we need for force close them all */
        font_disable_all();
    }
#endif

    usb_acknowledge(SYS_USB_CONNECTED_ACK);

    while (1)
    {
        usb_screens_draw(usb_screen_vps_ar);
#ifdef SIMULATOR
        if (button_get_w_tmo(HZ/2))
            break;
        send_event(GUI_EVENT_ACTIONUPDATE, NULL);
#else
        if (handle_usb_events())
            break;
#endif /* SIMULATOR */
    }

    FOR_NB_SCREENS(i)
    {
        const struct viewport* vp = NULL;

#if defined(HAVE_LCD_BITMAP) && defined(USB_ENABLE_HID)
        vp = usb_hid ? &usb_screen_vps_ar[i].title : NULL;
#elif !defined(HAVE_LCD_BITMAP)
        vp = &usb_screen_vps_ar[i].parent;
#endif
        if (vp)
            screens[i].scroll_stop_viewport(vp);
    }
#ifdef USB_ENABLE_HID
    if (global_settings.usb_keypad_mode != usb_keypad_mode)
    {
        global_settings.usb_keypad_mode = usb_keypad_mode;
        settings_save();
    }
#endif

#ifdef HAVE_TOUCHSCREEN
    touchscreen_set_mode(old_mode);
#endif

#ifdef HAVE_LCD_CHARCELLS
    status_set_usb(false);
#endif /* HAVE_LCD_CHARCELLS */

#ifdef HAVE_LCD_BITMAP
    if(!early_usb)
    {
        font_enable_all();
        /* Not pretty, reload all settings so fonts are loaded again correctly */
        settings_apply(true);
        /* Reload playlist */
        playlist_resume();
    }
#endif

    FOR_NB_SCREENS(i)
    {
        screens[i].backlight_on();
        viewportmanager_theme_undo(i, false);
    }

    pop_current_activity();
}
Exemple #13
0
void gui_usb_screen_run(void)
{
    int i;
    struct usb_screen_vps_t usb_screen_vps_ar[NB_SCREENS];
#if defined HAVE_TOUCHSCREEN
    enum touchscreen_mode old_mode = touchscreen_get_mode();

    /* TODO: Paint buttons on screens OR switch to point mode and use
     * touchscreen as a touchpad to move the host's mouse cursor */
    touchscreen_set_mode(TOUCHSCREEN_BUTTON);
#endif

#ifndef SIMULATOR
    usb_acknowledge(SYS_USB_CONNECTED_ACK);
#endif

#ifdef USB_ENABLE_HID
    usb_hid = global_settings.usb_hid;
    usb_keypad_mode = global_settings.usb_keypad_mode;
#endif

    FOR_NB_SCREENS(i)
    {
        struct screen *screen = &screens[i];

        screen->set_viewport(NULL);
#ifdef HAVE_LCD_BITMAP
        usb_screen_fix_viewports(screen, &usb_screen_vps_ar[i]);
#endif
    }

    while (1)
    {
        usb_screens_draw(usb_screen_vps_ar);
#ifdef SIMULATOR
        if (button_get_w_tmo(HZ/2))
            break;
        send_event(GUI_EVENT_ACTIONUPDATE, NULL);
#else
        if (handle_usb_events())
            break;
#endif /* SIMULATOR */
    }

    FOR_NB_SCREENS(i)
    {
        const struct viewport* vp = NULL;

#if defined(HAVE_LCD_BITMAP) && defined(USB_ENABLE_HID)
        vp = usb_hid ? &usb_screen_vps_ar[i].title : NULL;
#elif !defined(HAVE_LCD_BITMAP)
        vp = &usb_screen_vps_ar[i].parent;
#endif
        if (vp)
            screens[i].scroll_stop(vp);
    }
#ifdef USB_ENABLE_HID
    if (global_settings.usb_keypad_mode != usb_keypad_mode)
    {
        global_settings.usb_keypad_mode = usb_keypad_mode;
        settings_save();
    }
#endif

#ifdef HAVE_TOUCHSCREEN
    touchscreen_set_mode(old_mode);
#endif

#ifdef HAVE_LCD_CHARCELLS
    status_set_usb(false);
#endif /* HAVE_LCD_CHARCELLS */
    FOR_NB_SCREENS(i)
    {
        screens[i].backlight_on();
        viewportmanager_theme_undo(i, false);
    }

}
Exemple #14
0
void buffering_thread(void)
{
    bool filling = false;
    struct queue_event ev;

    while (true)
    {
        if (!filling) {
            cancel_cpu_boost();
        }

        queue_wait_w_tmo(&buffering_queue, &ev, filling ? 5 : HZ/2);

        switch (ev.id)
        {
            case Q_START_FILL:
                LOGFQUEUE("buffering < Q_START_FILL %d", (int)ev.data);
                /* Call buffer callbacks here because this is one of two ways
                 * to begin a full buffer fill */
                send_event(BUFFER_EVENT_BUFFER_LOW, 0);
                shrink_buffer();
                queue_reply(&buffering_queue, 1);
                filling |= buffer_handle((int)ev.data);
                break;

            case Q_BUFFER_HANDLE:
                LOGFQUEUE("buffering < Q_BUFFER_HANDLE %d", (int)ev.data);
                queue_reply(&buffering_queue, 1);
                buffer_handle((int)ev.data);
                break;

            case Q_RESET_HANDLE:
                LOGFQUEUE("buffering < Q_RESET_HANDLE %d", (int)ev.data);
                queue_reply(&buffering_queue, 1);
                reset_handle((int)ev.data);
                break;

            case Q_CLOSE_HANDLE:
                LOGFQUEUE("buffering < Q_CLOSE_HANDLE %d", (int)ev.data);
                queue_reply(&buffering_queue, close_handle((int)ev.data));
                break;

            case Q_HANDLE_ADDED:
                LOGFQUEUE("buffering < Q_HANDLE_ADDED %d", (int)ev.data);
                /* A handle was added: the disk is spinning, so we can fill */
                filling = true;
                break;

            case Q_BASE_HANDLE:
                LOGFQUEUE("buffering < Q_BASE_HANDLE %d", (int)ev.data);
                base_handle_id = (int)ev.data;
                break;

#ifndef SIMULATOR
            case SYS_USB_CONNECTED:
                LOGFQUEUE("buffering < SYS_USB_CONNECTED");
                usb_acknowledge(SYS_USB_CONNECTED_ACK);
                usb_wait_for_disconnect(&buffering_queue);
                break;
#endif

            case SYS_TIMEOUT:
                LOGFQUEUE_SYS_TIMEOUT("buffering < SYS_TIMEOUT");
                break;
        }

        update_data_counters();

        /* If the buffer is low, call the callbacks to get new data */
        if (num_handles > 0 && data_counters.useful <= conf_watermark)
            send_event(BUFFER_EVENT_BUFFER_LOW, 0);

#if 0
        /* TODO: This needs to be fixed to use the idle callback, disable it
         * for simplicity until its done right */
#if MEM > 8
        /* If the disk is spinning, take advantage by filling the buffer */
        else if (storage_disk_is_active() && queue_empty(&buffering_queue))
        {
            if (num_handles > 0 && data_counters.useful <= high_watermark)
                send_event(BUFFER_EVENT_BUFFER_LOW, 0);

            if (data_counters.remaining > 0 && BUF_USED <= high_watermark)
            {
                /* This is a new fill, shrink the buffer up first */
                if (!filling)
                    shrink_buffer();
                filling = fill_buffer();
                update_data_counters();
            }
        }
#endif
#endif

        if (queue_empty(&buffering_queue)) {
            if (filling) {
                if (data_counters.remaining > 0 && BUF_USED < buffer_len)
                    filling = fill_buffer();
                else if (data_counters.remaining == 0)
                    filling = false;
            }
            else if (ev.id == SYS_TIMEOUT)
            {
                if (data_counters.remaining > 0 &&
                    data_counters.useful <= conf_watermark) {
                    shrink_buffer();
                    filling = fill_buffer();
                }
            }
        }
    }
}
Exemple #15
0
static void sd_thread(void)
{
    struct queue_event ev;

    while (1)
    {
        queue_wait_w_tmo(&sd_queue, &ev, HZ);

        switch(ev.id)
        {
        case SYS_HOTSWAP_INSERTED:
        case SYS_HOTSWAP_EXTRACTED:
        {
            fat_lock();          /* lock-out FAT activity first -
                                    prevent deadlocking via disk_mount that
                                    would cause a reverse-order attempt with
                                    another thread */
            mutex_lock(&sd_mutex); /* lock-out card activity - direct calls
                                    into driver that bypass the fat cache */

            /* We now have exclusive control of fat cache and sd */

            disk_unmount(sd_first_drive);     /* release "by force", ensure file
                                    descriptors aren't leaked and any busy
                                    ones are invalid if mounting */
            /* Force card init for new card, re-init for re-inserted one or
             * clear if the last attempt to init failed with an error. */
            card_info.initialized = 0;

            if(ev.id == SYS_HOTSWAP_INSERTED)
            {
                int ret = sd_init_card();
                if(ret == 0)
                {
                    ret = disk_mount(sd_first_drive); /* 0 if fail */
                    if(ret < 0)
                        DEBUGF("disk_mount failed: %d", ret);
                }
                else
                    DEBUGF("sd_init_card failed: %d", ret);
            }

            /*
             * Mount succeeded, or this was an EXTRACTED event,
             * in both cases notify the system about the changed filesystems
             */
            if(card_info.initialized)
                queue_broadcast(SYS_FS_CHANGED, 0);

            /* Access is now safe */
            mutex_unlock(&sd_mutex);
            fat_unlock();
            }
            break;
        case SYS_TIMEOUT:
            if(!TIME_BEFORE(current_tick, last_disk_activity+(3*HZ)))
                sd_enable(false);
            break;
        case SYS_USB_CONNECTED:
            usb_acknowledge(SYS_USB_CONNECTED_ACK);
            /* Wait until the USB cable is extracted again */
            usb_wait_for_disconnect(&sd_queue);
            break;
        }
    }
}