mirror of
https://github.com/hathach/tinyusb.git
synced 2025-02-14 09:39:50 +00:00
- add ch34x_set_data_format()
- add ch34x_set_line_coding()
This commit is contained in:
parent
23c2d929a1
commit
98781bb903
@ -27,20 +27,11 @@
|
||||
#include "tusb.h"
|
||||
#include "bsp/board_api.h"
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// MACRO TYPEDEF CONSTANT ENUM DECLARATION
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
|
||||
//------------- IMPLEMENTATION -------------//
|
||||
|
||||
size_t get_console_inputs(uint8_t* buf, size_t bufsize)
|
||||
{
|
||||
size_t get_console_inputs(uint8_t* buf, size_t bufsize) {
|
||||
size_t count = 0;
|
||||
while (count < bufsize)
|
||||
{
|
||||
while (count < bufsize) {
|
||||
int ch = board_getchar();
|
||||
if ( ch <= 0 ) break;
|
||||
if (ch <= 0) break;
|
||||
|
||||
buf[count] = (uint8_t) ch;
|
||||
count++;
|
||||
@ -49,22 +40,18 @@ size_t get_console_inputs(uint8_t* buf, size_t bufsize)
|
||||
return count;
|
||||
}
|
||||
|
||||
void cdc_app_task(void)
|
||||
{
|
||||
uint8_t buf[64+1]; // +1 for extra null character
|
||||
uint32_t const bufsize = sizeof(buf)-1;
|
||||
void cdc_app_task(void) {
|
||||
uint8_t buf[64 + 1]; // +1 for extra null character
|
||||
uint32_t const bufsize = sizeof(buf) - 1;
|
||||
|
||||
uint32_t count = get_console_inputs(buf, bufsize);
|
||||
buf[count] = 0;
|
||||
|
||||
// loop over all mounted interfaces
|
||||
for(uint8_t idx=0; idx<CFG_TUH_CDC; idx++)
|
||||
{
|
||||
if ( tuh_cdc_mounted(idx) )
|
||||
{
|
||||
for (uint8_t idx = 0; idx < CFG_TUH_CDC; idx++) {
|
||||
if (tuh_cdc_mounted(idx)) {
|
||||
// console --> cdc interfaces
|
||||
if (count)
|
||||
{
|
||||
if (count) {
|
||||
tuh_cdc_write(idx, buf, count);
|
||||
tuh_cdc_write_flush(idx);
|
||||
}
|
||||
@ -72,11 +59,14 @@ void cdc_app_task(void)
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// TinyUSB callbacks
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
// Invoked when received new data
|
||||
void tuh_cdc_rx_cb(uint8_t idx)
|
||||
{
|
||||
uint8_t buf[64+1]; // +1 for extra null character
|
||||
uint32_t const bufsize = sizeof(buf)-1;
|
||||
void tuh_cdc_rx_cb(uint8_t idx) {
|
||||
uint8_t buf[64 + 1]; // +1 for extra null character
|
||||
uint32_t const bufsize = sizeof(buf) - 1;
|
||||
|
||||
// forward cdc interfaces -> console
|
||||
uint32_t count = tuh_cdc_read(idx, buf, bufsize);
|
||||
@ -85,29 +75,31 @@ void tuh_cdc_rx_cb(uint8_t idx)
|
||||
printf((char*) buf);
|
||||
}
|
||||
|
||||
void tuh_cdc_mount_cb(uint8_t idx)
|
||||
{
|
||||
tuh_itf_info_t itf_info = { 0 };
|
||||
// Invoked when a device with CDC interface is mounted
|
||||
// idx is index of cdc interface in the internal pool.
|
||||
void tuh_cdc_mount_cb(uint8_t idx) {
|
||||
tuh_itf_info_t itf_info = {0};
|
||||
tuh_cdc_itf_get_info(idx, &itf_info);
|
||||
|
||||
printf("CDC Interface is mounted: address = %u, itf_num = %u\r\n", itf_info.daddr, itf_info.desc.bInterfaceNumber);
|
||||
printf("CDC Interface is mounted: address = %u, itf_num = %u\r\n", itf_info.daddr,
|
||||
itf_info.desc.bInterfaceNumber);
|
||||
|
||||
#ifdef CFG_TUH_CDC_LINE_CODING_ON_ENUM
|
||||
// CFG_TUH_CDC_LINE_CODING_ON_ENUM must be defined for line coding is set by tinyusb in enumeration
|
||||
// otherwise you need to call tuh_cdc_set_line_coding() first
|
||||
cdc_line_coding_t line_coding = { 0 };
|
||||
if ( tuh_cdc_get_local_line_coding(idx, &line_coding) )
|
||||
{
|
||||
cdc_line_coding_t line_coding = {0};
|
||||
if (tuh_cdc_get_local_line_coding(idx, &line_coding)) {
|
||||
printf(" Baudrate: %lu, Stop Bits : %u\r\n", line_coding.bit_rate, line_coding.stop_bits);
|
||||
printf(" Parity : %u, Data Width: %u\r\n", line_coding.parity , line_coding.data_bits);
|
||||
printf(" Parity : %u, Data Width: %u\r\n", line_coding.parity, line_coding.data_bits);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void tuh_cdc_umount_cb(uint8_t idx)
|
||||
{
|
||||
tuh_itf_info_t itf_info = { 0 };
|
||||
// Invoked when a device with CDC interface is unmounted
|
||||
void tuh_cdc_umount_cb(uint8_t idx) {
|
||||
tuh_itf_info_t itf_info = {0};
|
||||
tuh_cdc_itf_get_info(idx, &itf_info);
|
||||
|
||||
printf("CDC Interface is unmounted: address = %u, itf_num = %u\r\n", itf_info.daddr, itf_info.desc.bInterfaceNumber);
|
||||
printf("CDC Interface is unmounted: address = %u, itf_num = %u\r\n", itf_info.daddr,
|
||||
itf_info.desc.bInterfaceNumber);
|
||||
}
|
||||
|
@ -1327,48 +1327,88 @@ static void ch34x_control_complete(tuh_xfer_t* xfer) {
|
||||
process_internal_control_complete(p_cdc, 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) {
|
||||
// uint8_t const lcr = ch34x_get_lcr(stop_bits, parity, data_bits);
|
||||
// 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;
|
||||
//
|
||||
// TU_ASSERT (ch34x_control_out(p_cdc, CH34X_REQ_WRITE_REG, CH32X_REG16_LCR2_LCR, lcr,
|
||||
// complete_cb ? ch34x_control_complete : NULL, user_data));
|
||||
// return false;
|
||||
//}
|
||||
|
||||
static bool ch34x_set_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);
|
||||
TU_VERIFY(div_ps != 0);
|
||||
|
||||
p_cdc->requested_line_coding.bit_rate = baudrate;
|
||||
p_cdc->user_control_cb = complete_cb;
|
||||
TU_ASSERT(ch34x_write_reg(p_cdc, CH34X_REG16_DIVISOR_PRESCALER, div_ps,
|
||||
complete_cb ? ch34x_control_complete : NULL, 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) {
|
||||
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);
|
||||
TU_ASSERT (ch34x_control_out(p_cdc, CH34X_REQ_WRITE_REG, CH32X_REG16_LCR2_LCR, lcr,
|
||||
complete_cb ? ch34x_control_complete : NULL, user_data));
|
||||
return true;
|
||||
}
|
||||
|
||||
//static void ch34x_set_line_coding_stage1(tuh_xfer_t* xfer) {
|
||||
//
|
||||
//}
|
||||
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);
|
||||
TU_VERIFY(div_ps != 0);
|
||||
TU_ASSERT(ch34x_write_reg(p_cdc, CH34X_REG16_DIVISOR_PRESCALER, div_ps,
|
||||
complete_cb, 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;
|
||||
p_cdc->user_control_cb = complete_cb;
|
||||
TU_ASSERT(ch34x_write_reg_baudrate(p_cdc, baudrate,
|
||||
complete_cb ? ch34x_control_complete : NULL, user_data));
|
||||
return true;
|
||||
}
|
||||
|
||||
static void ch34x_set_line_coding_stage1_complete(tuh_xfer_t* xfer) {
|
||||
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);
|
||||
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, p_cdc->requested_line_coding.stop_bits, p_cdc->requested_line_coding.parity,
|
||||
p_cdc->requested_line_coding.data_bits, ch34x_control_complete, xfer->user_data), );
|
||||
} else {
|
||||
// stage 1 failed, notify user
|
||||
xfer->complete_cb = p_cdc->user_control_cb;
|
||||
if (xfer->complete_cb) {
|
||||
xfer->complete_cb(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->baudrate_requested = line_coding->bit_rate;
|
||||
// p_cdc->user_control_cb = complete_cb;
|
||||
// uint8_t factor, divisor, lcr;
|
||||
// TU_ASSERT (ch34x_get_factor_divisor(line_coding->bit_rate, &factor, &divisor));
|
||||
// TU_ASSERT (ch34x_get_lcr(line_coding, &lcr));
|
||||
// TU_ASSERT (ch34x_control_out(p_cdc, CH34X_REQ_SERIAL_INIT, (uint16_t) (lcr << 8 | 0x9c), (uint16_t) (factor << 8 | 0x80 | divisor),
|
||||
// complete_cb ? ch34x_control_complete : NULL, user_data));
|
||||
(void) p_cdc;
|
||||
(void) line_coding;
|
||||
(void) complete_cb;
|
||||
(void) user_data;
|
||||
p_cdc->requested_line_coding = *line_coding;
|
||||
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));
|
||||
} 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_VERIFY(result == XFER_RESULT_SUCCESS);
|
||||
p_cdc->line_coding.bit_rate = 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_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) {
|
||||
user_data = result;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -63,7 +63,8 @@
|
||||
#define CH341_REG_0x2C 0x2C // undocumented register
|
||||
#define CH341_REG_0x27 0x27 // hardware flow control (cts/rts)
|
||||
|
||||
#define CH34X_REG16_DIVISOR_PRESCALER TU_U16(CH34X_REG_DIVISOR, CH34X_REG_PRESCALER)
|
||||
#define CH34X_REG16_DIVISOR_PRESCALER TU_U16(CH34X_REG_DIVISOR, CH34X_REG_PRESCALER)
|
||||
#define CH32X_REG16_LCR2_LCR TU_U16(CH34X_REG_LCR2, CH34X_REG_LCR)
|
||||
|
||||
// modem control bits
|
||||
#define CH34X_BIT_RTS ( 1 << 6 )
|
||||
|
Loading…
x
Reference in New Issue
Block a user