summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
Diffstat (limited to 'firmware')
-rw-r--r--firmware/drivers/usb/arcotg_dcd.c116
-rw-r--r--firmware/drivers/usb/arcotg_dcd.h1
2 files changed, 70 insertions, 47 deletions
diff --git a/firmware/drivers/usb/arcotg_dcd.c b/firmware/drivers/usb/arcotg_dcd.c
index 8555a923c3..46dc0ca29b 100644
--- a/firmware/drivers/usb/arcotg_dcd.c
+++ b/firmware/drivers/usb/arcotg_dcd.c
@@ -238,20 +238,14 @@ void usb_arcotg_dcd_irq(void)
238 /* copy data from queue head to local buffer */ 238 /* copy data from queue head to local buffer */
239 memcpy(&dcd_controller.local_setup_buff, 239 memcpy(&dcd_controller.local_setup_buff,
240 (uint8_t *) &dev_qh[0].setup_buffer, 8); 240 (uint8_t *) &dev_qh[0].setup_buffer, 8);
241
241 /* ack setup packet*/ 242 /* ack setup packet*/
242 UDC_ENDPTSETUPSTAT = UDC_ENDPTSETUPSTAT; 243 UDC_ENDPTSETUPSTAT = UDC_ENDPTSETUPSTAT;
243 setup_received_int(&dcd_controller.local_setup_buff); 244 setup_received_int(&dcd_controller.local_setup_buff);
244 } 245 }
245/*
246 if (UDC_ENDPTCOMPLETE) {
247 UDC_ENDPTCOMPLETE = UDC_ENDPTCOMPLETE;
248 }*/
249 }
250 246
251 for (i = 0; i < USB_MAX_ENDPOINTS; i++) { 247 if (UDC_ENDPTCOMPLETE) {
252 if ((UDC_ENDPTCOMPLETE & (1 << i)) == 1) { 248 dtd_complete();
253 logf("COMPLETE on %d", i);
254 UDC_ENDPTCOMPLETE |= (1 << i);
255 } 249 }
256 } 250 }
257 251
@@ -287,7 +281,6 @@ static void setup_received_int(struct usb_ctrlrequest* request)
287 int handled = 0; /* set to zero if we do not handle the message, */ 281 int handled = 0; /* set to zero if we do not handle the message, */
288 /* and should pass it to the driver */ 282 /* and should pass it to the driver */
289 283
290 logf("setup_int");
291 into_usb_ctrlrequest(request); 284 into_usb_ctrlrequest(request);
292 285
293 /* handle all requests we support */ 286 /* handle all requests we support */
@@ -307,7 +300,6 @@ static void setup_received_int(struct usb_ctrlrequest* request)
307 break; 300 break;
308 301
309 case USB_REQ_GET_STATUS: 302 case USB_REQ_GET_STATUS:
310 logf("sending status..");
311 response.buf = &dcd_controller.usb_state; 303 response.buf = &dcd_controller.usb_state;
312 response.length = 2; 304 response.length = 2;
313 305
@@ -317,38 +309,33 @@ static void setup_received_int(struct usb_ctrlrequest* request)
317 309
318 case USB_REQ_CLEAR_FEATURE: 310 case USB_REQ_CLEAR_FEATURE:
319 case USB_REQ_SET_FEATURE: 311 case USB_REQ_SET_FEATURE:
320 /* we only support set/clear feature for endpoint */ 312 if (request->bRequestType != USB_RECIP_ENDPOINT) {
321 if (request->bRequestType == USB_RECIP_ENDPOINT) { 313 break;
322 int dir = (request->wIndex & 0x0080) ? EP_DIR_IN : EP_DIR_OUT;
323 int num = (request->wIndex & 0x000f);
324 struct usb_ep *ep;
325
326 if (request->wValue != 0 ||
327 request->wLength != 0 ||
328 (num * 2 + dir) > USB_MAX_PIPES) {
329 break;
330 }
331 ep = &dcd_controller.endpoints[num * 2 + dir];
332
333 if (request->bRequest == USB_REQ_SET_FEATURE) {
334 logf("SET_FEATURE doing set_halt");
335 handled = usb_arcotg_dcd_set_halt(ep, 1);
336 } else {
337 logf("CLEAR_FEATURE doing clear_halt");
338 handled = usb_arcotg_dcd_set_halt(ep, 0);
339 }
340
341 if (handled == 0) {
342 handled = 1; /* dont pass it to driver */
343 }
344 } 314 }
345#if 0 315
346 if (rc == 0) { 316 int dir = (request->wIndex & 0x0080) ? EP_DIR_IN : EP_DIR_OUT;
347 /* send status only if _arcotg_ep_set_halt success */ 317 int num = (request->wIndex & 0x000f);
348 if (ep0_prime_status(udc, EP_DIR_IN)) 318 struct usb_ep *ep;
349 Ep0Stall(udc); 319
320 if (request->wValue != 0 ||
321 request->wLength != 0 ||
322 (num * 2 + dir) > USB_MAX_PIPES) {
323 break;
350 } 324 }
351#endif 325 ep = &dcd_controller.endpoints[num * 2 + dir];
326
327 if (request->bRequest == USB_REQ_SET_FEATURE) {
328 logf("HALT");
329 handled = usb_arcotg_dcd_set_halt(ep, true);
330 } else {
331 logf("UNHALT");
332 handled = usb_arcotg_dcd_set_halt(ep, false);
333 }
334
335 if (handled == 0) {
336 handled = 1; /* dont pass it to driver */
337 }
338
352 break; 339 break;
353 } 340 }
354 341
@@ -427,6 +414,35 @@ static void port_change_int(void)
427 } 414 }
428} 415}
429 416
417static void dtd_complete(void) {
418
419 uint32_t bit_pos;
420 int i, ep_num, direction, bit_mask, status;
421
422 /* clear the bits in the register */
423 bit_pos = UDC_ENDPTCOMPLETE;
424 UDC_ENDPTCOMPLETE = bit_pos;
425
426 if (!bit_pos) {
427 return;
428 }
429
430 for (i = 0; i < USB_MAX_ENDPOINTS * 2; i++) {
431 ep_num = i >> 1;
432 direction = i % 2;
433
434 bit_mask = 1 << (ep_num + 16 * direction);
435
436 if (!(bit_pos & bit_mask)) {
437 continue;
438 }
439
440 logf(" ");
441 logf("TRAFFIC");
442 logf(" -> on ep %d dir %d", i, direction);
443 }
444}
445
430static void suspend_int(void) 446static void suspend_int(void)
431{ 447{
432 dcd_controller.resume_state = dcd_controller.usb_state; 448 dcd_controller.resume_state = dcd_controller.usb_state;
@@ -500,6 +516,7 @@ int usb_arcotg_dcd_enable(struct usb_ep* ep,
500 unsigned char mult = 0, zlt = 0; 516 unsigned char mult = 0, zlt = 0;
501 int retval = 0; 517 int retval = 0;
502 char *val = NULL; /* for debug */ 518 char *val = NULL; /* for debug */
519 struct timer t;
503 520
504 /* catch bogus parameter */ 521 /* catch bogus parameter */
505 if (!ep) { 522 if (!ep) {
@@ -695,33 +712,41 @@ int usb_arcotg_dcd_set_halt(struct usb_ep* ep, bool halt)
695 goto out; 712 goto out;
696 } 713 }
697 714
698 status = 0;
699 dir = ep_is_in(ep) ? USB_RECV : USB_SEND; 715 dir = ep_is_in(ep) ? USB_RECV : USB_SEND;
700 716
717 logf("modify halt of %d", ep->ep_num);
701 tmp_epctrl = UDC_ENDPTCTRL(ep->ep_num); 718 tmp_epctrl = UDC_ENDPTCTRL(ep->ep_num);
719 logf("reg %x", tmp_epctrl);
702 720
703 if (halt) { 721 if (halt) {
722 logf("halting...");
704 /* set the stall bit */ 723 /* set the stall bit */
705 if (dir) { 724 if (dir) {
725 logf("..tx..");
706 tmp_epctrl |= EPCTRL_TX_EP_STALL; 726 tmp_epctrl |= EPCTRL_TX_EP_STALL;
707 } else { 727 } else {
728 logf("..rx..");
708 tmp_epctrl |= EPCTRL_RX_EP_STALL; 729 tmp_epctrl |= EPCTRL_RX_EP_STALL;
709 } 730 }
710 } else { 731 } else {
732 logf("UNhalting...");
711 /* clear the stall bit and reset data toggle */ 733 /* clear the stall bit and reset data toggle */
712 if (dir) { 734 if (dir) {
735 logf("..tx..");
713 tmp_epctrl &= ~EPCTRL_TX_EP_STALL; 736 tmp_epctrl &= ~EPCTRL_TX_EP_STALL;
714 tmp_epctrl |= EPCTRL_TX_DATA_TOGGLE_RST; 737 tmp_epctrl |= EPCTRL_TX_DATA_TOGGLE_RST;
715 } else { 738 } else {
739 logf("..rx..");
716 tmp_epctrl &= ~EPCTRL_RX_EP_STALL; 740 tmp_epctrl &= ~EPCTRL_RX_EP_STALL;
717 tmp_epctrl |= EPCTRL_RX_DATA_TOGGLE_RST; 741 tmp_epctrl |= EPCTRL_RX_DATA_TOGGLE_RST;
718 } 742 }
719 } 743 }
720 UDC_ENDPTCTRL(ep->ep_num) = tmp_epctrl; 744 UDC_ENDPTCTRL(ep->ep_num) = tmp_epctrl;
745 logf("reg %x", tmp_epctrl);
721 746
722out: 747out:
723 logf("%s %s halt rc=%d", ep->name, halt ? "set" : "clear", status); 748 logf("%s %s halt", ep->name, halt ? "set" : "clear");
724 return status; 749 return 0;
725} 750}
726 751
727int usb_arcotg_dcd_send(struct usb_ep* ep, struct usb_response* res) 752int usb_arcotg_dcd_send(struct usb_ep* ep, struct usb_response* res)
@@ -748,7 +773,6 @@ int usb_arcotg_dcd_send(struct usb_ep* ep, struct usb_response* res)
748 td = &dev_td[index]; 773 td = &dev_td[index];
749 qh = &dev_qh[index]; 774 qh = &dev_qh[index];
750 mask = 1 << (15 + index); 775 mask = 1 << (15 + index);
751 logf("sending mask: %x", mask);
752 776
753 do { 777 do {
754 /* calculate how much to copy and send */ 778 /* calculate how much to copy and send */
@@ -1011,10 +1035,8 @@ static int usb_ack(struct usb_ctrlrequest * s, int error)
1011 res.length = 0; 1035 res.length = 0;
1012 1036
1013 if (s->bRequestType & 0x80) { 1037 if (s->bRequestType & 0x80) {
1014 logf("ack in");
1015 return usb_arcotg_dcd_receive(NULL, &res); 1038 return usb_arcotg_dcd_receive(NULL, &res);
1016 } else { 1039 } else {
1017 logf("ack out");
1018 return usb_arcotg_dcd_send(NULL, &res); 1040 return usb_arcotg_dcd_send(NULL, &res);
1019 } 1041 }
1020} 1042}
diff --git a/firmware/drivers/usb/arcotg_dcd.h b/firmware/drivers/usb/arcotg_dcd.h
index 253101fea5..79f03f1bcc 100644
--- a/firmware/drivers/usb/arcotg_dcd.h
+++ b/firmware/drivers/usb/arcotg_dcd.h
@@ -158,6 +158,7 @@ int usb_arcotg_dcd_receive(struct usb_ep* ep, struct usb_response* res);
158/* interrupt handlers */ 158/* interrupt handlers */
159static void setup_received_int(struct usb_ctrlrequest* request); 159static void setup_received_int(struct usb_ctrlrequest* request);
160static void port_change_int(void); 160static void port_change_int(void);
161static void dtd_complete(void);
161static void reset_int(void); 162static void reset_int(void);
162static void suspend_int(void); 163static void suspend_int(void);
163static void resume_int(void); 164static void resume_int(void);