From 404fc94705ed7f395a9a7ba8328d2cead44437ad Mon Sep 17 00:00:00 2001
From: etagle <ejtagle@hotmail.com>
Date: Thu, 15 Mar 2018 00:56:28 -0300
Subject: [PATCH] DUE USB CDC: Do not send any character if no program on the
PC is listening to them. This avoids Marlin waiting until the user actually
opens a program that is able to consume the output of Marlin
---
.../src/HAL/HAL_DUE/MarlinSerialUSB_Due.cpp | 21 ++++++++++++++++++-
Marlin/src/HAL/HAL_DUE/usb/udi_cdc.c | 4 ++--
Marlin/src/HAL/HAL_DUE/usb/usb_task.c | 12 +++++++++--
Marlin/src/HAL/HAL_DUE/usb/usb_task.h | 13 ++++++++++++
4 files changed, 45 insertions(+), 5 deletions(-)
diff --git a/Marlin/src/HAL/HAL_DUE/MarlinSerialUSB_Due.cpp b/Marlin/src/HAL/HAL_DUE/MarlinSerialUSB_Due.cpp
index c773877375..dc8edf9a3a 100644
--- a/Marlin/src/HAL/HAL_DUE/MarlinSerialUSB_Due.cpp
+++ b/Marlin/src/HAL/HAL_DUE/MarlinSerialUSB_Due.cpp
@@ -36,6 +36,7 @@
// Imports from Atmel USB Stack/CDC implementation
extern "C" {
bool usb_task_cdc_isenabled(void);
+ bool usb_task_cdc_dtr_active(void);
bool udi_cdc_is_rx_ready(void);
int udi_cdc_getc(void);
bool udi_cdc_is_tx_ready(void);
@@ -56,9 +57,11 @@ int MarlinSerialUSB::peek(void) {
if (pending_char >= 0)
return pending_char;
+ // If USB CDC not enumerated or not configured on the PC side
if (!usb_task_cdc_isenabled())
return -1;
+ // If no bytes sent from the PC
if (!udi_cdc_is_rx_ready())
return -1;
@@ -73,9 +76,11 @@ int MarlinSerialUSB::read(void) {
return ret;
}
+ // If USB CDC not enumerated or not configured on the PC side
if (!usb_task_cdc_isenabled())
return -1;
+ // If no bytes sent from the PC
if (!udi_cdc_is_rx_ready())
return -1;
@@ -83,7 +88,10 @@ int MarlinSerialUSB::read(void) {
}
bool MarlinSerialUSB::available(void) {
+ /* If Pending chars */
return pending_char >= 0 ||
+ /* or USB CDC enumerated and configured on the PC side and some
+ bytes where sent to us */
(usb_task_cdc_isenabled() && udi_cdc_is_rx_ready());
}
@@ -92,11 +100,22 @@ void MarlinSerialUSB::flush(void) {
void MarlinSerialUSB::write(const uint8_t c) {
+ /* Do not even bother sending anything if USB CDC is not enumerated
+ or not configured on the PC side or there is no program on the PC
+ listening to our messages */
+ if (!usb_task_cdc_isenabled() || !usb_task_cdc_dtr_active())
+ return;
+
+ /* Wait until the PC has read the pending to be sent data */
while (usb_task_cdc_isenabled() &&
+ usb_task_cdc_dtr_active() &&
!udi_cdc_is_tx_ready()) {
};
- if (!usb_task_cdc_isenabled())
+ /* Do not even bother sending anything if USB CDC is not enumerated
+ or not configured on the PC side or there is no program on the PC
+ listening to our messages at this point */
+ if (!usb_task_cdc_isenabled() || !usb_task_cdc_dtr_active())
return;
// Fifo full
diff --git a/Marlin/src/HAL/HAL_DUE/usb/udi_cdc.c b/Marlin/src/HAL/HAL_DUE/usb/udi_cdc.c
index f8ae82cf8b..c8ab19b4b3 100644
--- a/Marlin/src/HAL/HAL_DUE/usb/udi_cdc.c
+++ b/Marlin/src/HAL/HAL_DUE/usb/udi_cdc.c
@@ -1012,7 +1012,7 @@ iram_size_t udi_cdc_read_buf(void* buf, iram_size_t size)
return udi_cdc_multi_read_buf(0, buf, size);
}
-iram_size_t udi_cdc_multi_get_free_tx_buffer(uint8_t port)
+iram_size_t __attribute__((optimize("O0"))) udi_cdc_multi_get_free_tx_buffer(uint8_t port)
{
irqflags_t flags;
iram_size_t buf_sel_nb, retval;
@@ -1097,7 +1097,7 @@ int udi_cdc_putc(int value)
return udi_cdc_multi_putc(0, value);
}
-iram_size_t udi_cdc_multi_write_buf(uint8_t port, const void* buf, iram_size_t size)
+iram_size_t __attribute__((optimize("O0"))) udi_cdc_multi_write_buf(uint8_t port, const void* buf, iram_size_t size)
{
irqflags_t flags;
uint8_t buf_sel;
diff --git a/Marlin/src/HAL/HAL_DUE/usb/usb_task.c b/Marlin/src/HAL/HAL_DUE/usb/usb_task.c
index bd004c9ca4..711cbf9640 100644
--- a/Marlin/src/HAL/HAL_DUE/usb/usb_task.c
+++ b/Marlin/src/HAL/HAL_DUE/usb/usb_task.c
@@ -52,6 +52,7 @@
static volatile bool main_b_msc_enable = false;
static volatile bool main_b_cdc_enable = false;
+static volatile bool main_b_dtr_active = false;
void HAL_idletask(void) {
// Attend SD card access from the USB MSD -- Prioritize access to improve speed
@@ -69,7 +70,7 @@ void usb_task_msc_disable(void) { main_b_msc_enable = false; }
bool usb_task_msc_isenabled(void) { return main_b_msc_enable; }
bool usb_task_cdc_enable(const uint8_t port) { return ((main_b_cdc_enable = true)); }
-void usb_task_cdc_disable(const uint8_t port) { main_b_cdc_enable = false; }
+void usb_task_cdc_disable(const uint8_t port) { main_b_cdc_enable = false; main_b_dtr_active = false; }
bool usb_task_cdc_isenabled(void) { return main_b_cdc_enable; }
/*! \brief Called by CDC interface
@@ -87,12 +88,17 @@ void usb_task_cdc_config(const uint8_t port, usb_cdc_line_coding_t *cfg) {
dwDTERate = cfg->dwDTERate;
}
+
void usb_task_cdc_set_dtr(const uint8_t port, const bool b_enable) {
+
+ // Keep DTR status
+ main_b_dtr_active = b_enable;
+
// Implement Arduino-Compatible kludge to enter programming mode from
// the native port:
// "Auto-reset into the bootloader is triggered when the port, already
// open at 1200 bps, is closed."
-
+
if (1200 == dwDTERate) {
// We check DTR state to determine if host port is open (bit 0 of lineState).
if (!b_enable)
@@ -102,6 +108,8 @@ void usb_task_cdc_set_dtr(const uint8_t port, const bool b_enable) {
}
}
+bool usb_task_cdc_dtr_active(void) { return main_b_dtr_active; }
+
/// Microsoft WCID descriptor
typedef struct USB_MicrosoftCompatibleDescriptor_Interface {
uint8_t bFirstInterfaceNumber;
diff --git a/Marlin/src/HAL/HAL_DUE/usb/usb_task.h b/Marlin/src/HAL/HAL_DUE/usb/usb_task.h
index f535c9df7a..22328e6de4 100644
--- a/Marlin/src/HAL/HAL_DUE/usb/usb_task.h
+++ b/Marlin/src/HAL/HAL_DUE/usb/usb_task.h
@@ -78,6 +78,19 @@ void usb_task_cdc_disable(const uint8_t port);
*/
void usb_task_cdc_set_dtr(const uint8_t port, const bool b_enable);
+/*! \brief Check if MSC is enumerated and configured on the PC side
+ */
+bool usb_task_msc_isenabled(void);
+
+/*! \brief Check if CDC is enumerated and configured on the PC side
+ */
+bool usb_task_cdc_isenabled(void);
+
+/*! \brief Check if CDC is actually OPEN by an application on the PC side
+ * assuming DTR signal means a program is listening to messages
+ */
+bool usb_task_cdc_dtr_active(void);
+
/*! \brief Called by UDC when USB Host request a extra string different
* of this specified in USB device descriptor
*/
--
GitLab