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
This commit is contained in:
parent
4aebe3d82e
commit
404fc94705
4 changed files with 45 additions and 5 deletions
|
@ -36,6 +36,7 @@
|
||||||
// Imports from Atmel USB Stack/CDC implementation
|
// Imports from Atmel USB Stack/CDC implementation
|
||||||
extern "C" {
|
extern "C" {
|
||||||
bool usb_task_cdc_isenabled(void);
|
bool usb_task_cdc_isenabled(void);
|
||||||
|
bool usb_task_cdc_dtr_active(void);
|
||||||
bool udi_cdc_is_rx_ready(void);
|
bool udi_cdc_is_rx_ready(void);
|
||||||
int udi_cdc_getc(void);
|
int udi_cdc_getc(void);
|
||||||
bool udi_cdc_is_tx_ready(void);
|
bool udi_cdc_is_tx_ready(void);
|
||||||
|
@ -56,9 +57,11 @@ int MarlinSerialUSB::peek(void) {
|
||||||
if (pending_char >= 0)
|
if (pending_char >= 0)
|
||||||
return pending_char;
|
return pending_char;
|
||||||
|
|
||||||
|
// If USB CDC not enumerated or not configured on the PC side
|
||||||
if (!usb_task_cdc_isenabled())
|
if (!usb_task_cdc_isenabled())
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
// If no bytes sent from the PC
|
||||||
if (!udi_cdc_is_rx_ready())
|
if (!udi_cdc_is_rx_ready())
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
@ -73,9 +76,11 @@ int MarlinSerialUSB::read(void) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If USB CDC not enumerated or not configured on the PC side
|
||||||
if (!usb_task_cdc_isenabled())
|
if (!usb_task_cdc_isenabled())
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
// If no bytes sent from the PC
|
||||||
if (!udi_cdc_is_rx_ready())
|
if (!udi_cdc_is_rx_ready())
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
@ -83,7 +88,10 @@ int MarlinSerialUSB::read(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MarlinSerialUSB::available(void) {
|
bool MarlinSerialUSB::available(void) {
|
||||||
|
/* If Pending chars */
|
||||||
return pending_char >= 0 ||
|
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());
|
(usb_task_cdc_isenabled() && udi_cdc_is_rx_ready());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,11 +100,22 @@ void MarlinSerialUSB::flush(void) {
|
||||||
|
|
||||||
void MarlinSerialUSB::write(const uint8_t c) {
|
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() &&
|
while (usb_task_cdc_isenabled() &&
|
||||||
|
usb_task_cdc_dtr_active() &&
|
||||||
!udi_cdc_is_tx_ready()) {
|
!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;
|
return;
|
||||||
|
|
||||||
// Fifo full
|
// 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);
|
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;
|
irqflags_t flags;
|
||||||
iram_size_t buf_sel_nb, retval;
|
iram_size_t buf_sel_nb, retval;
|
||||||
|
@ -1097,7 +1097,7 @@ int udi_cdc_putc(int value)
|
||||||
return udi_cdc_multi_putc(0, 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;
|
irqflags_t flags;
|
||||||
uint8_t buf_sel;
|
uint8_t buf_sel;
|
||||||
|
|
|
@ -52,6 +52,7 @@
|
||||||
|
|
||||||
static volatile bool main_b_msc_enable = false;
|
static volatile bool main_b_msc_enable = false;
|
||||||
static volatile bool main_b_cdc_enable = false;
|
static volatile bool main_b_cdc_enable = false;
|
||||||
|
static volatile bool main_b_dtr_active = false;
|
||||||
|
|
||||||
void HAL_idletask(void) {
|
void HAL_idletask(void) {
|
||||||
// Attend SD card access from the USB MSD -- Prioritize access to improve speed
|
// 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_msc_isenabled(void) { return main_b_msc_enable; }
|
||||||
|
|
||||||
bool usb_task_cdc_enable(const uint8_t port) { return ((main_b_cdc_enable = true)); }
|
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; }
|
bool usb_task_cdc_isenabled(void) { return main_b_cdc_enable; }
|
||||||
|
|
||||||
/*! \brief Called by CDC interface
|
/*! \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;
|
dwDTERate = cfg->dwDTERate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void usb_task_cdc_set_dtr(const uint8_t port, const bool b_enable) {
|
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
|
// Implement Arduino-Compatible kludge to enter programming mode from
|
||||||
// the native port:
|
// the native port:
|
||||||
// "Auto-reset into the bootloader is triggered when the port, already
|
// "Auto-reset into the bootloader is triggered when the port, already
|
||||||
// open at 1200 bps, is closed."
|
// open at 1200 bps, is closed."
|
||||||
|
|
||||||
if (1200 == dwDTERate) {
|
if (1200 == dwDTERate) {
|
||||||
// We check DTR state to determine if host port is open (bit 0 of lineState).
|
// We check DTR state to determine if host port is open (bit 0 of lineState).
|
||||||
if (!b_enable)
|
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
|
/// Microsoft WCID descriptor
|
||||||
typedef struct USB_MicrosoftCompatibleDescriptor_Interface {
|
typedef struct USB_MicrosoftCompatibleDescriptor_Interface {
|
||||||
uint8_t bFirstInterfaceNumber;
|
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);
|
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
|
/*! \brief Called by UDC when USB Host request a extra string different
|
||||||
* of this specified in USB device descriptor
|
* of this specified in USB device descriptor
|
||||||
*/
|
*/
|
||||||
|
|
Reference in a new issue