From 8d81b71d6ed14bcc2bd8de1fdee086ddce02c71a Mon Sep 17 00:00:00 2001 From: Vitja Makarov Date: Mon, 20 Oct 2008 17:18:14 +0000 Subject: Using polling instead of interrupts make TX work better, storage worked, but still unstable! git-svn-id: svn://svn.rockbox.org/rockbox/trunk@18847 a1c6a512-1295-4272-9138-f99709370657 --- firmware/target/arm/tcc77x/usb-tcc77x.c | 77 ++++++++++++++++++++------------- 1 file changed, 48 insertions(+), 29 deletions(-) (limited to 'firmware') diff --git a/firmware/target/arm/tcc77x/usb-tcc77x.c b/firmware/target/arm/tcc77x/usb-tcc77x.c index 1092ed60a1..f5bb7c9ff2 100644 --- a/firmware/target/arm/tcc77x/usb-tcc77x.c +++ b/firmware/target/arm/tcc77x/usb-tcc77x.c @@ -35,7 +35,7 @@ #define TCC7xx_USB_EPIF_IRQ_MASK 0xf -static int dbg_level = 0x02; +static int dbg_level = 0x00; static int global_ep_irq_mask = 0x1; #define DEBUG(level, fmt, args...) do { if (dbg_level & (level)) printf(fmt, ## args); } while (0) @@ -91,7 +91,7 @@ static struct tcc_ep tcc_endpoints[] = { }, } ; -static int usb_drv_write_packet(volatile unsigned short *buf, unsigned char *data, int len, int max); +static bool usb_drv_write_ep(struct tcc_ep *ep); static void usb_set_speed(int); int usb_drv_request_endpoint(int dir) @@ -315,36 +315,27 @@ void handle_ep_in(struct tcc_ep *tcc_ep, uint16_t stat) static void handle_ep_out(struct tcc_ep *tcc_ep, uint16_t stat) { + bool done; (void) stat; if (tcc_ep->dir != USB_DIR_IN) { panicf_my("ep%d: is out only", tcc_ep->id); } - if (tcc_ep->buf == NULL) { - panicf_my("%s:%d", __FILE__, __LINE__); - } +// if (tcc_ep->buf == NULL) { +// panicf_my("%s:%d", __FILE__, __LINE__); +// } - if (tcc_ep->max_len) { - int count = usb_drv_write_packet(tcc_ep->ep, - tcc_ep->buf, - tcc_ep->max_len, - 512); - tcc_ep->buf += count; - tcc_ep->max_len -= count; - tcc_ep->count += count; - } else { - tcc_ep->buf = NULL; - } + done = usb_drv_write_ep(tcc_ep); - TCC7xx_USB_EP_STAT = 0x2; /* Clear TX stat */ +// TCC7xx_USB_EP_STAT = 0x2; /* Clear TX stat */ TCC7xx_USB_EPIF = tcc_ep->mask; - if (tcc_ep->buf == NULL) { + if (done) { // tcc_ep->buf == NULL) { TCC7xx_USB_EPIE &= ~tcc_ep->mask; global_ep_irq_mask &= ~tcc_ep->mask; - usb_core_transfer_complete(tcc_ep->id, USB_DIR_IN, 0, tcc_ep->count); +// usb_core_transfer_complete(tcc_ep->id, USB_DIR_IN, 0, tcc_ep->count); } } @@ -528,6 +519,29 @@ static int usb_drv_write_packet(volatile unsigned short *buf, unsigned char *dat return len; } +static bool usb_drv_write_ep(struct tcc_ep *ep) +{ + int count; + + if (ep->max_len == 0) + return true; + + count = usb_drv_write_packet(ep->ep, ep->buf, ep->max_len, 512); + TCC7xx_USB_EP_STAT = 0x2; /* Clear TX stat */ + + ep->buf += count; + ep->count += count; + ep->max_len -= count; + + if (ep->max_len == 0) { + usb_core_transfer_complete(ep->id, USB_DIR_IN, 0, ep->count); + ep->buf = NULL; +// return true; + } + + return false; +} + int usb_drv_send(int endpoint, void *ptr, int length) { int flags = disable_irq_save(); @@ -556,6 +570,7 @@ int usb_drv_send(int endpoint, void *ptr, int length) return rc; } + int usb_drv_send_nonblocking(int endpoint, void *ptr, int length) { int flags; @@ -574,20 +589,24 @@ int usb_drv_send_nonblocking(int endpoint, void *ptr, int length) panicf_my("%s: ep is already busy", __func__); } - TCC7xx_USB_INDEX = ep->id; - - count = usb_drv_write_packet(ep->ep, data, length, 512); - - data += count; - length -= count; - ep->buf = data; ep->max_len = length; ep->count = count; - TCC7xx_USB_EPIE |= ep->mask; - global_ep_irq_mask |= ep->mask; - + TCC7xx_USB_INDEX = ep->id; +#if 1 + TCC7xx_USB_EP_STAT = 0x2; + /* TODO: use interrupts instead */ + while (!usb_drv_write_ep(ep)) { + while (0==(TCC7xx_USB_EP_STAT & 0x2)) + ; + } +#else + if (!usb_drv_write_ep(ep)) { + TCC7xx_USB_EPIE |= ep->mask; + global_ep_irq_mask |= ep->mask; + } +#endif restore_irq(flags); DEBUG(2, "%s end", __func__); -- cgit v1.2.3