Skip to content

Commit

Permalink
fixed hathach#2448
Browse files Browse the repository at this point in the history
  • Loading branch information
Heiko Kuester committed Feb 14, 2024
1 parent 8fcf084 commit b0d1da4
Showing 1 changed file with 54 additions and 35 deletions.
89 changes: 54 additions & 35 deletions src/class/cdc/cdc_host.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,17 @@ typedef struct {
bool mounted; // Enumeration is complete
cdc_acm_capability_t acm_capability;

tuh_xfer_cb_t user_control_cb;
#if CFG_TUH_CDC_CP210X || CFG_TUH_CDC_CH34X
tuh_xfer_cb_t requested_complete_cb;
#endif

TU_ATTR_ALIGNED(4) cdc_line_coding_t line_coding; // Baudrate, stop bits, parity, data width
TU_ATTR_ALIGNED(4) cdc_line_coding_t requested_line_coding;

uint8_t line_state; // DTR (bit0), RTS (bit1)
uint8_t requested_line_state;

tuh_xfer_cb_t user_control_cb;

struct {
tu_edpt_stream_t tx;
tu_edpt_stream_t rx;
Expand Down Expand Up @@ -1342,12 +1345,33 @@ 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_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);

return ch34x_write_reg(p_cdc, CH32X_REG16_LCR2_LCR, lcr, complete_cb, user_data);
}

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));
return true;

return ch34x_write_reg(p_cdc, CH34X_REG16_DIVISOR_PRESCALER, div_ps, complete_cb, user_data);
}

static bool ch34x_modem_ctrl_request(cdch_interface_t * p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data) {
uint8_t control = 0;
if (p_cdc->requested_line_state & CDC_CONTROL_LINE_STATE_RTS) {
control |= CH34X_BIT_RTS;
}
if (p_cdc->requested_line_state & CDC_CONTROL_LINE_STATE_DTR) {
control |= CH34X_BIT_DTR;
}

// CH34x signals are inverted
control = ~control;

return ch34x_control_out(p_cdc, CH34X_REQ_MODEM_CTRL, control, 0, complete_cb, user_data);
}

//------------- Driver API -------------//
Expand Down Expand Up @@ -1396,10 +1420,7 @@ static void ch34x_internal_control_complete(tuh_xfer_t * xfer) {
}

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));
TU_ASSERT(ch34x_write_reg_data_format(p_cdc, complete_cb ? ch34x_internal_control_complete : NULL, user_data));

return true;
}
Expand All @@ -1418,9 +1439,9 @@ static void ch34x_set_line_coding_stage1_complete(tuh_xfer_t* xfer) {
TU_ASSERT(p_cdc, );

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, ch34x_internal_control_complete, xfer->user_data), );
// stage 1 success, continue with stage 2
p_cdc->user_control_cb = p_cdc->requested_complete_cb;
ch34x_set_data_format(p_cdc, p_cdc->user_control_cb, xfer->user_data);
} else {
// stage 1 failed, notify user
xfer->complete_cb = p_cdc->user_control_cb;
Expand All @@ -1434,43 +1455,41 @@ static void ch34x_set_line_coding_stage1_complete(tuh_xfer_t* xfer) {
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
TU_ASSERT(ch34x_write_reg_baudrate(p_cdc, ch34x_set_line_coding_stage1_complete, user_data));
p_cdc->requested_complete_cb = complete_cb;
return ch34x_set_baudrate(p_cdc, ch34x_set_line_coding_stage1_complete, user_data);
} else {
// sync call
xfer_result_t result;

// blocking sequence
// stage 1 set baudrate
TU_ASSERT(ch34x_write_reg_baudrate(p_cdc, NULL, (uintptr_t) &result));
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
TU_ASSERT(ch34x_set_data_format(p_cdc, NULL, (uintptr_t) &result));
TU_VERIFY(result == XFER_RESULT_SUCCESS);
result = XFER_RESULT_INVALID;
ret = ch34x_write_reg_data_format(p_cdc, NULL, (uintptr_t) &result);

// update transfer result, user_data is expected to point to xfer_result_t
// 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 true;
}

static bool ch34x_set_modem_ctrl(cdch_interface_t* p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data) {
uint8_t control = 0;
if (p_cdc->requested_line_state & CDC_CONTROL_LINE_STATE_RTS) {
control |= CH34X_BIT_RTS;
}
if (p_cdc->requested_line_state & CDC_CONTROL_LINE_STATE_DTR) {
control |= CH34X_BIT_DTR;
}

// CH34x signals are inverted
control = ~control;
TU_ASSERT (ch34x_modem_ctrl_request(p_cdc, complete_cb ? ch34x_internal_control_complete : NULL, user_data));

TU_ASSERT (ch34x_control_out(p_cdc, CH34X_REQ_MODEM_CTRL, control, 0,
complete_cb ? ch34x_internal_control_complete : NULL, user_data));
return true;
}

Expand Down Expand Up @@ -1558,7 +1577,7 @@ static void ch34x_process_config(tuh_xfer_t* xfer) {
case CONFIG_CH34X_MODEM_CONTROL:
// !always! set modem controls RTS/DTR (CH34x has no reset state after CH34X_REQ_SERIAL_INIT)
p_cdc->requested_line_state = CFG_TUH_CDC_LINE_CONTROL_ON_ENUM;
TU_ASSERT_COMPLETE(ch34x_set_modem_ctrl(p_cdc, ch34x_process_config, CONFIG_CH34X_COMPLETE));
TU_ASSERT_COMPLETE(ch34x_modem_ctrl_request(p_cdc, ch34x_process_config, CONFIG_CH34X_COMPLETE));
break;

case CONFIG_CH34X_COMPLETE:
Expand Down

0 comments on commit b0d1da4

Please sign in to comment.