diff options
Diffstat (limited to 'firmware/target/arm/tcc77x/usb-tcc77x.c')
-rw-r--r-- | firmware/target/arm/tcc77x/usb-tcc77x.c | 77 |
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 | ||
38 | static int dbg_level = 0x02; | 38 | static int dbg_level = 0x00; |
39 | static int global_ep_irq_mask = 0x1; | 39 | static 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 | ||
94 | static int usb_drv_write_packet(volatile unsigned short *buf, unsigned char *data, int len, int max); | 94 | static bool usb_drv_write_ep(struct tcc_ep *ep); |
95 | static void usb_set_speed(int); | 95 | static void usb_set_speed(int); |
96 | 96 | ||
97 | int usb_drv_request_endpoint(int dir) | 97 | int usb_drv_request_endpoint(int dir) |
@@ -315,36 +315,27 @@ void handle_ep_in(struct tcc_ep *tcc_ep, uint16_t stat) | |||
315 | static | 315 | static |
316 | void handle_ep_out(struct tcc_ep *tcc_ep, uint16_t stat) | 316 | void 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 | ||
522 | static 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 | |||
531 | int usb_drv_send(int endpoint, void *ptr, int length) | 545 | int 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 | |||
559 | int usb_drv_send_nonblocking(int endpoint, void *ptr, int length) | 574 | int 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__); |