supervisor: Improve serial connection detection

These changes remove the caveat from supervisor.runtime.serial_connected.

It appears that _tud_cdc_connected() only tracks explicit changes to the
"DTR" bit, which leads to disconnects not being registered.

Instead:
 * when line state is changed explicitly, track the dtr value in
   _serial_connected
 * when the USB bus is suspended, set _serial_connected to False

Testing performed (using sam e54 xplained):  Run a program to show
the state of `serial_connected` on the LED:
```
import digitalio
import supervisor
import board

led = digitalio.DigitalInOut(board.LED)
while True:
    led.switch_to_output(not supervisor.runtime.serial_connected)
```

Try all the following:
 * open, close serial terminal program
    - LED status tracks whether terminal is open
 * turn on/off data lines using the switchable charge-only cable
    - LED turns off when switch is in "charger" position
    - LED turns back on when switch is in Data position and terminal is
      opened (but doesn't turn back on just because switch position is
      changed)
This commit is contained in:
Jeff Epler 2020-09-03 13:36:15 -05:00
parent 7f60ebd6c7
commit 28043c94b5
4 changed files with 9 additions and 8 deletions

View File

@ -46,13 +46,7 @@
//|
//| serial_connected: bool
//| """Returns the USB serial communication status (read-only).
//|
//| .. note::
//|
//| SAMD: Will return ``True`` if the USB serial connection
//| has been established at any point. Will not reset if
//| USB is disconnected but power remains (e.g. battery connected)"""
//| """Returns the USB serial communication status (read-only)."""
//|
STATIC mp_obj_t supervisor_get_serial_connected(mp_obj_t self){

View File

@ -47,4 +47,5 @@ char serial_read(void);
bool serial_bytes_available(void);
bool serial_connected(void);
extern volatile bool _serial_connected;
#endif // MICROPY_INCLUDED_SUPERVISOR_SERIAL_H

View File

@ -47,6 +47,8 @@ busio_uart_obj_t debug_uart;
byte buf_array[64];
#endif
volatile bool _serial_connected;
void serial_early_init(void) {
#if defined(DEBUG_UART_TX) && defined(DEBUG_UART_RX)
debug_uart.base.type = &busio_uart_type;
@ -69,7 +71,7 @@ bool serial_connected(void) {
#if defined(DEBUG_UART_TX) && defined(DEBUG_UART_RX)
return true;
#else
return tud_cdc_connected();
return _serial_connected;
#endif
}

View File

@ -29,6 +29,7 @@
#include "shared-module/usb_midi/__init__.h"
#include "supervisor/background_callback.h"
#include "supervisor/port.h"
#include "supervisor/serial.h"
#include "supervisor/usb.h"
#include "lib/utils/interrupt_char.h"
#include "lib/mp-readline/readline.h"
@ -115,6 +116,7 @@ void tud_umount_cb(void) {
// remote_wakeup_en : if host allows us to perform remote wakeup
// USB Specs: Within 7ms, device must draw an average current less than 2.5 mA from bus
void tud_suspend_cb(bool remote_wakeup_en) {
_serial_connected = false;
}
// Invoked when usb bus is resumed
@ -126,6 +128,8 @@ void tud_resume_cb(void) {
void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) {
(void) itf; // interface ID, not used
_serial_connected = dtr;
// DTR = false is counted as disconnected
if ( !dtr )
{