Browse Source

Merge pull request #10110 from ejtagle/bugfix-2.0.x

[2.0.x] DUE - native port hang (USB CDC: Do not send any character if no program on the PC is listening)
Bob-the-Kuhn 7 years ago
parent
commit
e5157dc63d
No account linked to committer's email address

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

36
 // Imports from Atmel USB Stack/CDC implementation
36
 // Imports from Atmel USB Stack/CDC implementation
37
 extern "C" {
37
 extern "C" {
38
   bool usb_task_cdc_isenabled(void);
38
   bool usb_task_cdc_isenabled(void);
39
+  bool usb_task_cdc_dtr_active(void);
39
   bool udi_cdc_is_rx_ready(void);
40
   bool udi_cdc_is_rx_ready(void);
40
   int udi_cdc_getc(void);
41
   int udi_cdc_getc(void);
41
   bool udi_cdc_is_tx_ready(void);
42
   bool udi_cdc_is_tx_ready(void);
56
   if (pending_char >= 0)
57
   if (pending_char >= 0)
57
     return pending_char;
58
     return pending_char;
58
 
59
 
60
+  // If USB CDC not enumerated or not configured on the PC side
59
   if (!usb_task_cdc_isenabled())
61
   if (!usb_task_cdc_isenabled())
60
     return -1;
62
     return -1;
61
 
63
 
64
+  // If no bytes sent from the PC
62
   if (!udi_cdc_is_rx_ready())
65
   if (!udi_cdc_is_rx_ready())
63
     return -1;
66
     return -1;
64
 
67
 
73
     return ret;
76
     return ret;
74
   }
77
   }
75
 
78
 
79
+  // If USB CDC not enumerated or not configured on the PC side
76
   if (!usb_task_cdc_isenabled())
80
   if (!usb_task_cdc_isenabled())
77
     return -1;
81
     return -1;
78
 
82
 
83
+  // If no bytes sent from the PC
79
   if (!udi_cdc_is_rx_ready())
84
   if (!udi_cdc_is_rx_ready())
80
     return -1;
85
     return -1;
81
 
86
 
83
 }
88
 }
84
 
89
 
85
 bool MarlinSerialUSB::available(void) {
90
 bool MarlinSerialUSB::available(void) {
91
+    /* If Pending chars */
86
   return pending_char >= 0 ||
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
       (usb_task_cdc_isenabled() && udi_cdc_is_rx_ready());
95
       (usb_task_cdc_isenabled() && udi_cdc_is_rx_ready());
88
 }
96
 }
89
 
97
 
92
 
100
 
93
 void MarlinSerialUSB::write(const uint8_t c) {
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
   while (usb_task_cdc_isenabled() &&
110
   while (usb_task_cdc_isenabled() &&
111
+         usb_task_cdc_dtr_active() &&
96
         !udi_cdc_is_tx_ready()) {
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
     return;
119
     return;
101
 
120
 
102
   // Fifo full
121
   // Fifo full

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

1012
 	return udi_cdc_multi_read_buf(0, buf, size);
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
 	irqflags_t flags;
1017
 	irqflags_t flags;
1018
 	iram_size_t buf_sel_nb, retval;
1018
 	iram_size_t buf_sel_nb, retval;
1097
 	return udi_cdc_multi_putc(0, value);
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
 	irqflags_t flags;
1102
 	irqflags_t flags;
1103
 	uint8_t buf_sel;
1103
 	uint8_t buf_sel;

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

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

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

78
  */
78
  */
79
 void usb_task_cdc_set_dtr(const uint8_t port, const bool b_enable);
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
 /*! \brief Called by UDC when USB Host request a extra string different
94
 /*! \brief Called by UDC when USB Host request a extra string different
82
  * of this specified in USB device descriptor
95
  * of this specified in USB device descriptor
83
  */
96
  */

Loading…
Cancel
Save