@@ -154,6 +154,7 @@ static inline ehci_qhd_t* qhd_next (ehci_qhd_t const * p_qhd);
154
154
static inline ehci_qhd_t * qhd_find_free (void );
155
155
static inline ehci_qhd_t * qhd_get_from_addr (uint8_t dev_addr , uint8_t ep_addr );
156
156
static void qhd_init (ehci_qhd_t * p_qhd , uint8_t dev_addr , tusb_desc_endpoint_t const * ep_desc );
157
+ static void qhd_attach_qtd (ehci_qhd_t * qhd , ehci_qtd_t * qtd );
157
158
158
159
static inline ehci_qtd_t * qtd_find_free (void );
159
160
static void qtd_init (ehci_qtd_t * qtd , void const * buffer , uint16_t total_bytes );
@@ -468,13 +469,9 @@ bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet
468
469
td -> pid = EHCI_PID_SETUP ;
469
470
470
471
hcd_dcache_clean ((void * ) setup_packet , 8 );
471
- hcd_dcache_clean_invalidate (td , sizeof (ehci_qtd_t ));
472
472
473
- // attach TD
474
- qhd -> p_attached_qtd = td ; // software management
475
- qhd -> qtd_overlay .next .address = (uint32_t ) td ;
476
-
477
- hcd_dcache_clean_invalidate (qhd , sizeof (ehci_qhd_t ));
473
+ // attach TD to QHD -> start transferring
474
+ qhd_attach_qtd (qhd , td );
478
475
479
476
return true;
480
477
}
@@ -513,13 +510,9 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *
513
510
}else {
514
511
hcd_dcache_clean (buffer , buflen );
515
512
}
516
- hcd_dcache_clean_invalidate (qtd , sizeof (ehci_qtd_t ));
517
513
518
- // attach TD to QHD start transferring
519
- qhd -> p_attached_qtd = qtd ; // software management
520
- qhd -> qtd_overlay .next .address = (uint32_t ) qtd ;
521
-
522
- hcd_dcache_clean_invalidate (qhd , sizeof (ehci_qhd_t ));
514
+ // attach TD to QHD -> start transferring
515
+ qhd_attach_qtd (qhd , qtd );
523
516
524
517
return true;
525
518
}
@@ -569,10 +562,9 @@ void port_connect_status_change_isr(uint8_t rhport)
569
562
}
570
563
571
564
TU_ATTR_ALWAYS_INLINE static inline
572
- void qhd_xfer_complete_isr (ehci_qhd_t * p_qhd )
573
- {
565
+ void qhd_xfer_complete_isr (ehci_qhd_t * qhd ) {
574
566
// examine TD attached to queue head
575
- ehci_qtd_t * volatile qtd = (ehci_qtd_t * volatile ) p_qhd -> p_attached_qtd ;
567
+ ehci_qtd_t * volatile qtd = (ehci_qtd_t * volatile ) qhd -> attached_qtd ;
576
568
if (qtd == NULL ) return ; // no TD attached
577
569
hcd_dcache_invalidate (qtd , sizeof (ehci_qtd_t ));
578
570
@@ -581,15 +573,22 @@ void qhd_xfer_complete_isr(ehci_qhd_t * p_qhd)
581
573
return ;
582
574
}
583
575
576
+ uint8_t dir = (qtd -> pid == EHCI_PID_IN ) ? 1 : 0 ;
584
577
uint32_t const xferred_bytes = qtd -> expected_bytes - qtd -> total_bytes ;
585
- uint8_t const ep_addr = tu_edpt_addr (p_qhd -> ep_number , qtd -> pid == EHCI_PID_IN ? 1 : 0 );
578
+
579
+ // invalidate dcache if IN transfer
580
+ if (dir == 1 && qhd -> attached_buffer != 0 ) {
581
+ hcd_dcache_invalidate ((void * ) qhd -> attached_buffer , xferred_bytes );
582
+ }
586
583
587
584
// remove and free TD before invoking callback
588
- p_qhd -> p_attached_qtd = NULL ;
585
+ qhd -> attached_qtd = NULL ;
586
+ qhd -> attached_buffer = 0 ;
589
587
qtd -> used = 0 ; // free QTD
590
588
591
- // IOC is always set
592
- hcd_event_xfer_complete (p_qhd -> dev_addr , ep_addr , xferred_bytes , XFER_RESULT_SUCCESS , true);
589
+ // notify usbh
590
+ uint8_t const ep_addr = tu_edpt_addr (qhd -> ep_number , dir );
591
+ hcd_event_xfer_complete (qhd -> dev_addr , ep_addr , xferred_bytes , XFER_RESULT_SUCCESS , true);
593
592
}
594
593
595
594
TU_ATTR_ALWAYS_INLINE static inline
@@ -651,10 +650,11 @@ void period_list_xfer_complete_isr(uint8_t rhport, uint32_t interval_ms)
651
650
}
652
651
}
653
652
653
+ // TODO merge with qhd_xfer_complete_isr()
654
654
TU_ATTR_ALWAYS_INLINE static inline
655
- void qhd_xfer_error_isr (ehci_qhd_t * p_qhd )
655
+ void qhd_xfer_error_isr (ehci_qhd_t * qhd )
656
656
{
657
- volatile ehci_qtd_t * qtd_overlay = & p_qhd -> qtd_overlay ;
657
+ volatile ehci_qtd_t * qtd_overlay = & qhd -> qtd_overlay ;
658
658
659
659
// TD has error
660
660
if (qtd_overlay -> halted ) {
@@ -674,28 +674,37 @@ void qhd_xfer_error_isr(ehci_qhd_t * p_qhd)
674
674
// while(1){}
675
675
// }
676
676
677
- ehci_qtd_t * volatile qtd = (ehci_qtd_t * volatile ) p_qhd -> p_attached_qtd ;
677
+ ehci_qtd_t * volatile qtd = (ehci_qtd_t * volatile ) qhd -> attached_qtd ;
678
678
TU_ASSERT (qtd , ); // No TD yet, probably a race condition or cache issue !?
679
679
680
680
hcd_dcache_invalidate (qtd , sizeof (ehci_qtd_t ));
681
+
682
+ uint8_t dir = (qtd -> pid == EHCI_PID_IN ) ? 1 : 0 ;
681
683
uint32_t const xferred_bytes = qtd -> expected_bytes - qtd -> total_bytes ;
682
684
683
- p_qhd -> p_attached_qtd = NULL ;
685
+ // invalidate dcache if IN transfer
686
+ if (dir == 1 && qhd -> attached_buffer != 0 ) {
687
+ hcd_dcache_invalidate ((void * ) qhd -> attached_buffer , xferred_bytes );
688
+ }
689
+
690
+ // remove and free TD before invoking callback
691
+ qhd -> attached_qtd = NULL ;
692
+ qhd -> attached_buffer = 0 ;
684
693
qtd -> used = 0 ; // free QTD
685
694
686
- if ( 0 == p_qhd -> ep_number ) {
695
+ if (0 == qhd -> ep_number ) {
687
696
// control cannot be halted
688
- p_qhd -> qtd_overlay .next .terminate = 1 ;
689
- p_qhd -> qtd_overlay .alternate .terminate = 1 ;
690
- p_qhd -> qtd_overlay .halted = 0 ;
697
+ qhd -> qtd_overlay .next .terminate = 1 ;
698
+ qhd -> qtd_overlay .alternate .terminate = 1 ;
699
+ qhd -> qtd_overlay .halted = 0 ;
691
700
692
- ehci_qtd_t * p_setup = qtd_control (p_qhd -> dev_addr );
701
+ ehci_qtd_t * p_setup = qtd_control (qhd -> dev_addr );
693
702
p_setup -> used = 0 ;
694
703
}
695
704
696
705
// notify usbh
697
- uint8_t const ep_addr = tu_edpt_addr (p_qhd -> ep_number , p_qhd -> pid == EHCI_PID_IN ? 1 : 0 );
698
- hcd_event_xfer_complete (p_qhd -> dev_addr , ep_addr , xferred_bytes , xfer_result , true);
706
+ uint8_t const ep_addr = tu_edpt_addr (qhd -> ep_number , dir );
707
+ hcd_event_xfer_complete (qhd -> dev_addr , ep_addr , xferred_bytes , xfer_result , true);
699
708
}
700
709
}
701
710
@@ -846,22 +855,10 @@ static inline ehci_qhd_t* qhd_get_from_addr(uint8_t dev_addr, uint8_t ep_addr)
846
855
return NULL ;
847
856
}
848
857
849
- //------------- TD helper -------------//
850
- static inline ehci_qtd_t * qtd_find_free (void )
851
- {
852
- for (uint32_t i = 0 ; i < QTD_MAX ; i ++ )
853
- {
854
- if ( !ehci_data .qtd_pool [i ].used ) return & ehci_data .qtd_pool [i ];
855
- }
856
-
857
- return NULL ;
858
- }
859
-
860
858
static void qhd_init (ehci_qhd_t * p_qhd , uint8_t dev_addr , tusb_desc_endpoint_t const * ep_desc )
861
859
{
862
860
// address 0 is used as async head, which always on the list --> cannot be cleared (ehci halted otherwise)
863
- if (dev_addr != 0 )
864
- {
861
+ if (dev_addr != 0 ) {
865
862
tu_memclr (p_qhd , sizeof (ehci_qhd_t ));
866
863
}
867
864
@@ -911,26 +908,47 @@ static void qhd_init(ehci_qhd_t *p_qhd, uint8_t dev_addr, tusb_desc_endpoint_t c
911
908
p_qhd -> int_smask = p_qhd -> fl_int_cmask = 0 ;
912
909
}
913
910
914
- p_qhd -> fl_hub_addr = devtree_info .hub_addr ;
915
- p_qhd -> fl_hub_port = devtree_info .hub_port ;
916
- p_qhd -> mult = 1 ; // TODO not use high bandwidth/park mode yet
911
+ p_qhd -> fl_hub_addr = devtree_info .hub_addr ;
912
+ p_qhd -> fl_hub_port = devtree_info .hub_port ;
913
+ p_qhd -> mult = 1 ; // TODO not use high bandwidth/park mode yet
917
914
918
915
//------------- HCD Management Data -------------//
919
- p_qhd -> used = 1 ;
920
- p_qhd -> removing = 0 ;
921
- p_qhd -> p_attached_qtd = NULL ;
916
+ p_qhd -> used = 1 ;
917
+ p_qhd -> removing = 0 ;
918
+ p_qhd -> attached_qtd = NULL ;
922
919
p_qhd -> pid = tu_edpt_dir (ep_desc -> bEndpointAddress ) ? EHCI_PID_IN : EHCI_PID_OUT ; // PID for TD under this endpoint
923
920
924
921
//------------- active, but no TD list -------------//
925
922
p_qhd -> qtd_overlay .halted = 0 ;
926
923
p_qhd -> qtd_overlay .next .terminate = 1 ;
927
924
p_qhd -> qtd_overlay .alternate .terminate = 1 ;
925
+
928
926
if (TUSB_XFER_BULK == xfer_type && p_qhd -> ep_speed == TUSB_SPEED_HIGH && p_qhd -> pid == EHCI_PID_OUT )
929
927
{
930
928
p_qhd -> qtd_overlay .ping_err = 1 ; // do PING for Highspeed Bulk OUT, EHCI section 4.11
931
929
}
932
930
}
933
931
932
+ static void qhd_attach_qtd (ehci_qhd_t * qhd , ehci_qtd_t * qtd ) {
933
+ qhd -> attached_qtd = qtd ;
934
+ qhd -> attached_buffer = qtd -> buffer [0 ];
935
+
936
+ // clean and invalidate cache before physically write
937
+ hcd_dcache_clean_invalidate (qtd , sizeof (ehci_qtd_t ));
938
+
939
+ qhd -> qtd_overlay .next .address = (uint32_t ) qtd ;
940
+ hcd_dcache_clean_invalidate (qhd , sizeof (ehci_qhd_t ));
941
+ }
942
+
943
+
944
+ //------------- TD helper -------------//
945
+ static inline ehci_qtd_t * qtd_find_free (void ) {
946
+ for (uint32_t i = 0 ; i < QTD_MAX ; i ++ ) {
947
+ if (!ehci_data .qtd_pool [i ].used ) return & ehci_data .qtd_pool [i ];
948
+ }
949
+ return NULL ;
950
+ }
951
+
934
952
static void qtd_init (ehci_qtd_t * qtd , void const * buffer , uint16_t total_bytes )
935
953
{
936
954
tu_memclr (qtd , sizeof (ehci_qtd_t ));
0 commit comments