summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIngHK <[email protected]>2024-02-21 17:25:13 +0100
committerIngHK <[email protected]>2024-02-24 12:57:54 +0100
commit0b5f85eee0f34a80dd8debe2f764607070293119 (patch)
tree996577fe57a25dffc8c51dda43bd5064f9c0364b /src
parentdb511fb2f3df190f538d84d08b6be83746adae0e (diff)
created set_line_coding_sequence() and void set_line_coding_stage1_complete() to be reused by FTDI & CP210x
Diffstat (limited to 'src')
-rw-r--r--src/class/cdc/cdc_host.c131
1 files changed, 81 insertions, 50 deletions
diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c
index 850c1fceb..8deeffc37 100644
--- a/src/class/cdc/cdc_host.c
+++ b/src/class/cdc/cdc_host.c
@@ -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) {