Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CDC device line state notification #2395

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
32 changes: 31 additions & 1 deletion src/class/cdc/cdc_device.c
Expand Up @@ -128,6 +128,36 @@ uint8_t tud_cdc_n_get_line_state (uint8_t itf)
return _cdcd_itf[itf].line_state;
}

bool tud_cdc_n_notif_line_state (uint8_t itf, uint8_t state)
{
cdcd_interface_t* p_cdc = &_cdcd_itf[itf];

TU_VERIFY(tud_ready());

uint8_t const rhport = 0;

// claim endpoint
TU_VERIFY(usbd_edpt_claim(rhport, p_cdc->ep_notif));

// prepare packet
uint8_t packet[10];
packet[0] = 0xA1; // bmRequestType
packet[1] = CDC_NOTIF_SERIAL_STATE; // bNotification
packet[2] = 0x00; // wValue
packet[3] = 0x00;
packet[4] = p_cdc->itf_num; // wIndex
packet[5] = 0x00;
packet[6] = 0x02; // wLength
packet[7] = 0x00;
packet[8] = state & 0x7F; // Data (UART State bitmap)
packet[9] = 0x00;

// transfer
TU_ASSERT( usbd_edpt_xfer(rhport, p_cdc->ep_notif, packet, sizeof(packet)), 0 );

return true;
}

void tud_cdc_n_get_line_coding (uint8_t itf, cdc_line_coding_t* coding)
{
(*coding) = _cdcd_itf[itf].line_coding;
Expand Down Expand Up @@ -432,7 +462,7 @@ bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_
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 ) ) break;
if ( ( ep_addr == p_cdc->ep_out ) || ( ep_addr == p_cdc->ep_in ) || ( ep_addr == p_cdc->ep_notif ) ) break;
}
TU_ASSERT(itf < CFG_TUD_CDC);

Expand Down
74 changes: 42 additions & 32 deletions src/class/cdc/cdc_device.h
Expand Up @@ -56,73 +56,78 @@
//--------------------------------------------------------------------+

// Check if terminal is connected to this port
bool tud_cdc_n_connected (uint8_t itf);
bool tud_cdc_n_connected (uint8_t itf);

// Get current line state. Bit 0: DTR (Data Terminal Ready), Bit 1: RTS (Request to Send)
uint8_t tud_cdc_n_get_line_state (uint8_t itf);
uint8_t tud_cdc_n_get_line_state (uint8_t itf);

// Set serial state.
// Bit 0: DCD, Bit 1: DSR, Bit 2: Break, Bit 3: Ring, Bit 4: Framing error, Bit 5: Parity error, Bit 6: Overrun.
bool tud_cdc_n_notif_line_state (uint8_t itf, uint8_t state);

// 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);
void tud_cdc_n_get_line_coding (uint8_t itf, cdc_line_coding_t* coding);

// 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);
void tud_cdc_n_set_wanted_char (uint8_t itf, char wanted);

// Get the number of bytes available for reading
uint32_t tud_cdc_n_available (uint8_t itf);
uint32_t tud_cdc_n_available (uint8_t itf);

// Read received bytes
uint32_t tud_cdc_n_read (uint8_t itf, void* buffer, uint32_t bufsize);
uint32_t tud_cdc_n_read (uint8_t itf, void* buffer, uint32_t bufsize);

// Read a byte, return -1 if there is none
static inline
int32_t tud_cdc_n_read_char (uint8_t itf);
int32_t tud_cdc_n_read_char (uint8_t itf);

// Clear the received FIFO
void tud_cdc_n_read_flush (uint8_t itf);
void tud_cdc_n_read_flush (uint8_t itf);

// Get a byte from FIFO without removing it
bool tud_cdc_n_peek (uint8_t itf, uint8_t* ui8);
bool tud_cdc_n_peek (uint8_t itf, uint8_t* ui8);

// Write bytes to TX FIFO, data may remain in the FIFO for a while
uint32_t tud_cdc_n_write (uint8_t itf, void const* buffer, uint32_t bufsize);
uint32_t tud_cdc_n_write (uint8_t itf, void const* buffer, uint32_t bufsize);

// Write a byte
static inline
uint32_t tud_cdc_n_write_char (uint8_t itf, char ch);
uint32_t tud_cdc_n_write_char (uint8_t itf, char ch);

// Write a null-terminated string
static inline
uint32_t tud_cdc_n_write_str (uint8_t itf, char const* str);
uint32_t tud_cdc_n_write_str (uint8_t itf, char const* str);

// Force sending data if possible, return number of forced bytes
uint32_t tud_cdc_n_write_flush (uint8_t itf);
uint32_t tud_cdc_n_write_flush (uint8_t itf);

// Return the number of bytes (characters) available for writing to TX FIFO buffer in a single n_write operation.
uint32_t tud_cdc_n_write_available (uint8_t itf);
uint32_t tud_cdc_n_write_available (uint8_t itf);

// Clear the transmit FIFO
bool tud_cdc_n_write_clear (uint8_t itf);
bool tud_cdc_n_write_clear (uint8_t itf);

//--------------------------------------------------------------------+
// Application API (Single Port)
//--------------------------------------------------------------------+
static inline bool tud_cdc_connected (void);
static inline uint8_t tud_cdc_get_line_state (void);
static inline void tud_cdc_get_line_coding (cdc_line_coding_t* coding);
static inline void tud_cdc_set_wanted_char (char wanted);

static inline uint32_t tud_cdc_available (void);
static inline int32_t tud_cdc_read_char (void);
static inline uint32_t tud_cdc_read (void* buffer, uint32_t bufsize);
static inline void tud_cdc_read_flush (void);
static inline bool tud_cdc_peek (uint8_t* ui8);

static inline uint32_t tud_cdc_write_char (char ch);
static inline uint32_t tud_cdc_write (void const* buffer, uint32_t bufsize);
static inline uint32_t tud_cdc_write_str (char const* str);
static inline uint32_t tud_cdc_write_flush (void);
static inline uint32_t tud_cdc_write_available (void);
static inline bool tud_cdc_write_clear (void);
static inline bool tud_cdc_connected (void);
static inline uint8_t tud_cdc_get_line_state (void);
static inline bool tud_cdc_notif_line_state (uint8_t state);
static inline void tud_cdc_get_line_coding (cdc_line_coding_t* coding);
static inline void tud_cdc_set_wanted_char (char wanted);

static inline uint32_t tud_cdc_available (void);
static inline int32_t tud_cdc_read_char (void);
static inline uint32_t tud_cdc_read (void* buffer, uint32_t bufsize);
static inline void tud_cdc_read_flush (void);
static inline bool tud_cdc_peek (uint8_t* ui8);

static inline uint32_t tud_cdc_write_char (char ch);
static inline uint32_t tud_cdc_write (void const* buffer, uint32_t bufsize);
static inline uint32_t tud_cdc_write_str (char const* str);
static inline uint32_t tud_cdc_write_flush (void);
static inline uint32_t tud_cdc_write_available (void);
static inline bool tud_cdc_write_clear (void);

//--------------------------------------------------------------------+
// Application Callback API (weak is optional)
Expand Down Expand Up @@ -175,6 +180,11 @@ static inline uint8_t tud_cdc_get_line_state (void)
return tud_cdc_n_get_line_state(0);
}

static inline bool tud_cdc_notif_line_state (uint8_t state)
{
return tud_cdc_n_notif_line_state(0, state);
}

static inline void tud_cdc_get_line_coding (cdc_line_coding_t* coding)
{
tud_cdc_n_get_line_coding(0, coding);
Expand Down