Skip to content

Commit fb5fe33

Browse files
committed
allow call tuh cdc with blocking (callback = NULL)
- tuh_cdc_set_control_line_state() - tuh_cdc_set_baudrate() - tuh_cdc_set_line_coding()
1 parent 0a43a7b commit fb5fe33

File tree

2 files changed

+73
-11
lines changed

2 files changed

+73
-11
lines changed

src/class/cdc/cdc_host.c

Lines changed: 72 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -437,22 +437,78 @@ static void cdch_internal_control_complete(tuh_xfer_t* xfer)
437437
bool tuh_cdc_set_control_line_state(uint8_t idx, uint16_t line_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data) {
438438
cdch_interface_t* p_cdc = get_itf(idx);
439439
TU_VERIFY(p_cdc && p_cdc->serial_drid < SERIAL_DRIVER_COUNT);
440-
return serial_drivers[p_cdc->serial_drid].set_control_line_state(p_cdc, line_state, complete_cb, user_data);
440+
cdch_serial_driver_t const* driver = &serial_drivers[p_cdc->serial_drid];
441+
442+
if ( complete_cb ) {
443+
return driver->set_control_line_state(p_cdc, line_state, complete_cb, user_data);
444+
}else {
445+
// blocking
446+
xfer_result_t result;
447+
bool ret = driver->set_control_line_state(p_cdc, line_state, complete_cb, (uintptr_t) &result);
448+
449+
if (user_data) {
450+
// user_data is not NULL, return result via user_data
451+
*((xfer_result_t*) user_data) = result;
452+
}
453+
454+
if (result == XFER_RESULT_SUCCESS) {
455+
p_cdc->line_state = (uint8_t) line_state;
456+
}
457+
458+
return ret;
459+
}
441460
}
442461

443462
bool tuh_cdc_set_baudrate(uint8_t idx, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data) {
444463
cdch_interface_t* p_cdc = get_itf(idx);
445464
TU_VERIFY(p_cdc && p_cdc->serial_drid < SERIAL_DRIVER_COUNT);
446-
return serial_drivers[p_cdc->serial_drid].set_baudrate(p_cdc, baudrate, complete_cb, user_data);
465+
cdch_serial_driver_t const* driver = &serial_drivers[p_cdc->serial_drid];
466+
467+
if ( complete_cb ) {
468+
return driver->set_baudrate(p_cdc, baudrate, complete_cb, user_data);
469+
}else {
470+
// blocking
471+
xfer_result_t result;
472+
bool ret = driver->set_baudrate(p_cdc, baudrate, complete_cb, (uintptr_t) &result);
473+
474+
if (user_data) {
475+
// user_data is not NULL, return result via user_data
476+
*((xfer_result_t*) user_data) = result;
477+
}
478+
479+
if (result == XFER_RESULT_SUCCESS) {
480+
p_cdc->line_coding.bit_rate = baudrate;
481+
}
482+
483+
return ret;
484+
}
447485
}
448486

449487
bool tuh_cdc_set_line_coding(uint8_t idx, cdc_line_coding_t const* line_coding, tuh_xfer_cb_t complete_cb, uintptr_t user_data)
450488
{
451489
cdch_interface_t* p_cdc = get_itf(idx);
452-
TU_VERIFY(p_cdc);
453490
// only ACM support this set line coding request
454-
TU_VERIFY(p_cdc->serial_drid == SERIAL_DRIVER_ACM && p_cdc->acm_capability.support_line_request);
455-
return acm_set_line_coding(p_cdc, line_coding, complete_cb, user_data);
491+
TU_VERIFY(p_cdc && p_cdc->serial_drid == SERIAL_DRIVER_ACM);
492+
TU_VERIFY(p_cdc->acm_capability.support_line_request);
493+
494+
if ( complete_cb ) {
495+
return acm_set_line_coding(p_cdc, line_coding, complete_cb, user_data);
496+
}else {
497+
// blocking
498+
xfer_result_t result;
499+
bool ret = acm_set_line_coding(p_cdc, line_coding, complete_cb, (uintptr_t) &result);
500+
501+
if (user_data) {
502+
// user_data is not NULL, return result via user_data
503+
*((xfer_result_t*) user_data) = result;
504+
}
505+
506+
if (result == XFER_RESULT_SUCCESS) {
507+
p_cdc->line_coding = *line_coding;
508+
}
509+
510+
return ret;
511+
}
456512
}
457513

458514
//--------------------------------------------------------------------+
@@ -752,6 +808,7 @@ static void acm_process_config(tuh_xfer_t* xfer)
752808
static bool acm_set_control_line_state(cdch_interface_t* p_cdc, uint16_t line_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data) {
753809
TU_VERIFY(p_cdc->acm_capability.support_line_request);
754810
TU_LOG_CDCH("CDC ACM Set Control Line State\r\n");
811+
755812
tusb_control_request_t const request = {
756813
.bmRequestType_bit = {
757814
.recipient = TUSB_REQ_RCPT_INTERFACE,
@@ -771,7 +828,7 @@ static bool acm_set_control_line_state(cdch_interface_t* p_cdc, uint16_t line_st
771828
.ep_addr = 0,
772829
.setup = &request,
773830
.buffer = NULL,
774-
.complete_cb = cdch_internal_control_complete,
831+
.complete_cb = complete_cb ? cdch_internal_control_complete : NULL, // complete_cb is NULL for sync call
775832
.user_data = user_data
776833
};
777834

@@ -804,7 +861,7 @@ static bool acm_set_line_coding(cdch_interface_t* p_cdc, cdc_line_coding_t const
804861
.ep_addr = 0,
805862
.setup = &request,
806863
.buffer = enum_buf,
807-
.complete_cb = cdch_internal_control_complete,
864+
.complete_cb = complete_cb ? cdch_internal_control_complete : NULL, // complete_cb is NULL for sync call
808865
.user_data = user_data
809866
};
810867

@@ -886,7 +943,8 @@ static bool ftdi_sio_set_modem_ctrl(cdch_interface_t* p_cdc, uint16_t line_state
886943
{
887944
TU_LOG_CDCH("CDC FTDI Set Control Line State\r\n");
888945
p_cdc->user_control_cb = complete_cb;
889-
TU_ASSERT(ftdi_sio_set_request(p_cdc, FTDI_SIO_MODEM_CTRL, 0x0300 | line_state, cdch_internal_control_complete, user_data));
946+
TU_ASSERT(ftdi_sio_set_request(p_cdc, FTDI_SIO_MODEM_CTRL, 0x0300 | line_state,
947+
complete_cb ? cdch_internal_control_complete : NULL, user_data));
890948
return true;
891949
}
892950

@@ -923,7 +981,8 @@ static bool ftdi_sio_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tu
923981

924982
p_cdc->user_control_cb = complete_cb;
925983
_ftdi_requested_baud = baudrate;
926-
TU_ASSERT(ftdi_sio_set_request(p_cdc, FTDI_SIO_SET_BAUD_RATE, divisor, cdch_internal_control_complete, user_data));
984+
TU_ASSERT(ftdi_sio_set_request(p_cdc, FTDI_SIO_SET_BAUD_RATE, divisor,
985+
complete_cb ? cdch_internal_control_complete : NULL, user_data));
927986

928987
return true;
929988
}
@@ -1056,14 +1115,16 @@ static bool cp210x_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_
10561115
TU_LOG_CDCH("CDC CP210x Set BaudRate = %lu\n", baudrate);
10571116
uint32_t baud_le = tu_htole32(baudrate);
10581117
p_cdc->user_control_cb = complete_cb;
1059-
return cp210x_set_request(p_cdc, CP210X_SET_BAUDRATE, 0, (uint8_t *) &baud_le, 4, cdch_internal_control_complete, user_data);
1118+
return cp210x_set_request(p_cdc, CP210X_SET_BAUDRATE, 0, (uint8_t *) &baud_le, 4,
1119+
complete_cb ? cdch_internal_control_complete : NULL, user_data);
10601120
}
10611121

10621122
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)
10631123
{
10641124
TU_LOG_CDCH("CDC CP210x Set Control Line State\r\n");
10651125
p_cdc->user_control_cb = complete_cb;
1066-
return cp210x_set_request(p_cdc, CP210X_SET_MHS, 0x0300 | line_state, NULL, 0, cdch_internal_control_complete, user_data);
1126+
return cp210x_set_request(p_cdc, CP210X_SET_MHS, 0x0300 | line_state, NULL, 0,
1127+
complete_cb ? cdch_internal_control_complete : NULL, user_data);
10671128
}
10681129

10691130
static void cp210x_process_config(tuh_xfer_t* xfer) {

src/class/cdc/cdc_host.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ bool tuh_cdc_set_control_line_state(uint8_t idx, uint16_t line_state, tuh_xfer_c
148148
bool tuh_cdc_set_baudrate(uint8_t idx, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data);
149149

150150
// Request to Set Line Coding (ACM only)
151+
// Should only use if you don't work with serial devices such as FTDI/CP210x
151152
bool tuh_cdc_set_line_coding(uint8_t idx, cdc_line_coding_t const* line_coding, tuh_xfer_cb_t complete_cb, uintptr_t user_data);
152153

153154
// Request to Get Line Coding (ACM only)

0 commit comments

Comments
 (0)