mirror of
https://github.com/hathach/tinyusb.git
synced 2025-10-14 01:58:41 +08:00
Merge branch 'dcd_notif' into testing
This commit is contained in:
@@ -98,7 +98,6 @@ void tud_umount_cb(void) {
|
||||
blink_interval_ms = BLINK_NOT_MOUNTED;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// USB CDC
|
||||
//--------------------------------------------------------------------+
|
||||
@@ -119,6 +118,16 @@ static void cdc_task(void) {
|
||||
echo_serial_port(0, buf, count);
|
||||
echo_serial_port(1, buf, count);
|
||||
}
|
||||
|
||||
// Press on-board button to send Uart status notification
|
||||
static uint32_t btn_prev = 0;
|
||||
static cdc_uart_state_t state = {0};
|
||||
uint32_t btn = board_button_read();
|
||||
if (!btn_prev && btn) {
|
||||
state.bTxCarrier ^= 1;
|
||||
tud_cdc_send_uart_state(state);
|
||||
}
|
||||
btn_prev = btn;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -136,10 +136,10 @@ uint8_t const desc_fs_configuration[] =
|
||||
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100),
|
||||
|
||||
// 1st CDC: Interface number, string index, EP notification address and size, EP data address (out, in) and size.
|
||||
TUD_CDC_DESCRIPTOR(ITF_NUM_CDC_0, 4, EPNUM_CDC_0_NOTIF, 8, EPNUM_CDC_0_OUT, EPNUM_CDC_0_IN, 64),
|
||||
TUD_CDC_DESCRIPTOR(ITF_NUM_CDC_0, 4, EPNUM_CDC_0_NOTIF, 10, EPNUM_CDC_0_OUT, EPNUM_CDC_0_IN, 64),
|
||||
|
||||
// 2nd CDC: Interface number, string index, EP notification address and size, EP data address (out, in) and size.
|
||||
TUD_CDC_DESCRIPTOR(ITF_NUM_CDC_1, 4, EPNUM_CDC_1_NOTIF, 8, EPNUM_CDC_1_OUT, EPNUM_CDC_1_IN, 64),
|
||||
TUD_CDC_DESCRIPTOR(ITF_NUM_CDC_1, 4, EPNUM_CDC_1_NOTIF, 10, EPNUM_CDC_1_OUT, EPNUM_CDC_1_IN, 64),
|
||||
};
|
||||
|
||||
#if TUD_OPT_HIGH_SPEED
|
||||
@@ -151,10 +151,10 @@ uint8_t const desc_hs_configuration[] =
|
||||
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100),
|
||||
|
||||
// 1st CDC: Interface number, string index, EP notification address and size, EP data address (out, in) and size.
|
||||
TUD_CDC_DESCRIPTOR(ITF_NUM_CDC_0, 4, EPNUM_CDC_0_NOTIF, 8, EPNUM_CDC_0_OUT, EPNUM_CDC_0_IN, 512),
|
||||
TUD_CDC_DESCRIPTOR(ITF_NUM_CDC_0, 4, EPNUM_CDC_0_NOTIF, 10, EPNUM_CDC_0_OUT, EPNUM_CDC_0_IN, 512),
|
||||
|
||||
// 2nd CDC: Interface number, string index, EP notification address and size, EP data address (out, in) and size.
|
||||
TUD_CDC_DESCRIPTOR(ITF_NUM_CDC_1, 4, EPNUM_CDC_1_NOTIF, 8, EPNUM_CDC_1_OUT, EPNUM_CDC_1_IN, 512),
|
||||
TUD_CDC_DESCRIPTOR(ITF_NUM_CDC_1, 4, EPNUM_CDC_1_NOTIF, 10, EPNUM_CDC_1_OUT, EPNUM_CDC_1_IN, 512),
|
||||
};
|
||||
|
||||
// device qualifier is mostly similar to device descriptor since we don't change configuration based on speed
|
||||
|
@@ -412,6 +412,35 @@ typedef struct TU_ATTR_PACKED
|
||||
|
||||
TU_VERIFY_STATIC(sizeof(cdc_line_control_state_t) == 2, "size is not correct");
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Notifications
|
||||
//--------------------------------------------------------------------+
|
||||
typedef struct TU_ATTR_PACKED
|
||||
{
|
||||
uint16_t bRxCarrier : 1;
|
||||
uint16_t bTxCarrier : 1;
|
||||
uint16_t bBreak : 1;
|
||||
uint16_t bRingSignal : 1;
|
||||
uint16_t bFraming : 1;
|
||||
uint16_t bParity : 1;
|
||||
uint16_t bOverRun : 1;
|
||||
uint16_t : 9;
|
||||
} cdc_uart_state_t;
|
||||
|
||||
typedef struct TU_ATTR_PACKED
|
||||
{
|
||||
uint8_t bmRequestType;
|
||||
uint8_t bNotification;
|
||||
uint16_t wValue;
|
||||
uint16_t wIndex;
|
||||
uint16_t wLength;
|
||||
cdc_uart_state_t bmUartState;
|
||||
} cdc_notif_serial_state_t;
|
||||
|
||||
TU_VERIFY_STATIC(sizeof(cdc_notif_serial_state_t) == 10, "size is not correct");
|
||||
|
||||
#define CDC_REQ_TYPE_NOTIF 0xA1 ///< Direction IN; Type Class; Recipient Interface
|
||||
|
||||
TU_ATTR_PACKED_END // End of all packed definitions
|
||||
TU_ATTR_BIT_FIELD_ORDER_END
|
||||
|
||||
|
@@ -46,6 +46,7 @@
|
||||
#define BULK_PACKET_SIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
|
||||
|
||||
typedef struct {
|
||||
uint8_t rhport;
|
||||
uint8_t itf_num;
|
||||
uint8_t ep_notif;
|
||||
uint8_t ep_in;
|
||||
@@ -74,6 +75,7 @@ typedef struct {
|
||||
typedef struct {
|
||||
TUD_EPBUF_DEF(epout, CFG_TUD_CDC_EP_BUFSIZE);
|
||||
TUD_EPBUF_DEF(epin, CFG_TUD_CDC_EP_BUFSIZE);
|
||||
TUD_EPBUF_TYPE_DEF(cdc_notif_serial_state_t, epnotif);
|
||||
} cdcd_epbuf_t;
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
@@ -101,7 +103,7 @@ static bool _prep_out_transaction(uint8_t itf) {
|
||||
TU_VERIFY(available >= CFG_TUD_CDC_EP_BUFSIZE);
|
||||
|
||||
// claim endpoint
|
||||
TU_VERIFY(usbd_edpt_claim(rhport, p_cdc->ep_out));
|
||||
TU_VERIFY(usbd_edpt_claim(p_cdc->rhport, p_cdc->ep_out));
|
||||
|
||||
// fifo can be changed before endpoint is claimed
|
||||
available = tu_fifo_remaining(&p_cdc->rx_ff);
|
||||
@@ -110,7 +112,7 @@ static bool _prep_out_transaction(uint8_t itf) {
|
||||
return usbd_edpt_xfer(rhport, p_cdc->ep_out, p_epbuf->epout, CFG_TUD_CDC_EP_BUFSIZE);
|
||||
} else {
|
||||
// Release endpoint since we don't make any transfer
|
||||
usbd_edpt_release(rhport, p_cdc->ep_out);
|
||||
usbd_edpt_release(p_cdc->rhport, p_cdc->ep_out);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -142,6 +144,27 @@ void tud_cdc_n_get_line_coding(uint8_t itf, cdc_line_coding_t* coding) {
|
||||
(*coding) = _cdcd_itf[itf].line_coding;
|
||||
}
|
||||
|
||||
bool tud_cdc_n_send_uart_state (uint8_t itf, cdc_uart_state_t state) {
|
||||
cdcd_interface_t* p_cdc = &_cdcd_itf[itf];
|
||||
cdcd_epbuf_t* p_epbuf = &_cdcd_epbuf[itf];
|
||||
|
||||
// Skip if usb is not ready yet
|
||||
TU_VERIFY(tud_ready(), 0);
|
||||
|
||||
// claim endpoint
|
||||
TU_VERIFY(usbd_edpt_claim(p_cdc->rhport, p_cdc->ep_notif));
|
||||
|
||||
p_epbuf->epnotif.bmRequestType = CDC_REQ_TYPE_NOTIF;
|
||||
p_epbuf->epnotif.bNotification = CDC_NOTIF_SERIAL_STATE;
|
||||
p_epbuf->epnotif.wValue = 0;
|
||||
p_epbuf->epnotif.wIndex = p_cdc->itf_num;
|
||||
p_epbuf->epnotif.wLength = 2;
|
||||
p_epbuf->epnotif.bmUartState = state;
|
||||
|
||||
// transfer
|
||||
return usbd_edpt_xfer(p_cdc->rhport, p_cdc->ep_notif, (uint8_t *)&p_epbuf->epnotif, sizeof(cdc_notif_serial_state_t));
|
||||
}
|
||||
|
||||
void tud_cdc_n_set_wanted_char(uint8_t itf, char wanted) {
|
||||
_cdcd_itf[itf].wanted_char = wanted;
|
||||
}
|
||||
@@ -204,7 +227,7 @@ uint32_t tud_cdc_n_write_flush(uint8_t itf) {
|
||||
const uint8_t rhport = 0;
|
||||
|
||||
// Claim the endpoint
|
||||
TU_VERIFY(usbd_edpt_claim(rhport, p_cdc->ep_in), 0);
|
||||
TU_VERIFY(usbd_edpt_claim(p_cdc->rhport, p_cdc->ep_in), 0);
|
||||
|
||||
// Pull data from FIFO
|
||||
const uint16_t count = tu_fifo_read_n(&p_cdc->tx_ff, p_epbuf->epin, CFG_TUD_CDC_EP_BUFSIZE);
|
||||
@@ -215,7 +238,7 @@ uint32_t tud_cdc_n_write_flush(uint8_t itf) {
|
||||
} else {
|
||||
// Release endpoint since we don't make any transfer
|
||||
// Note: data is dropped if terminal is not connected
|
||||
usbd_edpt_release(rhport, p_cdc->ep_in);
|
||||
usbd_edpt_release(p_cdc->rhport, p_cdc->ep_in);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -319,6 +342,7 @@ uint16_t cdcd_open(uint8_t rhport, const tusb_desc_interface_t* itf_desc, uint16
|
||||
TU_ASSERT(cdc_id < CFG_TUD_CDC, 0);
|
||||
|
||||
//------------- Control Interface -------------//
|
||||
p_cdc->rhport = rhport;
|
||||
p_cdc->itf_num = itf_desc->bInterfaceNumber;
|
||||
|
||||
uint16_t drv_len = sizeof(tusb_desc_interface_t);
|
||||
@@ -455,7 +479,7 @@ bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_
|
||||
// Identify which interface to use
|
||||
for (itf = 0; itf < CFG_TUD_CDC; itf++) {
|
||||
p_cdc = &_cdcd_itf[itf];
|
||||
if ((ep_addr == p_cdc->ep_out) || (ep_addr == p_cdc->ep_in)) {
|
||||
if ((ep_addr == p_cdc->ep_out) || (ep_addr == p_cdc->ep_in) || (ep_addr == p_cdc->ep_notif)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@@ -83,6 +83,9 @@ uint8_t tud_cdc_n_get_line_state(uint8_t itf);
|
||||
// Get current line encoding: bit rate, stop bits parity etc ..
|
||||
void tud_cdc_n_get_line_coding(uint8_t itf, cdc_line_coding_t* coding);
|
||||
|
||||
// Send UART status notification: DCD, DSR etc ..
|
||||
bool tud_cdc_n_send_uart_state(uint8_t itf, cdc_uart_state_t state);
|
||||
|
||||
// Set special character that will trigger tud_cdc_rx_wanted_cb() callback on receiving
|
||||
void tud_cdc_n_set_wanted_char(uint8_t itf, char wanted);
|
||||
|
||||
@@ -146,6 +149,11 @@ TU_ATTR_ALWAYS_INLINE static inline void tud_cdc_get_line_coding(cdc_line_coding
|
||||
tud_cdc_n_get_line_coding(0, coding);
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline bool tud_cdc_send_uart_state(cdc_uart_state_t state) {
|
||||
return tud_cdc_n_send_uart_state(0, state);
|
||||
}
|
||||
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline void tud_cdc_set_wanted_char(char wanted) {
|
||||
tud_cdc_n_set_wanted_char(0, wanted);
|
||||
}
|
||||
|
Reference in New Issue
Block a user