mirror of
https://github.com/hathach/tinyusb.git
synced 2025-04-23 17:42:22 +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 "tusb.h"
|
||||||
#include "bsp/board_api.h"
|
#include "bsp/board_api.h"
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
size_t get_console_inputs(uint8_t* buf, size_t bufsize) {
|
||||||
// MACRO TYPEDEF CONSTANT ENUM DECLARATION
|
|
||||||
//--------------------------------------------------------------------+
|
|
||||||
|
|
||||||
|
|
||||||
//------------- IMPLEMENTATION -------------//
|
|
||||||
|
|
||||||
size_t get_console_inputs(uint8_t* buf, size_t bufsize)
|
|
||||||
{
|
|
||||||
size_t count = 0;
|
size_t count = 0;
|
||||||
while (count < bufsize)
|
while (count < bufsize) {
|
||||||
{
|
|
||||||
int ch = board_getchar();
|
int ch = board_getchar();
|
||||||
if ( ch <= 0 ) break;
|
if (ch <= 0) break;
|
||||||
|
|
||||||
buf[count] = (uint8_t) ch;
|
buf[count] = (uint8_t) ch;
|
||||||
count++;
|
count++;
|
||||||
@ -49,22 +40,18 @@ size_t get_console_inputs(uint8_t* buf, size_t bufsize)
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cdc_app_task(void)
|
void cdc_app_task(void) {
|
||||||
{
|
uint8_t buf[64 + 1]; // +1 for extra null character
|
||||||
uint8_t buf[64+1]; // +1 for extra null character
|
uint32_t const bufsize = sizeof(buf) - 1;
|
||||||
uint32_t const bufsize = sizeof(buf)-1;
|
|
||||||
|
|
||||||
uint32_t count = get_console_inputs(buf, bufsize);
|
uint32_t count = get_console_inputs(buf, bufsize);
|
||||||
buf[count] = 0;
|
buf[count] = 0;
|
||||||
|
|
||||||
// loop over all mounted interfaces
|
// loop over all mounted interfaces
|
||||||
for(uint8_t idx=0; idx<CFG_TUH_CDC; idx++)
|
for (uint8_t idx = 0; idx < CFG_TUH_CDC; idx++) {
|
||||||
{
|
if (tuh_cdc_mounted(idx)) {
|
||||||
if ( tuh_cdc_mounted(idx) )
|
|
||||||
{
|
|
||||||
// console --> cdc interfaces
|
// console --> cdc interfaces
|
||||||
if (count)
|
if (count) {
|
||||||
{
|
|
||||||
tuh_cdc_write(idx, buf, count);
|
tuh_cdc_write(idx, buf, count);
|
||||||
tuh_cdc_write_flush(idx);
|
tuh_cdc_write_flush(idx);
|
||||||
}
|
}
|
||||||
@ -72,11 +59,14 @@ void cdc_app_task(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// TinyUSB callbacks
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
// Invoked when received new data
|
// Invoked when received new data
|
||||||
void tuh_cdc_rx_cb(uint8_t idx)
|
void tuh_cdc_rx_cb(uint8_t idx) {
|
||||||
{
|
uint8_t buf[64 + 1]; // +1 for extra null character
|
||||||
uint8_t buf[64+1]; // +1 for extra null character
|
uint32_t const bufsize = sizeof(buf) - 1;
|
||||||
uint32_t const bufsize = sizeof(buf)-1;
|
|
||||||
|
|
||||||
// forward cdc interfaces -> console
|
// forward cdc interfaces -> console
|
||||||
uint32_t count = tuh_cdc_read(idx, buf, bufsize);
|
uint32_t count = tuh_cdc_read(idx, buf, bufsize);
|
||||||
@ -85,29 +75,31 @@ void tuh_cdc_rx_cb(uint8_t idx)
|
|||||||
printf((char*) buf);
|
printf((char*) buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tuh_cdc_mount_cb(uint8_t idx)
|
// Invoked when a device with CDC interface is mounted
|
||||||
{
|
// idx is index of cdc interface in the internal pool.
|
||||||
tuh_itf_info_t itf_info = { 0 };
|
void tuh_cdc_mount_cb(uint8_t idx) {
|
||||||
|
tuh_itf_info_t itf_info = {0};
|
||||||
tuh_cdc_itf_get_info(idx, &itf_info);
|
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
|
#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
|
// 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
|
// otherwise you need to call tuh_cdc_set_line_coding() first
|
||||||
cdc_line_coding_t line_coding = { 0 };
|
cdc_line_coding_t line_coding = {0};
|
||||||
if ( tuh_cdc_get_local_line_coding(idx, &line_coding) )
|
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(" 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
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void tuh_cdc_umount_cb(uint8_t idx)
|
// 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_itf_info_t itf_info = {0};
|
||||||
tuh_cdc_itf_get_info(idx, &itf_info);
|
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);
|
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,
|
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) {
|
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.stop_bits = stop_bits;
|
p_cdc->requested_line_coding.parity = parity;
|
||||||
// p_cdc->requested_line_coding.parity = parity;
|
p_cdc->requested_line_coding.data_bits = data_bits;
|
||||||
// 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));
|
|
||||||
|
|
||||||
|
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;
|
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,
|
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) {
|
tuh_xfer_cb_t complete_cb, uintptr_t user_data) {
|
||||||
// p_cdc->baudrate_requested = line_coding->bit_rate;
|
p_cdc->requested_line_coding = *line_coding;
|
||||||
// p_cdc->user_control_cb = complete_cb;
|
p_cdc->user_control_cb = complete_cb;
|
||||||
// uint8_t factor, divisor, lcr;
|
|
||||||
// TU_ASSERT (ch34x_get_factor_divisor(line_coding->bit_rate, &factor, &divisor));
|
if (complete_cb) {
|
||||||
// TU_ASSERT (ch34x_get_lcr(line_coding, &lcr));
|
// stage 1 set baudrate
|
||||||
// TU_ASSERT (ch34x_control_out(p_cdc, CH34X_REQ_SERIAL_INIT, (uint16_t) (lcr << 8 | 0x9c), (uint16_t) (factor << 8 | 0x80 | divisor),
|
TU_ASSERT(ch34x_write_reg_baudrate(p_cdc, line_coding->bit_rate,
|
||||||
// complete_cb ? ch34x_control_complete : NULL, user_data));
|
ch34x_set_line_coding_stage1_complete, user_data));
|
||||||
(void) p_cdc;
|
} else {
|
||||||
(void) line_coding;
|
// sync call
|
||||||
(void) complete_cb;
|
xfer_result_t result;
|
||||||
(void) user_data;
|
|
||||||
|
// 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;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,8 @@
|
|||||||
#define CH341_REG_0x2C 0x2C // undocumented register
|
#define CH341_REG_0x2C 0x2C // undocumented register
|
||||||
#define CH341_REG_0x27 0x27 // hardware flow control (cts/rts)
|
#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
|
// modem control bits
|
||||||
#define CH34X_BIT_RTS ( 1 << 6 )
|
#define CH34X_BIT_RTS ( 1 << 6 )
|
||||||
|
Loading…
x
Reference in New Issue
Block a user