5757//--------------------------------------------------------------------+
5858// MACRO TYPEDEF CONSTANT ENUM
5959//--------------------------------------------------------------------+
60+ enum {
61+ PIPE_COUNT = 10 ,
62+ };
6063
61- /* Start of definition of packed structs (used by the CCRX toolchain) */
62- TU_ATTR_PACKED_BEGIN
63- TU_ATTR_BIT_FIELD_ORDER_BEGIN
64-
65- typedef struct TU_ATTR_PACKED
66- {
64+ typedef struct {
6765 void * buf ; /* the start address of a transfer data buffer */
6866 uint16_t length ; /* the number of bytes in the buffer */
6967 uint16_t remaining ; /* the number of bytes remaining in the buffer */
70- struct {
71- uint32_t ep : 8 ; /* an assigned endpoint address */
72- uint32_t ff : 1 ; /* `buf` is TU_FUFO or POD */
73- uint32_t : 0 ;
74- };
75- } pipe_state_t ;
7668
77- TU_ATTR_PACKED_END // End of definition of packed structs (used by the CCRX toolchain)
78- TU_ATTR_BIT_FIELD_ORDER_END
69+ uint8_t ep ; /* an assigned endpoint address */
70+ uint8_t ff ; /* `buf` is TU_FUFO or POD */
71+ } pipe_state_t ;
7972
8073typedef struct
8174{
82- pipe_state_t pipe [10 ];
75+ pipe_state_t pipe [PIPE_COUNT ];
8376 uint8_t ep [2 ][16 ]; /* a lookup table for a pipe index from an endpoint address */
8477} dcd_data_t ;
8578
@@ -89,70 +82,60 @@ static dcd_data_t _dcd;
8982// INTERNAL OBJECT & FUNCTION DECLARATION
9083//--------------------------------------------------------------------+
9184
92- // Transfer conditions specifiable for each pipe:
93- // - Pipe 0: Control transfer with 64-byte single buffer
94- // - Pipes 1 and 2: Bulk isochronous transfer continuous transfer mode with programmable buffer size up
95- // to 2 KB and optional double buffer
96- // - Pipes 3 to 5: Bulk transfer continuous transfer mode with programmable buffer size up to 2 KB and
97- // optional double buffer
98- // - Pipes 6 to 9: Interrupt transfer with 64-byte single buffer
99- enum {
100- PIPE_1ST_BULK = 3 ,
101- PIPE_1ST_INTERRUPT = 6 ,
102- PIPE_COUNT = 10 ,
103- };
104-
105- static unsigned find_pipe (unsigned xfer )
106- {
107- switch (xfer ) {
108- case TUSB_XFER_ISOCHRONOUS :
109- for (int i = 1 ; i < PIPE_1ST_BULK ; ++ i ) {
110- if (0 == _dcd .pipe [i ].ep ) return i ;
111- }
112- break ;
11385
114- case TUSB_XFER_BULK :
115- for (int i = PIPE_1ST_BULK ; i < PIPE_1ST_INTERRUPT ; ++ i ) {
116- if (0 == _dcd .pipe [i ].ep ) return i ;
117- }
118- for (int i = 1 ; i < PIPE_1ST_BULK ; ++ i ) {
119- if (0 == _dcd .pipe [i ].ep ) return i ;
120- }
121- break ;
86+ // Transfer conditions specifiable for each pipe for most MCUs
87+ // - Pipe 0: Control transfer with 64-byte single buffer
88+ // - Pipes 1 and 2: Bulk or ISO
89+ // - Pipes 3 to 5: Bulk
90+ // - Pipes 6 to 9: Interrupt
91+ //
92+ // Note: for small mcu such as
93+ // - RA2A1: only pipe 4-7 are available, and no support for ISO
94+ static unsigned find_pipe (unsigned xfer_type ) {
95+ #if defined(BSP_MCU_GROUP_RA2A1 )
96+ const uint8_t pipe_idx_arr [4 ][2 ] = {
97+ { 0 , 0 }, // Control
98+ { 0 , 0 }, // Isochronous not supported
99+ { 4 , 5 }, // Bulk
100+ { 6 , 7 }, // Interrupt
101+ };
102+ #else
103+ const uint8_t pipe_idx_arr [4 ][2 ] = {
104+ { 0 , 0 }, // Control
105+ { 1 , 2 }, // Isochronous
106+ { 1 , 5 }, // Bulk
107+ { 6 , 9 }, // Interrupt
108+ };
109+ #endif
122110
123- case TUSB_XFER_INTERRUPT :
124- for (int i = PIPE_1ST_INTERRUPT ; i < PIPE_COUNT ; ++ i ) {
125- if (0 == _dcd .pipe [i ].ep ) return i ;
126- }
127- break ;
111+ // find backward since only pipe 1, 2 support ISO
112+ const uint8_t idx_first = pipe_idx_arr [xfer_type ][0 ];
113+ const uint8_t idx_last = pipe_idx_arr [xfer_type ][1 ];
128114
129- default :
130- /* No support for control transfer */
131- break ;
115+ for (int i = idx_last ; i >= idx_first ; i -- ) {
116+ if (0 == _dcd .pipe [i ].ep ) return i ;
132117 }
118+
133119 return 0 ;
134120}
135121
136- static volatile uint16_t * get_pipectr (rusb2_reg_t * rusb , unsigned num )
137- {
122+ static volatile uint16_t * get_pipectr (rusb2_reg_t * rusb , unsigned num ) {
138123 if (num ) {
139124 return (volatile uint16_t * )& (rusb -> PIPE_CTR [num - 1 ]);
140125 } else {
141126 return (volatile uint16_t * )& (rusb -> DCPCTR );
142127 }
143128}
144129
145- static volatile reg_pipetre_t * get_pipetre (rusb2_reg_t * rusb , unsigned num )
146- {
130+ static volatile reg_pipetre_t * get_pipetre (rusb2_reg_t * rusb , unsigned num ) {
147131 volatile reg_pipetre_t * tre = NULL ;
148132 if ((1 <= num ) && (num <= 5 )) {
149133 tre = (volatile reg_pipetre_t * )& (rusb -> PIPE_TR [num - 1 ].E );
150134 }
151135 return tre ;
152136}
153137
154- static volatile uint16_t * ep_addr_to_pipectr (uint8_t rhport , unsigned ep_addr )
155- {
138+ static volatile uint16_t * ep_addr_to_pipectr (uint8_t rhport , unsigned ep_addr ) {
156139 rusb2_reg_t * rusb = RUSB2_REG (rhport );
157140 const unsigned epn = tu_edpt_number (ep_addr );
158141
@@ -165,19 +148,16 @@ static volatile uint16_t* ep_addr_to_pipectr(uint8_t rhport, unsigned ep_addr)
165148 }
166149}
167150
168- static uint16_t edpt0_max_packet_size (rusb2_reg_t * rusb )
169- {
151+ static uint16_t edpt0_max_packet_size (rusb2_reg_t * rusb ) {
170152 return rusb -> DCPMAXP_b .MXPS ;
171153}
172154
173- static uint16_t edpt_max_packet_size (rusb2_reg_t * rusb , unsigned num )
174- {
155+ static uint16_t edpt_max_packet_size (rusb2_reg_t * rusb , unsigned num ) {
175156 rusb -> PIPESEL = num ;
176157 return rusb -> PIPEMAXP ;
177158}
178159
179- static inline void pipe_wait_for_ready (rusb2_reg_t * rusb , unsigned num )
180- {
160+ static inline void pipe_wait_for_ready (rusb2_reg_t * rusb , unsigned num ) {
181161 while ( rusb -> D0FIFOSEL_b .CURPIPE != num ) {}
182162 while ( !rusb -> D0FIFOCTR_b .FRDY ) {}
183163}
@@ -835,7 +815,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc)
835815 }
836816
837817 rusb -> PIPECFG = cfg ;
838- rusb -> BRDYSTS = 0x1FFu ^ TU_BIT (num );
818+ rusb -> BRDYSTS = 0x3FFu ^ TU_BIT (num );
839819 rusb -> BRDYENB |= TU_BIT (num );
840820
841821 if (dir || (xfer != TUSB_XFER_BULK )) {
@@ -935,6 +915,18 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr)
935915//--------------------------------------------------------------------+
936916// ISR
937917//--------------------------------------------------------------------+
918+
919+ #if defined(__CCRX__ )
920+ TU_ATTR_ALWAYS_INLINE static inline unsigned __builtin_ctz (unsigned int value ) {
921+ unsigned int count = 0 ;
922+ while ((value & 1 ) == 0 ) {
923+ value >>= 1 ;
924+ count ++ ;
925+ }
926+ return count ;
927+ }
928+ #endif
929+
938930void dcd_int_handler (uint8_t rhport )
939931{
940932 rusb2_reg_t * rusb = RUSB2_REG (rhport );
@@ -1026,17 +1018,7 @@ void dcd_int_handler(uint8_t rhport)
10261018 /* clear active bits (don't write 0 to already cleared bits according to the HW manual) */
10271019 rusb -> BRDYSTS = ~s ;
10281020 while (s ) {
1029- #if defined(__CCRX__ )
1030- static const int Mod37BitPosition [] = {
1031- -1 , 0 , 1 , 26 , 2 , 23 , 27 , 0 , 3 , 16 , 24 , 30 , 28 , 11 , 0 , 13 , 4 ,
1032- 7 , 17 , 0 , 25 , 22 , 31 , 15 , 29 , 10 , 12 , 6 , 0 , 21 , 14 , 9 , 5 ,
1033- 20 , 8 , 19 , 18
1034- };
1035-
1036- const unsigned num = Mod37BitPosition [(- s & s ) % 37 ];
1037- #else
10381021 const unsigned num = __builtin_ctz (s );
1039- #endif
10401022 process_pipe_brdy (rhport , num );
10411023 s &= ~TU_BIT (num );
10421024 }
0 commit comments