@@ -401,7 +401,9 @@ bool tuh_cdc_read_clear (uint8_t idx) {
401401// Control Endpoint API
402402//--------------------------------------------------------------------+
403403
404- static void process_internal_control_complete (cdch_interface_t * p_cdc , tuh_xfer_t * xfer ) {
404+ static void process_internal_control_complete (tuh_xfer_t * xfer , uint8_t itf_num ) {
405+ uint8_t idx = tuh_cdc_itf_get_index (xfer -> daddr , itf_num );
406+ cdch_interface_t * p_cdc = get_itf (idx );
405407 TU_ASSERT (p_cdc , );
406408 uint16_t const value = tu_le16toh (xfer -> setup -> wValue );
407409
@@ -515,10 +517,7 @@ static void process_internal_control_complete(cdch_interface_t* p_cdc, tuh_xfer_
515517// internal control complete to update state such as line state, encoding
516518static void cdch_internal_control_complete (tuh_xfer_t * xfer ) {
517519 uint8_t const itf_num = (uint8_t ) tu_le16toh (xfer -> setup -> wIndex );
518- uint8_t idx = tuh_cdc_itf_get_index (xfer -> daddr , itf_num );
519- cdch_interface_t * p_cdc = get_itf (idx );
520-
521- process_internal_control_complete (p_cdc , xfer );
520+ process_internal_control_complete (xfer , itf_num );
522521}
523522
524523bool tuh_cdc_set_control_line_state (uint8_t idx , uint16_t line_state , tuh_xfer_cb_t complete_cb , uintptr_t user_data ) {
@@ -1294,7 +1293,8 @@ static void cp210x_process_config(tuh_xfer_t* xfer) {
12941293static uint8_t ch34x_get_lcr (uint8_t stop_bits , uint8_t parity , uint8_t data_bits );
12951294static uint16_t ch34x_get_divisor_prescaler (uint32_t baval );
12961295
1297- //------------- control requestt -------------//
1296+ //------------- control request -------------//
1297+
12981298static bool ch34x_set_request (cdch_interface_t * p_cdc , uint8_t direction , uint8_t request , uint16_t value ,
12991299 uint16_t index , uint8_t * buffer , uint16_t length , tuh_xfer_cb_t complete_cb , uintptr_t user_data ) {
13001300 tusb_control_request_t const request_setup = {
@@ -1366,10 +1366,7 @@ static bool ch34x_write_reg_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate,
13661366// internal control complete to update state such as line state, encoding
13671367static void ch34x_control_complete (tuh_xfer_t * xfer ) {
13681368 // CH34x only has 1 interface and use wIndex as payload and not for bInterfaceNumber
1369- uint8_t const itf_num = 0 ;
1370- uint8_t const idx = tuh_cdc_itf_get_index (xfer -> daddr , itf_num );
1371- cdch_interface_t * p_cdc = get_itf (idx );
1372- process_internal_control_complete (p_cdc , xfer );
1369+ process_internal_control_complete (xfer , 0 );
13731370}
13741371
13751372static bool ch34x_set_data_format (cdch_interface_t * p_cdc , uint8_t stop_bits , uint8_t parity , uint8_t data_bits ,
@@ -1379,6 +1376,7 @@ static bool ch34x_set_data_format(cdch_interface_t* p_cdc, uint8_t stop_bits, ui
13791376 p_cdc -> requested_line_coding .data_bits = data_bits ;
13801377
13811378 uint8_t const lcr = ch34x_get_lcr (stop_bits , parity , data_bits );
1379+ TU_VERIFY (lcr != 0 );
13821380 TU_ASSERT (ch34x_control_out (p_cdc , CH34X_REQ_WRITE_REG , CH32X_REG16_LCR2_LCR , lcr ,
13831381 complete_cb ? ch34x_control_complete : NULL , user_data ));
13841382 return true;
@@ -1527,35 +1525,26 @@ static void ch34x_process_config(tuh_xfer_t* xfer) {
15271525 TU_LOG_DRV ("[%u] CDCh CH34x Chip Version = %02x\r\n" , p_cdc -> daddr , version );
15281526 // only versions >= 0x30 are tested, below 0x30 seems having other programming, see drivers from WCH vendor, Linux kernel and FreeBSD
15291527 TU_ASSERT (version >= 0x30 ,);
1530-
1531- #ifdef CFG_TUH_CDC_LINE_CODING_ON_ENUM
1532- cdc_line_coding_t const line_coding = CFG_TUH_CDC_LINE_CODING_ON_ENUM ;
1533- uint8_t const lcr = ch34x_get_lcr (line_coding .stop_bits , line_coding .parity , line_coding .data_bits );
1534- uint16_t const first_arg = tu_u16 (lcr , 0x9c );
1528+ // init CH34x with line coding
1529+ cdc_line_coding_t const line_coding = CFG_TUH_CDC_LINE_CODING_ON_ENUM_CH34X ;
15351530 uint16_t const div_ps = ch34x_get_divisor_prescaler (line_coding .bit_rate );
15361531 TU_ASSERT (div_ps != 0 , );
1537- #else
1538- uint16_t const first_arg = 0 ;
1539- uint16_t const div_ps = 0 ;
1540- #endif
1541-
1542- // Init CH34x with line coding
1543- TU_ASSERT (ch34x_control_out (p_cdc , CH34X_REQ_SERIAL_INIT , first_arg , div_ps ,
1532+ uint8_t const lcr = ch34x_get_lcr (line_coding .stop_bits , line_coding .parity , line_coding .data_bits );
1533+ TU_ASSERT (lcr != 0 , );
1534+ TU_ASSERT (ch34x_control_out (p_cdc , CH34X_REQ_SERIAL_INIT , tu_u16 (lcr , 0x9c ), div_ps ,
15441535 ch34x_process_config , CONFIG_CH34X_SPECIAL_REG_WRITE ),);
15451536 break ;
15461537 }
15471538
15481539 case CONFIG_CH34X_SPECIAL_REG_WRITE :
1549- // do special reg write, purpose unknown, overtaken from WCH driver
1550- #ifdef CFG_TUH_CDC_LINE_CODING_ON_ENUM
1551- p_cdc -> line_coding = ((cdc_line_coding_t ) CFG_TUH_CDC_LINE_CODING_ON_ENUM );
1552- #endif
1553- TU_ASSERT (ch34x_write_reg (p_cdc , 0x0f2c , 0x0007 , ch34x_process_config , CONFIG_CH34X_FLOW_CONTROL ),);
1540+ // overtake line coding and do special reg write, purpose unknown, overtaken from WCH driver
1541+ p_cdc -> line_coding = ((cdc_line_coding_t ) CFG_TUH_CDC_LINE_CODING_ON_ENUM_CH34X );
1542+ TU_ASSERT (ch34x_write_reg (p_cdc , TU_U16 (CH341_REG_0x0F , CH341_REG_0x2C ), 0x0007 , ch34x_process_config , CONFIG_CH34X_FLOW_CONTROL ),);
15541543 break ;
15551544
15561545 case CONFIG_CH34X_FLOW_CONTROL :
15571546 // no hardware flow control
1558- TU_ASSERT (ch34x_write_reg (p_cdc , 0x2727 , 0x0000 , ch34x_process_config , CONFIG_CH34X_MODEM_CONTROL ),);
1547+ TU_ASSERT (ch34x_write_reg (p_cdc , TU_U16 ( CH341_REG_0x27 , CH341_REG_0x27 ) , 0x0000 , ch34x_process_config , CONFIG_CH34X_MODEM_CONTROL ),);
15591548 break ;
15601549
15611550 case CONFIG_CH34X_MODEM_CONTROL :
@@ -1581,6 +1570,7 @@ static uint16_t ch34x_get_divisor_prescaler(uint32_t baval) {
15811570 uint8_t b ;
15821571 uint32_t c ;
15831572
1573+ TU_VERIFY (baval != 0 , 0 );
15841574 switch (baval ) {
15851575 case 921600 :
15861576 a = 0xf3 ;
@@ -1606,7 +1596,7 @@ static uint16_t ch34x_get_divisor_prescaler(uint32_t baval) {
16061596 b = 0 ;
16071597 c = 11719 ;
16081598 }
1609- a = (unsigned char ) (c / baval );
1599+ a = (uint8_t ) (c / baval );
16101600 if (a == 0 || a == 0xFF ) {
16111601 return 0 ;
16121602 }
@@ -1620,29 +1610,33 @@ static uint16_t ch34x_get_divisor_prescaler(uint32_t baval) {
16201610 // reg divisor = a, reg prescaler = b
16211611 // According to linux code we need to set bit 7 of UCHCOM_REG_BPS_PRE,
16221612 // otherwise the chip will buffer data.
1623- return (uint16_t ) (a << 8 | 0x80 | b );
1613+ return (uint16_t ) (( uint16_t ) a << 8 | 0x80 | b );
16241614}
16251615
16261616// calculate lcr value from data coding
16271617static uint8_t ch34x_get_lcr (uint8_t stop_bits , uint8_t parity , uint8_t data_bits ) {
16281618 uint8_t lcr = CH34X_LCR_ENABLE_RX | CH34X_LCR_ENABLE_TX ;
1629- TU_VERIFY (data_bits >= 5 , 0 );
1619+ TU_VERIFY (data_bits >= 5 && data_bits <= 8 , 0 );
16301620 lcr |= (uint8_t ) (data_bits - 5 );
16311621
1632- if (parity ) {
1633- lcr |= CH34X_LCR_ENABLE_PAR ;
1634- }
16351622 switch (parity ) {
1623+ case CDC_LINE_CODING_PARITY_NONE :
1624+ break ;
1625+
1626+ case CDC_LINE_CODING_PARITY_ODD :
1627+ lcr |= CH34X_LCR_ENABLE_PAR ;
1628+ break ;
1629+
16361630 case CDC_LINE_CODING_PARITY_EVEN :
1637- lcr |= CH34X_LCR_PAR_EVEN ;
1631+ lcr |= CH34X_LCR_ENABLE_PAR | CH34X_LCR_PAR_EVEN ;
16381632 break ;
16391633
16401634 case CDC_LINE_CODING_PARITY_MARK :
1641- lcr |= CH34X_LCR_MARK_SPACE ;
1635+ lcr |= CH34X_LCR_ENABLE_PAR | CH34X_LCR_MARK_SPACE ;
16421636 break ;
16431637
16441638 case CDC_LINE_CODING_PARITY_SPACE :
1645- lcr |= CH34X_LCR_MARK_SPACE | CH34X_LCR_PAR_EVEN ;
1639+ lcr |= CH34X_LCR_ENABLE_PAR | CH34X_LCR_MARK_SPACE | CH34X_LCR_PAR_EVEN ;
16461640 break ;
16471641
16481642 default : break ;
0 commit comments