Browse Source

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

etagle 6 years ago
parent
commit
404fc94705

+ 20
- 1
Marlin/src/HAL/HAL_DUE/MarlinSerialUSB_Due.cpp View File

@@ -36,6 +36,7 @@
36 36
 // Imports from Atmel USB Stack/CDC implementation
37 37
 extern "C" {
38 38
   bool usb_task_cdc_isenabled(void);
39
+  bool usb_task_cdc_dtr_active(void);
39 40
   bool udi_cdc_is_rx_ready(void);
40 41
   int udi_cdc_getc(void);
41 42
   bool udi_cdc_is_tx_ready(void);
@@ -56,9 +57,11 @@ int MarlinSerialUSB::peek(void) {
56 57
   if (pending_char >= 0)
57 58
     return pending_char;
58 59
 
60
+  // If USB CDC not enumerated or not configured on the PC side
59 61
   if (!usb_task_cdc_isenabled())
60 62
     return -1;
61 63
 
64
+  // If no bytes sent from the PC
62 65
   if (!udi_cdc_is_rx_ready())
63 66
     return -1;
64 67
 
@@ -73,9 +76,11 @@ int MarlinSerialUSB::read(void) {
73 76
     return ret;
74 77
   }
75 78
 
79
+  // If USB CDC not enumerated or not configured on the PC side
76 80
   if (!usb_task_cdc_isenabled())
77 81
     return -1;
78 82
 
83
+  // If no bytes sent from the PC
79 84
   if (!udi_cdc_is_rx_ready())
80 85
     return -1;
81 86
 
@@ -83,7 +88,10 @@ int MarlinSerialUSB::read(void) {
83 88
 }
84 89
 
85 90
 bool MarlinSerialUSB::available(void) {
91
+    /* If Pending chars */
86 92
   return pending_char >= 0 ||
93
+    /* or USB CDC enumerated and configured on the PC side and some
94
+       bytes where sent to us */
87 95
       (usb_task_cdc_isenabled() && udi_cdc_is_rx_ready());
88 96
 }
89 97
 
@@ -92,11 +100,22 @@ void MarlinSerialUSB::flush(void) {
92 100
 
93 101
 void MarlinSerialUSB::write(const uint8_t c) {
94 102
 
103
+  /* Do not even bother sending anything if USB CDC is not enumerated
104
+     or not configured on the PC side or there is no program on the PC
105
+     listening to our messages */
106
+  if (!usb_task_cdc_isenabled() || !usb_task_cdc_dtr_active())
107
+    return;
108
+
109
+  /* Wait until the PC has read the pending to be sent data */
95 110
   while (usb_task_cdc_isenabled() &&
111
+         usb_task_cdc_dtr_active() &&
96 112
         !udi_cdc_is_tx_ready()) {
97 113
   };
98 114
 
99
-  if (!usb_task_cdc_isenabled())
115
+  /* Do not even bother sending anything if USB CDC is not enumerated
116
+     or not configured on the PC side or there is no program on the PC
117
+     listening to our messages at this point */
118
+  if (!usb_task_cdc_isenabled() || !usb_task_cdc_dtr_active())
100 119
     return;
101 120
 
102 121
   // Fifo full

+ 2
- 2
Marlin/src/HAL/HAL_DUE/usb/udi_cdc.c View File

@@ -1012,7 +1012,7 @@ iram_size_t udi_cdc_read_buf(void* buf, iram_size_t size)
1012 1012
 	return udi_cdc_multi_read_buf(0, buf, size);
1013 1013
 }
1014 1014
 
1015
-iram_size_t udi_cdc_multi_get_free_tx_buffer(uint8_t port)
1015
+iram_size_t __attribute__((optimize("O0"))) udi_cdc_multi_get_free_tx_buffer(uint8_t port)
1016 1016
 {
1017 1017
 	irqflags_t flags;
1018 1018
 	iram_size_t buf_sel_nb, retval;
@@ -1097,7 +1097,7 @@ int udi_cdc_putc(int value)
1097 1097
 	return udi_cdc_multi_putc(0, value);
1098 1098
 }
1099 1099
 
1100
-iram_size_t udi_cdc_multi_write_buf(uint8_t port, const void* buf, iram_size_t size)
1100
+iram_size_t __attribute__((optimize("O0"))) udi_cdc_multi_write_buf(uint8_t port, const void* buf, iram_size_t size)
1101 1101
 {
1102 1102
 	irqflags_t flags;
1103 1103
 	uint8_t buf_sel;

+ 10
- 2
Marlin/src/HAL/HAL_DUE/usb/usb_task.c View File

@@ -52,6 +52,7 @@
52 52
 
53 53
 static volatile bool main_b_msc_enable = false;
54 54
 static volatile bool main_b_cdc_enable = false;
55
+static volatile bool main_b_dtr_active = false;
55 56
 
56 57
 void HAL_idletask(void) {
57 58
   // 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; }
69 70
 bool usb_task_msc_isenabled(void)             { return main_b_msc_enable; }
70 71
 
71 72
 bool usb_task_cdc_enable(const uint8_t port)  { return ((main_b_cdc_enable = true)); }
72
-void usb_task_cdc_disable(const uint8_t port) { main_b_cdc_enable = false; }
73
+void usb_task_cdc_disable(const uint8_t port) { main_b_cdc_enable = false; main_b_dtr_active = false; }
73 74
 bool usb_task_cdc_isenabled(void)             { return main_b_cdc_enable; }
74 75
 
75 76
 /*! \brief Called by CDC interface
@@ -87,12 +88,17 @@ void usb_task_cdc_config(const uint8_t port, usb_cdc_line_coding_t *cfg) {
87 88
     dwDTERate = cfg->dwDTERate;
88 89
 }
89 90
 
91
+
90 92
 void usb_task_cdc_set_dtr(const uint8_t port, const bool b_enable) {
93
+
94
+  // Keep DTR status
95
+  main_b_dtr_active = b_enable;
96
+
91 97
   //  Implement Arduino-Compatible kludge to enter programming mode from
92 98
   // the native port:
93 99
   //  "Auto-reset into the bootloader is triggered when the port, already
94 100
   // open at 1200 bps, is closed."
95
-    
101
+
96 102
   if (1200 == dwDTERate) {
97 103
     // We check DTR state to determine if host port is open (bit 0 of lineState).
98 104
     if (!b_enable)
@@ -102,6 +108,8 @@ void usb_task_cdc_set_dtr(const uint8_t port, const bool b_enable) {
102 108
   }
103 109
 }
104 110
 
111
+bool usb_task_cdc_dtr_active(void)             { return main_b_dtr_active; }
112
+
105 113
 /// Microsoft WCID descriptor
106 114
 typedef struct USB_MicrosoftCompatibleDescriptor_Interface {
107 115
   uint8_t bFirstInterfaceNumber;

+ 13
- 0
Marlin/src/HAL/HAL_DUE/usb/usb_task.h View File

@@ -78,6 +78,19 @@ void usb_task_cdc_disable(const uint8_t port);
78 78
  */
79 79
 void usb_task_cdc_set_dtr(const uint8_t port, const bool b_enable);
80 80
 
81
+/*! \brief Check if MSC is enumerated and configured on the PC side
82
+ */
83
+bool usb_task_msc_isenabled(void);
84
+
85
+/*! \brief Check if CDC is enumerated and configured on the PC side
86
+ */
87
+bool usb_task_cdc_isenabled(void);
88
+
89
+/*! \brief Check if CDC is actually OPEN by an application on the PC side
90
+ *  assuming DTR signal means a program is listening to messages
91
+ */
92
+bool usb_task_cdc_dtr_active(void);
93
+
81 94
 /*! \brief Called by UDC when USB Host request a extra string different
82 95
  * of this specified in USB device descriptor
83 96
  */

Loading…
Cancel
Save