Simulate usb plugging on the sim better using sim_tasks.

Now all threads need to ack the connection like on real target, dircache is unloaded and playback stops accordingly.

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@31009 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Thomas Martitz 2011-11-17 18:40:00 +00:00
parent 2a8eacdbfc
commit 1645c148e3
9 changed files with 101 additions and 21 deletions

View file

@ -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;

View file

@ -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");

View file

@ -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
}
}
}

View file

@ -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
}
}
}

View file

@ -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
}
}
}

View file

@ -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;

View file

@ -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 */

View file

@ -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;
}

View file

@ -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