Skip to content
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions examples/MassStorage/msc_external_flash/.skip.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
pico_rp2040_tinyusb_host
CH32V20x_EVT
feather_rp2040_tinyusb
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See #500

1 change: 1 addition & 0 deletions examples/MassStorage/msc_external_flash_sdcard/.skip.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
pico_rp2040_tinyusb_host
CH32V20x_EVT
feather_rp2040_tinyusb
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See #500

1 change: 1 addition & 0 deletions examples/MassStorage/msc_sdfat/.skip.txt
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
pico_rp2040_tinyusb_host
feather_rp2040_tinyusb
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See #500

40 changes: 39 additions & 1 deletion src/arduino/Adafruit_USBD_CDC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,15 @@
// esp32 use built-in core cdc
#if CFG_TUD_CDC && !defined(ARDUINO_ARCH_ESP32)

// Include before "Arduino.h" because TinyUSB is part of platform cores
// When developing TinyUSB, it needs to include the local version, not the
// platform core version, which is what gets included by Arduino.h
#include "Adafruit_USBD_CDC.h"

#include "Arduino.h"

#include "Adafruit_TinyUSB_API.h"

#include "Adafruit_USBD_CDC.h"
#include "Adafruit_USBD_Device.h"

#ifndef TINYUSB_API_VERSION
Expand Down Expand Up @@ -170,6 +174,40 @@ int Adafruit_USBD_CDC::dtr(void) {
return tud_cdc_n_connected(_instance);
}

bool Adafruit_USBD_CDC::rts(void) {
return tud_cdc_n_get_line_state(_instance) & CDC_CONTROL_LINE_STATE_RTS;
}

bool Adafruit_USBD_CDC::dsr(void) {
return tud_cdc_n_get_serial_state(_instance).dsr;
}

bool Adafruit_USBD_CDC::dcd(void) {
return tud_cdc_n_get_serial_state(_instance).dcd;
}

bool Adafruit_USBD_CDC::ri(void) {
return tud_cdc_n_get_serial_state(_instance).ri;
}

void Adafruit_USBD_CDC::dsr(bool c) {
cdc_serial_state_t serial_state = tud_cdc_n_get_serial_state(_instance);
serial_state.dsr = c;
tud_cdc_n_set_serial_state(_instance, serial_state);
}

void Adafruit_USBD_CDC::dcd(bool c) {
cdc_serial_state_t serial_state = tud_cdc_n_get_serial_state(_instance);
serial_state.dcd = c;
tud_cdc_n_set_serial_state(_instance, serial_state);
}

void Adafruit_USBD_CDC::ri(bool c) {
cdc_serial_state_t serial_state = tud_cdc_n_get_serial_state(_instance);
serial_state.ri = c;
tud_cdc_n_set_serial_state(_instance, serial_state);
}

Adafruit_USBD_CDC::operator bool() {
if (!isValid()) {
return false;
Expand Down
16 changes: 15 additions & 1 deletion src/arduino/Adafruit_USBD_CDC.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,21 @@ class Adafruit_USBD_CDC : public Stream, public Adafruit_USBD_Interface {
uint8_t stopbits(void);
uint8_t paritytype(void);
uint8_t numbits(void);
int dtr(void);

// Flow control bit getters.
int dtr(void); // pre-existing, I don't want to change the return type.
bool rts(void);
// bool cts(void); // NOT PART OF THE CDC ACM SPEC?!
bool dsr(void);
bool dcd(void);
bool ri(void);

// Flow control bit setters.
// void cts(bool c); // NOT PART OF CDC ACM SPEC?!
void dsr(bool c);
void dcd(bool c);
void ri(bool c);
// Break is a little harder, it's an event, not a state.

// Stream API
virtual int available(void);
Expand Down
43 changes: 43 additions & 0 deletions src/class/cdc/cdc.h
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,49 @@ typedef struct TU_ATTR_PACKED

TU_VERIFY_STATIC(sizeof(cdc_line_control_state_t) == 2, "size is not correct");

//--------------------------------------------------------------------+
// Notifications
//--------------------------------------------------------------------+

typedef union TU_ATTR_PACKED {
struct {
uint16_t dcd :1;
uint16_t dsr :1;
uint16_t break_err :1;
uint16_t ri :1;
uint16_t frame_err :1;
uint16_t parity_err :1;
uint16_t overrun_err :1;
uint16_t :9;
};
uint16_t state;
} cdc_serial_state_t;

TU_VERIFY_STATIC(sizeof(cdc_serial_state_t) == 2, "size is not correct");

typedef struct TU_ATTR_PACKED {
tusb_notification_t header;
union {
cdc_serial_state_t serial_state;
// Add more Notification "Data" payloads here as more are implemented.
};
} cdc_notify_struct_t;

TU_VERIFY_STATIC(sizeof(cdc_notify_struct_t) == 10, "size is not correct");

tu_static const cdc_notify_struct_t cdc_notify_serial_status = {
.header = {
.bmRequestType_bit = {
.recipient = TUSB_REQ_RCPT_INTERFACE,
.type = TUSB_REQ_TYPE_CLASS,
.direction = TUSB_DIR_IN,
},
.bNotification = CDC_NOTIF_SERIAL_STATE,
.wValue = 0,
.wLength = sizeof(cdc_serial_state_t),
}
};

TU_ATTR_PACKED_END // End of all packed definitions
TU_ATTR_BIT_FIELD_ORDER_END

Expand Down
51 changes: 48 additions & 3 deletions src/class/cdc/cdc_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ typedef struct {
// Bit 0: DTR (Data Terminal Ready), Bit 1: RTS (Request to Send)
uint8_t line_state;

// Notify host of flow control bits: DSR, DCD, RI, and some error flags.
cdc_serial_state_t serial_state;
bool serial_state_changed;

/*------------- From this point, data is not cleared by bus reset -------------*/
char wanted_char;
TU_ATTR_ALIGNED(4) cdc_line_coding_t line_coding;
Expand All @@ -76,6 +80,7 @@ typedef struct {
// Endpoint Transfer buffer
CFG_TUSB_MEM_ALIGN uint8_t epout_buf[CFG_TUD_CDC_EP_BUFSIZE];
CFG_TUSB_MEM_ALIGN uint8_t epin_buf[CFG_TUD_CDC_EP_BUFSIZE];
CFG_TUSB_MEM_ALIGN cdc_notify_struct_t epnotif_buf;
} cdcd_interface_t;

#define ITF_MEM_RESET_SIZE offsetof(cdcd_interface_t, wanted_char)
Expand Down Expand Up @@ -115,6 +120,29 @@ static bool _prep_out_transaction (cdcd_interface_t* p_cdc) {
}
}

bool _send_serial_state_notification(cdcd_interface_t *p_cdc) {
const uint8_t rhport = 0;

if (!p_cdc->serial_state_changed) {
// Nothing to do.
return true;
}

if (!usbd_edpt_claim(rhport, p_cdc->ep_notif)) {
// If claim failed, we're already in the middle of a transaction.
// cdcd_xfer_cb() will pick up this change.
return true;
}

// We have the end point. Build and send the notification.
p_cdc->serial_state_changed = false;

p_cdc->epnotif_buf = cdc_notify_serial_status;
p_cdc->epnotif_buf.header.wIndex = p_cdc->itf_num;
p_cdc->epnotif_buf.serial_state = p_cdc->serial_state;
return usbd_edpt_xfer(rhport, p_cdc->ep_notif, (uint8_t *) &(p_cdc->epnotif_buf), sizeof(p_cdc->epnotif_buf));
}

//--------------------------------------------------------------------+
// APPLICATION API
//--------------------------------------------------------------------+
Expand All @@ -138,6 +166,19 @@ uint8_t tud_cdc_n_get_line_state(uint8_t itf) {
return _cdcd_itf[itf].line_state;
}

cdc_serial_state_t tud_cdc_n_get_serial_state(uint8_t itf) {
return _cdcd_itf[itf].serial_state;
}

void tud_cdc_n_set_serial_state(uint8_t itf, cdc_serial_state_t serial_state) {
cdcd_interface_t* p_cdc = &_cdcd_itf[itf];
if (p_cdc->serial_state.state != serial_state.state) {
p_cdc->serial_state_changed = true;
p_cdc->serial_state = serial_state;
_send_serial_state_notification(p_cdc);
}
}

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 @@ -437,10 +478,10 @@ 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)) 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);

// Received new data
if (ep_addr == p_cdc->ep_out) {
tu_fifo_write_n(&p_cdc->rx_ff, p_cdc->epout_buf, (uint16_t) xferred_bytes);
Expand Down Expand Up @@ -479,7 +520,11 @@ bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_
}
}

// nothing to do with notif endpoint for now
// Notifications
if (ep_addr == p_cdc->ep_notif) {
// Send any changes that may have come in while sending the previous change.
return _send_serial_state_notification(p_cdc);
}

return true;
}
Expand Down
14 changes: 14 additions & 0 deletions src/class/cdc/cdc_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,12 @@ 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);

// Get current serial state.
cdc_serial_state_t tud_cdc_n_get_serial_state(uint8_t itf);

// Set current serial state.
void tud_cdc_n_set_serial_state(uint8_t itf, cdc_serial_state_t ser_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);

Expand Down Expand Up @@ -132,6 +138,14 @@ TU_ATTR_ALWAYS_INLINE static inline uint8_t tud_cdc_get_line_state(void) {
return tud_cdc_n_get_line_state(0);
}

TU_ATTR_ALWAYS_INLINE static inline cdc_serial_state_t tud_cdc_get_serial_state(void) {
return tud_cdc_n_get_serial_state(0);
}

TU_ATTR_ALWAYS_INLINE static inline void tud_cdc_set_serial_state(cdc_serial_state_t ser_state) {
tud_cdc_n_set_serial_state(0, ser_state);
}

TU_ATTR_ALWAYS_INLINE static inline void tud_cdc_get_line_coding(cdc_line_coding_t* coding) {
tud_cdc_n_get_line_coding(0, coding);
}
Expand Down
21 changes: 21 additions & 0 deletions src/common/tusb_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,27 @@ typedef struct TU_ATTR_PACKED {

TU_VERIFY_STATIC( sizeof(tusb_control_request_t) == 8, "size is not correct");


typedef struct TU_ATTR_PACKED {
union {
struct TU_ATTR_PACKED {
uint8_t recipient : 5; ///< Recipient type tusb_request_recipient_t.
uint8_t type : 2; ///< Request type tusb_request_type_t.
uint8_t direction : 1; ///< Direction type. tusb_dir_t
} bmRequestType_bit;

uint8_t bmRequestType;
};

uint8_t bNotification;
uint16_t wValue;
uint16_t wIndex;
uint16_t wLength;
} tusb_notification_t;

TU_VERIFY_STATIC( sizeof(tusb_notification_t) == 8, "size is not correct");


TU_ATTR_PACKED_END // End of all packed definitions
TU_ATTR_BIT_FIELD_ORDER_END

Expand Down