update acm and pl2303 to match the rest of drivers
This commit is contained in:
@@ -117,8 +117,6 @@ static bool acm_open(uint8_t daddr, tusb_desc_interface_t const * itf_desc, uint
|
|||||||
static bool acm_process_set_config(cdch_interface_t *p_cdc, tuh_xfer_t *xfer);
|
static bool acm_process_set_config(cdch_interface_t *p_cdc, tuh_xfer_t *xfer);
|
||||||
static void acm_internal_control_complete(cdch_interface_t *p_cdc, tuh_xfer_t *xfer);
|
static void acm_internal_control_complete(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_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_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, tuh_xfer_cb_t complete_cb, uintptr_t user_data);
|
static bool acm_set_control_line_state(cdch_interface_t * p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data);
|
||||||
|
|
||||||
@@ -169,8 +167,6 @@ static bool pl2303_open(uint8_t daddr, tusb_desc_interface_t const * itf_desc, u
|
|||||||
static bool pl2303_process_set_config(cdch_interface_t *p_cdc, 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(cdch_interface_t *p_cdc, tuh_xfer_t *xfer);
|
static void pl2303_internal_control_complete(cdch_interface_t *p_cdc, 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_data_format(cdch_interface_t * p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data);
|
|
||||||
static bool pl2303_set_line_coding(cdch_interface_t * p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data);
|
static bool pl2303_set_line_coding(cdch_interface_t * p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data);
|
||||||
static bool pl2303_set_modem_ctrl(cdch_interface_t * p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data);
|
static bool pl2303_set_modem_ctrl(cdch_interface_t * p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data);
|
||||||
#endif
|
#endif
|
||||||
@@ -228,10 +224,9 @@ static const cdch_serial_driver_t serial_drivers[] = {
|
|||||||
.open = acm_open,
|
.open = acm_open,
|
||||||
.process_set_config = acm_process_set_config,
|
.process_set_config = acm_process_set_config,
|
||||||
.request_complete = acm_internal_control_complete,
|
.request_complete = acm_internal_control_complete,
|
||||||
|
|
||||||
.set_control_line_state = acm_set_control_line_state,
|
.set_control_line_state = acm_set_control_line_state,
|
||||||
.set_baudrate = acm_set_baudrate,
|
.set_baudrate = acm_set_line_coding,
|
||||||
.set_data_format = acm_set_data_format,
|
.set_data_format = acm_set_line_coding,
|
||||||
.set_line_coding = acm_set_line_coding,
|
.set_line_coding = acm_set_line_coding,
|
||||||
DRIVER_NAME_DECLARE("ACM")
|
DRIVER_NAME_DECLARE("ACM")
|
||||||
},
|
},
|
||||||
@@ -290,8 +285,8 @@ static const cdch_serial_driver_t serial_drivers[] = {
|
|||||||
.process_set_config = pl2303_process_set_config,
|
.process_set_config = pl2303_process_set_config,
|
||||||
.request_complete = pl2303_internal_control_complete,
|
.request_complete = pl2303_internal_control_complete,
|
||||||
.set_control_line_state = pl2303_set_modem_ctrl,
|
.set_control_line_state = pl2303_set_modem_ctrl,
|
||||||
.set_baudrate = pl2303_set_baudrate,
|
.set_baudrate = pl2303_set_line_coding,
|
||||||
.set_data_format = pl2303_set_data_format,
|
.set_data_format = pl2303_set_line_coding,
|
||||||
.set_line_coding = pl2303_set_line_coding,
|
.set_line_coding = pl2303_set_line_coding,
|
||||||
DRIVER_NAME_DECLARE("PL2303")
|
DRIVER_NAME_DECLARE("PL2303")
|
||||||
}
|
}
|
||||||
@@ -586,10 +581,11 @@ bool tuh_cdc_set_line_coding(uint8_t idx, cdc_line_coding_t const *line_coding,
|
|||||||
CDC_LINE_CODING_STOP_BITS_TEXT(line_coding->stop_bits));
|
CDC_LINE_CODING_STOP_BITS_TEXT(line_coding->stop_bits));
|
||||||
cdch_serial_driver_t const *driver = &serial_drivers[p_cdc->serial_drid];
|
cdch_serial_driver_t const *driver = &serial_drivers[p_cdc->serial_drid];
|
||||||
p_cdc->requested_line.coding = *line_coding;
|
p_cdc->requested_line.coding = *line_coding;
|
||||||
|
p_cdc->user_complete_cb = complete_cb;
|
||||||
|
|
||||||
if (driver->set_line_coding) {
|
if (driver->set_line_coding) {
|
||||||
// driver support set_line_coding request
|
// driver support set_line_coding request
|
||||||
TU_VERIFY(driver->set_line_coding(p_cdc, complete_cb, user_data));
|
TU_VERIFY(driver->set_line_coding(p_cdc, complete_cb ? cdch_internal_control_complete : NULL, user_data));
|
||||||
|
|
||||||
if (!complete_cb) {
|
if (!complete_cb) {
|
||||||
p_cdc->line.coding = *line_coding;
|
p_cdc->line.coding = *line_coding;
|
||||||
@@ -598,7 +594,6 @@ bool tuh_cdc_set_line_coding(uint8_t idx, cdc_line_coding_t const *line_coding,
|
|||||||
// driver does not support set_line_coding and need 2 stage to set baudrate and data format separately
|
// driver does not support set_line_coding and need 2 stage to set baudrate and data format separately
|
||||||
if (complete_cb) {
|
if (complete_cb) {
|
||||||
// non-blocking
|
// non-blocking
|
||||||
p_cdc->user_complete_cb = complete_cb;
|
|
||||||
TU_VERIFY(driver->set_baudrate(p_cdc, cdch_set_line_coding_stage1_baudrate_complete, user_data));
|
TU_VERIFY(driver->set_baudrate(p_cdc, cdch_set_line_coding_stage1_baudrate_complete, user_data));
|
||||||
} else {
|
} else {
|
||||||
// blocking
|
// blocking
|
||||||
@@ -795,7 +790,7 @@ bool cdch_set_config(uint8_t daddr, uint8_t itf_num) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_config_complete(cdch_interface_t *p_cdc, uint8_t itf_offset, bool success) {
|
static void set_config_complete(cdch_interface_t *p_cdc, bool success) {
|
||||||
if (success) {
|
if (success) {
|
||||||
const uint8_t idx = get_idx_by_ptr(p_cdc);
|
const uint8_t idx = get_idx_by_ptr(p_cdc);
|
||||||
p_cdc->mounted = true;
|
p_cdc->mounted = true;
|
||||||
@@ -811,6 +806,7 @@ static void set_config_complete(cdch_interface_t *p_cdc, uint8_t itf_offset, boo
|
|||||||
}
|
}
|
||||||
|
|
||||||
// notify usbh that driver enumeration is complete
|
// notify usbh that driver enumeration is complete
|
||||||
|
const uint8_t itf_offset = (p_cdc->serial_drid == SERIAL_DRIVER_ACM) ? 1 : 0;
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -821,8 +817,7 @@ static void cdch_process_set_config(tuh_xfer_t *xfer) {
|
|||||||
const cdch_serial_driver_t *driver = &serial_drivers[p_cdc->serial_drid];
|
const cdch_serial_driver_t *driver = &serial_drivers[p_cdc->serial_drid];
|
||||||
|
|
||||||
if (!driver->process_set_config(p_cdc, xfer)) {
|
if (!driver->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, false);
|
||||||
set_config_complete(p_cdc, itf_offset, false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -858,11 +853,9 @@ static bool set_line_state_on_enum(cdch_interface_t *p_cdc, tuh_xfer_t *xfer) {
|
|||||||
TU_ATTR_FALLTHROUGH;
|
TU_ATTR_FALLTHROUGH;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
case ENUM_SET_LINE_COMPLETE: {
|
case ENUM_SET_LINE_COMPLETE:
|
||||||
const uint8_t itf_offset = (p_cdc->serial_drid == SERIAL_DRIVER_ACM) ? 1 : 0;
|
set_config_complete(p_cdc, true);
|
||||||
set_config_complete(p_cdc, itf_offset, true);
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
@@ -874,11 +867,8 @@ static bool set_line_state_on_enum(cdch_interface_t *p_cdc, tuh_xfer_t *xfer) {
|
|||||||
static void cdch_process_line_state_on_enum(tuh_xfer_t *xfer) {
|
static void cdch_process_line_state_on_enum(tuh_xfer_t *xfer) {
|
||||||
cdch_interface_t *p_cdc = get_itf_by_xfer(xfer);
|
cdch_interface_t *p_cdc = get_itf_by_xfer(xfer);
|
||||||
TU_ASSERT(p_cdc && p_cdc->serial_drid < SERIAL_DRIVER_COUNT,);
|
TU_ASSERT(p_cdc && p_cdc->serial_drid < SERIAL_DRIVER_COUNT,);
|
||||||
TU_LOG_DRV(" xfer result = %u\r\n", xfer->result);
|
|
||||||
|
|
||||||
if (xfer->result != XFER_RESULT_SUCCESS || !set_line_state_on_enum(p_cdc, xfer)) {
|
if (xfer->result != XFER_RESULT_SUCCESS || !set_line_state_on_enum(p_cdc, xfer)) {
|
||||||
const uint8_t itf_offset = (p_cdc->serial_drid == SERIAL_DRIVER_ACM) ? 1 : 0;
|
set_config_complete(p_cdc, false);
|
||||||
set_config_complete(p_cdc, itf_offset, false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -967,20 +957,16 @@ static bool acm_set_control_line_state(cdch_interface_t *p_cdc, tuh_xfer_cb_t co
|
|||||||
.wLength = 0
|
.wLength = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
p_cdc->user_complete_cb = complete_cb;
|
|
||||||
|
|
||||||
tuh_xfer_t xfer = {
|
tuh_xfer_t xfer = {
|
||||||
.daddr = p_cdc->daddr,
|
.daddr = p_cdc->daddr,
|
||||||
.ep_addr = 0,
|
.ep_addr = 0,
|
||||||
.setup = &request,
|
.setup = &request,
|
||||||
.buffer = NULL,
|
.buffer = NULL,
|
||||||
.complete_cb = complete_cb ? cdch_internal_control_complete : NULL,
|
.complete_cb = complete_cb,
|
||||||
.user_data = user_data
|
.user_data = user_data
|
||||||
};
|
};
|
||||||
|
|
||||||
TU_ASSERT(tuh_control_xfer(&xfer));
|
return tuh_control_xfer(&xfer);
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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_line_coding(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data) {
|
||||||
@@ -1004,35 +990,21 @@ static bool acm_set_line_coding(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_
|
|||||||
uint8_t *enum_buf = usbh_get_enum_buf();
|
uint8_t *enum_buf = usbh_get_enum_buf();
|
||||||
memcpy(enum_buf, &p_cdc->requested_line.coding, sizeof(cdc_line_coding_t));
|
memcpy(enum_buf, &p_cdc->requested_line.coding, sizeof(cdc_line_coding_t));
|
||||||
|
|
||||||
p_cdc->user_complete_cb = complete_cb;
|
|
||||||
|
|
||||||
tuh_xfer_t xfer = {
|
tuh_xfer_t xfer = {
|
||||||
.daddr = p_cdc->daddr,
|
.daddr = p_cdc->daddr,
|
||||||
.ep_addr = 0,
|
.ep_addr = 0,
|
||||||
.setup = &request,
|
.setup = &request,
|
||||||
.buffer = enum_buf,
|
.buffer = enum_buf,
|
||||||
.complete_cb = complete_cb ? cdch_internal_control_complete : NULL,
|
.complete_cb = complete_cb,
|
||||||
.user_data = user_data
|
.user_data = user_data
|
||||||
};
|
};
|
||||||
|
|
||||||
TU_ASSERT(tuh_control_xfer(&xfer));
|
return tuh_control_xfer(&xfer);
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool acm_set_data_format(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data) {
|
|
||||||
return acm_set_line_coding(p_cdc, complete_cb, user_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool acm_set_baudrate(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data) {
|
|
||||||
return acm_set_line_coding(p_cdc, complete_cb, user_data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------- Enumeration -------------//
|
//------------- Enumeration -------------//
|
||||||
enum {
|
enum {
|
||||||
CONFIG_ACM_SET_CONTROL_LINE_STATE = 0,
|
CONFIG_ACM_COMPLETE = 0
|
||||||
CONFIG_ACM_SET_LINE_CODING,
|
|
||||||
CONFIG_ACM_COMPLETE
|
|
||||||
};
|
};
|
||||||
|
|
||||||
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) {
|
||||||
@@ -1084,30 +1056,11 @@ static bool acm_process_set_config(cdch_interface_t *p_cdc, tuh_xfer_t *xfer) {
|
|||||||
TU_ASSERT(xfer->result == XFER_RESULT_SUCCESS);
|
TU_ASSERT(xfer->result == XFER_RESULT_SUCCESS);
|
||||||
const uintptr_t state = xfer->user_data;
|
const uintptr_t state = xfer->user_data;
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case CONFIG_ACM_SET_CONTROL_LINE_STATE:
|
case CONFIG_ACM_COMPLETE: {
|
||||||
#ifdef CFG_TUH_CDC_LINE_CONTROL_ON_ENUM
|
xfer->user_data = 0; // kick-off set line state on enum
|
||||||
if (p_cdc->acm.capability.support_line_request) {
|
cdch_process_line_state_on_enum(xfer);
|
||||||
p_cdc->requested_line.control_state.value = CFG_TUH_CDC_LINE_CONTROL_ON_ENUM;
|
|
||||||
TU_ASSERT(acm_set_control_line_state(p_cdc, cdch_process_set_config, CONFIG_ACM_SET_LINE_CODING));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
TU_ATTR_FALLTHROUGH;
|
|
||||||
|
|
||||||
case CONFIG_ACM_SET_LINE_CODING:
|
|
||||||
#ifdef CFG_TUH_CDC_LINE_CODING_ON_ENUM
|
|
||||||
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, cdch_process_set_config, CONFIG_ACM_COMPLETE));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
TU_ATTR_FALLTHROUGH;
|
|
||||||
|
|
||||||
case CONFIG_ACM_COMPLETE:
|
|
||||||
// itf_num+1 to account for data interface as well
|
|
||||||
set_config_complete(p_cdc, 1, true);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return false; // invalid state
|
return false; // invalid state
|
||||||
@@ -2023,18 +1976,40 @@ static inline bool pl2303_supports_hx_status(cdch_interface_t *p_cdc, tuh_xfer_c
|
|||||||
&buf, 1, complete_cb, user_data);
|
&buf, 1, complete_cb, user_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool pl2303_set_control_lines(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data) {
|
//static bool pl2303_get_line_request(cdch_interface_t * p_cdc, uint8_t buf[PL2303_LINE_CODING_BUFSIZE]) {
|
||||||
// PL2303 has the same bit coding
|
|
||||||
return pl2303_set_request(p_cdc, PL2303_SET_CONTROL_REQUEST, PL2303_SET_CONTROL_REQUEST_TYPE,
|
|
||||||
p_cdc->requested_line.control_state.value, 0, NULL, 0, complete_cb, user_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
//static bool pl2303_get_line_request(cdch_interface_t * p_cdc, uint8_t buf[PL2303_LINE_CODING_BUFSIZE])
|
|
||||||
//{
|
|
||||||
// return pl2303_set_request(p_cdc, PL2303_GET_LINE_REQUEST, PL2303_GET_LINE_REQUEST_TYPE, 0, 0, buf, PL2303_LINE_CODING_BUFSIZE);
|
// return pl2303_set_request(p_cdc, PL2303_GET_LINE_REQUEST, PL2303_GET_LINE_REQUEST_TYPE, 0, 0, buf, PL2303_LINE_CODING_BUFSIZE);
|
||||||
//}
|
//}
|
||||||
|
|
||||||
static bool pl2303_set_line_request(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data) {
|
//static bool pl2303_set_break(cdch_interface_t * p_cdc, bool enable) {
|
||||||
|
// uint16_t state = enable ? PL2303_BREAK_ON : PL2303_BREAK_OFF;
|
||||||
|
// return pl2303_set_request(p_cdc, PL2303_BREAK_REQUEST, PL2303_BREAK_REQUEST_TYPE, state, 0, NULL, 0);
|
||||||
|
//}
|
||||||
|
|
||||||
|
static inline int pl2303_clear_halt(cdch_interface_t *p_cdc, uint8_t endp, tuh_xfer_cb_t complete_cb, uintptr_t user_data) {
|
||||||
|
/* we don't care if it wasn't halted first. in fact some devices
|
||||||
|
* (like some ibmcam model 1 units) seem to expect hosts to make
|
||||||
|
* this request for iso endpoints, which can't halt!
|
||||||
|
*/
|
||||||
|
return pl2303_set_request(p_cdc, TUSB_REQ_CLEAR_FEATURE, PL2303_CLEAR_HALT_REQUEST_TYPE, TUSB_REQ_FEATURE_EDPT_HALT, endp,
|
||||||
|
NULL, 0, complete_cb, user_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------- Driver API -------------//
|
||||||
|
|
||||||
|
// internal control complete to update state such as line state, encoding
|
||||||
|
static void pl2303_internal_control_complete(cdch_interface_t *p_cdc, tuh_xfer_t *xfer) {
|
||||||
|
TU_VERIFY(xfer->result == XFER_RESULT_SUCCESS,);
|
||||||
|
if (xfer->setup->bRequest == PL2303_SET_LINE_REQUEST &&
|
||||||
|
xfer->setup->bmRequestType == PL2303_SET_LINE_REQUEST_TYPE) {
|
||||||
|
p_cdc->line.coding = p_cdc->requested_line.coding;
|
||||||
|
}
|
||||||
|
if (xfer->setup->bRequest == PL2303_SET_CONTROL_REQUEST &&
|
||||||
|
xfer->setup->bmRequestType == PL2303_SET_CONTROL_REQUEST_TYPE) {
|
||||||
|
p_cdc->line.control_state = p_cdc->requested_line.control_state;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool pl2303_set_line_coding(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data) {
|
||||||
// the caller has to precheck, that the new line coding different than the current, else false returned
|
// the caller has to precheck, that the new line coding different than the current, else false returned
|
||||||
uint8_t buf[PL2303_LINE_CODING_BUFSIZE];
|
uint8_t buf[PL2303_LINE_CODING_BUFSIZE];
|
||||||
/*
|
/*
|
||||||
@@ -2070,63 +2045,10 @@ static bool pl2303_set_line_request(cdch_interface_t *p_cdc, tuh_xfer_cb_t compl
|
|||||||
buf, PL2303_LINE_CODING_BUFSIZE, complete_cb, user_data);
|
buf, PL2303_LINE_CODING_BUFSIZE, complete_cb, user_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
//static bool pl2303_set_break(cdch_interface_t * p_cdc, bool enable)
|
|
||||||
//{
|
|
||||||
// uint16_t state = enable ? PL2303_BREAK_ON : PL2303_BREAK_OFF;
|
|
||||||
// return pl2303_set_request(p_cdc, PL2303_BREAK_REQUEST, PL2303_BREAK_REQUEST_TYPE, state, 0, NULL, 0);
|
|
||||||
//}
|
|
||||||
|
|
||||||
static inline int pl2303_clear_halt(cdch_interface_t *p_cdc, uint8_t endp, tuh_xfer_cb_t complete_cb, uintptr_t user_data) {
|
|
||||||
/* we don't care if it wasn't halted first. in fact some devices
|
|
||||||
* (like some ibmcam model 1 units) seem to expect hosts to make
|
|
||||||
* this request for iso endpoints, which can't halt!
|
|
||||||
*/
|
|
||||||
return pl2303_set_request(p_cdc, TUSB_REQ_CLEAR_FEATURE, PL2303_CLEAR_HALT_REQUEST_TYPE, TUSB_REQ_FEATURE_EDPT_HALT, endp,
|
|
||||||
NULL, 0, complete_cb, user_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------- Driver API -------------//
|
|
||||||
|
|
||||||
// internal control complete to update state such as line state, encoding
|
|
||||||
static void pl2303_internal_control_complete(cdch_interface_t *p_cdc, tuh_xfer_t *xfer) {
|
|
||||||
TU_VERIFY(xfer->result == XFER_RESULT_SUCCESS,);
|
|
||||||
if (xfer->setup->bRequest == PL2303_SET_LINE_REQUEST &&
|
|
||||||
xfer->setup->bmRequestType == PL2303_SET_LINE_REQUEST_TYPE) {
|
|
||||||
p_cdc->line.coding = p_cdc->requested_line.coding;
|
|
||||||
}
|
|
||||||
if (xfer->setup->bRequest == PL2303_SET_CONTROL_REQUEST &&
|
|
||||||
xfer->setup->bmRequestType == PL2303_SET_CONTROL_REQUEST_TYPE) {
|
|
||||||
p_cdc->line.control_state = p_cdc->requested_line.control_state;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool pl2303_set_line_coding(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data) {
|
|
||||||
p_cdc->user_complete_cb = complete_cb;
|
|
||||||
TU_ASSERT(pl2303_set_line_request(p_cdc, complete_cb ? cdch_internal_control_complete : NULL, user_data));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool pl2303_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;
|
|
||||||
p_cdc->user_complete_cb = complete_cb;
|
|
||||||
TU_ASSERT(pl2303_set_line_request(p_cdc, complete_cb ? cdch_internal_control_complete : NULL, user_data));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool pl2303_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;
|
|
||||||
p_cdc->user_complete_cb = complete_cb;
|
|
||||||
TU_ASSERT(pl2303_set_line_request(p_cdc, complete_cb ? cdch_internal_control_complete : NULL, user_data));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool pl2303_set_modem_ctrl(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data) {
|
static bool pl2303_set_modem_ctrl(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data) {
|
||||||
// PL2303 has the same bit coding
|
// PL2303 has the same bit coding
|
||||||
p_cdc->user_complete_cb = complete_cb;
|
return pl2303_set_request(p_cdc, PL2303_SET_CONTROL_REQUEST, PL2303_SET_CONTROL_REQUEST_TYPE,
|
||||||
TU_ASSERT(pl2303_set_control_lines(p_cdc, complete_cb ? cdch_internal_control_complete : NULL, user_data));
|
p_cdc->requested_line.control_state.value, 0, NULL, 0, complete_cb, user_data);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------- Enumeration -------------//
|
//------------- Enumeration -------------//
|
||||||
@@ -2146,8 +2068,6 @@ enum {
|
|||||||
CONFIG_PL2303_WRITE5,
|
CONFIG_PL2303_WRITE5,
|
||||||
CONFIG_PL2303_RESET_ENDP1,
|
CONFIG_PL2303_RESET_ENDP1,
|
||||||
CONFIG_PL2303_RESET_ENDP2,
|
CONFIG_PL2303_RESET_ENDP2,
|
||||||
CONFIG_PL2303_LINE_CODING,
|
|
||||||
CONFIG_PL2303_MODEM_CONTROL,
|
|
||||||
// CONFIG_PL2303_FLOW_CTRL_READ,
|
// CONFIG_PL2303_FLOW_CTRL_READ,
|
||||||
// CONFIG_PL2303_FLOW_CTRL_WRITE,
|
// CONFIG_PL2303_FLOW_CTRL_WRITE,
|
||||||
CONFIG_PL2303_COMPLETE
|
CONFIG_PL2303_COMPLETE
|
||||||
@@ -2190,7 +2110,6 @@ static bool pl2303_process_set_config(cdch_interface_t *p_cdc, tuh_xfer_t *xfer)
|
|||||||
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:
|
||||||
p_cdc->user_complete_cb = cdch_process_set_config;// set once for whole process config
|
|
||||||
// get type and quirks (step 1)
|
// get type and quirks (step 1)
|
||||||
type = pl2303_detect_type(p_cdc, 1);
|
type = pl2303_detect_type(p_cdc, 1);
|
||||||
TU_ASSERT(type != PL2303_TYPE_UNKNOWN);
|
TU_ASSERT(type != PL2303_TYPE_UNKNOWN);
|
||||||
@@ -2313,7 +2232,7 @@ static bool pl2303_process_set_config(cdch_interface_t *p_cdc, tuh_xfer_t *xfer)
|
|||||||
if (p_cdc->pl2303.type == PL2303_TYPE_HXN) {
|
if (p_cdc->pl2303.type == PL2303_TYPE_HXN) {
|
||||||
TU_ASSERT(pl2303_vendor_write(p_cdc, PL2303_HXN_RESET_REG,// skip CONFIG_PL2303_RESET_ENDP2, no 2nd step
|
TU_ASSERT(pl2303_vendor_write(p_cdc, PL2303_HXN_RESET_REG,// skip CONFIG_PL2303_RESET_ENDP2, no 2nd step
|
||||||
PL2303_HXN_RESET_UPSTREAM_PIPE | PL2303_HXN_RESET_DOWNSTREAM_PIPE,
|
PL2303_HXN_RESET_UPSTREAM_PIPE | PL2303_HXN_RESET_DOWNSTREAM_PIPE,
|
||||||
cdch_process_set_config, CONFIG_PL2303_LINE_CODING));
|
cdch_process_set_config, CONFIG_PL2303_COMPLETE));
|
||||||
} else {
|
} else {
|
||||||
pl2303_vendor_write(p_cdc, 8, 0, cdch_process_set_config, CONFIG_PL2303_RESET_ENDP2);
|
pl2303_vendor_write(p_cdc, 8, 0, cdch_process_set_config, CONFIG_PL2303_RESET_ENDP2);
|
||||||
}
|
}
|
||||||
@@ -2323,37 +2242,17 @@ static bool pl2303_process_set_config(cdch_interface_t *p_cdc, tuh_xfer_t *xfer)
|
|||||||
case CONFIG_PL2303_RESET_ENDP2:
|
case CONFIG_PL2303_RESET_ENDP2:
|
||||||
// step 2
|
// step 2
|
||||||
if (p_cdc->pl2303.quirks & PL2303_QUIRK_LEGACY) {
|
if (p_cdc->pl2303.quirks & PL2303_QUIRK_LEGACY) {
|
||||||
TU_ASSERT(pl2303_clear_halt(p_cdc, PL2303_IN_EP, cdch_process_set_config, CONFIG_PL2303_LINE_CODING));
|
TU_ASSERT(pl2303_clear_halt(p_cdc, PL2303_IN_EP, cdch_process_set_config, CONFIG_PL2303_COMPLETE));
|
||||||
} else {
|
} else {
|
||||||
/* reset upstream data pipes */
|
/* reset upstream data pipes */
|
||||||
if (p_cdc->pl2303.type == PL2303_TYPE_HXN) {
|
if (p_cdc->pl2303.type == PL2303_TYPE_HXN) {
|
||||||
// here nothing to do, only structure of previous step overtaken for better reading and comparison
|
// here nothing to do, only structure of previous step overtaken for better reading and comparison
|
||||||
} else {
|
} else {
|
||||||
TU_ASSERT(pl2303_vendor_write(p_cdc, 9, 0, cdch_process_set_config, CONFIG_PL2303_LINE_CODING));
|
TU_ASSERT(pl2303_vendor_write(p_cdc, 9, 0, cdch_process_set_config, CONFIG_PL2303_COMPLETE));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// from here sequence overtaken from Linux Kernel function pl2303_set_termios()
|
|
||||||
// unnecessary pl2303_get_line_request() is skipped due to a stall
|
|
||||||
case CONFIG_PL2303_LINE_CODING:
|
|
||||||
#ifdef CFG_TUH_CDC_LINE_CODING_ON_ENUM
|
|
||||||
p_cdc->requested_line.coding = (cdc_line_coding_t) CFG_TUH_CDC_LINE_CODING_ON_ENUM;
|
|
||||||
TU_ASSERT(pl2303_set_line_request(p_cdc, cdch_internal_control_complete, CONFIG_PL2303_MODEM_CONTROL));
|
|
||||||
break;
|
|
||||||
#else
|
|
||||||
TU_ATTR_FALLTHROUGH;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
case CONFIG_PL2303_MODEM_CONTROL:
|
|
||||||
#ifdef CFG_TUH_CDC_LINE_CONTROL_ON_ENUM
|
|
||||||
p_cdc->requested_line.control_state.value = CFG_TUH_CDC_LINE_CONTROL_ON_ENUM;
|
|
||||||
TU_ASSERT(pl2303_set_control_lines(p_cdc, cdch_internal_control_complete, CONFIG_PL2303_COMPLETE));
|
|
||||||
break;
|
|
||||||
#else
|
|
||||||
TU_ATTR_FALLTHROUGH;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// skipped, because it's not working with each PL230x. flow control can be also set by PL2303 EEPROM Writer Program
|
// skipped, because it's not working with each PL230x. flow control can be also set by PL2303 EEPROM Writer Program
|
||||||
// case CONFIG_PL2303_FLOW_CTRL_READ:
|
// case CONFIG_PL2303_FLOW_CTRL_READ:
|
||||||
// // read flow control register for modify & write back in next step
|
// // read flow control register for modify & write back in next step
|
||||||
@@ -2383,7 +2282,8 @@ static bool pl2303_process_set_config(cdch_interface_t *p_cdc, tuh_xfer_t *xfer)
|
|||||||
// break;
|
// break;
|
||||||
|
|
||||||
case CONFIG_PL2303_COMPLETE:
|
case CONFIG_PL2303_COMPLETE:
|
||||||
set_config_complete(p_cdc, 0, true);
|
xfer->user_data = 0; // kick-off set line state on enum
|
||||||
|
cdch_process_line_state_on_enum(xfer);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
Reference in New Issue
Block a user