Forum Rule: Always post complete source code & details to reproduce any issue!
Page 1 of 2 1 2 LastLast
Results 1 to 25 of 37

Thread: Software Serial (USB) parity bit

  1. #1
    Senior Member
    Join Date
    Jan 2015
    Posts
    176

    Software Serial (USB) parity bit

    Hello,

    I need to implement a particular serial comm protocol and I need to be able to set the parity bit. Moreover, I need to be able to use the "mark/space" settings for this parity bit instead of the more common options "none/odd/even".

    What's the corresponding library for the virtual (usb) Serial port? Is it the one located at "/hardware/teensy/avr/cores/teensy3/usb_serial.c"? I found some references to the parity bit in its header but I don't know how to actually use it.

    Does anyone have any clue about it? Thanks in advance for any help.

  2. #2
    Senior Member
    Join Date
    Jan 2015
    Posts
    176
    Any help, please? At least a quick guide on how to do it at registry level (I can't find any specific informations online)?
    Thank you very much for your time.

  3. #3
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    10,065
    Not sure if this is looking for Soft Serial versus Hardware - or USB versus UART Serial - On Teensy they are unique and independant, and ther eis some software Serial support - but only on hardware serial ports. That is its own library.

    The indicated file is part of the CORE Teensy code for Arduino - not a 'library' to be included. That is a USB source file not a UART Serial file. Depending on the Teensy in use it will be a Serial# or hardwareSerial type source file IIRC.

    The UART Serial Parity and .begin() settings basically follow these details: https://www.arduino.cc/reference/en/.../serial/begin/

    It shows Parity as the standard No/Odd/Even.

  4. #4
    Senior Member
    Join Date
    Jan 2015
    Posts
    176
    Thank you very much for your reply!

    I need to communicate over the virtual (USB) serial port. I'm going to use Teensy 3.2 for this project but I was running some tests on a Teensy LC and those Serial.begin() options (e.g. SERIAL_8E1) were unavailable. As far as I read, they are only available for the "true" (hardware) UART ports. Am I wrong?

    Do you know what's the core file (or library - it doesn't really matter, I just need to modify anything to make it work) for this virtual (usb emulated) serial port?

    Beside, I need to find a way to implement "force mark" (bit 1) or "force space" (bit 0) for the parity settings as this is a part of the specific comm protocol I'm implementing.

  5. #5
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    20,758
    Quote Originally Posted by someteen View Post
    As far as I read, they are only available for the "true" (hardware) UART ports. Am I wrong?
    Confirmed, this is correct, the parity bits are only used with actual hardware serial ports. Software emulation of those port (eg, the SoftwareSerial and AltSoftSerial libs) do not support parity, but theoretically could.

    But USB virtual serial can never use parity bits. That's not how USB works. However, USB virtual serial does have a feature to communicate the serial setting on your PC to software on Teensy. Those settings aren't used by the USB virtual serial in any way. It simply allows you to see what the serial setting were on the PC side.

    Do you know what's the core file (or library - it doesn't really matter, I just need to modify anything to make it work) for this virtual (usb emulated) serial port?
    Well, to directly answer your question: yes, I do know the core library pretty well, since I wrote it.

    But maybe you really meant to ask something else? Your question is lacking context about what you're actually trying to accomplish. Without context, nobody can understand your real needs. The best we can do for narrow technical questions is not-so-helpful answers.

    Beside, I need to find a way to implement "force mark" (bit 1) or "force space" (bit 0) for the parity settings as this is a part of the specific comm protocol I'm implementing.
    These parity settings apply only to actual serial (either hardware or software, but not USB virtual). The normal way things are done involves communication between the PC and Teensy over USB using whatever virtual serial really does (hint: it's a deep rabbit hole to learn all the USB details) and then code running on Teensy in turn communicate with the serial device using the necessary settings like parity and stop bits.

    Whether that helps you, I just do not know because I have no understanding of what you really are trying to do. The best I can tell you is these facts about how virtual serial and regular serial (whether done by hardware or software emulation) really works.

  6. #6
    Senior Member
    Join Date
    Jan 2015
    Posts
    176
    Thank you very much for your kind support, Paul!

    I need to implement a custom serial protocol where the parity bit is used as a "message start" identifier... that's it, the parity bit needs to be set (1) only for the first byte to be sent then it needs to be cleared (0) for every subsequent byte of that message (the parity bit is not used for CRC purpose as intended by the 232 standard).

    Is there any chance to adjust the core files/libraries to achieve this goal? As I have mentioned before, I'm talking about the USB virtual port.

    LE: Is there any hack available for "tunneling" a hardware UART port through the USB connection? (o some kind of loopback between the virtual (USB) port and a physical one)
    Last edited by someteen; 11-22-2019 at 11:37 AM.

  7. #7
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    5,699
    @someteen - I could be wrong, but it appears to me like you can easily handle this without having to change anything in the core? Or am I missing something?

    That is if you are generating the messages, just send the right stuff?

    Example: if you have some form of packet, where you have a Message Start example 0x85 and has data like 0x00 0x01 0x02, you could simply send out those bytes like:
    Code:
    uint8_t myMessage[] = {0x85, 0x00, 0x01, 0x02};
    Serial.write(myMessage, sizeof(myMessage));
    Obviously this can be expanded and the like. But again I don't know exactly what protocol you are trying to emulate on the RS232 standard?

  8. #8
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    5,699
    Quote Originally Posted by someteen View Post
    LE: Is there any hack available for "tunneling" a hardware UART port through the USB connection? (o some kind of loopback between the virtual (USB) port and a physical one)
    Forgot to talk about this...
    Have you looked at the Example sketch: examples\Teensy\usb_serial\USBtoSerial?

    In this example sketch it turns a Teensy into a USB To Serial adapter. Defaults to Serial1. In this example it checks to see what baud rate the Host has asked for
    Code:
      if (Serial.baud() != baud) {
    And if then changes the Hardware Serial port to use that Baud Rate. And while I don't think this example loooks at some of the other settings, if you look at cores\teensy3\usb_serial.h
    Or teensy4... Don't know which teensy you are using?

    There are other methods like: stopbits, paritytype, numbits
    Which return bits of the usb_cdc_line_coding structure...

    Example, you could try something like: Serial.println(Serial.paritytype(), HEX);
    to see what value gets printed out for the different settings you do on the PC.
    The comments show: // 0=none, 1=odd, 2=even

    But don't know if there might be others in that byte of the structure.

  9. #9
    Senior Member
    Join Date
    Jan 2015
    Posts
    176
    @KurtE:

    Many thanks for your support! Actually, it's not a protocol customized by me but a standard one. Quoting from the protocol datasheet:

    Communication between the client and server occurs through a serial data link operating at 19.2 K in a "wakeup" mode. The 11-bit data packet consists of one start bit, eight data bits, a ninth ‘wakeup’ bit, and one stop bit.

    The client sets the 9th (wakeup) bit each time it sends the first byte of a message to the server. For all additional bytes in the message, this bit is cleared. The server use the wakeup bit to determine whether the received byte is the first byte of a new message or an additional byte of the current message.

    For UARTs that do not directly support wakeup mode, the parity bit can be used in place of the wakeup bit.
    According to this protocol, the server needs to read the 9th bit (the parity one) and to decide by itself if that's the start byte of a new message (parity bit is "1") or it's a "body" byte (parity bit is "0").


    LE: I saw your second post after sending my reply. Well, it looks like it could be the answer, right? It's the "tunneling" I was talking about? Teensy (btw, I'm going to use a T3.2) is processing the virtual (USB) data as it was coming from the (hw) Serial1 pins? It's actually a loopback between the virtual (USB) serial and the hardware Serial1 UART registers?

    LE2: The next challange would be to force the parity bit ("1" or "0") programmatically, as odd/even settings would set that bit dynamically, based on the actual data byte parity.
    Last edited by someteen; 11-22-2019 at 03:24 PM.

  10. #10
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    20,758
    This is often call "9 bit protocol". If you search you'll find it has been discussed many times before. Teensy does support it, but not by default. You will need to edit this line in the core lib.

    https://github.com/PaulStoffregen/co...reSerial.h#L36

    This is not enabled by default because it increases the memory used by the hardware serial ports.

    To send data with the 9th bit, use Serial.write9bit(). Documentation is here:

    https://www.pjrc.com/teensy/td_uart.html

    On the USB side, you will need to build your own special code to communicate the 9th bit, because USB serial is always 8 bit bytes. The simplest way would involve using 2 bytes to send each normal byte in ASCII hexadecimal. Then use another character to indicate when the 9th bit is set. So for the case of setting the 9th bit you would transmit 3 characters instead of only 2. If you choose 10 (line feed '\n') as your special char, the data will print nicely in the Arduino serial monitor, which makes testing easier. Of course, build receiving code which looks for these 17 characters.

    Of course you could build more a more efficient but more complex way to pack your 9 bit messages into the 8 bit bytes. Hexadecimal uses only 4 bits of each 8 bit bybe. But USB is so fast compared to hardware serial that you probably don't need to bother with efficient bit packing.

    USB serial does have a special Serial.send_now() function. You will probably want to call this after you've written a complete message to be transmitted to your PC. Without this, a small delay will occur before the USB code on the Teensy side actually makes the data ready to send to your PC. This small delay may or may not matter for your needs, but I'm mentioning it because it is sometime an issue with this sort of communication protocol... and because I now have an understanding of which protocol you're actually trying to use.
    Last edited by PaulStoffregen; 11-22-2019 at 04:05 PM. Reason: typo

  11. #11
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    5,699
    @someteen (@PaulStoffregen) - maybe I am wrong, but what you describe is a 9 bit serial, that is something like 8NE or the like.

    The Teensy hardware serial ports support this type of stuff, however I am not sure if it has been test much on T4, but luckily you are using T3.2...

    Built in to SerialX.begin() you have options like:
    Code:
    Serial1.begin(19200, SERIAL_8N1);
    Likewise you have support for 8E1...

    But not 9 data bits. To do so, you need to go into the file HardwareSerial.h
    And uncomment the line:
    Code:
    // Uncomment to enable 9 bit formats.  These are default disabled to save memory.
    //#define SERIAL_9BIT_SUPPORT
    With this you have the option of turning on: 9 data bits with: SERIAL_9N1

    Again I don't know of any MARK or ZERO type definition, but this does allow you to enable the ability for you to set the 9th bit. BUT as a side effect all of the internal buffers for Serial ports will double in size (16 bit entries instead of 8 bit)...

    What I don't know is if or how USB_CDC support works (if at all) for 9 bit serial. i.e. is it supported at all at the USB level and if so what does it do the Teensy USB driver...

  12. #12
    Senior Member
    Join Date
    Jan 2015
    Posts
    176
    @Paul & @KurtE:

    Thank you both for the detailed answers (sorry for the delay - blame it on the timezone).

    Anyway, looks like the whole 9-bit solution still applies to hardware serial only (e.g. Serial1). As I only have the USB connection available (on the PC side) I need to stick with the virtual port.

    In the mean time, I have (re)read the MK20DX256VLH7 datasheet (especially the UART section) and I found no reference to mark/space options for the parity bit (just odd/even). I could manage this situation by checking the parity of every message byte and change the parity settings accordingly before sending that byte (though that means I'll have to restart the serial interface each time a byte needs to be sent - and that's overkill).

    But the real problem is if the virtual (USB) serial allow this parity bit to be set/sent or it's just only sending 8 bit (1 byte) data packets without the start/stop/parity bits whatsoever (that's what I have understood reading the @Paul's message above).

    Looks like the Serial-to-USB sketch is just a data registry loopback between the virtual (USB) port and a hardware serial port. It does not reflect the rest of the hardware UART registry (start/stop/parity bits) to the virtual (USB) port corresponding remote device (a PC, in my particular situation).

    Btw, I understood @Paul suggestion of doubling the bytes to be sent and using every second byte as a carrier for the parity informations but I'll have to stick with the protocol requirements (1xstart/8xdata/1xparity/1xstop) as the remote PC app is not developed by myself hence it is just attempting to read the wakeup/parity bit.

  13. #13
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    5,699
    Totally understand the timezone differences with delays...

    Yep if you look at the K20P64M172SF1RM.pdf (assuming I typed the name correctly), but this is the reference manual for the T3.2 which you can get from the PJRC website...

    At section 47.4.5.2 It talks about 9 bit configuration.

    Likewise the T4 reference Manual in section 48.3.5.1 (Data Modes under Aditional LPUART functions). ...
    Which has a paragraph:
    The 9-bit data mode is typically used with parity to allow eight bits of data plus the parity
    in the ninth bit, or it is used with address-mark wakeup so the ninth data bit can serve as
    the wakeup bit.
    As you mention, most of the documents do not describe Mark/Space Parity, as what does that mean? It typically implies something like either the bit is either always a 1 or always a 0 (not much of a parity bit?)....

    But internal to the SerialX code there is setup to handle 9 bit data, as we both mentioned. Once you turn it on, you send words instead of bytes to the UART and it updates the 9th bit appropriately. But again that implies everything you send to it is Words, not bytes. So things like: Serial1.print("This is text"); will only output low order 8 bits for each one, but I believe it will setup to store those as words in queue....

    Yes the Sketch mentioned, only monitors that the Baud rate changed, not that parity/word length option changed on the USB side, which probably valid for maybe 95+% of the usages that I have seen, that work using 8N1. It could easily be extended to turn on modes like 7E1 or 7O1.

    The one I would more likely change for some slow devices to to monitor the number of stop bits, to allow changing the hardware uart to something like 8N2...

    What I think Paul was saying and what I sort of mentioned that maybe Paul could answer, was the USB standard USB_CDC standard have any defined way to say transfer 9 bit mode. His answer was more or less NO, with the caveat that you as an application developer are free to develop you own way to do so.

    But Again I don't know your setup, or exactly what it is you are trying to do... Things like, is there some specific software package you are running on a PC, that is outputting this, stuff, that you are trying to emulate and get between it and a device?

    If so you may need to know what the device does to handle it. If you are developing your own, then you are free to do it any which way that works for you.

    Again I don't know your data flow or desired stuff. If mainly you are trying to capture a data from input sensor, so send back to PC, then simply setup the UART to receive the data, then choose any which format of data that you wish for and then send it to the PC... i.e. no requirement for special packing with 9 bits...

    Likewise if the PC is generating a request that goes through Teensy, to device, on the PC choose a convenient way to send the data to the Teensy, who can then convert that request into the format the device needs...

  14. #14
    Senior Member
    Join Date
    Jan 2015
    Posts
    176
    That's right, @KurtE, a 9-bit communication may solve the problem but, than again, I don't know if it works with the virtual (USB) port.

    As you have suggested, I'm going to read the full USB CDC/ACM specifications to see if there's any chance of using a 9-bit serial communication through the USB port.

    Btw, I don't have access to the PC application (commercial stuff) hence I'll have to stick to the protocol as tight as possible. Once again, many thanks for your kind support! I'll post back after reading that CDC/ACM stuff.


    LE:

    Looks like there are some class requests defined in the CDC/ACM specifications, namely the SET_LINE_CODING (code 20H, configures baud rate, stop-bits, parity, and number-of-character bits) and the corresponding GET_LINE_CODING (code 21H).

    Moreover, the line coding format allows the parity type as follow: 0:None 1: Odd 2: Even 3: Mark 4: Space.

    Unfortunatelly, the DataBits format allows only 5, 6, 7, 8 or 16 bit values (hence no 9-bit support).

    I'm looking forward for the @Paul insight on this matter (I guess the CDC is implemented at the bootloader level so there's nothing I can do about it).
    Last edited by someteen; 11-23-2019 at 07:45 PM.

  15. #15
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    5,699
    As mentioned, Paul does grab the line coding information... That is how we grab all of those interesting settings, already mentioned...

    So again it may really depend on exactly what your PC software is doing...

    Warning, I don't understand what you mean by the virtual USB port?

    Note all of the software normally used on Teensy is part of the Teensy code base...

    So if you are talking about the Serial emulation, that Paul puts in, such that for example you have the Serial Monitor available if you configured your USB code to be something else like a joystick, or a mouse...

    I believe all of that code is in usb_seremu.c (.h) This one is more limited than the real USB Serial code.
    Like if you ask for baud it returns 9600, if you ask for paritytype it returns 0...

    I believe Paul already mentioned, sort of the similar stuff.

    Again sort of just shooting in the dark, as now so far all I know is it is a commercial product. Don't know any specifics of what it is talking to? What PC driver it uses to talk to device?
    For example FTDI devices have a different driver. On Linux a Teensy shows up like ttyACM0, ttyACM1... where as an FTDI device shows up as ttyUSB0, ttyUSB1...
    Likewise there are other drivers for other USB to Serial....

    Each of them may have different functionality and configurations... So again hard to give specific suggestions.

    Note: when I am working on the USBHost_t36 software to try to add support for some new device, some of the steps I do include:

    a) google to see if someone has already done it.

    b) Plug it into a Linux box (at times maybe just an RPI3 or 4), and print out all of the data that the dmesg | tail -50
    Plus do things like HID dumps to get more details on what drivers may support the device and ideas of if it is HID, what reports and the like it has defined...

    b1) Plug into PC and see what Device Manager says is begin used...

    c) Setup my Saleae logic analyzer to some cut up serial cable that I can get to the USB D+ and D- signals and capture some of the USB conversations and then try to extract what logical packets are being sent both directions and the like... (Sort of a pain). Paul has a hardware USB analyzer I believe something like a Beagle USB 480.... Which would be be great if you did things like that a lot of the time, but...


    d) See if there is some sources for some of the drivers if someone one has already done it... Like Linux driver sources, or USB Host Shield 2...

    But again not sure what else I can mention, without having a clue... And the clue may be more of the information in the above steps.

  16. #16
    Senior Member
    Join Date
    Jan 2015
    Posts
    176
    Glad to hear you're an advanced USB/CDC developer! This is my first project of this kind and I don't know if it worth investing in a hw analyzers & stuff (I have an oscilloscope though).

    So, Teensy uses no coding informations on the CDC/ACM emulator? Unfortunately, that means I'll have to replace the T3.2.. but I guess the whole Teensy range has the same (mis)functionality?

  17. #17
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    5,699
    Experienced? A little more by trial and error.

    As I mentioned, I am shooting stuff out here with my eyes closed. i.e. have no clue what your device is doing or expecting.

    Also you talk both about USB and Hardware Serial? So how is this device Actually connected up to a PC?

    Again are you a) trying to emulate the device and/or b) you wish to intercept and update and or log the data?

    Again have you plugged the device into a PC and know which device drivers it is using? Something standard like the Teensy uses. Like on my Windows 10 machine a Teensy shows up as: USB Serial Device, driver by Microsoft, with driver details, shows it using ...\windows\system32\DRIVERS\usbser.sys

    i.e. generic...

    But if I for example plug in a FTDI USB to serial adapter and look at device manager it shows Driver Provider: FTDI
    And it shows maybe 4 drivers under details...

    Does your device show up the same or does it potentially have either some other drivers?

    If it is a standard Serial device CDC_ACM, and you plug in your teensy and tell your PC to use the teensy Serial port. What does it do? Does it send out a packet to the device?

    If it were me, one of the first things I would do is to see if I could do a quick and dirty dump of the data coming from the PC?

    I would probably plug in the teensy and hex dump everything it receives maybe with some form of time stamps... I would probably dump it out to some other Hardware Serial port like Serial1, and then hook up Serial1 back to my PC with one of my USB to Serial adapters...

    i.e. something like:

    Code:
    void setup() {
        Serial1.begin(2000000);  // whatever speed your usb to serial device can handle...
        while (!Serial && millis() < 5000) ; // wait up to 5 seconds for monitor to open...
        Serial.begin(115200);
    }
    
    void loop() {
        if (Serial.available()) {
            Serial1.printf("\nT:%u: Baud:%d num bits: %d Parity: %d Stop:%d \n", uint32_t millis(), Serial.baud(), Serial.numbits(), Serial.paritytype(), Serial.stopbits()); // might use micros if not enough resolution...
            uint8_t cnt=0;
            int ch;
            while ((ch=Serial.read() != -1) {
                Serial1.printf(" 02x", ch); 
                if (!(++cnt &0xf) Serial1.println();
            }
            Serial1.println();
        }
    }
    Again really lame, typed in on the fly, so probably has bugs, but would start to get an idea of what the host is sending...
    Also a little about timings and bauds and ...

    Then depending on what I saw there, would dictate what I would do next.

    But again, we are just guessing in the dark

  18. #18
    Senior Member
    Join Date
    Jan 2015
    Posts
    176
    Many thanks for your extended answer and sorry for the lack of information.

    There's no comercial hardware device involved but an app running on a PC (x86). That app could only be controlled through a serial connection (RS-232 over USB) using that uncommon protocol (9-bit/wakeup-bit). Now here I am, trying to use a Teensy to emulate a (wired) remote controller for that app.

    That's it, I just need to build a USB-to-serial adapter that is capable of sending/reading coding informations (parity bit) to communicate with that app. For testing purpose only, I'm going to buy a commercial USB-to-serial adapter to check if it actually uses that coding informations (parity) hence I could use it to communicate with that app . Could you recommend a particular manufacturer (FTDI)?

  19. #19
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    5,699
    @someteen - Good luck, I am not sure I can give you any other suggestions.

    As for ones to try: Sparkfun for example sells several different ones with different chip sets like:

    Like FTDI (probably the most used chip set?) https://www.sparkfun.com/products/12731
    CY7C65213 : https://www.sparkfun.com/products/13830
    CH340: https://www.sparkfun.com/products/15096

    Probably the 2nd most popular chipset maybe was prolific PL2303, which I don't know if prolific actually exists anymore? But you can still get things with it: LIke from Amazon
    https://smile.amazon.com/Adapter-Pro.../dp/B0758B6MK6

    Many of these may require you to install a driver on Windows, to use them. Which again,

    If you actually have your PC app installed and have one of their wired remote controller, you should hopefully then be able to deduce which chip set that controller uses by looking in the device manager. Likewise many PC apps will end up installing drivers like this and sometimes it is obvious of which one... Or if it just uses the default Windows Serial driver?

    Again if it were me, I would do a couple of quick tests to get ideas of what actually is being sent/received.

    a) One to see if the App is sending something that makes sense, like I posted in previous message.

    b) One that connects up the remote control to a Teensy, and again write an app like the one I mentioned but in reverse. That is dump everything it receives from the device out through debug monitor....

    Again I don't know what you mean by:
    That app could only be controlled through a serial connection (RS-232 over USB) using that uncommon protocol (9-bit/wakeup-bit).
    Are you saying that the actual device has a serial connection coming out of it and there is another thing it plugs into to adapt it to USB?

    If I had a setup with actual RS232 signals, I might also be tempted to try converting the signals to TTL like (https://www.sparkfun.com/products/11189) and then look at what data stream I get, both by intercepting by Teensy and/Or Logic analyzer...

    Or if it were me and I had the USB connection from the controller, I might again do the steps I mentioned earlier to plug into Linux and get lots of the details...

    I then might plug it into a T3.6 with USBHost, and have one of our USBHost apps running with a lot of debug prints turned on and again try to see what hints might there be...

    Good luck

  20. #20
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    20,758
    Quote Originally Posted by someteen View Post
    (I guess the CDC is implemented at the bootloader level so there's nothing I can do about it).
    Nope, that's a wrong assumption on your part. CDC ACM protocol is indeed implemented by the core library, which you can edit. On Teensy 3.2, the main files are usb_serial.c and usb_dev.c.

    How does this PC software accesses the 9th bit on the host side? Is it running on Windows? If so, does it use only WIN32 APIs, or is it using trickery to directly access UART registers? I'm not a Windows expert (I mainly use Linux and sometimes Macs) but a quick search turns up answers like this which seem to say special hardware and drivers are needed on Windows to do 9 bit serial. So I wonder what PC serial port hardware this mystery software would normally support?

  21. #21
    Senior Member
    Join Date
    Jan 2015
    Posts
    176
    Quote Originally Posted by PaulStoffregen View Post
    How does this PC software accesses the 9th bit on the host side? Is it running on Windows? If so, does it use only WIN32 APIs, or is it using trickery to directly access UART registers?
    @Paul, I'll post again the protocol specifications used by the host app:

    The 11-bit data packet consists of one start bit, eight data bits, a ninth ‘wakeup’ bit, and one stop bit.

    The client sets the 9th (wakeup) bit each time it sends the first byte of a message to the server. For all additional bytes in the message, this bit is cleared. The server use the wakeup bit to determine whether the received byte is the first byte of a new message or an additional byte of the current message.

    For UARTs that do not directly support wakeup mode, the parity bit can be used in place of the wakeup bit.
    The host app is written in Java hence it runs on different platforms. According to the protocol specifications, this is not a "true" 9-bit communication but a "8P1" one, where the parity bit isn't used for CRC purpose but message header identification.

    Quote Originally Posted by PaulStoffregen View Post
    So I wonder what PC serial port hardware this mystery software would normally support?
    The host app uses a regular virtual comm port (USB) - or a hardware RS-232 one, of course. It just needs CDC_SET_LINE_CODING to be sent by the remote controller, for the host to be able to read the parity bit.

    Quote Originally Posted by PaulStoffregen View Post
    CDC ACM protocol is indeed implemented by the core library, which you can edit. On Teensy 3.2, the main files are usb_serial.c and usb_dev.c.
    Are you suggesting that I could enable that CDC_SET_LINE_CODING for the virtual port? I've read the content of the core files you've pointed out but I don't know what needs to be modified. Could you be more specific, please?

  22. #22
    Senior Member
    Join Date
    Jan 2015
    Posts
    176
    Quote Originally Posted by KurtE View Post
    If you actually have your PC app installed and have one of their wired remote controller, you should hopefully then be able to deduce which chip set that controller uses by looking in the device manager. Likewise many PC apps will end up installing drivers like this and sometimes it is obvious of which one... Or if it just uses the default Windows Serial driver?
    Unfortunatelly, I don't have any genuine remote controller. But, according to the protocol, it runs over a standard RS-232 serial connection.

    Quote Originally Posted by KurtE View Post
    Again if it were me, I would do a couple of quick tests to get ideas of what actually is being sent/received.
    a) One to see if the App is sending something that makes sense, like I posted in previous message.
    The host app is not "talking" alone. According to the protocol, the host needs to wait for the remote controller requests (polling).

  23. #23
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    5,699
    Sorry - no hints here at all to tell you anything additional, as again no details.

    Like does it install drivers? Which ones?

    If you plug a teensy in with program that tries to guess what it tries to configure the data to? Does it actually receive anything?


    Do you have another top level protocol document that says, when the user presses a key it should send out a message with the following format?

    Have you tried sending one like that?

  24. #24
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    20,758
    Perhaps you could modify usb_dev.c to blink a LED or increment a global variable each time it receives the set line coding control transfer. Then you could try running the host software with Teensy and observe whether the host really is sending those messages. With most PC software, only 1 or 2 of those messages are sent when a program opens the port, depending on how it sets the baud rate.

    If that software does cause lots of set line coding control transfers, maybe you could expand that code to parse those messages. Or maybe the existing function will work. From usb_serial.h:

    Code:
            uint8_t paritytype(void) { return usb_cdc_line_coding[1] >> 8; } // 0=none, 1=odd, 2=even
    Even though the comment in code mentions only 3 values, I hope you can see it is simply copying the entire byte the host sends. If the hosts sends 3, 4, 5 or any other number in that byte, you can read it with Serial.paritytype(). If the host really is sending the parity config changes, maybe you can craft code on the Teensy side to read those changes and send the appropriate data with Serial1.write9bit(). How exactly to do that will depend on the specific timing details of that software, so this advice is pretty much the end of how I can help.

    If the host software doesn't send those messages, and you have no way to edit the host software, then I'm afraid there probably isn't any way to make this work over CDC ACM (at least not with the normal drivers).

  25. #25
    Senior Member
    Join Date
    Jan 2015
    Posts
    176
    @PaulStoffregen & @KurtE:

    Many thanks for your kind support. Unfortunately, I could not post more informations about the protocol as it is proprietary & confidential (license based).

    The protocol requirements sound prety clear to me though: a data packet consists of 11 bits (one start bit, eight data bits, one parity bit (used as a "wakeup" bit) and one stop bit.

    To mark the first byte of each mesage, the client needs to set the parity bit ("1"). For all additional bytes in the message, the client needs to clear ("0") the parity bit.

    The server uses that parity bit to determine whether the received byte is the first byte of a new message or an additional byte of the current message.

    --

    To sum up:

    Is it possible to send that 11-bit data packets (described above) over the virtual serial port (CDC/ACM) using Teensy 3.2?

    Quote Originally Posted by PaulStoffregen View Post
    Or maybe the existing function will work. From usb_serial.h:

    Code:
            uint8_t paritytype(void) { return usb_cdc_line_coding[1] >> 8; } // 0=none, 1=odd, 2=even
    Even though the comment in code mentions only 3 values, I hope you can see it is simply copying the entire byte the host sends. If the hosts sends 3, 4, 5 or any other number in that byte, you can read it with Serial.paritytype().
    That's exactly what needs to be done. The Teensy must be able to set the parity bit ("1" or "0") before sending every byte of the message. I thought it's all about a simple writing to the (virtual) UART registers.

    Thank you once again for your support, I just need to know if that could be done using a Teensy 3.2 (so I could do further research on this matter).

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •