4343__attribute__((aligned (4 ))) static uint8_t USBFS_RX_Buf [USBFS_RX_BUF_LEN ];
4444__attribute__((aligned (4 ))) static uint8_t USBFS_TX_Buf [USBFS_TX_BUF_LEN ];
4545
46- #define USB_XFER_TIMEOUT_MILLIS 500
46+ #define USB_XFER_TIMEOUT_MILLIS 100
47+ #define USB_INTERRUPT_XFER_TIMEOUT_MILLIS 1
4748
4849#define PANIC (...) do { printf("\r\nPANIC: " __VA_ARGS__); while (true) { } } while (false)
4950
5051#define LOG_CH32_USBFSH (...) TU_LOG3(__VA_ARGS__)
5152
5253// Busywait for delay microseconds/nanoseconds
53- // static void loopdelay(uint32_t count)
54- // {
55- // volatile uint32_t c = count / 3;
56- // // while (c-- != 0);
57- // asm volatile(
58- // "1: \n" // loop label
59- // " addi %0, %0, -1 \n" // c--
60- // " bne %0, zero, 1b \n" // if (c != 0) goto loop
61- // : "+r"(c) // c is input/output operand
62- // );
63- // }
54+ static void loopdelay (uint32_t count )
55+ {
56+ volatile uint32_t c = count / 3 ;
57+ if (c == 0 ) { return ; }
58+ // while (c-- != 0);
59+ asm volatile (
60+ "1: \n" // loop label
61+ " addi %0, %0, -1 \n" // c--
62+ " bne %0, zero, 1b \n" // if (c != 0) goto loop
63+ : "+r" (c ) // c is input/output operand
64+ );
65+ }
6466
6567
6668// Endpoint status
@@ -71,21 +73,30 @@ typedef struct usb_edpt
7173
7274 uint8_t dev_addr ;
7375 uint8_t ep_addr ;
74- uint16_t max_packet_size ;
76+ uint8_t max_packet_size ;
77+
78+ uint8_t xfer_type ;
7579
7680 // Data toggle (0 or not 0) for DATA0/1
7781 uint8_t data_toggle ;
82+ } usb_edpt_t ;
83+
84+
85+ static usb_edpt_t usb_edpt_list [CFG_TUH_DEVICE_MAX * 6 ] = {};
86+
7887
88+ typedef struct usb_current_xfer_st {
89+ bool is_busy ;
90+ uint8_t dev_addr ;
91+ uint8_t ep_addr ;
7992 // Xfer started time in millis for timeout
8093 uint32_t current_xfer_packet_start_millis ;
8194 uint8_t * current_xfer_buffer ;
8295 uint16_t current_xfer_bufferlen ;
8396 uint16_t current_xfer_xferred_len ;
97+ } usb_current_xfer_t ;
8498
85- } usb_edpt_t ;
86-
87-
88- static usb_edpt_t usb_edpt_list [8 ] = { };
99+ static volatile usb_current_xfer_t usb_current_xfer_info = {};
89100
90101
91102static usb_edpt_t * get_edpt_record (uint8_t dev_addr , uint8_t ep_addr )
@@ -113,26 +124,26 @@ static usb_edpt_t* get_empty_record_slot(void)
113124 return NULL ;
114125}
115126
116- static usb_edpt_t * add_edpt_record (uint8_t dev_addr , uint8_t ep_addr , uint16_t max_packet_size )
127+ static usb_edpt_t * add_edpt_record (uint8_t dev_addr , uint8_t ep_addr , uint16_t max_packet_size , uint8_t xfer_type )
117128{
118129 usb_edpt_t * slot = get_empty_record_slot ();
130+ if (slot == NULL ) {
131+ PANIC ("add_edpt_record(0x%02x, 0x%02x, ...) no slot for new record\r\n" , dev_addr , ep_addr );
132+ }
119133 TU_ASSERT (slot != NULL , NULL );
120134
121135 slot -> dev_addr = dev_addr ;
122136 slot -> ep_addr = ep_addr ;
123137 slot -> max_packet_size = max_packet_size ;
138+ slot -> xfer_type = xfer_type ;
124139 slot -> data_toggle = 0 ;
125- slot -> current_xfer_packet_start_millis = 0 ;
126- slot -> current_xfer_buffer = NULL ;
127- slot -> current_xfer_bufferlen = 0 ;
128- slot -> current_xfer_xferred_len = 0 ;
129140
130141 slot -> configured = true;
131142
132143 return slot ;
133144}
134145
135- static usb_edpt_t * get_or_add_edpt_record (uint8_t dev_addr , uint8_t ep_addr , uint16_t max_packet_size )
146+ static usb_edpt_t * get_or_add_edpt_record (uint8_t dev_addr , uint8_t ep_addr , uint16_t max_packet_size , uint8_t xfer_type )
136147{
137148 usb_edpt_t * ret = get_edpt_record (dev_addr , ep_addr );
138149 if (ret != NULL )
@@ -141,7 +152,7 @@ static usb_edpt_t* get_or_add_edpt_record(uint8_t dev_addr, uint8_t ep_addr, uin
141152 }
142153 else
143154 {
144- return add_edpt_record (dev_addr , ep_addr , max_packet_size );
155+ return add_edpt_record (dev_addr , ep_addr , max_packet_size , xfer_type );
145156 }
146157}
147158
@@ -157,6 +168,17 @@ static void remove_edpt_record_for_device(uint8_t dev_addr)
157168 }
158169}
159170
171+ // static void dump_edpt_record_list() {
172+ // for (size_t i = 0; i < TU_ARRAY_SIZE(usb_edpt_list); i++) {
173+ // usb_edpt_t* cur = &usb_edpt_list[i];
174+ // if (cur->configured) {
175+ // printf("[%2d] Device 0x%02x Endpoint 0x%02x\r\n", i, cur->dev_addr, cur->ep_addr);
176+ // } else {
177+ // printf("[%2d] not configured\r\n", i);
178+ // }
179+ // }
180+ // }
181+
160182
161183/** Enable or disable USBFS Host function */
162184static void hardware_init_host (bool enabled )
@@ -180,7 +202,8 @@ static void hardware_init_host(bool enabled)
180202 USBOTG_H_FS -> HOST_EP_MOD = USBFS_UH_EP_TX_EN | USBFS_UH_EP_RX_EN ;
181203 USBOTG_H_FS -> HOST_RX_DMA = (uint32_t )USBFS_RX_Buf ;
182204 USBOTG_H_FS -> HOST_TX_DMA = (uint32_t )USBFS_TX_Buf ;
183- USBOTG_H_FS -> INT_EN = USBFS_UIE_TRANSFER | USBFS_UIE_DETECT ;
205+ // USBOTG_H_FS->INT_EN = USBFS_UIE_TRANSFER | USBFS_UIE_DETECT;
206+ USBOTG_H_FS -> INT_EN = USBFS_UIE_DETECT ;
184207 }
185208}
186209
@@ -199,6 +222,7 @@ static bool hardware_start_xfer(uint8_t pid, uint8_t ep_addr, uint8_t data_toggl
199222 USBOTG_H_FS -> HOST_TX_CTRL = (data_toggle != 0 ) ? USBFS_UH_T_TOG : 0 ;
200223 USBOTG_H_FS -> HOST_RX_CTRL = (data_toggle != 0 ) ? USBFS_UH_R_TOG : 0 ;
201224 USBOTG_H_FS -> HOST_EP_PID = pid_edpt ;
225+ USBOTG_H_FS -> INT_EN |= USBFS_UIE_TRANSFER ;
202226 USBOTG_H_FS -> INT_FG = USBFS_UIF_TRANSFER ;
203227 return true;
204228}
@@ -371,19 +395,21 @@ void hcd_int_handler(uint8_t rhport, bool in_isr)
371395
372396 if (USBOTG_H_FS -> INT_FG & USBFS_UIF_TRANSFER )
373397 {
398+ // Disable transfer interrupt
399+ USBOTG_H_FS -> INT_EN &= ~USBFS_UIE_TRANSFER ;
400+ // Clear the flag
401+ // USBOTG_H_FS->INT_FG = USBFS_UIF_TRANSFER;
374402 // Copy PID and Endpoint
375403 uint8_t pid_edpt = USBOTG_H_FS -> HOST_EP_PID ;
376404 uint8_t status = USBOTG_H_FS -> INT_ST ;
405+ uint8_t dev_addr = USBOTG_H_FS -> DEV_ADDR & USBFS_USB_ADDR_MASK ;
377406 // Clear register to stop transfer
378- USBOTG_H_FS -> HOST_EP_PID = 0 ;
379- // Clear the flag
380- USBOTG_H_FS -> INT_FG = USBFS_UIF_TRANSFER ;
407+ // USBOTG_H_FS->HOST_EP_PID = 0x00;
381408
382409 LOG_CH32_USBFSH ("hcd_int_handler() pid_edpt=0x%02x\r\n" , pid_edpt );
383410
384411 uint8_t request_pid = pid_edpt >> 4 ;
385- uint8_t response_pid = USBOTG_H_FS -> INT_ST & USBFS_UIS_H_RES_MASK ;
386- uint8_t dev_addr = USBOTG_H_FS -> DEV_ADDR ;
412+ uint8_t response_pid = status & USBFS_UIS_H_RES_MASK ;
387413 uint8_t ep_addr = pid_edpt & 0x0f ;
388414 if (request_pid == USB_PID_IN )
389415 {
@@ -393,7 +419,7 @@ void hcd_int_handler(uint8_t rhport, bool in_isr)
393419 usb_edpt_t * edpt_info = get_edpt_record (dev_addr , ep_addr );
394420 if (edpt_info == NULL )
395421 {
396- PANIC ("\r\nget_edpt_record() returned NULL in USBHD_IRQHandler\r\n" );
422+ PANIC ("\r\nget_edpt_record(0x%02x, 0x%02x ) returned NULL in USBHD_IRQHandler\r\n" , dev_addr , ep_addr );
397423 }
398424
399425 if (status & USBFS_UIS_TOG_OK )
@@ -406,43 +432,45 @@ void hcd_int_handler(uint8_t rhport, bool in_isr)
406432 case USB_PID_OUT :
407433 {
408434 uint16_t tx_len = USBOTG_H_FS -> HOST_TX_LEN ;
409- edpt_info -> current_xfer_bufferlen -= tx_len ;
410- edpt_info -> current_xfer_xferred_len += tx_len ;
411- if (edpt_info -> current_xfer_bufferlen == 0 )
435+ usb_current_xfer_info . current_xfer_bufferlen -= tx_len ;
436+ usb_current_xfer_info . current_xfer_xferred_len += tx_len ;
437+ if (usb_current_xfer_info . current_xfer_bufferlen == 0 )
412438 {
413- LOG_CH32_USBFSH ("USB_PID_OUT completed %d bytes\r\n" , edpt_info -> current_xfer_xferred_len );
414- hcd_event_xfer_complete (dev_addr , ep_addr , edpt_info -> current_xfer_xferred_len , XFER_RESULT_SUCCESS , true);
439+ LOG_CH32_USBFSH ("USB_PID_%s completed %d bytes\r\n" , request_pid == USB_PID_OUT ? "OUT" : "SETUP" , usb_current_xfer_info .current_xfer_xferred_len );
440+ usb_current_xfer_info .is_busy = false;
441+ hcd_event_xfer_complete (dev_addr , ep_addr , usb_current_xfer_info .current_xfer_xferred_len , XFER_RESULT_SUCCESS , true);
415442 return ;
416443 }
417444 else
418445 {
419446 LOG_CH32_USBFSH ("USB_PID_OUT continue...\r\n" );
420- edpt_info -> current_xfer_buffer += tx_len ;
447+ usb_current_xfer_info . current_xfer_buffer += tx_len ;
421448 uint16_t copylen = USBFS_TX_BUF_LEN ;
422- if (copylen > edpt_info -> current_xfer_bufferlen )
449+ if (copylen > usb_current_xfer_info . current_xfer_bufferlen )
423450 {
424- copylen = edpt_info -> current_xfer_bufferlen ;
451+ copylen = usb_current_xfer_info . current_xfer_bufferlen ;
425452 }
426- memcpy (USBFS_TX_Buf , edpt_info -> current_xfer_buffer , copylen );
453+ memcpy (USBFS_TX_Buf , usb_current_xfer_info . current_xfer_buffer , copylen );
427454 hardware_start_xfer (USB_PID_OUT , ep_addr , edpt_info -> data_toggle );
428455 return ;
429456 }
430457 }
431458 case USB_PID_IN :
432459 {
433460 uint16_t received_len = USBOTG_H_FS -> RX_LEN ;
434- edpt_info -> current_xfer_xferred_len += received_len ;
435- uint16_t xferred_len = edpt_info -> current_xfer_xferred_len ;
461+ usb_current_xfer_info . current_xfer_xferred_len += received_len ;
462+ uint16_t xferred_len = usb_current_xfer_info . current_xfer_xferred_len ;
436463 LOG_CH32_USBFSH ("Read %d bytes\r\n" , received_len );
437- // if (received_len > 0 && (edpt_info-> current_xfer_buffer == NULL || edpt_info-> current_xfer_bufferlen == 0)) {
464+ // if (received_len > 0 && (usb_current_xfer_info. current_xfer_buffer == NULL || usb_current_xfer_info. current_xfer_bufferlen == 0)) {
438465 // PANIC("Data received but buffer not set\r\n");
439466 // }
440- memcpy (edpt_info -> current_xfer_buffer , USBFS_RX_Buf , received_len );
441- edpt_info -> current_xfer_buffer += received_len ;
442- if ((received_len < edpt_info -> max_packet_size ) || (xferred_len == edpt_info -> current_xfer_bufferlen ))
467+ memcpy (usb_current_xfer_info . current_xfer_buffer , USBFS_RX_Buf , received_len );
468+ usb_current_xfer_info . current_xfer_buffer += received_len ;
469+ if ((received_len < edpt_info -> max_packet_size ) || (xferred_len == usb_current_xfer_info . current_xfer_bufferlen ))
443470 {
444471 // USB device sent all data.
445472 LOG_CH32_USBFSH ("USB_PID_IN completed\r\n" );
473+ usb_current_xfer_info .is_busy = false;
446474 hcd_event_xfer_complete (dev_addr , ep_addr , xferred_len , XFER_RESULT_SUCCESS , true);
447475 return ;
448476 }
@@ -464,18 +492,24 @@ void hcd_int_handler(uint8_t rhport, bool in_isr)
464492 {
465493 if (response_pid == USB_PID_STALL )
466494 {
467- LOG_CH32_USBFSH ("Data toggle mismatched and STALL\r\n" );
495+ LOG_CH32_USBFSH ("STALL response \r\n" );
468496 hcd_edpt_clear_stall (0 , dev_addr , ep_addr );
469497 edpt_info -> data_toggle = 0 ;
470498 hardware_start_xfer (request_pid , ep_addr , 0 );
471499 return ;
472500 }
473501 else if (response_pid == USB_PID_NAK )
474502 {
475- LOG_CH32_USBFSH ("Data toggle mismatched and NAK\r\n" );
476- uint32_t elapsed_time = board_millis () - edpt_info -> current_xfer_packet_start_millis ;
477- if (elapsed_time > USB_XFER_TIMEOUT_MILLIS )
503+ LOG_CH32_USBFSH ("NAK reposense \r\n" );
504+ uint32_t elapsed_time = board_millis () - usb_current_xfer_info . current_xfer_packet_start_millis ;
505+ if (edpt_info -> xfer_type == TUSB_XFER_INTERRUPT && ( elapsed_time > USB_INTERRUPT_XFER_TIMEOUT_MILLIS ) )
478506 {
507+ usb_current_xfer_info .is_busy = false;
508+ hcd_event_xfer_complete (dev_addr , ep_addr , 0 , XFER_RESULT_SUCCESS , true);
509+ }
510+ else if (elapsed_time > USB_XFER_TIMEOUT_MILLIS )
511+ {
512+ usb_current_xfer_info .is_busy = false;
479513 hcd_event_xfer_complete (dev_addr , ep_addr , 0 , XFER_RESULT_FAILED , true);
480514 }
481515 else
@@ -487,12 +521,14 @@ void hcd_int_handler(uint8_t rhport, bool in_isr)
487521 else if (response_pid == USB_PID_DATA0 || response_pid == USB_PID_DATA1 )
488522 {
489523 LOG_CH32_USBFSH ("Data toggle mismatched and DATA0/1 (not STALL). RX_LEN=%d\r\n" , USBOTG_H_FS -> RX_LEN );
524+ usb_current_xfer_info .is_busy = false;
490525 hcd_event_xfer_complete (dev_addr , ep_addr , 0 , XFER_RESULT_FAILED , true);
491526 return ;
492527 }
493528 else
494529 {
495530 LOG_CH32_USBFSH ("In USBHD_IRQHandler, unexpected response PID: 0x%02x\r\n" , response_pid );
531+ usb_current_xfer_info .is_busy = false;
496532 hcd_event_xfer_complete (dev_addr , ep_addr , 0 , XFER_RESULT_FAILED , true);
497533 return ;
498534 }
@@ -510,16 +546,17 @@ bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const
510546 uint8_t ep_addr = ep_desc -> bEndpointAddress ;
511547 uint8_t ep_num = tu_edpt_number (ep_addr );
512548 uint16_t max_packet_size = ep_desc -> wMaxPacketSize ;
513- LOG_CH32_USBFSH ("hcd_edpt_open(rhport=%d, dev_addr=0x%02x, %p) EndpointAdderss=0x%02x,maxPacketSize=%d\r\n" , rhport , dev_addr , ep_desc , ep_addr , max_packet_size );
549+ uint8_t xfer_type = ep_desc -> bmAttributes .xfer ;
550+ LOG_CH32_USBFSH ("hcd_edpt_open(rhport=%d, dev_addr=0x%02x, %p) EndpointAdderss=0x%02x,maxPacketSize=%d,xfer_type=%d\r\n" , rhport , dev_addr , ep_desc , ep_addr , max_packet_size , xfer_type );
514551
515552 if (ep_num == 0x00 )
516553 {
517- TU_ASSERT (get_or_add_edpt_record (dev_addr , 0x00 , max_packet_size ) != NULL , false);
518- TU_ASSERT (get_or_add_edpt_record (dev_addr , 0x80 , max_packet_size ) != NULL , false);
554+ TU_ASSERT (get_or_add_edpt_record (dev_addr , 0x00 , max_packet_size , xfer_type ) != NULL , false);
555+ TU_ASSERT (get_or_add_edpt_record (dev_addr , 0x80 , max_packet_size , xfer_type ) != NULL , false);
519556 }
520557 else
521558 {
522- TU_ASSERT (get_or_add_edpt_record (dev_addr , ep_addr , max_packet_size ) != NULL , false);
559+ TU_ASSERT (get_or_add_edpt_record (dev_addr , ep_addr , max_packet_size , xfer_type ) != NULL , false);
523560 }
524561
525562 update_device_address (dev_addr );
@@ -540,26 +577,36 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *
540577{
541578 (void )rhport ;
542579
580+ while (usb_current_xfer_info .is_busy ) {
581+ osal_task_delay (1 );
582+ }
583+ usb_current_xfer_info .is_busy = true;
584+
543585 usb_edpt_t * edpt_info = get_edpt_record (dev_addr , ep_addr );
544586 if (edpt_info == NULL )
545587 {
546588 PANIC ("get_edpt_record() returned NULL in hcd_edpt_xfer()\r\n" );
547589 }
590+
591+ update_device_address (dev_addr );
592+ tusb_speed_t device_speed = hcd_port_speed_get (rhport );
593+ update_port_speed (device_speed );
548594
549- edpt_info -> current_xfer_buffer = buffer ;
550- edpt_info -> current_xfer_bufferlen = buflen ;
551-
552- edpt_info -> current_xfer_packet_start_millis = board_millis ();
553- edpt_info -> current_xfer_xferred_len = 0 ;
595+ usb_current_xfer_info .dev_addr = dev_addr ;
596+ usb_current_xfer_info .ep_addr = ep_addr ;
597+ usb_current_xfer_info .current_xfer_buffer = buffer ;
598+ usb_current_xfer_info .current_xfer_bufferlen = buflen ;
599+ usb_current_xfer_info .current_xfer_packet_start_millis = board_millis ();
600+ usb_current_xfer_info .current_xfer_xferred_len = 0 ;
554601
555602 if (tu_edpt_dir (ep_addr ) == TUSB_DIR_IN )
556603 {
557- LOG_CH32_USBFSH ("hcd_edpt_xfer(): READ, ep_addr=0x%02x, len=%d\r\n" , ep_addr , buflen );
604+ LOG_CH32_USBFSH ("hcd_edpt_xfer(): READ, dev_addr=0x%02x, ep_addr=0x%02x, len=%d\r\n" , dev_addr , ep_addr , buflen );
558605 return hardware_start_xfer (USB_PID_IN , ep_addr , edpt_info -> data_toggle );
559606 }
560607 else
561608 {
562- LOG_CH32_USBFSH ("hcd_edpt_xfer(): WRITE, ep_addr=0x%02x, len=%d\r\n" , ep_addr , buflen );
609+ LOG_CH32_USBFSH ("hcd_edpt_xfer(): WRITE, dev_addr=0x%02x, ep_addr=0x%02x, len=%d\r\n" , dev_addr , ep_addr , buflen );
563610 uint16_t copylen = USBFS_TX_BUF_LEN ;
564611 if (copylen > buflen )
565612 {
@@ -584,8 +631,20 @@ bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr)
584631bool hcd_setup_send (uint8_t rhport , uint8_t dev_addr , uint8_t const setup_packet [8 ])
585632{
586633 (void )rhport ;
634+
635+ if (usb_current_xfer_info .is_busy ) {
636+ osal_task_delay (1 );
637+ }
638+ usb_current_xfer_info .is_busy = true;
639+
587640 LOG_CH32_USBFSH ("hcd_setup_send(rhport=%d, dev_addr=0x%02x, %p)\r\n" , rhport , dev_addr , setup_packet );
588641
642+ // loopdelay(SystemCoreClock / 1000000 * 100);
643+ loopdelay (1 );
644+
645+ update_device_address (dev_addr );
646+ tusb_speed_t device_speed = hcd_port_speed_get (rhport );
647+ update_port_speed (device_speed );
589648
590649 usb_edpt_t * edpt_info_tx = get_edpt_record (dev_addr , 0x00 );
591650 usb_edpt_t * edpt_info_rx = get_edpt_record (dev_addr , 0x80 );
@@ -600,11 +659,13 @@ bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet
600659 const uint16_t setup_packet_datalen = 8 ;
601660 memcpy (USBFS_TX_Buf , setup_packet , setup_packet_datalen );
602661 USBOTG_H_FS -> HOST_TX_LEN = setup_packet_datalen ;
603-
604- edpt_info_tx -> current_xfer_packet_start_millis = board_millis ();
605- edpt_info_tx -> current_xfer_buffer = USBFS_TX_Buf ;
606- edpt_info_tx -> current_xfer_bufferlen = setup_packet_datalen ;
607- edpt_info_tx -> current_xfer_xferred_len = 0 ;
662+ uint8_t ep_addr = (setup_packet [0 ] & 0x80 ) ? 0x80 : 0x00 ;
663+ usb_current_xfer_info .dev_addr = dev_addr ;
664+ usb_current_xfer_info .ep_addr = ep_addr ;
665+ usb_current_xfer_info .current_xfer_packet_start_millis = board_millis ();
666+ usb_current_xfer_info .current_xfer_buffer = USBFS_TX_Buf ;
667+ usb_current_xfer_info .current_xfer_bufferlen = setup_packet_datalen ;
668+ usb_current_xfer_info .current_xfer_xferred_len = 0 ;
608669
609670 hardware_start_xfer (USB_PID_SETUP , 0 , 0 );
610671
0 commit comments