USBSerial topic much ado about DTR

Post here first, or if you can't find a relevant section!
Post Reply
ag123
Posts: 1655
Joined: Thu Dec 19, 2019 5:30 am
Answers: 24

USBSerial topic much ado about DTR

Post by ag123 »

recently i'm messing around USBSerial codes with stm32duino STM core.
in part to fix a startup stalling problem i encountered in linux, that one is solved
viewtopic.php?f=62&t=1000

then i accidentally walked into the trenches of another problem DTR. It is pretty interesting really.
some one needs USBSerial without DTR
https://github.com/stm32duino/Arduino_C ... ssues/1193
viewtopic.php?f=62&t=461

well with USB Serial, why do we need DTR after all? ok well there is RS232 - die hard, die harder ... it never dies, the concept lives on never mind that today we are doing 5g millimeter wave comms, we'd soon need visible light frequencies, then uv, euv and x-rays frequencies for higher speeds ;)

it turns out the issue isn't about DTR.

an off topic item:
there is a big *headache* about usb (serial) comms because, of os differences and add serial monitor (terminal) differences.
windows is jittery about 'drivers', if you connect some terminal programs, then happily disconnect the wire, re-connect. oops doesn't enumerate lol
https://github.com/stm32duino/Arduino_C ... -471624638

then next the serial monitors
unlike the prior op, 'i'dont care if DTR is set, just send the data across, any anyway someone receives the parcel, it works ;)'
there are others who are paranoid about losing data
https://github.com/stm32duino/Arduino_C ... -468534671
why the serial assistant on PC can't receive data with follow sketch:

Code: Select all

#include <Arduino.h>
#include "USBSerial.h"

void setup()
{
    SerialUSB.begin();
    pinMode(LED_BUILTIN, OUTPUT);
}

void loop()
{
//    if (SerialUSB.available() > 0)
    {
       SerialUSB.println("testing read and wirte");
    }
    digitalToggle(LED_BUILTIN);
    delay(300);
}

Only when I add this line "if (SerialUSB.available() > 0)", then send some data with serial assistant on PC, the PC can receive data continusly.
then as it turns out serial monitors (terminals) can be classified into 'well behaved' (sets the DTR or i'm not sure what eise) vs some other that 'doesn't bother'
@fpistm @ghent360 Thanks for your help. As you said, when I test with Arduino serial monitor, it's work well with "
while(!SerialUSB)"; But when test with other Serial Assistant on PC, it can't work. I think mabe the Arduino serial monitor have done something when opened.
Testing with putty and it works. Maybe this PR handling the DTR will allow to work with your term
@fpistm Yes, the Putty works fine, thank you . I have just tested another serial assistant.
.....
maybe some conclusion:

it turns out this PR kind of tells what is the state-of-the-art or rather bleeding edge
USBSerial should (would) not block on write if the USB inteface is not connected
https://github.com/stm32duino/Arduino_C ... 2/pull/444

it turns out this has something to do with the USB polling design, in USB all comm is initiated by the host - polling !
including all that IN and OUT packets, the host need to issue an IN or OUT to the board/mcu and the mcu simply responds.

this now becomes a catch sort of, we'd not know if there is 'someone on the line at the other end answering the phone'.
so DTR becomes a convenient flag kind of if a terminal / monitor connects and that it has to set DTR to conform to this 'protocol'.

there are 'unanswered questions':
e.g. - can we tell if usb is connected from the usb stack if usb is enumerated? i.e. the host has done enumeration and usb-serial is initialized.
- and can we consider this being 'connected'? i.e. now if i've any data parcel, i'd just put that in the queue for scotty to beam it up.
- then there is this very gray area if you pull that wire, then literally that 'USBSerial should not block PR' fails as well.
but that happens whether it is DTR or just that usb is enumerated. i.e. 'USB is not connected' has to be that it is *never connected*,
at least since reset/power up.
- if enumeration can be deem *connected*, then we can do away with DTR and simply throw the parcel through the window or leave it at the door.
if it is stolen too bad ;)
then there is the known unknown about all that windows/linux/mac os 'drivers' and 'terminals' handling of the usb-serial comms on the host side.
e.g. if we just leave the parcel at the door that's ok? i.e. if the host ask for an IN for usb-serial, we'd just give the data, that's all. why do we need to care who answer the call :lol:
ag123
Posts: 1655
Joined: Thu Dec 19, 2019 5:30 am
Answers: 24

Re: USBSerial topic much ado about DTR

Post by ag123 »

closely related to this is the topic of *flow control*

it turns out USB CDC ACM provides for DTE and RTS
setcontrollinestate.png
setcontrollinestate.png (17.19 KiB) Viewed 2443 times
but DSR and CTS is missing

that effectively makes it 'useless' for 'flow control' implementations
ag123
Posts: 1655
Joined: Thu Dec 19, 2019 5:30 am
Answers: 24

Re: USBSerial topic much ado about DTR

Post by ag123 »

the DTR and RTS signals are rather 'commonly' (ab)used for some other things as they don't serve the original purpose of 'flow control'
e.g. in stm32loader, DTR and RTS 'signals' are used to toggle reset and boot0 for flashing firmware using internal uart boot loader
https://github.com/jsnyder/stm32loader
the use of DTR signal may create issues if say we want to make a usb-uart implementation where the DTR/RTS signals can be used for 'other' purpose
ag123
Posts: 1655
Joined: Thu Dec 19, 2019 5:30 am
Answers: 24

Re: USBSerial topic much ado about DTR

Post by ag123 »

the check for USBSerial.availableforWrite() is necessary for anyone needing a 'reliable' transfer scheme.
the reason is that print(), write() etc would otherwise block, and that is not ok in most circumstances even in loop().

so anyone who want to receive the data without fail has to use.

Code: Select all

if(USBSerial.availableforWrite() > length) {
    USBSerial.println("print from usbserial");
}
as it would be unreasonable for println() or write() to block for any reason and prevent other processing.
i.e. anyone who needs 'blocking' serial behavior has to do so themselves.
Post Reply

Return to “General discussion”