chipKIT® Development Platform

Inspired by Arduino™

[solved] Can we polling USB CDC for DTR / RTS LineState?

Created Wed, 20 Dec 2017 20:53:27 +0000 by sopal


sopal

Wed, 20 Dec 2017 20:53:27 +0000

hi

like the topic says, i would know, can someone help to give a hint? i read here and there in the chipKIT docus, but have not found yet an answere for this.

i would use USB Serial as base Serial

Serial.begin(115200);

and in the loop i would ask for DTR / RTS signal in this USB COM and would act then or is there an ISR / INT for this need/available? how i can do this? polling like this would help for first steps

..
if ( USB_cdc_DTR == 0 )
.. 
// or 
if ( USB_cdc_RTS == 0 ) ..
..

i want use chipKIT Lenny board ( wait for delivery ) edit: typo

edit:

i did also test usb driver on this way but find not out, how we can read the status line ( or set )

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

USBFS usbDriver;
USBManager USB(usbDriver, 0x0403, 0xA662);

CDCACM usbSerialPort;


void setup() {
	
	USB.addDevice(usbSerialPort);
	USB.begin();
}

void loop() {

	usbSerialPort.println("usbSerial");
	delay(1000);

	usbSerialPort.print("Status: ");

	// is private
	// usbSerialPort.println(usbSerialPort._lineState);
	// how i can check/set for DTR/DSR RTS/CTS
}

majenko

Thu, 21 Dec 2017 11:58:10 +0000

There is no specific function for getting the DTR, but the int operator of the Serial classes is designed to return the status of the port, which is gleaned from either of the two lowest bits of the line coding being 1 (that is equivalent to DTR and RTS).

This is standard Arduino functionality:

if(Serial) Description Indicates if the specified Serial port is ready. On the Leonardo, if (Serial) indicates whether or not the USB CDC serial connection is open. For all other instances, including if (Serial1) on the Leonardo, this will always return true. This was introduced in Arduino IDE 1.0.1. Syntax All boards: if (Serial) Arduino Leonardo specific: if (Serial1) Arduino Mega specific: if (Serial1) if (Serial2) if (Serial3) Parameters Nothing Returns boolean : returns true if the specified serial port is available. This will only return false if querying the Leonardo’s USB CDC serial connection before it is ready. Example Code void setup() { //Initialize serial and wait for port to open: Serial.begin(9600); while (!Serial) { ; // wait for serial port to connect. Needed for native USB } } void loop() { //proceed normally }


sopal

Fri, 22 Dec 2017 21:14:35 +0000

There is no specific function for getting the DTR, but the int operator of the Serial classes is designed to return the status of the port, which is gleaned from either of the two lowest bits of the line coding being 1 (that is equivalent to DTR and RTS).

hi majenko

thank you for your friendly help.

i hope i have understand right, can we check DTR and RTS by this 'int' operator? do i understand this right by doing this: ( not sure´i have right understand , do the right )

void loop() {
..
..
// DTR
	if (bitRead(usbSerialPort,0) == 0) {
		// DTR = 0
		digitalWrite(LED_DTR,0);
	}

	// DTR
	if (bitRead(usbSerialPort,0) == 1) {
		// DTR = 1
		digitalWrite(LED_DTR,1);
	}

	// RTS
	if (bitRead(usbSerialPort,1) == 0) {
		// RTS = 0
		digitalWrite(LED_RTS,0);
	}

	// RTS
	if (bitRead(usbSerialPort,1) == 1) {
		// RTS = 1
		digitalWrite(LED_RTS,1);
	}
..
..
} // loop

is there a way to check (example code before) set ( not sure how we could do this like on FTDI and Co )
on PIC32 ( Lenny ) with Serial ( i did understand that is the "USB UART" and Serial0 "HW UART2" and Serial1 "HW UART1".

any hint i thank you. i will do likewise things with FTDI and switch the DTR and RTS line / ceck this lines.

for the DTR i did test this too: i saw, that if i switch the DTR from a Com Serial Programm like HTERM

that then Serial starts

if(Serial) {
 // DTR = 0
		digitalWrite(LED_DTR,0);
}

so i think, the PIC ( usb uart ) must knowing this signal on a way for exist or not exist. if i switch off the DTR from terminal programm, then usb uart stops. ( this is fine )

does we can "filter" trigger the RTS too? i would use this RTS Signal then for an other digi pin for switching.

any help is welcome.


majenko

Sat, 23 Dec 2017 13:47:13 +0000

You can't filter the two signals out, no. It's only an "if either are set" signal.

The internal code is simply:

CDCACM::operator int() {
    return _lineState > 0;
}

I guess code could be added to get the line state, but it would be non-standard (i.e., not in the Arduino specification).


EmbeddedMan

Sun, 24 Dec 2017 13:28:29 +0000

Maybe we should add some chipKIT specific calls to the USB stack to allow a sketch access to these two bits then?

It seems like a useful piece of information to have.

*Brian


majenko

Sun, 24 Dec 2017 13:36:30 +0000

It can be added in USB.h in the CDCACM class as one line:

int getLineState() { return _lineState; }

I guess it could be further divided down for convenience:

bool getDTR() { return ((_lineState & 0x01) == 0x01); }
    bool getRTS() { return ((_lineState & 0x02) == 0x02); }

Since we've just done the merge of the USB stack, though, I suggest we freeze it as it is at the moment so we can get it out. If you want to open an issue on Github for the new functionality we can add it to the next release after this one.


sopal

Tue, 26 Dec 2017 18:19:44 +0000

@majenko

at first i want thank you for fast delivery, the kit was delivered on 23.Dez ( happy for this ) so now i can do testings on this hardware too.

[attachment=0]chipKitLenny_delivered_s.jpg[/attachment]

second, your suggest to usb.h - it work's like it must now. thanks for the friendly help. and yes, i would make a PR on this - i think too, that can be a nice addone for doings directly on PIC ( without a FTDI ) example in combine of ESP8266 / ESP32 or other.

*FYI: just in time i work on an application basic code for the PIC32, that start at 0x0 ( without bootloader, PICKit then need ) the application code runs the app code like programmed. after a toggle of DTR / RTS ( esptool ) the application code switch to download mode ( transparent USB < - >HW UART ) and we can then upload firmware to a connected ESP8266 / ESP32 after the upload, the application code runs from start and boot the ESP

with this code line in usb.h *

int getLineState() { return _lineState; }

is this now possible without an extra Button for reset the ESP for boot.

the same then with "tristate" bootloader, but i think i need from you again a little help then - but first i try it
*

the _Status Line testcode was:

#include &lt;Arduino.h&gt;
#include "USB.h"

#define LED_DTR 24 // RA8 
#define LED_RTS 27 // RA9 

USBFS usbDriver;
USBManager USB(usbDriver, 0x0403, 0xA662);

CDCACM usbSerialPort;

void setup() {

	// PINS as Output
	pinMode(LED_DTR,OUTPUT);
	pinMode(LED_RTS,OUTPUT);

	// pins set 0
	digitalWrite(LED_DTR,0);
	digitalWrite(LED_RTS,0);

	USB.addDevice(usbSerialPort);
	USB.begin();
}

void loop() {

	// Testcase
	usbSerialPort.print("\r"); // start allways in the same line
	// usbSerialPort.print("_Line Status is: ");
	usbSerialPort.print(usbSerialPort.getLineState());
        usbSerialPort.print("\r"); // simple return

	if (usbSerialPort.getRTS()==true) {
		digitalWrite(LED_RTS,1);
	}

	if (usbSerialPort.getRTS()!=true) {
		digitalWrite(LED_RTS,0);
	}


	if (usbSerialPort.getDTR()==true) {
		digitalWrite(LED_DTR,1);
	}

	if (usbSerialPort.getDTR()!=true) {
		digitalWrite(LED_DTR,0);
	}
}

a simple doing on open com, set/unset DTR , set/unset RTS was

Com Open


DTR False RTS False -> COM Port offline DTR True RTS False -> COM Port online -> Line Status : 1 DTR True RTS True -> COM Port online -> Line Status : 1 DTR False RTS True -> COM Port online -> Line Status: 2 DTR True ("again") RTS True -> COM Port online -> Line Status: 3 DTR False RTS True -> COM Port online -> Line Status: 2

a live hack was this then: [attachment=1]testcase.gif[/attachment]

we have now 3 status if we set DTR, COM is starting ( 1 ) if we set RTS and and toogle DTR (2) and again set DTR (3)

if we want start with status 3 then we set first RTS then we set DTR and we have Status 3 toggle DTR line we have Status 2 toogle RTS ( DTR active ) and toggle DTR we go to Status 1

with this knowledge we have now a fine extra many thank you for the friendly help and friendly service! merry christmas ( the gif is an animation - not sure if this run in a forum , perhabs download it )


majenko

Tue, 26 Dec 2017 21:09:52 +0000

One thing you really need to be aware of is that the USB core uses the line state internally to know if the port is opened. If DTR and RTS are both 0 then it won't ever send anything out:

size_t CDCACM::write(uint8_t b) {

    if (_lineState == 0) return 0;