summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVitja Makarov <vitja.makarov@gmail.com>2008-10-20 17:18:14 +0000
committerVitja Makarov <vitja.makarov@gmail.com>2008-10-20 17:18:14 +0000
commit8d81b71d6ed14bcc2bd8de1fdee086ddce02c71a (patch)
tree967a4c94eac6804ff8300a433de2f6e9ed1eabf6
parent761366d8b84e523a39d182779d4824fefa6aae7f (diff)
downloadrockbox-8d81b71d6ed14bcc2bd8de1fdee086ddce02c71a.tar.gz
rockbox-8d81b71d6ed14bcc2bd8de1fdee086ddce02c71a.zip
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
-rw-r--r--firmware/target/arm/tcc77x/usb-tcc77x.c77
1 files changed, 48 insertions, 29 deletions
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 @@
35 35
36#define TCC7xx_USB_EPIF_IRQ_MASK 0xf 36#define TCC7xx_USB_EPIF_IRQ_MASK 0xf
37 37
38static int dbg_level = 0x02; 38static int dbg_level = 0x00;
39static int global_ep_irq_mask = 0x1; 39static int global_ep_irq_mask = 0x1;
40#define DEBUG(level, fmt, args...) do { if (dbg_level & (level)) printf(fmt, ## args); } while (0) 40#define DEBUG(level, fmt, args...) do { if (dbg_level & (level)) printf(fmt, ## args); } while (0)
41 41
@@ -91,7 +91,7 @@ static struct tcc_ep tcc_endpoints[] = {
91 }, 91 },
92} ; 92} ;
93 93
94static int usb_drv_write_packet(volatile unsigned short *buf, unsigned char *data, int len, int max); 94static bool usb_drv_write_ep(struct tcc_ep *ep);
95static void usb_set_speed(int); 95static void usb_set_speed(int);
96 96
97int usb_drv_request_endpoint(int dir) 97int usb_drv_request_endpoint(int dir)
@@ -315,36 +315,27 @@ void handle_ep_in(struct tcc_ep *tcc_ep, uint16_t stat)
315static 315static
316void handle_ep_out(struct tcc_ep *tcc_ep, uint16_t stat) 316void handle_ep_out(struct tcc_ep *tcc_ep, uint16_t stat)
317{ 317{
318 bool done;
318 (void) stat; 319 (void) stat;
319 320
320 if (tcc_ep->dir != USB_DIR_IN) { 321 if (tcc_ep->dir != USB_DIR_IN) {
321 panicf_my("ep%d: is out only", tcc_ep->id); 322 panicf_my("ep%d: is out only", tcc_ep->id);
322 } 323 }
323 324
324 if (tcc_ep->buf == NULL) { 325// if (tcc_ep->buf == NULL) {
325 panicf_my("%s:%d", __FILE__, __LINE__); 326// panicf_my("%s:%d", __FILE__, __LINE__);
326 } 327// }
327 328
328 if (tcc_ep->max_len) { 329 done = usb_drv_write_ep(tcc_ep);
329 int count = usb_drv_write_packet(tcc_ep->ep,
330 tcc_ep->buf,
331 tcc_ep->max_len,
332 512);
333 tcc_ep->buf += count;
334 tcc_ep->max_len -= count;
335 tcc_ep->count += count;
336 } else {
337 tcc_ep->buf = NULL;
338 }
339 330
340 TCC7xx_USB_EP_STAT = 0x2; /* Clear TX stat */ 331// TCC7xx_USB_EP_STAT = 0x2; /* Clear TX stat */
341 TCC7xx_USB_EPIF = tcc_ep->mask; 332 TCC7xx_USB_EPIF = tcc_ep->mask;
342 333
343 if (tcc_ep->buf == NULL) { 334 if (done) { // tcc_ep->buf == NULL) {
344 TCC7xx_USB_EPIE &= ~tcc_ep->mask; 335 TCC7xx_USB_EPIE &= ~tcc_ep->mask;
345 global_ep_irq_mask &= ~tcc_ep->mask; 336 global_ep_irq_mask &= ~tcc_ep->mask;
346 337
347 usb_core_transfer_complete(tcc_ep->id, USB_DIR_IN, 0, tcc_ep->count); 338// usb_core_transfer_complete(tcc_ep->id, USB_DIR_IN, 0, tcc_ep->count);
348 } 339 }
349} 340}
350 341
@@ -528,6 +519,29 @@ static int usb_drv_write_packet(volatile unsigned short *buf, unsigned char *dat
528 return len; 519 return len;
529} 520}
530 521
522static bool usb_drv_write_ep(struct tcc_ep *ep)
523{
524 int count;
525
526 if (ep->max_len == 0)
527 return true;
528
529 count = usb_drv_write_packet(ep->ep, ep->buf, ep->max_len, 512);
530 TCC7xx_USB_EP_STAT = 0x2; /* Clear TX stat */
531
532 ep->buf += count;
533 ep->count += count;
534 ep->max_len -= count;
535
536 if (ep->max_len == 0) {
537 usb_core_transfer_complete(ep->id, USB_DIR_IN, 0, ep->count);
538 ep->buf = NULL;
539// return true;
540 }
541
542 return false;
543}
544
531int usb_drv_send(int endpoint, void *ptr, int length) 545int usb_drv_send(int endpoint, void *ptr, int length)
532{ 546{
533 int flags = disable_irq_save(); 547 int flags = disable_irq_save();
@@ -556,6 +570,7 @@ int usb_drv_send(int endpoint, void *ptr, int length)
556 return rc; 570 return rc;
557} 571}
558 572
573
559int usb_drv_send_nonblocking(int endpoint, void *ptr, int length) 574int usb_drv_send_nonblocking(int endpoint, void *ptr, int length)
560{ 575{
561 int flags; 576 int flags;
@@ -574,20 +589,24 @@ int usb_drv_send_nonblocking(int endpoint, void *ptr, int length)
574 panicf_my("%s: ep is already busy", __func__); 589 panicf_my("%s: ep is already busy", __func__);
575 } 590 }
576 591
577 TCC7xx_USB_INDEX = ep->id;
578
579 count = usb_drv_write_packet(ep->ep, data, length, 512);
580
581 data += count;
582 length -= count;
583
584 ep->buf = data; 592 ep->buf = data;
585 ep->max_len = length; 593 ep->max_len = length;
586 ep->count = count; 594 ep->count = count;
587 595
588 TCC7xx_USB_EPIE |= ep->mask; 596 TCC7xx_USB_INDEX = ep->id;
589 global_ep_irq_mask |= ep->mask; 597#if 1
590 598 TCC7xx_USB_EP_STAT = 0x2;
599 /* TODO: use interrupts instead */
600 while (!usb_drv_write_ep(ep)) {
601 while (0==(TCC7xx_USB_EP_STAT & 0x2))
602 ;
603 }
604#else
605 if (!usb_drv_write_ep(ep)) {
606 TCC7xx_USB_EPIE |= ep->mask;
607 global_ep_irq_mask |= ep->mask;
608 }
609#endif
591 restore_irq(flags); 610 restore_irq(flags);
592 611
593 DEBUG(2, "%s end", __func__); 612 DEBUG(2, "%s end", __func__);