@@ -180,6 +180,7 @@ static bool ftdi_open(uint8_t daddr, const tusb_desc_interface_t *itf_desc, uint
180
180
return open_ep_stream_pair (p_cdc , desc_ep );
181
181
}
182
182
183
+ // set request without data
183
184
static bool ftdi_sio_set_request (cdch_interface_t * p_cdc , uint8_t command , uint16_t value , tuh_xfer_cb_t complete_cb , uintptr_t user_data ) {
184
185
tusb_control_request_t const request = {
185
186
.bmRequestType_bit = {
@@ -207,11 +208,10 @@ static bool ftdi_sio_set_request(cdch_interface_t* p_cdc, uint8_t command, uint1
207
208
208
209
static bool ftdi_sio_reset (cdch_interface_t * p_cdc , tuh_xfer_cb_t complete_cb , uintptr_t user_data )
209
210
{
210
- TU_ASSERT (ftdi_sio_set_request (p_cdc , FTDI_SIO_RESET , FTDI_SIO_RESET_SIO , complete_cb , user_data ));
211
- return true;
211
+ return ftdi_sio_set_request (p_cdc , FTDI_SIO_RESET , FTDI_SIO_RESET_SIO , complete_cb , user_data );
212
212
}
213
213
214
- static bool ftdi_sio_modem_ctrl (cdch_interface_t * p_cdc , uint16_t line_state , tuh_xfer_cb_t complete_cb , uintptr_t user_data )
214
+ static bool ftdi_sio_set_modem_ctrl (cdch_interface_t * p_cdc , uint16_t line_state , tuh_xfer_cb_t complete_cb , uintptr_t user_data )
215
215
{
216
216
p_cdc -> user_control_cb = complete_cb ;
217
217
TU_ASSERT (ftdi_sio_set_request (p_cdc , FTDI_SIO_MODEM_CTRL , 0x0300 | line_state , cdch_internal_control_complete , user_data ));
@@ -244,7 +244,8 @@ static void process_ftdi_config(tuh_xfer_t* xfer) {
244
244
245
245
case CONFIG_FTDI_MODEM_CTRL :
246
246
#if CFG_TUH_CDC_LINE_CONTROL_ON_ENUM
247
- TU_ASSERT (ftdi_sio_modem_ctrl (p_cdc , CFG_TUH_CDC_LINE_CONTROL_ON_ENUM , process_ftdi_config , CONFIG_FTDI_SET_BAUDRATE ),);
247
+ TU_ASSERT (
248
+ ftdi_sio_set_modem_ctrl (p_cdc , CFG_TUH_CDC_LINE_CONTROL_ON_ENUM , process_ftdi_config , CONFIG_FTDI_SET_BAUDRATE ),);
248
249
break ;
249
250
#else
250
251
TU_ATTR_FALLTHROUGH ;
@@ -298,7 +299,8 @@ enum {
298
299
CONFIG_CP210X_IFC_ENABLE = 0 ,
299
300
CONFIG_CP210X_SET_BAUDRATE ,
300
301
CONFIG_CP210X_SET_LINE_CTL ,
301
- CONFIG_CP210X_SET_MHS
302
+ CONFIG_CP210X_SET_DTR_RTS ,
303
+ CONFIG_CP210X_COMPLETE
302
304
};
303
305
304
306
static bool cp210x_open (uint8_t daddr , tusb_desc_interface_t const * itf_desc , uint16_t max_len ) {
@@ -319,6 +321,54 @@ static bool cp210x_open(uint8_t daddr, tusb_desc_interface_t const *itf_desc, ui
319
321
return open_ep_stream_pair (p_cdc , desc_ep );
320
322
}
321
323
324
+ static bool cp210x_set_request (cdch_interface_t * p_cdc , uint8_t command , uint16_t value , uint8_t * buffer , uint16_t length , tuh_xfer_cb_t complete_cb , uintptr_t user_data ) {
325
+ tusb_control_request_t const request = {
326
+ .bmRequestType_bit = {
327
+ .recipient = TUSB_REQ_RCPT_INTERFACE ,
328
+ .type = TUSB_REQ_TYPE_VENDOR ,
329
+ .direction = TUSB_DIR_OUT
330
+ },
331
+ .bRequest = command ,
332
+ .wValue = tu_htole16 (value ),
333
+ .wIndex = p_cdc -> bInterfaceNumber ,
334
+ .wLength = tu_htole16 (length )
335
+ };
336
+
337
+ // use usbh enum buf since application variable does not live long enough
338
+ uint8_t * enum_buf = NULL ;
339
+
340
+ if (buffer && length > 0 ) {
341
+ enum_buf = usbh_get_enum_buf ();
342
+ tu_memcpy_s (enum_buf , CFG_TUH_ENUMERATION_BUFSIZE , buffer , length );
343
+ }
344
+
345
+ tuh_xfer_t xfer = {
346
+ .daddr = p_cdc -> daddr ,
347
+ .ep_addr = 0 ,
348
+ .setup = & request ,
349
+ .buffer = enum_buf ,
350
+ .complete_cb = complete_cb ,
351
+ .user_data = user_data
352
+ };
353
+
354
+ return tuh_control_xfer (& xfer );
355
+ }
356
+
357
+ static bool cp210x_ifc_enable (cdch_interface_t * p_cdc , uint16_t enabled , tuh_xfer_cb_t complete_cb , uintptr_t user_data ) {
358
+ return cp210x_set_request (p_cdc , CP210X_IFC_ENABLE , enabled , NULL , 0 , complete_cb , user_data );
359
+ }
360
+
361
+ static bool cp210x_set_baudrate (cdch_interface_t * p_cdc , uint32_t baudrate , tuh_xfer_cb_t complete_cb , uintptr_t user_data ) {
362
+ baudrate = tu_htole32 (baudrate );
363
+ return cp210x_set_request (p_cdc , CP210X_SET_BAUDRATE , 0 , (uint8_t * ) & baudrate , 4 , complete_cb , user_data );
364
+ }
365
+
366
+ static bool cp210x_set_modem_ctrl (cdch_interface_t * p_cdc , uint16_t line_state , tuh_xfer_cb_t complete_cb , uintptr_t user_data )
367
+ {
368
+ p_cdc -> user_control_cb = complete_cb ;
369
+ return cp210x_set_request (p_cdc , CP210X_SET_MHS , 0x0300 | line_state , NULL , 0 , cdch_internal_control_complete , user_data );
370
+ }
371
+
322
372
static void process_cp210x_config (tuh_xfer_t * xfer ) {
323
373
uintptr_t const state = xfer -> user_data ;
324
374
uint8_t const itf_num = (uint8_t ) tu_le16toh (xfer -> setup -> wIndex );
@@ -328,7 +378,38 @@ static void process_cp210x_config(tuh_xfer_t* xfer) {
328
378
329
379
switch (state ) {
330
380
case CONFIG_CP210X_IFC_ENABLE :
381
+ TU_ASSERT (cp210x_ifc_enable (p_cdc , 1 , process_cp210x_config , CONFIG_CP210X_SET_BAUDRATE ),);
382
+ break ;
383
+
384
+ case CONFIG_CP210X_SET_BAUDRATE : {
385
+ #ifdef CFG_TUH_CDC_LINE_CODING_ON_ENUM
386
+ cdc_line_coding_t line_coding = CFG_TUH_CDC_LINE_CODING_ON_ENUM ;
387
+ TU_ASSERT (cp210x_set_baudrate (p_cdc , line_coding .bit_rate , process_cp210x_config , CONFIG_CP210X_SET_LINE_CTL ),);
388
+ break ;
389
+ #else
390
+ TU_ATTR_FALLTHROUGH ;
391
+ #endif
392
+ }
331
393
394
+ case CONFIG_CP210X_SET_LINE_CTL : {
395
+ #if defined(CFG_TUH_CDC_LINE_CODING_ON_ENUM ) && 0 // skip for now
396
+ cdc_line_coding_t line_coding = CFG_TUH_CDC_LINE_CODING_ON_ENUM ;
397
+ break ;
398
+ #else
399
+ TU_ATTR_FALLTHROUGH ;
400
+ #endif
401
+ }
402
+
403
+ case CONFIG_CP210X_SET_DTR_RTS :
404
+ #if CFG_TUH_CDC_LINE_CONTROL_ON_ENUM
405
+ TU_ASSERT (cp210x_set_modem_ctrl (p_cdc , CFG_TUH_CDC_LINE_CONTROL_ON_ENUM , process_cp210x_config , CONFIG_CP210X_COMPLETE ),);
406
+ break ;
407
+ #else
408
+ TU_ATTR_FALLTHROUGH ;
409
+ #endif
410
+
411
+ case CONFIG_CP210X_COMPLETE :
412
+ set_config_complete (p_cdc , idx , itf_num );
332
413
break ;
333
414
334
415
default : break ;
@@ -567,7 +648,7 @@ bool tuh_cdc_set_control_line_state(uint8_t idx, uint16_t line_state, tuh_xfer_c
567
648
}
568
649
#if CFG_TUH_CDC_FTDI
569
650
else if (p_cdc -> serial_protocol == SERIAL_PROTOCOL_FTDI ) {
570
- return ftdi_sio_modem_ctrl (p_cdc , line_state , complete_cb , user_data );
651
+ return ftdi_sio_set_modem_ctrl (p_cdc , line_state , complete_cb , user_data );
571
652
}
572
653
#endif
573
654
else {
0 commit comments