diff --git a/apps/gui/usb_screen.c b/apps/gui/usb_screen.c index 80b24c150c..32c0773ed6 100644 --- a/apps/gui/usb_screen.c +++ b/apps/gui/usb_screen.c @@ -251,9 +251,7 @@ void gui_usb_screen_run(bool early_usb) 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; diff --git a/apps/playback.c b/apps/playback.c index d591998bec..b20237cc7c 100644 --- a/apps/playback.c +++ b/apps/playback.c @@ -190,9 +190,7 @@ static enum filling_state STATE_FINISHED, /* all remaining tracks are fully buffered */ STATE_ENDING, /* audio playback is ending */ STATE_ENDED, /* audio playback is done */ -#if (CONFIG_PLATFORM & PLATFORM_NATIVE) STATE_USB, /* USB mode, ignore most messages */ -#endif } filling = STATE_IDLE; /* Track info - holds information about each track in the buffer */ @@ -3129,7 +3127,6 @@ static void audio_thread(void) break; #endif /* AUDIO_HAVE_RECORDING */ -#if (CONFIG_PLATFORM & PLATFORM_NATIVE) case SYS_USB_CONNECTED: LOGFQUEUE("audio < SYS_USB_CONNECTED"); audio_stop_playback(); @@ -3139,7 +3136,6 @@ static void audio_thread(void) filling = STATE_USB; usb_acknowledge(SYS_USB_CONNECTED_ACK); break; -#endif /* (CONFIG_PLATFORM & PLATFORM_NATIVE) */ case SYS_TIMEOUT: LOGFQUEUE_SYS_TIMEOUT("audio < SYS_TIMEOUT"); diff --git a/apps/playlist.c b/apps/playlist.c index 61432eb851..4588548d54 100644 --- a/apps/playlist.c +++ b/apps/playlist.c @@ -1337,12 +1337,10 @@ static void playlist_thread(void) break ; } -#if (CONFIG_PLATFORM & PLATFORM_NATIVE) case SYS_USB_CONNECTED: usb_acknowledge(SYS_USB_CONNECTED_ACK); usb_wait_for_disconnect(&playlist_queue); break ; -#endif } } } diff --git a/apps/tagcache.c b/apps/tagcache.c index 8d522b1536..058ab85f16 100644 --- a/apps/tagcache.c +++ b/apps/tagcache.c @@ -4705,13 +4705,11 @@ static void tagcache_thread(void) case SYS_POWEROFF: break ; -#if (CONFIG_PLATFORM & PLATFORM_NATIVE) case SYS_USB_CONNECTED: logf("USB: TagCache"); usb_acknowledge(SYS_USB_CONNECTED_ACK); usb_wait_for_disconnect(&tagcache_queue); break ; -#endif } } } diff --git a/firmware/common/dircache.c b/firmware/common/dircache.c index 3d7fbd520d..8d264a3e7c 100644 --- a/firmware/common/dircache.c +++ b/firmware/common/dircache.c @@ -864,12 +864,10 @@ static void dircache_thread(void) dircache_initialized = false; break ; -#if (CONFIG_PLATFORM & PLATFORM_NATIVE) case SYS_USB_CONNECTED: usb_acknowledge(SYS_USB_CONNECTED_ACK); usb_wait_for_disconnect(&dircache_queue); break ; -#endif } } } diff --git a/firmware/target/hosted/sdl/button-sdl.c b/firmware/target/hosted/sdl/button-sdl.c index ca1f2e5eb1..837cba4dc4 100644 --- a/firmware/target/hosted/sdl/button-sdl.c +++ b/firmware/target/hosted/sdl/button-sdl.c @@ -317,10 +317,7 @@ static void button_event(int key, bool pressed) if (!pressed) { usb_connected = !usb_connected; - if (usb_connected) - queue_post(&button_queue, SYS_USB_CONNECTED, 0); - else - queue_post(&button_queue, SYS_USB_DISCONNECTED, 0); + sim_trigger_usb(usb_connected); } return; diff --git a/firmware/usb.c b/firmware/usb.c index 4e71c06119..59462b952e 100644 --- a/firmware/usb.c +++ b/firmware/usb.c @@ -782,16 +782,14 @@ void usb_set_hid(bool enable) } #endif /* USB_ENABLE_HID */ -#else /* SIMULATOR || USB_NONE */ +#elif defined(USB_NONE) +/* Dummy functions for USB_NONE */ -#ifdef USB_NONE bool usb_inserted(void) { return false; } -#endif /* USB_NONE */ -/* Dummy simulator functions */ void usb_acknowledge(long id) { id = id; @@ -814,5 +812,5 @@ void usb_wait_for_disconnect(struct event_queue *q) { (void)q; } +#endif /* USB_NONE */ -#endif /* !USB_NONE && !SIMULATOR */ diff --git a/uisimulator/common/sim_tasks.c b/uisimulator/common/sim_tasks.c index 2fc887cc37..f154dacce6 100644 --- a/uisimulator/common/sim_tasks.c +++ b/uisimulator/common/sim_tasks.c @@ -8,6 +8,7 @@ * $Id$ * * Copyright (C) 2009 by Jens Arnold + * Copyright (C) 2011 by Thomas Martitz * * Rockbox simulator specific tasks * @@ -25,6 +26,8 @@ #include "kernel.h" #include "screendump.h" #include "thread.h" +#include "debug.h" +#include "usb.h" static void sim_thread(void); static long sim_thread_stack[DEFAULT_STACK_SIZE/sizeof(long)]; @@ -35,11 +38,15 @@ static struct event_queue sim_queue; /* possible events for the sim thread */ enum { SIM_SCREENDUMP, + SIM_USB_INSERTED, + SIM_USB_EXTRACTED, }; void sim_thread(void) { struct queue_event ev; + long last_broadcast_tick = current_tick; + int num_acks_to_expect; while (1) { @@ -52,6 +59,45 @@ void sim_thread(void) remote_screen_dump(); #endif break; + case SIM_USB_INSERTED: + /* from firmware/usb.c: */ + /* Tell all threads that they have to back off the storage. + We subtract one for our own thread. Expect an ACK for every + listener for each broadcast they received. If it has been too + long, the user might have entered a screen that didn't ACK + when inserting the cable, such as a debugging screen. In that + case, reset the count or else USB would be locked out until + rebooting because it most likely won't ever come. Simply + resetting to the most recent broadcast count is racy. */ + if(TIME_AFTER(current_tick, last_broadcast_tick + HZ*5)) + { + num_acks_to_expect = 0; + last_broadcast_tick = current_tick; + } + + num_acks_to_expect += queue_broadcast(SYS_USB_CONNECTED, 0) - 1; + DEBUGF("USB inserted. Waiting for %d acks...\n", + num_acks_to_expect); + break; + case SYS_USB_CONNECTED_ACK: + if(num_acks_to_expect > 0 && --num_acks_to_expect == 0) + { + DEBUGF("All threads have acknowledged the connect.\n"); + } + else + { + DEBUGF("usb: got ack, %d to go...\n", + num_acks_to_expect); + } + break; + case SIM_USB_EXTRACTED: + /* in usb.c, this is only done for exclusive storage + * do it here anyway but don't depend on the acks */ + queue_broadcast(SYS_USB_DISCONNECTED, 0); + break; + default: + DEBUGF("sim_tasks: unhandled event: %ld\n", ev.id); + break; } } } @@ -68,3 +114,47 @@ void sim_trigger_screendump(void) { queue_post(&sim_queue, SIM_SCREENDUMP, 0); } + +static bool is_usb_inserted; +void sim_trigger_usb(bool inserted) +{ + if (inserted) + queue_post(&sim_queue, SIM_USB_INSERTED, 0); + else + queue_post(&sim_queue, SIM_USB_EXTRACTED, 0); + is_usb_inserted = inserted; +} + +int usb_detect(void) +{ + return is_usb_inserted ? USB_INSERTED : USB_EXTRACTED; +} + +void usb_init(void) +{ +} + +void usb_start_monitoring(void) +{ +} + +void usb_acknowledge(long id) +{ + queue_post(&sim_queue, id, 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) + return; + } +#endif /* USB_FULL_INIT */ + (void)q; +} diff --git a/uisimulator/common/sim_tasks.h b/uisimulator/common/sim_tasks.h index fe42deeb97..dfecd4448e 100644 --- a/uisimulator/common/sim_tasks.h +++ b/uisimulator/common/sim_tasks.h @@ -21,5 +21,12 @@ * ****************************************************************************/ + +#ifndef __SIM_TASKS_H__ +#define __SIM_TASKS_H__ + void sim_tasks_init(void); void sim_trigger_screendump(void); +void sim_trigger_usb(bool inserted); + +#endif