57
57
//--------------------------------------------------------------------+
58
58
// MACRO TYPEDEF CONSTANT ENUM
59
59
//--------------------------------------------------------------------+
60
+ enum {
61
+ PIPE_COUNT = 10 ,
62
+ };
60
63
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 {
67
65
void * buf ; /* the start address of a transfer data buffer */
68
66
uint16_t length ; /* the number of bytes in the buffer */
69
67
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 ;
76
68
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 ;
79
72
80
73
typedef struct
81
74
{
82
- pipe_state_t pipe [10 ];
75
+ pipe_state_t pipe [PIPE_COUNT ];
83
76
uint8_t ep [2 ][16 ]; /* a lookup table for a pipe index from an endpoint address */
84
77
} dcd_data_t ;
85
78
@@ -89,70 +82,60 @@ static dcd_data_t _dcd;
89
82
// INTERNAL OBJECT & FUNCTION DECLARATION
90
83
//--------------------------------------------------------------------+
91
84
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 ;
113
85
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
122
110
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 ];
128
114
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 ;
132
117
}
118
+
133
119
return 0 ;
134
120
}
135
121
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 ) {
138
123
if (num ) {
139
124
return (volatile uint16_t * )& (rusb -> PIPE_CTR [num - 1 ]);
140
125
} else {
141
126
return (volatile uint16_t * )& (rusb -> DCPCTR );
142
127
}
143
128
}
144
129
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 ) {
147
131
volatile reg_pipetre_t * tre = NULL ;
148
132
if ((1 <= num ) && (num <= 5 )) {
149
133
tre = (volatile reg_pipetre_t * )& (rusb -> PIPE_TR [num - 1 ].E );
150
134
}
151
135
return tre ;
152
136
}
153
137
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 ) {
156
139
rusb2_reg_t * rusb = RUSB2_REG (rhport );
157
140
const unsigned epn = tu_edpt_number (ep_addr );
158
141
@@ -165,19 +148,16 @@ static volatile uint16_t* ep_addr_to_pipectr(uint8_t rhport, unsigned ep_addr)
165
148
}
166
149
}
167
150
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 ) {
170
152
return rusb -> DCPMAXP_b .MXPS ;
171
153
}
172
154
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 ) {
175
156
rusb -> PIPESEL = num ;
176
157
return rusb -> PIPEMAXP ;
177
158
}
178
159
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 ) {
181
161
while ( rusb -> D0FIFOSEL_b .CURPIPE != num ) {}
182
162
while ( !rusb -> D0FIFOCTR_b .FRDY ) {}
183
163
}
@@ -835,7 +815,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc)
835
815
}
836
816
837
817
rusb -> PIPECFG = cfg ;
838
- rusb -> BRDYSTS = 0x1FFu ^ TU_BIT (num );
818
+ rusb -> BRDYSTS = 0x3FFu ^ TU_BIT (num );
839
819
rusb -> BRDYENB |= TU_BIT (num );
840
820
841
821
if (dir || (xfer != TUSB_XFER_BULK )) {
@@ -935,6 +915,18 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr)
935
915
//--------------------------------------------------------------------+
936
916
// ISR
937
917
//--------------------------------------------------------------------+
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
+
938
930
void dcd_int_handler (uint8_t rhport )
939
931
{
940
932
rusb2_reg_t * rusb = RUSB2_REG (rhport );
@@ -1026,17 +1018,7 @@ void dcd_int_handler(uint8_t rhport)
1026
1018
/* clear active bits (don't write 0 to already cleared bits according to the HW manual) */
1027
1019
rusb -> BRDYSTS = ~s ;
1028
1020
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
1038
1021
const unsigned num = __builtin_ctz (s );
1039
- #endif
1040
1022
process_pipe_brdy (rhport , num );
1041
1023
s &= ~TU_BIT (num );
1042
1024
}
0 commit comments