refactor change signature of serial driver's process_set_config
adding serial driver's request_complete()
This commit is contained in:
		| @@ -112,11 +112,13 @@ CFG_TUH_MEM_SECTION static cdch_epbuf_t cdch_epbuf[CFG_TUH_CDC]; | |||||||
| // Serial Driver | // Serial Driver | ||||||
| //--------------------------------------------------------------------+ | //--------------------------------------------------------------------+ | ||||||
|  |  | ||||||
|  | // General driver | ||||||
| static void cdch_process_set_config(tuh_xfer_t *xfer); | static void cdch_process_set_config(tuh_xfer_t *xfer); | ||||||
|  | static void cdch_internal_control_complete(tuh_xfer_t *xfer); | ||||||
|  |  | ||||||
| //------------- ACM prototypes -------------// | //------------- ACM prototypes -------------// | ||||||
| static bool acm_open(uint8_t daddr, tusb_desc_interface_t const * itf_desc, uint16_t max_len); | static bool acm_open(uint8_t daddr, tusb_desc_interface_t const * itf_desc, uint16_t max_len); | ||||||
| static bool acm_process_set_config(tuh_xfer_t * xfer); | static bool acm_process_set_config(cdch_interface_t *p_cdc, tuh_xfer_t *xfer); | ||||||
|  |  | ||||||
| static bool acm_set_baudrate(cdch_interface_t * p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); | static bool acm_set_baudrate(cdch_interface_t * p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); | ||||||
| static bool acm_set_data_format(cdch_interface_t * p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); | static bool acm_set_data_format(cdch_interface_t * p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); | ||||||
| @@ -127,7 +129,8 @@ static bool acm_set_control_line_state(cdch_interface_t * p_cdc, tuh_xfer_cb_t c | |||||||
| #if CFG_TUH_CDC_FTDI | #if CFG_TUH_CDC_FTDI | ||||||
| static uint16_t const ftdi_vid_pid_list[][2] = {CFG_TUH_CDC_FTDI_VID_PID_LIST}; | static uint16_t const ftdi_vid_pid_list[][2] = {CFG_TUH_CDC_FTDI_VID_PID_LIST}; | ||||||
| static bool ftdi_open(uint8_t daddr, const tusb_desc_interface_t * itf_desc, uint16_t max_len); | static bool ftdi_open(uint8_t daddr, const tusb_desc_interface_t * itf_desc, uint16_t max_len); | ||||||
| static bool ftdi_proccess_set_config(tuh_xfer_t * xfer); | static bool ftdi_proccess_set_config(cdch_interface_t *p_cdc, tuh_xfer_t *xfer); | ||||||
|  | static void ftdi_internal_control_complete(cdch_interface_t* p_cdc, tuh_xfer_t *xfer); | ||||||
|  |  | ||||||
| static bool ftdi_set_baudrate(cdch_interface_t * p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); | static bool ftdi_set_baudrate(cdch_interface_t * p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); | ||||||
| static bool ftdi_set_data_format(cdch_interface_t * p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); | static bool ftdi_set_data_format(cdch_interface_t * p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); | ||||||
| @@ -140,7 +143,9 @@ static bool ftdi_set_modem_ctrl(cdch_interface_t * p_cdc, tuh_xfer_cb_t complete | |||||||
| static uint16_t const cp210x_vid_pid_list[][2] = {CFG_TUH_CDC_CP210X_VID_PID_LIST}; | static uint16_t const cp210x_vid_pid_list[][2] = {CFG_TUH_CDC_CP210X_VID_PID_LIST}; | ||||||
|  |  | ||||||
| static bool cp210x_open(uint8_t daddr, tusb_desc_interface_t const * itf_desc, uint16_t max_len); | static bool cp210x_open(uint8_t daddr, tusb_desc_interface_t const * itf_desc, uint16_t max_len); | ||||||
| static bool cp210x_process_set_config(tuh_xfer_t * xfer); | static bool cp210x_process_set_config(cdch_interface_t *p_cdc, tuh_xfer_t *xfer); | ||||||
|  | static void acm_internal_control_complete(tuh_xfer_t *xfer); | ||||||
|  | static void cp210x_internal_control_complete(tuh_xfer_t *xfer); | ||||||
|  |  | ||||||
| static bool cp210x_set_baudrate(cdch_interface_t * p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); | static bool cp210x_set_baudrate(cdch_interface_t * p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); | ||||||
| static bool cp210x_set_data_format(cdch_interface_t * p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); | static bool cp210x_set_data_format(cdch_interface_t * p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); | ||||||
| @@ -153,7 +158,8 @@ static bool cp210x_set_modem_ctrl(cdch_interface_t * p_cdc, tuh_xfer_cb_t comple | |||||||
| static uint16_t const ch34x_vid_pid_list[][2] = {CFG_TUH_CDC_CH34X_VID_PID_LIST}; | static uint16_t const ch34x_vid_pid_list[][2] = {CFG_TUH_CDC_CH34X_VID_PID_LIST}; | ||||||
|  |  | ||||||
| static bool ch34x_open(uint8_t daddr, tusb_desc_interface_t const * itf_desc, uint16_t max_len); | static bool ch34x_open(uint8_t daddr, tusb_desc_interface_t const * itf_desc, uint16_t max_len); | ||||||
| static bool ch34x_process_set_config(tuh_xfer_t *xfer); | static bool ch34x_process_set_config(cdch_interface_t *p_cdc, tuh_xfer_t *xfer); | ||||||
|  | static void ch34x_internal_control_complete(tuh_xfer_t *xfer); | ||||||
|  |  | ||||||
| static bool ch34x_set_baudrate(cdch_interface_t * p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); | static bool ch34x_set_baudrate(cdch_interface_t * p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); | ||||||
| static bool ch34x_set_data_format(cdch_interface_t * p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); | static bool ch34x_set_data_format(cdch_interface_t * p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); | ||||||
| @@ -167,7 +173,8 @@ static uint16_t const pl2303_vid_pid_list[][2] = {CFG_TUH_CDC_PL2303_VID_PID_LIS | |||||||
| static const pl2303_type_data_t pl2303_type_data[PL2303_TYPE_COUNT] = {PL2303_TYPE_DATA}; | static const pl2303_type_data_t pl2303_type_data[PL2303_TYPE_COUNT] = {PL2303_TYPE_DATA}; | ||||||
|  |  | ||||||
| static bool pl2303_open(uint8_t daddr, tusb_desc_interface_t const * itf_desc, uint16_t max_len); | static bool pl2303_open(uint8_t daddr, tusb_desc_interface_t const * itf_desc, uint16_t max_len); | ||||||
| static bool pl2303_process_set_config(tuh_xfer_t *xfer); | static bool pl2303_process_set_config(cdch_interface_t *p_cdc, tuh_xfer_t *xfer); | ||||||
|  | static void pl2303_internal_control_complete(tuh_xfer_t *xfer); | ||||||
|  |  | ||||||
| static bool pl2303_set_baudrate(cdch_interface_t * p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); | static bool pl2303_set_baudrate(cdch_interface_t * p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); | ||||||
| static bool pl2303_set_data_format(cdch_interface_t * p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); | static bool pl2303_set_data_format(cdch_interface_t * p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); | ||||||
| @@ -206,11 +213,11 @@ typedef struct { | |||||||
|   bool is_2stage_line_coding; // true if driver requires to set baudrate then data format separately |   bool is_2stage_line_coding; // true if driver requires to set baudrate then data format separately | ||||||
|  |  | ||||||
|   bool (*const open)(uint8_t daddr, const tusb_desc_interface_t * itf_desc, uint16_t max_len); |   bool (*const open)(uint8_t daddr, const tusb_desc_interface_t * itf_desc, uint16_t max_len); | ||||||
|   bool (*const process_set_config)(tuh_xfer_t * xfer); |   bool (*const process_set_config)(cdch_interface_t * p_cdc, tuh_xfer_t * xfer); | ||||||
|   const serial_driver_func_t set_control_line_state; |   void (*const request_complete)(cdch_interface_t * p_cdc, tuh_xfer_t * xfer); // internal request complete handler to update line state | ||||||
|   const serial_driver_func_t set_baudrate; |  | ||||||
|   const serial_driver_func_t set_data_format; |   serial_driver_func_t set_control_line_state, set_baudrate, set_data_format, set_line_coding; | ||||||
|   const serial_driver_func_t set_line_coding; |  | ||||||
|   #if CFG_TUSB_DEBUG && CFG_TUSB_DEBUG >= CFG_TUH_CDC_LOG_LEVEL |   #if CFG_TUSB_DEBUG && CFG_TUSB_DEBUG >= CFG_TUH_CDC_LOG_LEVEL | ||||||
|   const char * name; |   const char * name; | ||||||
|   #endif |   #endif | ||||||
| @@ -244,6 +251,7 @@ static const cdch_serial_driver_t serial_drivers[] = { | |||||||
|       .is_2stage_line_coding  = true, |       .is_2stage_line_coding  = true, | ||||||
|       .open                   = ftdi_open, |       .open                   = ftdi_open, | ||||||
|       .process_set_config     = ftdi_proccess_set_config, |       .process_set_config     = ftdi_proccess_set_config, | ||||||
|  |       .request_complete       = ftdi_internal_control_complete, | ||||||
|       .set_control_line_state = ftdi_set_modem_ctrl, |       .set_control_line_state = ftdi_set_modem_ctrl, | ||||||
|       .set_baudrate           = ftdi_set_baudrate, |       .set_baudrate           = ftdi_set_baudrate, | ||||||
|       .set_data_format        = ftdi_set_data_format, |       .set_data_format        = ftdi_set_data_format, | ||||||
| @@ -827,11 +835,9 @@ bool cdch_open(uint8_t rhport, uint8_t daddr, tusb_desc_interface_t const *itf_d | |||||||
|   return false; |   return false; | ||||||
| } | } | ||||||
|  |  | ||||||
| static void set_config_complete(uint8_t idx, uint8_t itf_offset, bool success) { | static void set_config_complete(cdch_interface_t *p_cdc, uint8_t itf_offset, bool success) { | ||||||
|   cdch_interface_t *p_cdc = get_itf(idx); |  | ||||||
|   TU_ASSERT(p_cdc, ); |  | ||||||
|  |  | ||||||
|   if (success) { |   if (success) { | ||||||
|  |     const uint8_t idx = get_idx_by_ptr(p_cdc); | ||||||
|     p_cdc->mounted = true; |     p_cdc->mounted = true; | ||||||
|     if (tuh_cdc_mount_cb) { |     if (tuh_cdc_mount_cb) { | ||||||
|       tuh_cdc_mount_cb(idx); |       tuh_cdc_mount_cb(idx); | ||||||
| @@ -848,19 +854,6 @@ static void set_config_complete(uint8_t idx, uint8_t itf_offset, bool success) { | |||||||
|   usbh_driver_set_config_complete(p_cdc->daddr, p_cdc->bInterfaceNumber + itf_offset); |   usbh_driver_set_config_complete(p_cdc->daddr, p_cdc->bInterfaceNumber + itf_offset); | ||||||
| } | } | ||||||
|  |  | ||||||
| static void cdch_process_set_config(tuh_xfer_t *xfer) { |  | ||||||
|   cdch_interface_t *p_cdc = get_itf_by_xfer(xfer); |  | ||||||
|   TU_ASSERT(p_cdc && p_cdc->serial_drid < SERIAL_DRIVER_COUNT,); |  | ||||||
|   const uint8_t idx = get_idx_by_ptr(p_cdc); |  | ||||||
|  |  | ||||||
|   TU_LOG_DRV("  state = %u\r\n", xfer->user_data); |  | ||||||
|  |  | ||||||
|   if (!serial_drivers[p_cdc->serial_drid].process_set_config(xfer)) { |  | ||||||
|     const uint8_t itf_offset = (p_cdc->serial_drid == SERIAL_DRIVER_ACM) ? 1 : 0; |  | ||||||
|     set_config_complete(idx, itf_offset, false); |  | ||||||
|   } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| bool cdch_set_config(uint8_t daddr, uint8_t itf_num) { | bool cdch_set_config(uint8_t daddr, uint8_t itf_num) { | ||||||
|   tusb_control_request_t request; |   tusb_control_request_t request; | ||||||
|   request.wIndex = tu_htole16((uint16_t) itf_num); |   request.wIndex = tu_htole16((uint16_t) itf_num); | ||||||
| @@ -880,6 +873,32 @@ bool cdch_set_config(uint8_t daddr, uint8_t itf_num) { | |||||||
|   return true; |   return true; | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | static void cdch_process_set_config(tuh_xfer_t *xfer) { | ||||||
|  |   cdch_interface_t *p_cdc = get_itf_by_xfer(xfer); | ||||||
|  |   TU_ASSERT(p_cdc && p_cdc->serial_drid < SERIAL_DRIVER_COUNT,); | ||||||
|  |   TU_LOG_DRV("  state = %u\r\n", xfer->user_data); | ||||||
|  |  | ||||||
|  |   if (!serial_drivers[p_cdc->serial_drid].process_set_config(p_cdc, xfer)) { | ||||||
|  |     const uint8_t itf_offset = (p_cdc->serial_drid == SERIAL_DRIVER_ACM) ? 1 : 0; | ||||||
|  |     set_config_complete(p_cdc, itf_offset, false); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void cdch_internal_control_complete(tuh_xfer_t *xfer) { | ||||||
|  |   cdch_interface_t *p_cdc = get_itf_by_xfer(xfer); | ||||||
|  |   TU_ASSERT(p_cdc && p_cdc->serial_drid < SERIAL_DRIVER_COUNT,); | ||||||
|  |  | ||||||
|  |   TU_LOG_DRV("  request result = %u\r\n", xfer->result); | ||||||
|  |   serial_drivers[p_cdc->serial_drid].request_complete(p_cdc, xfer); | ||||||
|  |  | ||||||
|  |   // Invoke application callback | ||||||
|  |   xfer->complete_cb = p_cdc->user_complete_cb; | ||||||
|  |   if (xfer->complete_cb) { | ||||||
|  |     xfer->complete_cb(xfer); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
| //--------------------------------------------------------------------+ | //--------------------------------------------------------------------+ | ||||||
| // ACM | // ACM | ||||||
| //--------------------------------------------------------------------+ | //--------------------------------------------------------------------+ | ||||||
| @@ -1046,13 +1065,9 @@ static bool acm_open(uint8_t daddr, tusb_desc_interface_t const *itf_desc, uint1 | |||||||
|   return true; |   return true; | ||||||
| } | } | ||||||
|  |  | ||||||
| static bool acm_process_set_config(tuh_xfer_t *xfer) { | static bool acm_process_set_config(cdch_interface_t *p_cdc, tuh_xfer_t *xfer) { | ||||||
|  |   TU_ASSERT(xfer->result == XFER_RESULT_SUCCESS); | ||||||
|   const uintptr_t state = xfer->user_data; |   const uintptr_t state = xfer->user_data; | ||||||
|   uint8_t const itf_num = (uint8_t) tu_le16toh(xfer->setup->wIndex); |  | ||||||
|   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 && xfer->result == XFER_RESULT_SUCCESS); |  | ||||||
|  |  | ||||||
|   switch (state) { |   switch (state) { | ||||||
|     case CONFIG_ACM_SET_CONTROL_LINE_STATE: |     case CONFIG_ACM_SET_CONTROL_LINE_STATE: | ||||||
|       #ifdef CFG_TUH_CDC_LINE_CONTROL_ON_ENUM |       #ifdef CFG_TUH_CDC_LINE_CONTROL_ON_ENUM | ||||||
| @@ -1076,7 +1091,7 @@ static bool acm_process_set_config(tuh_xfer_t *xfer) { | |||||||
|  |  | ||||||
|     case CONFIG_ACM_COMPLETE: |     case CONFIG_ACM_COMPLETE: | ||||||
|       // itf_num+1 to account for data interface as well |       // itf_num+1 to account for data interface as well | ||||||
|       set_config_complete(idx, 1, true); |       set_config_complete(p_cdc, 1, true); | ||||||
|       break; |       break; | ||||||
|  |  | ||||||
|     default: |     default: | ||||||
| @@ -1159,55 +1174,38 @@ static bool ftdi_set_data_request(cdch_interface_t *p_cdc, tuh_xfer_cb_t complet | |||||||
|                           value, p_cdc->ftdi.channel, complete_cb, user_data); |                           value, p_cdc->ftdi.channel, complete_cb, user_data); | ||||||
| } | } | ||||||
|  |  | ||||||
| static inline bool ftdi_update_mctrl(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { |  | ||||||
|   uint16_t value = (uint16_t) ((p_cdc->requested_line.control_state.dtr ? FTDI_SIO_SET_DTR_HIGH : FTDI_SIO_SET_DTR_LOW) | |  | ||||||
|                                (p_cdc->requested_line.control_state.rts ? FTDI_SIO_SET_RTS_HIGH : FTDI_SIO_SET_RTS_LOW)); |  | ||||||
|  |  | ||||||
|   return ftdi_set_request(p_cdc, FTDI_SIO_SET_MODEM_CTRL_REQUEST, FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE, |  | ||||||
|                           value, p_cdc->ftdi.channel, complete_cb, user_data); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| //------------- Driver API -------------// | //------------- Driver API -------------// | ||||||
|  |  | ||||||
| // internal control complete to update state such as line state, line_coding | // internal control complete to update state such as line state, line_coding | ||||||
| static void ftdi_internal_control_complete(tuh_xfer_t *xfer) { | static void ftdi_internal_control_complete(cdch_interface_t* p_cdc, tuh_xfer_t *xfer) { | ||||||
|   uint8_t const idx = ftdi_get_idx(xfer); |   const tusb_control_request_t * setup = xfer->setup; | ||||||
|   cdch_interface_t *p_cdc = get_itf(idx); |   if (xfer->result == XFER_RESULT_SUCCESS) { | ||||||
|   TU_ASSERT(p_cdc, ); |     if (setup->bRequest      == FTDI_SIO_SET_MODEM_CTRL_REQUEST && | ||||||
|   bool const success = (xfer->result == XFER_RESULT_SUCCESS); |         setup->bmRequestType == FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE ) { | ||||||
|  |  | ||||||
|   if (success) { |  | ||||||
|     if (xfer->setup->bRequest      == FTDI_SIO_SET_MODEM_CTRL_REQUEST && |  | ||||||
|         xfer->setup->bmRequestType == FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE ) { |  | ||||||
|       p_cdc->line.control_state = p_cdc->requested_line.control_state; |       p_cdc->line.control_state = p_cdc->requested_line.control_state; | ||||||
|     } |     } | ||||||
|     if (xfer->setup->bRequest      == FTDI_SIO_SET_DATA_REQUEST && |     if (setup->bRequest      == FTDI_SIO_SET_DATA_REQUEST && | ||||||
|         xfer->setup->bmRequestType == FTDI_SIO_SET_DATA_REQUEST_TYPE ) { |         setup->bmRequestType == FTDI_SIO_SET_DATA_REQUEST_TYPE ) { | ||||||
|       p_cdc->line.coding.stop_bits = p_cdc->requested_line.coding.stop_bits; |       p_cdc->line.coding.stop_bits = p_cdc->requested_line.coding.stop_bits; | ||||||
|       p_cdc->line.coding.parity    = p_cdc->requested_line.coding.parity; |       p_cdc->line.coding.parity    = p_cdc->requested_line.coding.parity; | ||||||
|       p_cdc->line.coding.data_bits = p_cdc->requested_line.coding.data_bits; |       p_cdc->line.coding.data_bits = p_cdc->requested_line.coding.data_bits; | ||||||
|     } |     } | ||||||
|     if (xfer->setup->bRequest      == FTDI_SIO_SET_BAUDRATE_REQUEST && |     if (setup->bRequest      == FTDI_SIO_SET_BAUDRATE_REQUEST && | ||||||
|         xfer->setup->bmRequestType == FTDI_SIO_SET_BAUDRATE_REQUEST_TYPE ) { |         setup->bmRequestType == FTDI_SIO_SET_BAUDRATE_REQUEST_TYPE ) { | ||||||
|       p_cdc->line.coding.bit_rate = p_cdc->requested_line.coding.bit_rate; |       p_cdc->line.coding.bit_rate = p_cdc->requested_line.coding.bit_rate; | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   xfer->complete_cb = p_cdc->user_complete_cb; |  | ||||||
|   if (xfer->complete_cb) { |  | ||||||
|     xfer->complete_cb(xfer); |  | ||||||
|   } |  | ||||||
| } | } | ||||||
|  |  | ||||||
| static bool ftdi_set_data_format(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { | static bool ftdi_set_data_format(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { | ||||||
|   p_cdc->user_complete_cb = complete_cb; |   p_cdc->user_complete_cb = complete_cb; | ||||||
|   TU_ASSERT(ftdi_set_data_request(p_cdc, complete_cb ? ftdi_internal_control_complete : NULL, user_data)); |   TU_ASSERT(ftdi_set_data_request(p_cdc, complete_cb ? cdch_internal_control_complete : NULL, user_data)); | ||||||
|   return true; |   return true; | ||||||
| } | } | ||||||
|  |  | ||||||
| static bool ftdi_set_baudrate(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { | static bool ftdi_set_baudrate(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { | ||||||
|   p_cdc->user_complete_cb = complete_cb; |   p_cdc->user_complete_cb = complete_cb; | ||||||
|   TU_ASSERT(ftdi_change_speed(p_cdc, complete_cb ? ftdi_internal_control_complete : NULL, user_data)); |   TU_ASSERT(ftdi_change_speed(p_cdc, complete_cb ? cdch_internal_control_complete : NULL, user_data)); | ||||||
|   return true; |   return true; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -1218,7 +1216,7 @@ static void ftdi_set_line_coding_stage1_complete(tuh_xfer_t *xfer) { | |||||||
|   uint8_t const itf_num = p_cdc->bInterfaceNumber; |   uint8_t const itf_num = p_cdc->bInterfaceNumber; | ||||||
|   set_line_coding_stage1_complete(xfer, itf_num, |   set_line_coding_stage1_complete(xfer, itf_num, | ||||||
|                                   ftdi_set_data_request,           // control request function to set data format |                                   ftdi_set_data_request,           // control request function to set data format | ||||||
|                                   ftdi_internal_control_complete); // control complete function to be called after request |                                   cdch_internal_control_complete); // control complete function to be called after request | ||||||
| } | } | ||||||
|  |  | ||||||
| // 2 stages: set baudrate (stage1) + set data format (stage2) | // 2 stages: set baudrate (stage1) + set data format (stage2) | ||||||
| @@ -1227,15 +1225,16 @@ static bool ftdi_set_line_coding(cdch_interface_t * p_cdc, tuh_xfer_cb_t complet | |||||||
|                                   ftdi_change_speed,                    // control request function to set baudrate |                                   ftdi_change_speed,                    // control request function to set baudrate | ||||||
|                                   ftdi_set_data_request,                // control request function to set data format |                                   ftdi_set_data_request,                // control request function to set data format | ||||||
|                                   ftdi_set_line_coding_stage1_complete, // function to be called after stage 1 completed |                                   ftdi_set_line_coding_stage1_complete, // function to be called after stage 1 completed | ||||||
|                                   ftdi_internal_control_complete,       // control complete function to be called after request |                                   cdch_internal_control_complete,       // control complete function to be called after request | ||||||
|                                   complete_cb, user_data); |                                   complete_cb, user_data); | ||||||
| } | } | ||||||
|  |  | ||||||
| static bool ftdi_set_modem_ctrl(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { | static bool ftdi_set_modem_ctrl(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { | ||||||
|  |   uint16_t line_state = (uint16_t) ((p_cdc->requested_line.control_state.dtr ? FTDI_SIO_SET_DTR_HIGH : FTDI_SIO_SET_DTR_LOW) | | ||||||
|  |                                     (p_cdc->requested_line.control_state.rts ? FTDI_SIO_SET_RTS_HIGH : FTDI_SIO_SET_RTS_LOW)); | ||||||
|   p_cdc->user_complete_cb = complete_cb; |   p_cdc->user_complete_cb = complete_cb; | ||||||
|   TU_ASSERT(ftdi_update_mctrl(p_cdc, complete_cb ? ftdi_internal_control_complete : NULL, user_data)); |   return ftdi_set_request(p_cdc, FTDI_SIO_SET_MODEM_CTRL_REQUEST, FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE, | ||||||
|  |                           line_state, p_cdc->ftdi.channel, complete_cb ? cdch_internal_control_complete : NULL, user_data); | ||||||
|   return true; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| //------------- Enumeration -------------// | //------------- Enumeration -------------// | ||||||
| @@ -1274,18 +1273,14 @@ static bool ftdi_open(uint8_t daddr, const tusb_desc_interface_t *itf_desc, uint | |||||||
|   return open_ep_stream_pair(p_cdc, desc_ep); |   return open_ep_stream_pair(p_cdc, desc_ep); | ||||||
| } | } | ||||||
|  |  | ||||||
| static bool ftdi_proccess_set_config(tuh_xfer_t *xfer) { | static bool ftdi_proccess_set_config(cdch_interface_t *p_cdc, tuh_xfer_t *xfer) { | ||||||
|  |   TU_ASSERT(xfer->result == XFER_RESULT_SUCCESS); | ||||||
|   const uintptr_t state = xfer->user_data; |   const uintptr_t state = xfer->user_data; | ||||||
|   uint8_t const idx = ftdi_get_idx(xfer); |  | ||||||
|   cdch_interface_t *p_cdc = get_itf(idx); |  | ||||||
|   uint8_t const itf_num = p_cdc->bInterfaceNumber; |  | ||||||
|   TU_ASSERT(p_cdc && xfer->result == XFER_RESULT_SUCCESS); |  | ||||||
|  |  | ||||||
|   switch (state) { |   switch (state) { | ||||||
|     // from here sequence overtaken from Linux Kernel function ftdi_port_probe() |     // from here sequence overtaken from Linux Kernel function ftdi_port_probe() | ||||||
|     case CONFIG_FTDI_DETERMINE_TYPE: |     case CONFIG_FTDI_DETERMINE_TYPE: | ||||||
|       // determine type |       // determine type | ||||||
|       if (itf_num == 0) { |       if (p_cdc->bInterfaceNumber == 0) { | ||||||
|         TU_ASSERT(ftdi_determine_type(p_cdc)); |         TU_ASSERT(ftdi_determine_type(p_cdc)); | ||||||
|       } else { |       } else { | ||||||
|         // other interfaces have same type as interface 0 |         // other interfaces have same type as interface 0 | ||||||
| @@ -1318,7 +1313,7 @@ static bool ftdi_proccess_set_config(tuh_xfer_t *xfer) { | |||||||
|       #ifdef CFG_TUH_CDC_LINE_CODING_ON_ENUM |       #ifdef CFG_TUH_CDC_LINE_CODING_ON_ENUM | ||||||
|       p_cdc->requested_line.coding = (cdc_line_coding_t) CFG_TUH_CDC_LINE_CODING_ON_ENUM; |       p_cdc->requested_line.coding = (cdc_line_coding_t) CFG_TUH_CDC_LINE_CODING_ON_ENUM; | ||||||
|       p_cdc->user_complete_cb = cdch_process_set_config; |       p_cdc->user_complete_cb = cdch_process_set_config; | ||||||
|       TU_ASSERT(ftdi_set_data_request(p_cdc, ftdi_internal_control_complete, CONFIG_FTDI_SET_BAUDRATE)); |       TU_ASSERT(ftdi_set_data_request(p_cdc, cdch_internal_control_complete, CONFIG_FTDI_SET_BAUDRATE)); | ||||||
|       break; |       break; | ||||||
|       #else |       #else | ||||||
|       TU_ATTR_FALLTHROUGH; |       TU_ATTR_FALLTHROUGH; | ||||||
| @@ -1327,7 +1322,7 @@ static bool ftdi_proccess_set_config(tuh_xfer_t *xfer) { | |||||||
|     case CONFIG_FTDI_SET_BAUDRATE: |     case CONFIG_FTDI_SET_BAUDRATE: | ||||||
|       #ifdef CFG_TUH_CDC_LINE_CODING_ON_ENUM |       #ifdef CFG_TUH_CDC_LINE_CODING_ON_ENUM | ||||||
|       p_cdc->user_complete_cb = cdch_process_set_config; |       p_cdc->user_complete_cb = cdch_process_set_config; | ||||||
|       TU_ASSERT(ftdi_change_speed(p_cdc, ftdi_internal_control_complete, CONFIG_FTDI_FLOW_CONTROL)); |       TU_ASSERT(ftdi_change_speed(p_cdc, cdch_internal_control_complete, CONFIG_FTDI_FLOW_CONTROL)); | ||||||
|       break; |       break; | ||||||
|       #else |       #else | ||||||
|       TU_ATTR_FALLTHROUGH; |       TU_ATTR_FALLTHROUGH; | ||||||
| @@ -1342,15 +1337,14 @@ static bool ftdi_proccess_set_config(tuh_xfer_t *xfer) { | |||||||
|     case CONFIG_FTDI_MODEM_CTRL: |     case CONFIG_FTDI_MODEM_CTRL: | ||||||
|       #ifdef CFG_TUH_CDC_LINE_CONTROL_ON_ENUM |       #ifdef CFG_TUH_CDC_LINE_CONTROL_ON_ENUM | ||||||
|       p_cdc->requested_line.control_state.value = CFG_TUH_CDC_LINE_CONTROL_ON_ENUM; |       p_cdc->requested_line.control_state.value = CFG_TUH_CDC_LINE_CONTROL_ON_ENUM; | ||||||
|       p_cdc->user_complete_cb = cdch_process_set_config; |       TU_ASSERT(ftdi_set_modem_ctrl(p_cdc, cdch_process_set_config, CONFIG_FTDI_COMPLETE)); | ||||||
|       TU_ASSERT(ftdi_update_mctrl(p_cdc, ftdi_internal_control_complete, CONFIG_FTDI_COMPLETE)); |  | ||||||
|       break; |       break; | ||||||
|       #else |       #else | ||||||
|       TU_ATTR_FALLTHROUGH; |       TU_ATTR_FALLTHROUGH; | ||||||
|       #endif |       #endif | ||||||
|  |  | ||||||
|     case CONFIG_FTDI_COMPLETE: |     case CONFIG_FTDI_COMPLETE: | ||||||
|       set_config_complete(idx, 0, true); |       set_config_complete(p_cdc, 0, true); | ||||||
|       break; |       break; | ||||||
|  |  | ||||||
|     default: |     default: | ||||||
| @@ -1754,12 +1748,9 @@ static bool cp210x_open(uint8_t daddr, tusb_desc_interface_t const *itf_desc, ui | |||||||
|   return open_ep_stream_pair(p_cdc, desc_ep); |   return open_ep_stream_pair(p_cdc, desc_ep); | ||||||
| } | } | ||||||
|  |  | ||||||
| static bool cp210x_process_set_config(tuh_xfer_t *xfer) { | static bool cp210x_process_set_config(cdch_interface_t *p_cdc, tuh_xfer_t *xfer) { | ||||||
|  |   TU_ASSERT(xfer->result == XFER_RESULT_SUCCESS); | ||||||
|   const uintptr_t state = xfer->user_data; |   const uintptr_t state = xfer->user_data; | ||||||
|   uint8_t const itf_num = (uint8_t) tu_le16toh(xfer->setup->wIndex); |  | ||||||
|   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 && xfer->result == XFER_RESULT_SUCCESS); |  | ||||||
|  |  | ||||||
|     switch (state) { |     switch (state) { | ||||||
|     case CONFIG_CP210X_IFC_ENABLE: |     case CONFIG_CP210X_IFC_ENABLE: | ||||||
| @@ -1796,7 +1787,7 @@ static bool cp210x_process_set_config(tuh_xfer_t *xfer) { | |||||||
|       #endif |       #endif | ||||||
|  |  | ||||||
|     case CONFIG_CP210X_COMPLETE: |     case CONFIG_CP210X_COMPLETE: | ||||||
|       set_config_complete(idx, 0, true); |       set_config_complete(p_cdc, 0, true); | ||||||
|       break; |       break; | ||||||
|  |  | ||||||
|     default: |     default: | ||||||
| @@ -2018,13 +2009,10 @@ static bool ch34x_open(uint8_t daddr, tusb_desc_interface_t const * itf_desc, ui | |||||||
|   return true; |   return true; | ||||||
| } | } | ||||||
|  |  | ||||||
| static bool ch34x_process_set_config(tuh_xfer_t *xfer) { | static bool ch34x_process_set_config(cdch_interface_t *p_cdc, tuh_xfer_t *xfer) { | ||||||
|   const uintptr_t state = xfer->user_data; |  | ||||||
|   uint8_t const itf_num = 0; // CH34x has only interface 0, since wIndex is used as payload |  | ||||||
|   uint8_t const idx = tuh_cdc_itf_get_index(xfer->daddr, itf_num); |  | ||||||
|   cdch_interface_t *p_cdc = get_itf(idx); |  | ||||||
|   uint8_t buffer[2];// TODO remove |   uint8_t buffer[2];// TODO remove | ||||||
|   TU_ASSERT(p_cdc && xfer->result == XFER_RESULT_SUCCESS); |   TU_ASSERT(xfer->result == XFER_RESULT_SUCCESS); | ||||||
|  |   const uintptr_t state = xfer->user_data; | ||||||
|  |  | ||||||
|   switch (state) { |   switch (state) { | ||||||
|     case CONFIG_CH34X_READ_VERSION: |     case CONFIG_CH34X_READ_VERSION: | ||||||
| @@ -2074,7 +2062,7 @@ static bool ch34x_process_set_config(tuh_xfer_t *xfer) { | |||||||
|       #endif |       #endif | ||||||
|  |  | ||||||
|     case CONFIG_CH34X_COMPLETE: |     case CONFIG_CH34X_COMPLETE: | ||||||
|       set_config_complete(idx, 0, true); |       set_config_complete(p_cdc, 0, true); | ||||||
|       break; |       break; | ||||||
|  |  | ||||||
|     default: |     default: | ||||||
| @@ -2410,18 +2398,13 @@ static bool pl2303_open(uint8_t daddr, tusb_desc_interface_t const *itf_desc, ui | |||||||
|   return true; |   return true; | ||||||
| } | } | ||||||
|  |  | ||||||
| static bool pl2303_process_set_config(tuh_xfer_t *xfer) { | static bool pl2303_process_set_config(cdch_interface_t *p_cdc, tuh_xfer_t *xfer) { | ||||||
|   const uintptr_t state = xfer->user_data; |  | ||||||
|   // PL2303 has only interface 0, because wIndex is 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); |  | ||||||
|   // state CONFIG_PL2303_READ1 may have no success due to expected stall by pl2303_supports_hx_status() |   // state CONFIG_PL2303_READ1 may have no success due to expected stall by pl2303_supports_hx_status() | ||||||
|  |   const uintptr_t state = xfer->user_data; | ||||||
|  |   TU_ASSERT(xfer->result == XFER_RESULT_SUCCESS || state == CONFIG_PL2303_READ1); | ||||||
|   uint8_t buf = 0; |   uint8_t buf = 0; | ||||||
|   pl2303_type_t type; |   pl2303_type_t type; | ||||||
|  |  | ||||||
|   TU_ASSERT(p_cdc && (xfer->result == XFER_RESULT_SUCCESS || state == CONFIG_PL2303_READ1)); |  | ||||||
|  |  | ||||||
|   switch (state) { |   switch (state) { | ||||||
|     // from here sequence overtaken from Linux Kernel function pl2303_startup() |     // from here sequence overtaken from Linux Kernel function pl2303_startup() | ||||||
|     case CONFIG_PL2303_DETECT_TYPE: |     case CONFIG_PL2303_DETECT_TYPE: | ||||||
| @@ -2618,7 +2601,7 @@ static bool pl2303_process_set_config(tuh_xfer_t *xfer) { | |||||||
|   //      break; |   //      break; | ||||||
|  |  | ||||||
|     case CONFIG_PL2303_COMPLETE: |     case CONFIG_PL2303_COMPLETE: | ||||||
|       set_config_complete(idx, 0, true); |       set_config_complete(p_cdc, 0, true); | ||||||
|       break; |       break; | ||||||
|  |  | ||||||
|     default: |     default: | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 hathach
					hathach