created set_line_coding_sequence() and void set_line_coding_stage1_complete() to be reused by FTDI & CP210x
This commit is contained in:
@@ -433,6 +433,77 @@ bool tuh_cdc_read_clear (uint8_t idx) {
|
||||
// Control Endpoint API
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
// set line coding using sequence with 2 stages: set baudrate (stage1) + set data format (stage2)
|
||||
static bool set_line_coding_sequence(
|
||||
cdch_interface_t * p_cdc,
|
||||
// control request function to set baudrate
|
||||
bool (*set_baudrate_request)(cdch_interface_t * p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data),
|
||||
// control request function to set data format
|
||||
bool (*set_data_format_request)(cdch_interface_t * p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data),
|
||||
// function to be called after stage 1 completed
|
||||
void (*set_line_coding_stage1_complete)(tuh_xfer_t * xfer),
|
||||
// control complete function to be called after request
|
||||
void (*internal_control_complete)(tuh_xfer_t * xfer),
|
||||
tuh_xfer_cb_t complete_cb, uintptr_t user_data) {
|
||||
if (complete_cb) {
|
||||
// non-blocking
|
||||
// stage 1 set baudrate
|
||||
p_cdc->requested_complete_cb = complete_cb; // store complete_cb to be used in set_line_coding_stage1_complete()
|
||||
p_cdc->user_control_cb = set_line_coding_stage1_complete;
|
||||
return set_baudrate_request(p_cdc, internal_control_complete, user_data);
|
||||
} else {
|
||||
// blocking sequence
|
||||
// stage 1 set baudrate
|
||||
xfer_result_t result = XFER_RESULT_INVALID; // use local result, because user_data ptr may be NULL
|
||||
bool ret = set_baudrate_request(p_cdc, NULL, (uintptr_t) &result);
|
||||
|
||||
if (user_data) {
|
||||
*((xfer_result_t *) user_data) = result;
|
||||
}
|
||||
|
||||
TU_ASSERT(ret);
|
||||
TU_VERIFY(result == XFER_RESULT_SUCCESS);
|
||||
|
||||
// overtake baudrate after successful request
|
||||
p_cdc->line_coding.bit_rate = p_cdc->requested_line_coding.bit_rate;
|
||||
|
||||
// stage 2 set data format
|
||||
result = XFER_RESULT_INVALID;
|
||||
ret = set_data_format_request(p_cdc, NULL, (uintptr_t) &result);
|
||||
|
||||
if (user_data) {
|
||||
*((xfer_result_t *) user_data) = result;
|
||||
}
|
||||
|
||||
TU_ASSERT(ret);
|
||||
return (result == XFER_RESULT_SUCCESS);
|
||||
// the overtaking of remaining requested_line_coding will be done in tuh_cdc_set_line_coding()
|
||||
}
|
||||
}
|
||||
|
||||
static void set_line_coding_stage1_complete(
|
||||
tuh_xfer_t * xfer, uint8_t const itf_num,
|
||||
// control request function to set data format
|
||||
bool (*set_data_format_request)(cdch_interface_t * p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data),
|
||||
// control complete function to be called after request
|
||||
void (*internal_control_complete)(tuh_xfer_t * xfer)) {
|
||||
uint8_t const idx = tuh_cdc_itf_get_index(xfer->daddr, itf_num);
|
||||
cdch_interface_t * p_cdc = get_itf(idx);
|
||||
TU_ASSERT(p_cdc,);
|
||||
|
||||
if (xfer->result == XFER_RESULT_SUCCESS) {
|
||||
// stage 1 success, continue with stage 2
|
||||
p_cdc->user_control_cb = p_cdc->requested_complete_cb;
|
||||
set_data_format_request(p_cdc, internal_control_complete, xfer->user_data);
|
||||
} else {
|
||||
// stage 1 failed, notify user
|
||||
xfer->complete_cb = p_cdc->requested_complete_cb;
|
||||
if (xfer->complete_cb) {
|
||||
xfer->complete_cb(xfer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// call of (non-)blocking set-functions (to set line state, baudrate, ...)
|
||||
static bool set_function_call (
|
||||
cdch_interface_t * p_cdc,
|
||||
@@ -1470,60 +1541,20 @@ static bool ch34x_set_baudrate(cdch_interface_t * p_cdc, tuh_xfer_cb_t complete_
|
||||
}
|
||||
|
||||
static void ch34x_set_line_coding_stage1_complete(tuh_xfer_t * xfer) {
|
||||
// CH34x only has 1 interface and wIndex used as payload and not for bInterfaceNumber
|
||||
uint8_t const itf_num = 0;
|
||||
uint8_t const idx = tuh_cdc_itf_get_index(xfer->daddr, itf_num);
|
||||
cdch_interface_t* p_cdc = get_itf(idx);
|
||||
TU_ASSERT(p_cdc, );
|
||||
|
||||
if (xfer->result == XFER_RESULT_SUCCESS) {
|
||||
// stage 1 success, continue with stage 2
|
||||
p_cdc->user_control_cb = p_cdc->requested_complete_cb;
|
||||
ch34x_write_reg_data_format(p_cdc, ch34x_internal_control_complete, xfer->user_data);
|
||||
} else {
|
||||
// stage 1 failed, notify user
|
||||
xfer->complete_cb = p_cdc->requested_complete_cb;
|
||||
if (xfer->complete_cb) {
|
||||
xfer->complete_cb(xfer);
|
||||
}
|
||||
}
|
||||
uint8_t const itf_num = 0; // CH34x has only interface 0, because wIndex is used as payload and not for bInterfaceNumber
|
||||
set_line_coding_stage1_complete(xfer, itf_num,
|
||||
ch34x_write_reg_data_format, // control request function to set data format
|
||||
ch34x_internal_control_complete); // control complete function to be called after request
|
||||
}
|
||||
|
||||
// 2 stages: set baudrate (stage1) + set data format (stage2)
|
||||
static bool ch34x_set_line_coding(cdch_interface_t * p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data) {
|
||||
if (complete_cb) {
|
||||
// stage 1 set baudrate
|
||||
p_cdc->requested_complete_cb = complete_cb;
|
||||
p_cdc->user_control_cb = ch34x_set_line_coding_stage1_complete;
|
||||
return ch34x_write_reg_baudrate(p_cdc, ch34x_internal_control_complete, user_data);
|
||||
} else {
|
||||
// blocking sequence
|
||||
// stage 1 set baudrate
|
||||
xfer_result_t result = XFER_RESULT_INVALID; // use local result, because user_data ptr may be NULL
|
||||
bool ret = ch34x_write_reg_baudrate(p_cdc, NULL, (uintptr_t) &result);
|
||||
|
||||
// store/check results
|
||||
if (user_data) {
|
||||
*((xfer_result_t*) user_data) = result;
|
||||
}
|
||||
TU_ASSERT(ret);
|
||||
TU_VERIFY(result == XFER_RESULT_SUCCESS);
|
||||
|
||||
// overtake baudrate
|
||||
p_cdc->line_coding.bit_rate = p_cdc->requested_line_coding.bit_rate;
|
||||
|
||||
// stage 2 set data format
|
||||
result = XFER_RESULT_INVALID;
|
||||
ret = ch34x_write_reg_data_format(p_cdc, NULL, (uintptr_t) &result);
|
||||
|
||||
// store/check results
|
||||
if (user_data) {
|
||||
*((xfer_result_t*) user_data) = result;
|
||||
}
|
||||
TU_ASSERT(ret);
|
||||
return (result == XFER_RESULT_SUCCESS);
|
||||
// the overtaking of remaining requested_line_coding will be done in tuh_cdc_set_line_coding()
|
||||
}
|
||||
return set_line_coding_sequence(p_cdc,
|
||||
ch34x_write_reg_baudrate, // control request function to set baudrate
|
||||
ch34x_write_reg_data_format, // control request function to set data format
|
||||
ch34x_set_line_coding_stage1_complete, // function to be called after stage 1 completed
|
||||
ch34x_internal_control_complete, // control complete function to be called after request
|
||||
complete_cb, user_data);
|
||||
}
|
||||
|
||||
static bool ch34x_set_modem_ctrl(cdch_interface_t * p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data) {
|
||||
|
Reference in New Issue
Block a user