Skip to content

Commit b0634ba

Browse files
committed
Queue Notification when setting, not waiting for the callback. #491
1 parent 0803d8e commit b0634ba

File tree

5 files changed

+51
-59
lines changed

5 files changed

+51
-59
lines changed

src/arduino/Adafruit_USBD_CDC.cpp

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -174,10 +174,6 @@ bool Adafruit_USBD_CDC::rts(void) {
174174
return tud_cdc_n_get_line_state(_instance) & CDC_CONTROL_LINE_STATE_RTS;
175175
}
176176

177-
bool Adafruit_USBD_CDC::cts(void) {
178-
return tud_cdc_n_get_serial_state(_instance).cts;
179-
}
180-
181177
bool Adafruit_USBD_CDC::dsr(void) {
182178
return tud_cdc_n_get_serial_state(_instance).dsr;
183179
}
@@ -190,12 +186,6 @@ bool Adafruit_USBD_CDC::ri(void) {
190186
return tud_cdc_n_get_serial_state(_instance).ri;
191187
}
192188

193-
void Adafruit_USBD_CDC::cts(bool c) {
194-
cdc_serial_state_t serial_state = tud_cdc_n_get_serial_state(_instance);
195-
serial_state.cts = c;
196-
tud_cdc_n_set_serial_state(_instance, serial_state);
197-
}
198-
199189
void Adafruit_USBD_CDC::dsr(bool c) {
200190
cdc_serial_state_t serial_state = tud_cdc_n_get_serial_state(_instance);
201191
serial_state.dsr = c;

src/arduino/Adafruit_USBD_CDC.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,16 +63,17 @@ class Adafruit_USBD_CDC : public Stream, public Adafruit_USBD_Interface {
6363
// Flow control bit getters.
6464
int dtr(void); // pre-existing, I don't want to change the return type.
6565
bool rts(void);
66-
bool cts(void);
66+
// bool cts(void); // NOT PART OF THE CDC ACM SPEC?!
6767
bool dsr(void);
6868
bool dcd(void);
6969
bool ri(void);
7070

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

7778
// Stream API
7879
virtual int available(void);

src/class/cdc/cdc.h

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -416,21 +416,22 @@ TU_VERIFY_STATIC(sizeof(cdc_line_control_state_t) == 2, "size is not correct");
416416
// Notifications
417417
//--------------------------------------------------------------------+
418418

419-
typedef struct TU_ATTR_PACKED {
420-
uint16_t dcd :1;
421-
uint16_t dsr :1;
422-
uint16_t break_err :1;
423-
uint16_t ri :1;
424-
uint16_t frame_err :1;
425-
uint16_t parity_err :1;
426-
uint16_t overrun_err :1;
427-
uint16_t cts :1; // https://community.st.com/t5/stm32-mcus-products/cts-signal-on-usb-cdc/td-p/325800
428-
uint16_t :8;
419+
typedef union TU_ATTR_PACKED {
420+
struct {
421+
uint16_t dcd :1;
422+
uint16_t dsr :1;
423+
uint16_t break_err :1;
424+
uint16_t ri :1;
425+
uint16_t frame_err :1;
426+
uint16_t parity_err :1;
427+
uint16_t overrun_err :1;
428+
uint16_t :9;
429+
};
430+
uint16_t state;
429431
} cdc_serial_state_t;
430432

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

433-
// Add more notifications here. PSTN120.pdf, Section 6.5
434435
typedef struct TU_ATTR_PACKED {
435436
tusb_notification_t header;
436437
union {

src/class/cdc/cdc_device.c

Lines changed: 35 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ typedef struct {
5959
// Bit 0: DTR (Data Terminal Ready), Bit 1: RTS (Request to Send)
6060
uint8_t line_state;
6161

62-
// Notify host of flow control bits: CTS, DSR, DCD, RI, and some error flags.
62+
// Notify host of flow control bits: DSR, DCD, RI, and some error flags.
6363
cdc_serial_state_t serial_state;
6464
bool serial_state_changed;
6565

@@ -120,6 +120,29 @@ static bool _prep_out_transaction (cdcd_interface_t* p_cdc) {
120120
}
121121
}
122122

123+
bool _send_serial_state_notification(cdcd_interface_t *p_cdc) {
124+
const uint8_t rhport = 0;
125+
126+
if (!p_cdc->serial_state_changed) {
127+
// Nothing to do.
128+
return true;
129+
}
130+
131+
if (!usbd_edpt_claim(rhport, p_cdc->ep_notif)) {
132+
// If claim failed, we're already in the middle of a transaction.
133+
// cdcd_xfer_cb() will pick up this change.
134+
return true;
135+
}
136+
137+
// We have the end point. Build and send the notification.
138+
p_cdc->serial_state_changed = false;
139+
140+
p_cdc->epnotif_buf = cdc_notify_serial_status;
141+
p_cdc->epnotif_buf.header.wIndex = p_cdc->itf_num;
142+
p_cdc->epnotif_buf.serial_state = p_cdc->serial_state;
143+
return usbd_edpt_xfer(rhport, p_cdc->ep_notif, (uint8_t *) &(p_cdc->epnotif_buf), sizeof(p_cdc->epnotif_buf));
144+
}
145+
123146
//--------------------------------------------------------------------+
124147
// APPLICATION API
125148
//--------------------------------------------------------------------+
@@ -148,11 +171,12 @@ cdc_serial_state_t tud_cdc_n_get_serial_state(uint8_t itf) {
148171
}
149172

150173
void tud_cdc_n_set_serial_state(uint8_t itf, cdc_serial_state_t serial_state) {
151-
if (memcmp(&(_cdcd_itf[itf].serial_state), &serial_state, sizeof(serial_state)) != 0) {
152-
TU_LOG_DRV(" Serial State Changed: %x -> %x\r\n", _cdcd_itf[itf].serial_state, serial_state);
153-
_cdcd_itf[itf].serial_state_changed = true;
174+
cdcd_interface_t* p_cdc = &_cdcd_itf[itf];
175+
if (p_cdc->serial_state.state != serial_state.state) {
176+
p_cdc->serial_state_changed = true;
177+
p_cdc->serial_state = serial_state;
178+
_send_serial_state_notification(p_cdc);
154179
}
155-
_cdcd_itf[itf].serial_state = serial_state;
156180
}
157181

158182
void tud_cdc_n_get_line_coding(uint8_t itf, cdc_line_coding_t* coding) {
@@ -343,13 +367,10 @@ uint16_t cdcd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint1
343367

344368
if (TUSB_DESC_ENDPOINT == tu_desc_type(p_desc)) {
345369
// notification endpoint
346-
tusb_desc_endpoint_t desc_ep = *(tusb_desc_endpoint_t const*) p_desc;
347-
TU_LOG_DRV(" Interval before: %d\r\n", desc_ep.bInterval);
348-
349-
desc_ep.bInterval = 1; // Query every frame, 1ms at Full Speed.
370+
tusb_desc_endpoint_t const* desc_ep = (tusb_desc_endpoint_t const*) p_desc;
350371

351-
TU_ASSERT(usbd_edpt_open(rhport, &desc_ep), 0);
352-
p_cdc->ep_notif = desc_ep.bEndpointAddress;
372+
TU_ASSERT(usbd_edpt_open(rhport, desc_ep), 0);
373+
p_cdc->ep_notif = desc_ep->bEndpointAddress;
353374

354375
drv_len += tu_desc_len(p_desc);
355376
p_desc = tu_desc_next(p_desc);
@@ -460,10 +481,9 @@ bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_
460481
if ((ep_addr == p_cdc->ep_out) || (ep_addr == p_cdc->ep_in) || (ep_addr == p_cdc->ep_notif)) break;
461482
}
462483
TU_ASSERT(itf < CFG_TUD_CDC);
463-
484+
464485
// Received new data
465486
if (ep_addr == p_cdc->ep_out) {
466-
TU_LOG_DRV(" XFer Out\r\n");
467487
tu_fifo_write_n(&p_cdc->rx_ff, p_cdc->epout_buf, (uint16_t) xferred_bytes);
468488

469489
// Check for wanted char and invoke callback if needed
@@ -486,7 +506,6 @@ bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_
486506
// Note: This will cause incorrect baudrate set in line coding.
487507
// Though maybe the baudrate is not really important !!!
488508
if (ep_addr == p_cdc->ep_in) {
489-
TU_LOG_DRV(" XFer In\r\n");
490509
// invoke transmit callback to possibly refill tx fifo
491510
if (tud_cdc_tx_complete_cb) tud_cdc_tx_complete_cb(itf);
492511

@@ -503,27 +522,8 @@ bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_
503522

504523
// Notifications
505524
if (ep_addr == p_cdc->ep_notif) {
506-
TU_LOG_DRV(" XFer Notification\r\n");
507-
uint8_t const rhport = 0;
508-
509-
// SERIAL_STATE notification. Send flow control signals.
510-
if (p_cdc->serial_state_changed) {
511-
p_cdc->serial_state_changed = false;
512-
513-
// Build the notification
514-
p_cdc->epnotif_buf = cdc_notify_serial_status;
515-
p_cdc->epnotif_buf.header.wIndex = p_cdc->itf_num;
516-
p_cdc->epnotif_buf.serial_state = p_cdc->serial_state;
517-
518-
// claim endpoint
519-
TU_VERIFY(usbd_edpt_claim(rhport, p_cdc->ep_notif), 0);
520-
521-
// Send notification
522-
return usbd_edpt_xfer(rhport, p_cdc->ep_notif, (uint8_t *) &(p_cdc->epnotif_buf), sizeof(p_cdc->epnotif_buf));
523-
}
524-
else {
525-
// Send a NAK?
526-
}
525+
// Send any changes that may have come in while sending the previous change.
526+
return _send_serial_state_notification(p_cdc);
527527
}
528528

529529
return true;

src/class/cdc/cdc_device.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ TU_ATTR_ALWAYS_INLINE static inline cdc_serial_state_t tud_cdc_get_serial_state(
143143
}
144144

145145
TU_ATTR_ALWAYS_INLINE static inline void tud_cdc_set_serial_state(cdc_serial_state_t ser_state) {
146-
return tud_cdc_n_set_serial_state(0, ser_state);
146+
tud_cdc_n_set_serial_state(0, ser_state);
147147
}
148148

149149
TU_ATTR_ALWAYS_INLINE static inline void tud_cdc_get_line_coding(cdc_line_coding_t* coding) {

0 commit comments

Comments
 (0)