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)
This commit is contained in:
commit
e5157dc63d
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
Loading…
Reference in a new issue