@@ -52,8 +52,12 @@ static bool _utcd_inited = false;
52
52
static bool _port_inited [TUP_TYPEC_RHPORTS_NUM ];
53
53
54
54
// Max possible PD size is 262 bytes
55
- static uint8_t _rx_buf [262 ] TU_ATTR_ALIGNED (4 );
56
- static uint8_t _tx_buf [100 ] TU_ATTR_ALIGNED (4 );
55
+ static uint8_t _rx_buf [64 ] TU_ATTR_ALIGNED (4 );
56
+ static uint8_t _tx_buf [64 ] TU_ATTR_ALIGNED (4 );
57
+
58
+ bool utcd_msg_send (uint8_t rhport , pd_header_t const * header , void const * data );
59
+ bool parse_msg_data (uint8_t rhport , pd_header_t const * header , uint8_t const * dobj , uint8_t const * p_end );
60
+ bool parse_msg_control (uint8_t rhport , pd_header_t const * header );
57
61
58
62
//--------------------------------------------------------------------+
59
63
//
@@ -79,6 +83,7 @@ bool tuc_init(uint8_t rhport, uint32_t port_type) {
79
83
}
80
84
81
85
TU_LOG_UTCD ("UTCD init on port %u\r\n" , rhport );
86
+ TU_LOG_INT (UTCD_DEBUG , sizeof (tcd_event_t ));
82
87
83
88
TU_ASSERT (tcd_init (rhport , port_type ));
84
89
tcd_int_enable (rhport );
@@ -87,137 +92,112 @@ bool tuc_init(uint8_t rhport, uint32_t port_type) {
87
92
return true;
88
93
}
89
94
90
- //--------------------------------------------------------------------+
91
- //
92
- //--------------------------------------------------------------------+
93
-
94
- bool utcd_msg_send (uint8_t rhport , pd_header_t const * header , void const * data ) {
95
- // copy header
96
- memcpy (_tx_buf , header , sizeof (pd_header_t ));
97
-
98
- // copy data objcet if available
99
- uint16_t const n_data_obj = header -> n_data_obj ;
100
- if (n_data_obj > 0 ) {
101
- memcpy (_tx_buf + sizeof (pd_header_t ), data , n_data_obj * 4 );
102
- }
95
+ void tuc_task_ext (uint32_t timeout_ms , bool in_isr ) {
96
+ (void ) in_isr ; // not implemented yet
103
97
104
- return tcd_msg_send ( rhport , _tx_buf , sizeof ( pd_header_t ) + n_data_obj * 4 );
105
- }
98
+ // Skip if stack is not initialized
99
+ if (! _utcd_inited ) return ;
106
100
107
- bool parse_message (uint8_t rhport , uint8_t const * buf , uint16_t len ) {
108
- (void ) rhport ;
109
- uint8_t const * p_end = buf + len ;
110
- pd_header_t const * header = (pd_header_t const * ) buf ;
111
- uint8_t const * ptr = buf + sizeof (pd_header_t );
101
+ // Loop until there is no more events in the queue
102
+ while (1 ) {
103
+ tcd_event_t event ;
104
+ if (!osal_queue_receive (_utcd_q , & event , timeout_ms )) return ;
112
105
113
- if (header -> n_data_obj == 0 ) {
114
- // control message
115
- switch (header -> msg_type ) {
116
- case PD_CTRL_GOOD_CRC :
106
+ switch (event .event_id ) {
107
+ case TCD_EVENT_CC_CHANGED :
117
108
break ;
118
109
119
- case PD_CTRL_ACCEPT :
120
- break ;
110
+ case TCD_EVENT_RX_COMPLETE :
111
+ // TODO process message here in ISR, move to thread later
112
+ if (event .xfer_complete .result == XFER_RESULT_SUCCESS ) {
113
+ pd_header_t const * header = (pd_header_t const * ) _rx_buf ;
121
114
122
- case PD_CTRL_REJECT :
123
- break ;
115
+ if ( header -> n_data_obj == 0 ) {
116
+ parse_msg_control ( event . rhport , header ) ;
124
117
125
- case PD_CTRL_PS_READY :
126
- break ;
118
+ }else {
119
+ uint8_t const * p_end = _rx_buf + event .xfer_complete .xferred_bytes ;
120
+ uint8_t const * dobj = _rx_buf + sizeof (pd_header_t );
127
121
128
- default : break ;
129
- }
130
- } else {
131
- // data message
132
- switch (header -> msg_type ) {
133
- case PD_DATA_SOURCE_CAP : {
134
- // Examine source capability and select a suitable PDO (starting from 1 with safe5v)
135
- uint8_t obj_pos = 1 ;
136
-
137
- for (size_t i = 0 ; i < header -> n_data_obj ; i ++ ) {
138
- TU_VERIFY (ptr < p_end );
139
- uint32_t const pdo = tu_le32toh (tu_unaligned_read32 (ptr ));
140
-
141
- switch ((pdo >> 30 ) & 0x03ul ) {
142
- case PD_PDO_TYPE_FIXED : {
143
- pd_pdo_fixed_t const * fixed = (pd_pdo_fixed_t const * ) & pdo ;
144
- TU_LOG3 ("[Fixed] %u mV %u mA\r\n" , fixed -> voltage_50mv * 50 , fixed -> current_max_10ma * 10 );
145
- break ;
146
- }
147
-
148
- case PD_PDO_TYPE_BATTERY :
149
- break ;
150
-
151
- case PD_PDO_TYPE_VARIABLE :
152
- break ;
153
-
154
- case PD_PDO_TYPE_APDO :
155
- break ;
122
+ parse_msg_data (event .rhport , header , dobj , p_end );
156
123
}
157
-
158
- ptr += 4 ;
159
124
}
160
125
161
- // Send request with selected PDO position as response to Source Cap
162
- pd_rdo_fixed_variable_t rdo = {
163
- .current_extremum_10ma = 50 , // max 500mA
164
- .current_operate_10ma = 30 , // 300mA
165
- .reserved = 0 ,
166
- .epr_mode_capable = 0 ,
167
- .unchunked_ext_msg_support = 0 ,
168
- .no_usb_suspend = 0 ,
169
- .usb_comm_capable = 1 ,
170
- .capability_mismatch = 0 ,
171
- .give_back_flag = 0 , // exteremum is max
172
- .object_position = obj_pos ,
173
- };
174
-
175
- pd_header_t const req_header = {
176
- .msg_type = PD_DATA_REQUEST ,
177
- .data_role = PD_DATA_ROLE_UFP ,
178
- .specs_rev = PD_REV_20 ,
179
- .power_role = PD_POWER_ROLE_SINK ,
180
- .msg_id = 0 ,
181
- .n_data_obj = 1 ,
182
- .extended = 0 ,
183
- };
184
-
185
- utcd_msg_send (rhport , & req_header , & rdo );
126
+ // prepare for next message
127
+ tcd_msg_receive (event .rhport , _rx_buf , sizeof (_rx_buf ));
128
+ break ;
186
129
130
+ case TCD_EVENT_TX_COMPLETE :
187
131
break ;
188
- }
189
132
190
133
default : break ;
191
134
}
192
135
}
136
+ }
137
+
138
+ bool parse_msg_data (uint8_t rhport , pd_header_t const * header , uint8_t const * dobj , uint8_t const * p_end ) {
139
+ if (tuc_pd_data_received_cb ) {
140
+ tuc_pd_data_received_cb (rhport , header , dobj , p_end );
141
+ }
142
+
143
+ return true;
144
+ }
145
+
146
+ bool parse_msg_control (uint8_t rhport , pd_header_t const * header ) {
147
+ if (tuc_pd_control_received_cb ) {
148
+ tuc_pd_control_received_cb (rhport , header );
149
+ }
193
150
194
151
return true;
195
152
}
196
153
154
+ //--------------------------------------------------------------------+
155
+ //
156
+ //--------------------------------------------------------------------+
157
+
158
+ bool utcd_msg_send (uint8_t rhport , pd_header_t const * header , void const * data ) {
159
+ // copy header
160
+ memcpy (_tx_buf , header , sizeof (pd_header_t ));
161
+
162
+ // copy data objcet if available
163
+ uint16_t const n_data_obj = header -> n_data_obj ;
164
+ if (n_data_obj > 0 ) {
165
+ memcpy (_tx_buf + sizeof (pd_header_t ), data , n_data_obj * 4 );
166
+ }
167
+
168
+ return tcd_msg_send (rhport , _tx_buf , sizeof (pd_header_t ) + n_data_obj * 4 );
169
+ }
170
+
171
+ bool tuc_msg_request (uint8_t rhport , void const * rdo ) {
172
+ pd_header_t const header = {
173
+ .msg_type = PD_DATA_REQUEST ,
174
+ .data_role = PD_DATA_ROLE_UFP ,
175
+ .specs_rev = PD_REV_30 ,
176
+ .power_role = PD_POWER_ROLE_SINK ,
177
+ .msg_id = 0 ,
178
+ .n_data_obj = 1 ,
179
+ .extended = 0 ,
180
+ };
181
+
182
+ return utcd_msg_send (rhport , & header , rdo );
183
+ }
184
+
197
185
void tcd_event_handler (tcd_event_t const * event , bool in_isr ) {
198
186
(void ) in_isr ;
199
187
switch (event -> event_id ) {
200
188
case TCD_EVENT_CC_CHANGED :
201
189
if (event -> cc_changed .cc_state [0 ] || event -> cc_changed .cc_state [1 ]) {
202
- // Attach
190
+ // Attach, start receiving
203
191
tcd_msg_receive (event -> rhport , _rx_buf , sizeof (_rx_buf ));
204
192
}else {
205
193
// Detach
206
194
}
207
195
break ;
208
196
209
- case TCD_EVENT_RX_COMPLETE :
210
- // TODO process message here in ISR, move to thread later
211
- if (event -> rx_complete .result == XFER_RESULT_SUCCESS ) {
212
- parse_message (event -> rhport , _rx_buf , event -> rx_complete .xferred_bytes );
213
- }
214
-
215
- // start new rx
216
- tcd_msg_receive (event -> rhport , _rx_buf , sizeof (_rx_buf ));
217
- break ;
218
-
219
197
default : break ;
220
198
}
199
+
200
+ osal_queue_send (_utcd_q , event , in_isr );
221
201
}
222
202
223
203
//--------------------------------------------------------------------+
0 commit comments