changed to use of p_cdc->requested_line_coding
This commit is contained in:
		| @@ -63,12 +63,10 @@ typedef struct { | ||||
|   cdc_acm_capability_t acm_capability; | ||||
|  | ||||
|   TU_ATTR_ALIGNED(4) cdc_line_coding_t line_coding; // Baudrate, stop bits, parity, data width | ||||
|   uint8_t line_state;                               // DTR (bit0), RTS (bit1) | ||||
|  | ||||
|   #if CFG_TUH_CDC_FTDI || CFG_TUH_CDC_CP210X || CFG_TUH_CDC_CH34X | ||||
|   cdc_line_coding_t requested_line_coding; | ||||
|   TU_ATTR_ALIGNED(4) cdc_line_coding_t requested_line_coding; | ||||
|   // 1 byte padding | ||||
|   #endif | ||||
|  | ||||
|   uint8_t line_state;                               // DTR (bit0), RTS (bit1) | ||||
|  | ||||
|   tuh_xfer_cb_t user_control_cb; | ||||
|  | ||||
| @@ -95,9 +93,9 @@ static cdch_interface_t cdch_data[CFG_TUH_CDC]; | ||||
| static bool acm_open(uint8_t daddr, tusb_desc_interface_t const *itf_desc, uint16_t max_len); | ||||
| static void acm_process_config(tuh_xfer_t* xfer); | ||||
|  | ||||
| static bool acm_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data); | ||||
| static bool acm_set_data_format(cdch_interface_t* p_cdc, uint8_t stop_bits, uint8_t parity, uint8_t data_bits, tuh_xfer_cb_t complete_cb, uintptr_t user_data); | ||||
| static bool acm_set_line_coding(cdch_interface_t* p_cdc, cdc_line_coding_t const* line_coding, 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_line_coding(cdch_interface_t* p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); | ||||
| 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); | ||||
|  | ||||
| //------------- FTDI prototypes -------------// | ||||
| @@ -109,9 +107,9 @@ 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 void ftdi_process_config(tuh_xfer_t* xfer); | ||||
|  | ||||
| static bool ftdi_sio_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data); | ||||
| static bool ftdi_set_data_format(cdch_interface_t* p_cdc, uint8_t stop_bits, uint8_t parity, uint8_t data_bits, tuh_xfer_cb_t complete_cb, uintptr_t user_data); | ||||
| static bool ftdi_set_line_coding(cdch_interface_t* p_cdc, cdc_line_coding_t const* line_coding, tuh_xfer_cb_t complete_cb, uintptr_t user_data); | ||||
| static bool ftdi_sio_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_line_coding(cdch_interface_t* p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); | ||||
| 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); | ||||
| #endif | ||||
|  | ||||
| @@ -124,9 +122,9 @@ static uint16_t const cp210x_vid_pid_list[][2] = {CFG_TUH_CDC_CP210X_VID_PID_LIS | ||||
| static bool cp210x_open(uint8_t daddr, tusb_desc_interface_t const *itf_desc, uint16_t max_len); | ||||
| static void cp210x_process_config(tuh_xfer_t* xfer); | ||||
|  | ||||
| static bool cp210x_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data); | ||||
| static bool cp210x_set_data_format(cdch_interface_t* p_cdc, uint8_t stop_bits, uint8_t parity, uint8_t data_bits, tuh_xfer_cb_t complete_cb, uintptr_t user_data); | ||||
| static bool cp210x_set_line_coding(cdch_interface_t* p_cdc, cdc_line_coding_t const* line_coding, 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_line_coding(cdch_interface_t* p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); | ||||
| 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); | ||||
| #endif | ||||
|  | ||||
| @@ -139,9 +137,9 @@ 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 void ch34x_process_config(tuh_xfer_t* xfer); | ||||
|  | ||||
| static bool ch34x_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data); | ||||
| static bool ch34x_set_data_format(cdch_interface_t* p_cdc, uint8_t stop_bits, uint8_t parity, uint8_t data_bits, tuh_xfer_cb_t complete_cb, uintptr_t user_data); | ||||
| static bool ch34x_set_line_coding(cdch_interface_t* p_cdc, cdc_line_coding_t const* line_coding, 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_line_coding(cdch_interface_t* p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); | ||||
| static bool ch34x_set_modem_ctrl(cdch_interface_t* p_cdc, uint16_t line_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data); | ||||
| #endif | ||||
|  | ||||
| @@ -170,9 +168,9 @@ typedef struct { | ||||
|   bool (*const open)(uint8_t daddr, const tusb_desc_interface_t *itf_desc, uint16_t max_len); | ||||
|   void (*const process_set_config)(tuh_xfer_t* xfer); | ||||
|   bool (*const set_control_line_state)(cdch_interface_t* p_cdc, uint16_t line_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data); | ||||
|   bool (*const set_baudrate)(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data); | ||||
|   bool (*const set_data_format)(cdch_interface_t* p_cdc, uint8_t stop_bits, uint8_t parity, uint8_t data_bits, tuh_xfer_cb_t complete_cb, uintptr_t user_data); | ||||
|   bool (*const set_line_coding)(cdch_interface_t* p_cdc, cdc_line_coding_t const* line_coding, tuh_xfer_cb_t complete_cb, uintptr_t user_data); | ||||
|   bool (*const set_baudrate)(cdch_interface_t* p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); | ||||
|   bool (*const set_data_format)(cdch_interface_t* p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); | ||||
|   bool (*const set_line_coding)(cdch_interface_t* p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); | ||||
|   #if CFG_TUSB_DEBUG && CFG_TUSB_DEBUG >= CFG_TUH_CDC_LOG_LEVEL | ||||
|   uint8_t const * name; | ||||
|   #endif | ||||
| @@ -276,6 +274,7 @@ static cdch_interface_t* make_new_itf(uint8_t daddr, tusb_desc_interface_t const | ||||
|       p_cdc->bInterfaceNumber   = itf_desc->bInterfaceNumber; | ||||
|       p_cdc->bInterfaceSubClass = itf_desc->bInterfaceSubClass; | ||||
|       p_cdc->bInterfaceProtocol = itf_desc->bInterfaceProtocol; | ||||
|       p_cdc->line_coding        = (cdc_line_coding_t) { 0, 0, 0, 0 }; | ||||
|       p_cdc->line_state         = 0; | ||||
|       return p_cdc; | ||||
|     } | ||||
| @@ -451,12 +450,14 @@ bool tuh_cdc_set_baudrate(uint8_t idx, uint32_t baudrate, tuh_xfer_cb_t complete | ||||
|   TU_LOG_P_CDC("set baudrate = %lu", baudrate); | ||||
|   cdch_serial_driver_t const* driver = &serial_drivers[p_cdc->serial_drid]; | ||||
|  | ||||
|   p_cdc->requested_line_coding.bit_rate = baudrate; | ||||
|  | ||||
|   if (complete_cb) { | ||||
|     return driver->set_baudrate(p_cdc, baudrate, complete_cb, user_data); | ||||
|     return driver->set_baudrate(p_cdc, complete_cb, user_data); | ||||
|   } else { | ||||
|     // blocking | ||||
|     xfer_result_t result = XFER_RESULT_INVALID; | ||||
|     bool ret = driver->set_baudrate(p_cdc, baudrate, complete_cb, (uintptr_t) &result); | ||||
|     bool ret = driver->set_baudrate(p_cdc, complete_cb, (uintptr_t) &result); | ||||
|  | ||||
|     if (user_data) { | ||||
|       // user_data is not NULL, return result via user_data | ||||
| @@ -477,12 +478,16 @@ bool tuh_cdc_set_data_format(uint8_t idx, uint8_t stop_bits, uint8_t parity, uin | ||||
|                data_bits, parity, stop_bits); | ||||
|   cdch_serial_driver_t const* driver = &serial_drivers[p_cdc->serial_drid]; | ||||
|  | ||||
|   p_cdc->requested_line_coding.stop_bits = stop_bits; | ||||
|   p_cdc->requested_line_coding.parity    = parity; | ||||
|   p_cdc->requested_line_coding.data_bits = data_bits; | ||||
|  | ||||
|   if (complete_cb) { | ||||
|     return driver->set_data_format(p_cdc, stop_bits, parity, data_bits, complete_cb, user_data); | ||||
|     return driver->set_data_format(p_cdc, complete_cb, user_data); | ||||
|   } else { | ||||
|     // blocking | ||||
|     xfer_result_t result = XFER_RESULT_INVALID; | ||||
|     bool ret = driver->set_data_format(p_cdc, stop_bits, parity, data_bits, complete_cb, (uintptr_t) &result); | ||||
|     bool ret = driver->set_data_format(p_cdc, complete_cb, (uintptr_t) &result); | ||||
|  | ||||
|     if (user_data) { | ||||
|       // user_data is not NULL, return result via user_data | ||||
| @@ -491,7 +496,7 @@ bool tuh_cdc_set_data_format(uint8_t idx, uint8_t stop_bits, uint8_t parity, uin | ||||
|  | ||||
|     TU_VERIFY(ret && result == XFER_RESULT_SUCCESS); | ||||
|     p_cdc->line_coding.stop_bits = stop_bits; | ||||
|     p_cdc->line_coding.parity = parity; | ||||
|     p_cdc->line_coding.parity    = parity; | ||||
|     p_cdc->line_coding.data_bits = data_bits; | ||||
|     return true; | ||||
|   } | ||||
| @@ -504,12 +509,14 @@ bool tuh_cdc_set_line_coding(uint8_t idx, cdc_line_coding_t const* line_coding, | ||||
|                line_coding->bit_rate, line_coding->data_bits, line_coding->parity, line_coding->stop_bits); | ||||
|   cdch_serial_driver_t const* driver = &serial_drivers[p_cdc->serial_drid]; | ||||
|  | ||||
|   p_cdc->requested_line_coding = *line_coding; | ||||
|  | ||||
|   if ( complete_cb ) { | ||||
|     return driver->set_line_coding(p_cdc, line_coding, complete_cb, user_data); | ||||
|     return driver->set_line_coding(p_cdc, complete_cb, user_data); | ||||
|   } else { | ||||
|     // blocking | ||||
|     xfer_result_t result = XFER_RESULT_INVALID; | ||||
|     bool ret = driver->set_line_coding(p_cdc, line_coding, complete_cb, (uintptr_t) &result); | ||||
|     bool ret = driver->set_line_coding(p_cdc, complete_cb, (uintptr_t) &result); | ||||
|  | ||||
|     if (user_data) { | ||||
|       // user_data is not NULL, return result via user_data | ||||
| @@ -714,8 +721,7 @@ static void acm_internal_control_complete(tuh_xfer_t * xfer) { | ||||
|         break; | ||||
|  | ||||
|       case CDC_REQUEST_SET_LINE_CODING: | ||||
|         uint16_t const len = tu_min16(sizeof(cdc_line_coding_t), tu_le16toh(xfer->setup->wLength)); | ||||
|         memcpy(&p_cdc->line_coding, xfer->buffer, len); | ||||
|         p_cdc->line_coding = p_cdc->requested_line_coding; | ||||
|         break; | ||||
|  | ||||
|       default: break; | ||||
| @@ -758,7 +764,7 @@ static bool acm_set_control_line_state(cdch_interface_t* p_cdc, uint16_t line_st | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| static bool acm_set_line_coding(cdch_interface_t* p_cdc, cdc_line_coding_t const* line_coding, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { | ||||
| static bool acm_set_line_coding(cdch_interface_t* p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { | ||||
|   tusb_control_request_t const request = { | ||||
|     .bmRequestType_bit = { | ||||
|       .recipient = TUSB_REQ_RCPT_INTERFACE, | ||||
| @@ -773,7 +779,7 @@ static bool acm_set_line_coding(cdch_interface_t* p_cdc, cdc_line_coding_t const | ||||
|  | ||||
|   // use usbh enum buf to hold line coding since user line_coding variable does not live long enough | ||||
|   uint8_t* enum_buf = usbh_get_enum_buf(); | ||||
|   memcpy(enum_buf, line_coding, sizeof(cdc_line_coding_t)); | ||||
|   memcpy(enum_buf, &p_cdc->requested_line_coding, sizeof(cdc_line_coding_t)); | ||||
|  | ||||
|   p_cdc->user_control_cb = complete_cb; | ||||
|   tuh_xfer_t xfer = { | ||||
| @@ -789,23 +795,19 @@ static bool acm_set_line_coding(cdch_interface_t* p_cdc, cdc_line_coding_t const | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| static bool acm_set_data_format(cdch_interface_t* p_cdc, uint8_t stop_bits, uint8_t parity, uint8_t data_bits, | ||||
|                                 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) { | ||||
|   p_cdc->requested_line_coding.bit_rate = p_cdc->line_coding.bit_rate; | ||||
|  | ||||
|   cdc_line_coding_t line_coding; | ||||
|   line_coding.bit_rate = p_cdc->line_coding.bit_rate; | ||||
|   line_coding.stop_bits = stop_bits; | ||||
|   line_coding.parity = parity; | ||||
|   line_coding.data_bits = data_bits; | ||||
|  | ||||
|   return acm_set_line_coding(p_cdc, &line_coding, complete_cb, user_data); | ||||
|   return acm_set_line_coding(p_cdc, complete_cb, user_data); | ||||
| } | ||||
|  | ||||
| static bool acm_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, 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) { | ||||
|   p_cdc->requested_line_coding.stop_bits = p_cdc->line_coding.stop_bits; | ||||
|   p_cdc->requested_line_coding.parity    = p_cdc->line_coding.parity; | ||||
|   p_cdc->requested_line_coding.data_bits = p_cdc->line_coding.data_bits; | ||||
|   TU_VERIFY(p_cdc->acm_capability.support_line_request); | ||||
|   cdc_line_coding_t line_coding = p_cdc->line_coding; | ||||
|   line_coding.bit_rate = baudrate; | ||||
|   return acm_set_line_coding(p_cdc, &line_coding, complete_cb, user_data); | ||||
|  | ||||
|   return acm_set_line_coding(p_cdc, complete_cb, user_data); | ||||
| } | ||||
|  | ||||
| //------------- Enumeration -------------// | ||||
| @@ -879,11 +881,11 @@ static void acm_process_config(tuh_xfer_t* xfer) { | ||||
|  | ||||
|     case CONFIG_ACM_SET_LINE_CODING: | ||||
|       #ifdef CFG_TUH_CDC_LINE_CODING_ON_ENUM | ||||
|       if (p_cdc->acm_capability.support_line_request) { | ||||
|         cdc_line_coding_t line_coding = CFG_TUH_CDC_LINE_CODING_ON_ENUM; | ||||
|         TU_ASSERT(acm_set_line_coding(p_cdc, &line_coding, acm_process_config, CONFIG_ACM_COMPLETE),); | ||||
|         break; | ||||
|       } | ||||
|         if (p_cdc->acm_capability.support_line_request) { | ||||
|           p_cdc->requested_line_coding = (cdc_line_coding_t) CFG_TUH_CDC_LINE_CODING_ON_ENUM; | ||||
|           TU_ASSERT(acm_set_line_coding(p_cdc, acm_process_config, CONFIG_ACM_COMPLETE),); | ||||
|           break; | ||||
|         } | ||||
|       #endif | ||||
|       TU_ATTR_FALLTHROUGH; | ||||
|  | ||||
| @@ -902,7 +904,7 @@ static void acm_process_config(tuh_xfer_t* xfer) { | ||||
| //--------------------------------------------------------------------+ | ||||
| #if CFG_TUH_CDC_FTDI | ||||
|  | ||||
| static uint32_t ftdi_232bm_baud_to_divisor(uint32_t baud); | ||||
| static uint32_t ftdi_232bm_baud_to_divisor(cdch_interface_t* p_cdc); | ||||
|  | ||||
| //------------- Control Request -------------// | ||||
|  | ||||
| @@ -967,32 +969,26 @@ static void ftdi_internal_control_complete(tuh_xfer_t * xfer) { | ||||
|   } | ||||
| } | ||||
|  | ||||
| static bool ftdi_sio_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { | ||||
|   uint16_t const divisor = (uint16_t) ftdi_232bm_baud_to_divisor(baudrate); | ||||
| static bool ftdi_sio_set_baudrate(cdch_interface_t* p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { | ||||
|   uint16_t const divisor = (uint16_t) ftdi_232bm_baud_to_divisor(p_cdc); | ||||
|  | ||||
|   p_cdc->user_control_cb = complete_cb; | ||||
|   p_cdc->requested_line_coding.bit_rate = baudrate; | ||||
|   TU_ASSERT(ftdi_sio_set_request(p_cdc, FTDI_SIO_SET_BAUD_RATE, divisor, | ||||
|                                  complete_cb ? ftdi_internal_control_complete : NULL, user_data)); | ||||
|  | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| static bool ftdi_set_data_format(cdch_interface_t* p_cdc, uint8_t stop_bits, uint8_t parity, uint8_t data_bits, | ||||
|                                  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) { | ||||
|   (void) p_cdc; | ||||
|   (void) stop_bits; | ||||
|   (void) parity; | ||||
|   (void) data_bits; | ||||
|   (void) complete_cb; | ||||
|   (void) user_data; | ||||
|   // TODO not implemented yet | ||||
|   return false; | ||||
| } | ||||
|  | ||||
| static bool ftdi_set_line_coding(cdch_interface_t* p_cdc, cdc_line_coding_t const* line_coding, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { | ||||
| static bool ftdi_set_line_coding(cdch_interface_t* p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { | ||||
|   (void) p_cdc; | ||||
|   (void) line_coding; | ||||
|   (void) complete_cb; | ||||
|   (void) user_data; | ||||
|   // TODO not implemented yet | ||||
| @@ -1056,11 +1052,11 @@ static void ftdi_process_config(tuh_xfer_t* xfer) { | ||||
|  | ||||
|     case CONFIG_FTDI_SET_BAUDRATE: { | ||||
|       #ifdef CFG_TUH_CDC_LINE_CODING_ON_ENUM | ||||
|       cdc_line_coding_t line_coding = CFG_TUH_CDC_LINE_CODING_ON_ENUM; | ||||
|       TU_ASSERT(ftdi_sio_set_baudrate(p_cdc, line_coding.bit_rate, ftdi_process_config, CONFIG_FTDI_SET_DATA),); | ||||
|       break; | ||||
|         p_cdc->requested_line_coding.bit_rate = ((cdc_line_coding_t) CFG_TUH_CDC_LINE_CODING_ON_ENUM).bit_rate; | ||||
|         TU_ASSERT(ftdi_sio_set_baudrate(p_cdc, ftdi_process_config, CONFIG_FTDI_SET_DATA),); | ||||
|         break; | ||||
|       #else | ||||
|       TU_ATTR_FALLTHROUGH; | ||||
|         TU_ATTR_FALLTHROUGH; | ||||
|       #endif | ||||
|     } | ||||
|  | ||||
| @@ -1107,8 +1103,8 @@ static uint32_t ftdi_232bm_baud_base_to_divisor(uint32_t baud, uint32_t base) { | ||||
|   return divisor; | ||||
| } | ||||
|  | ||||
| static uint32_t ftdi_232bm_baud_to_divisor(uint32_t baud) { | ||||
|   return ftdi_232bm_baud_base_to_divisor(baud, 48000000u); | ||||
| static uint32_t ftdi_232bm_baud_to_divisor(cdch_interface_t* p_cdc) { | ||||
|   return ftdi_232bm_baud_base_to_divisor(p_cdc->requested_line_coding.bit_rate, 48000000u); | ||||
| } | ||||
|  | ||||
| #endif | ||||
| @@ -1175,9 +1171,7 @@ static void cp210x_internal_control_complete(tuh_xfer_t * xfer) { | ||||
|         break; | ||||
|  | ||||
|       case CP210X_SET_BAUDRATE: | ||||
|         uint32_t baudrate; | ||||
|         memcpy(&baudrate, xfer->buffer, sizeof(uint32_t)); | ||||
|         p_cdc->line_coding.bit_rate = tu_le32toh(baudrate); | ||||
|         p_cdc->line_coding.bit_rate = p_cdc->requested_line_coding.bit_rate; | ||||
|         break; | ||||
|  | ||||
|       default: break; | ||||
| @@ -1190,29 +1184,24 @@ static void cp210x_internal_control_complete(tuh_xfer_t * xfer) { | ||||
|   } | ||||
| } | ||||
|  | ||||
| static bool cp210x_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { | ||||
|   uint32_t baud_le = tu_htole32(baudrate); | ||||
| static bool cp210x_set_baudrate(cdch_interface_t* p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { | ||||
|   uint32_t baud_le = tu_htole32(p_cdc->requested_line_coding.bit_rate); | ||||
|   p_cdc->user_control_cb = complete_cb; | ||||
|   return cp210x_set_request(p_cdc, CP210X_SET_BAUDRATE, 0, (uint8_t *) &baud_le, 4, | ||||
|                             complete_cb ? cp210x_internal_control_complete : NULL, user_data); | ||||
| } | ||||
|  | ||||
| static bool cp210x_set_data_format(cdch_interface_t* p_cdc, uint8_t stop_bits, uint8_t parity, uint8_t data_bits, | ||||
|                                    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) { | ||||
|   (void) p_cdc; | ||||
|   (void) stop_bits; | ||||
|   (void) parity; | ||||
|   (void) data_bits; | ||||
|   (void) complete_cb; | ||||
|   (void) user_data; | ||||
|   // TODO not implemented yet | ||||
|   return false; | ||||
| } | ||||
|  | ||||
| static bool cp210x_set_line_coding(cdch_interface_t* p_cdc, cdc_line_coding_t const* line_coding, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { | ||||
| static bool cp210x_set_line_coding(cdch_interface_t* p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { | ||||
|   // TODO implement later | ||||
|   (void) p_cdc; | ||||
|   (void) line_coding; | ||||
|   (void) complete_cb; | ||||
|   (void) user_data; | ||||
|   return false; | ||||
| @@ -1265,11 +1254,11 @@ static void cp210x_process_config(tuh_xfer_t* xfer) { | ||||
|  | ||||
|     case CONFIG_CP210X_SET_BAUDRATE: { | ||||
|       #ifdef CFG_TUH_CDC_LINE_CODING_ON_ENUM | ||||
|       cdc_line_coding_t line_coding = CFG_TUH_CDC_LINE_CODING_ON_ENUM; | ||||
|       TU_ASSERT(cp210x_set_baudrate(p_cdc, line_coding.bit_rate, cp210x_process_config, CONFIG_CP210X_SET_LINE_CTL),); | ||||
|       break; | ||||
|         p_cdc->requested_line_coding.bit_rate = ((cdc_line_coding_t) CFG_TUH_CDC_LINE_CODING_ON_ENUM).bit_rate; | ||||
|         TU_ASSERT(cp210x_set_baudrate(p_cdc, cp210x_process_config, CONFIG_CP210X_SET_LINE_CTL),); | ||||
|         break; | ||||
|       #else | ||||
|       TU_ATTR_FALLTHROUGH; | ||||
|         TU_ATTR_FALLTHROUGH; | ||||
|       #endif | ||||
|     } | ||||
|  | ||||
| @@ -1306,8 +1295,8 @@ static void cp210x_process_config(tuh_xfer_t* xfer) { | ||||
|  | ||||
| #if CFG_TUH_CDC_CH34X | ||||
|  | ||||
| static uint8_t ch34x_get_lcr(uint8_t stop_bits, uint8_t parity, uint8_t data_bits); | ||||
| static uint16_t ch34x_get_divisor_prescaler(uint32_t baval); | ||||
| static uint8_t ch34x_get_lcr(cdch_interface_t * p_cdc); | ||||
| static uint16_t ch34x_get_divisor_prescaler(cdch_interface_t * p_cdc); | ||||
|  | ||||
| //------------- Control Request -------------// | ||||
|  | ||||
| @@ -1368,9 +1357,8 @@ static inline bool ch34x_write_reg(cdch_interface_t* p_cdc, uint16_t reg, uint16 | ||||
| //  return ch34x_control_in ( p_cdc, CH34X_REQ_READ_REG, reg, 0, buffer, buffersize, complete_cb, user_data ); | ||||
| //} | ||||
|  | ||||
| static bool ch34x_write_reg_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, | ||||
|                                      tuh_xfer_cb_t complete_cb, uintptr_t user_data) { | ||||
|   uint16_t const div_ps = ch34x_get_divisor_prescaler(baudrate); | ||||
| static bool ch34x_write_reg_baudrate(cdch_interface_t* p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { | ||||
|   uint16_t const div_ps = ch34x_get_divisor_prescaler(p_cdc); | ||||
|   TU_VERIFY(div_ps); | ||||
|   TU_ASSERT(ch34x_write_reg(p_cdc, CH34X_REG16_DIVISOR_PRESCALER, div_ps, | ||||
|                             complete_cb, user_data)); | ||||
| @@ -1436,25 +1424,17 @@ static void ch34x_internal_control_complete(tuh_xfer_t * xfer) { | ||||
|   } | ||||
| } | ||||
|  | ||||
| static bool ch34x_set_data_format(cdch_interface_t* p_cdc, uint8_t stop_bits, uint8_t parity, uint8_t data_bits, | ||||
|                                 tuh_xfer_cb_t complete_cb, uintptr_t user_data) { | ||||
|   p_cdc->requested_line_coding.stop_bits = stop_bits; | ||||
|   p_cdc->requested_line_coding.parity = parity; | ||||
|   p_cdc->requested_line_coding.data_bits = data_bits; | ||||
|  | ||||
|   uint8_t const lcr = ch34x_get_lcr(stop_bits, parity, data_bits); | ||||
| static bool ch34x_set_data_format(cdch_interface_t* p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { | ||||
|   uint8_t const lcr = ch34x_get_lcr(p_cdc); | ||||
|   TU_VERIFY(lcr); | ||||
|   TU_ASSERT (ch34x_control_out(p_cdc, CH34X_REQ_WRITE_REG, CH32X_REG16_LCR2_LCR, lcr, | ||||
|                                complete_cb ? ch34x_internal_control_complete : NULL, user_data)); | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| static bool ch34x_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, | ||||
|                                tuh_xfer_cb_t complete_cb, uintptr_t user_data) { | ||||
|   p_cdc->requested_line_coding.bit_rate = baudrate; | ||||
| static bool ch34x_set_baudrate(cdch_interface_t* p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { | ||||
|   p_cdc->user_control_cb = complete_cb; | ||||
|   TU_ASSERT(ch34x_write_reg_baudrate(p_cdc, baudrate, | ||||
|                                      complete_cb ? ch34x_internal_control_complete : NULL, user_data)); | ||||
|   TU_ASSERT(ch34x_write_reg_baudrate(p_cdc, complete_cb ? ch34x_internal_control_complete : NULL, user_data)); | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| @@ -1468,8 +1448,7 @@ static void ch34x_set_line_coding_stage1_complete(tuh_xfer_t* xfer) { | ||||
|   if (xfer->result == XFER_RESULT_SUCCESS) { | ||||
|     // stage 1 success, continue to stage 2 | ||||
|     p_cdc->line_coding.bit_rate = p_cdc->requested_line_coding.bit_rate; | ||||
|     TU_ASSERT(ch34x_set_data_format(p_cdc, p_cdc->requested_line_coding.stop_bits, p_cdc->requested_line_coding.parity, | ||||
|                                     p_cdc->requested_line_coding.data_bits, ch34x_internal_control_complete, xfer->user_data), ); | ||||
|     TU_ASSERT(ch34x_set_data_format(p_cdc, ch34x_internal_control_complete, xfer->user_data), ); | ||||
|   } else { | ||||
|     // stage 1 failed, notify user | ||||
|     xfer->complete_cb = p_cdc->user_control_cb; | ||||
| @@ -1480,31 +1459,24 @@ static void ch34x_set_line_coding_stage1_complete(tuh_xfer_t* xfer) { | ||||
| } | ||||
|  | ||||
| // 2 stages: set baudrate (stage1) + set data format (stage2) | ||||
| static bool ch34x_set_line_coding(cdch_interface_t* p_cdc, cdc_line_coding_t const* line_coding, | ||||
|                                   tuh_xfer_cb_t complete_cb, uintptr_t user_data) { | ||||
|   p_cdc->requested_line_coding = *line_coding; | ||||
| static bool ch34x_set_line_coding(cdch_interface_t* p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { | ||||
|   p_cdc->user_control_cb = complete_cb; | ||||
|  | ||||
|   if (complete_cb) { | ||||
|     // stage 1 set baudrate | ||||
|     TU_ASSERT(ch34x_write_reg_baudrate(p_cdc, line_coding->bit_rate, | ||||
|                                        ch34x_set_line_coding_stage1_complete, user_data)); | ||||
|     TU_ASSERT(ch34x_write_reg_baudrate(p_cdc, ch34x_set_line_coding_stage1_complete, user_data)); | ||||
|   } else { | ||||
|     // sync call | ||||
|     xfer_result_t result; | ||||
|  | ||||
|     // stage 1 set baudrate | ||||
|     TU_ASSERT(ch34x_write_reg_baudrate(p_cdc, line_coding->bit_rate, NULL, (uintptr_t) &result)); | ||||
|     TU_ASSERT(ch34x_write_reg_baudrate(p_cdc, NULL, (uintptr_t) &result)); | ||||
|     TU_VERIFY(result == XFER_RESULT_SUCCESS); | ||||
|     p_cdc->line_coding.bit_rate = line_coding->bit_rate; | ||||
|     p_cdc->line_coding.bit_rate = p_cdc->requested_line_coding.bit_rate; | ||||
|  | ||||
|     // stage 2 set data format | ||||
|     TU_ASSERT(ch34x_set_data_format(p_cdc, line_coding->stop_bits, line_coding->parity, line_coding->data_bits, | ||||
|                                     NULL, (uintptr_t) &result)); | ||||
|     TU_ASSERT(ch34x_set_data_format(p_cdc, NULL, (uintptr_t) &result)); | ||||
|     TU_VERIFY(result == XFER_RESULT_SUCCESS); | ||||
|     p_cdc->line_coding.stop_bits = line_coding->stop_bits; | ||||
|     p_cdc->line_coding.parity = line_coding->parity; | ||||
|     p_cdc->line_coding.data_bits = line_coding->data_bits; | ||||
|  | ||||
|     // update transfer result, user_data is expected to point to xfer_result_t | ||||
|     if (user_data) { | ||||
| @@ -1592,10 +1564,10 @@ static void ch34x_process_config(tuh_xfer_t* xfer) { | ||||
|       // only versions >= 0x30 are tested, below 0x30 seems having other programming, see drivers from WCH vendor, Linux kernel and FreeBSD | ||||
|       TU_ASSERT (version >= 0x30,); | ||||
|       // init CH34x with line coding | ||||
|       cdc_line_coding_t const line_coding = CFG_TUH_CDC_LINE_CODING_ON_ENUM_CH34X; | ||||
|       uint16_t const div_ps = ch34x_get_divisor_prescaler(line_coding.bit_rate); | ||||
|       p_cdc->requested_line_coding = (cdc_line_coding_t) CFG_TUH_CDC_LINE_CODING_ON_ENUM_CH34X; | ||||
|       uint16_t const div_ps = ch34x_get_divisor_prescaler(p_cdc); | ||||
|       TU_ASSERT(div_ps, ); | ||||
|       uint8_t const lcr = ch34x_get_lcr(line_coding.stop_bits, line_coding.parity, line_coding.data_bits); | ||||
|       uint8_t const lcr = ch34x_get_lcr(p_cdc); | ||||
|       TU_ASSERT(lcr, ); | ||||
|       TU_ASSERT (ch34x_control_out(p_cdc, CH34X_REQ_SERIAL_INIT, tu_u16(lcr, 0x9c), div_ps, | ||||
|                                    ch34x_process_config, CONFIG_CH34X_SPECIAL_REG_WRITE),); | ||||
| @@ -1604,7 +1576,7 @@ static void ch34x_process_config(tuh_xfer_t* xfer) { | ||||
|  | ||||
|     case CONFIG_CH34X_SPECIAL_REG_WRITE: | ||||
|       // overtake line coding and do special reg write, purpose unknown, overtaken from WCH driver | ||||
|       p_cdc->line_coding = ((cdc_line_coding_t) CFG_TUH_CDC_LINE_CODING_ON_ENUM_CH34X); | ||||
|       p_cdc->line_coding = (cdc_line_coding_t) CFG_TUH_CDC_LINE_CODING_ON_ENUM_CH34X; | ||||
|       TU_ASSERT (ch34x_write_reg(p_cdc, TU_U16(CH341_REG_0x0F, CH341_REG_0x2C), 0x0007, ch34x_process_config, CONFIG_CH34X_FLOW_CONTROL),); | ||||
|       break; | ||||
|  | ||||
| @@ -1631,7 +1603,8 @@ static void ch34x_process_config(tuh_xfer_t* xfer) { | ||||
| //------------- Helper -------------// | ||||
|  | ||||
| // calculate divisor and prescaler for baudrate, return it as 16-bit combined value | ||||
| static uint16_t ch34x_get_divisor_prescaler(uint32_t baval) { | ||||
| static uint16_t ch34x_get_divisor_prescaler(cdch_interface_t * p_cdc) { | ||||
|   uint32_t const baval = p_cdc->requested_line_coding.bit_rate; | ||||
|   uint8_t a; | ||||
|   uint8_t b; | ||||
|   uint32_t c; | ||||
| @@ -1680,7 +1653,11 @@ static uint16_t ch34x_get_divisor_prescaler(uint32_t baval) { | ||||
| } | ||||
|  | ||||
| // calculate lcr value from data coding | ||||
| static uint8_t ch34x_get_lcr(uint8_t stop_bits, uint8_t parity, uint8_t data_bits) { | ||||
| static uint8_t ch34x_get_lcr(cdch_interface_t * p_cdc) { | ||||
|   uint8_t const stop_bits = p_cdc->requested_line_coding.stop_bits; | ||||
|   uint8_t const parity    = p_cdc->requested_line_coding.parity; | ||||
|   uint8_t const data_bits = p_cdc->requested_line_coding.data_bits; | ||||
|  | ||||
|   uint8_t lcr = CH34X_LCR_ENABLE_RX | CH34X_LCR_ENABLE_TX; | ||||
|   TU_VERIFY(data_bits >= 5 && data_bits <= 8, 0); | ||||
|   lcr |= (uint8_t) (data_bits - 5); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 IngHK
					IngHK