Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 14 of 14

Thread: disabling UART break detection in T3.x

  1. #1
    Junior Member
    Join Date
    Jun 2018
    Posts
    8

    disabling UART break detection in T3.x

    Does anyone know if it's possible to disable break detection altogether in a T3.x UART? I'm trying to use a T3.x to communicate w/ an established '485 network. But it has terminating resistors in the design that force an undriven line to a 0/spacing state (pull-down on D+, pull-up on D-). Well, to a T3.x, this looks like a break in the line, and that messes up any message that immediately follows. All the '485-to-USB converters seem to ignore breaks, so this hasn't been a problem for anyone else, only me, because I really want to use a T3.x here.

  2. #2
    Senior Member
    Join Date
    Dec 2013
    Posts
    225
    So are you connecting to UART (serial1 serial2 serial3) TX RX or USB D+ D-?
    Correct me if I'm wrong but Teensy 3.x does not have Noise Error, Parity Error or Break interrupt implemented by default on any of the uart serial ports.

    I'm no expert on USB (Universal Serial Bus) but you did mention (pull-down on D+, pull-up on D-).
    I did some Googling and find this:
    The pull-up on D+ perform two tasks, connection and speed sensing. Without a pull up resistor, USB assumes there is nothing connected to the bus.
    Some devices have this resistor built into its silicon, which can be turned on and off under firmware control, others require an external resistor.

  3. #3
    Junior Member
    Join Date
    Jun 2018
    Posts
    8
    Thanks! And sorry for the confusion.
    I'm using serial1, hardware serial, on RS-485. (I'm not clever or daring enough to mess with USB.) And labels D+ and D- are sometimes used on the two balanced-voltage lines in RS-485, too.
    If I remove the non-standard resistors, my T3.5 works great. If I leave the non-standard resistors in place, any other UART works fine, but not T3.5.
    Now, I might be wrong, but my difficulty is not software and interrupts. It seems that with this non-standard pull-up and -down arrangement, the T3.5 hardware has trouble finding the first start bit after the line driver turns on. This could be due to the appearance of a (false) start-bit when the driver turns off, changing my line from a 1 to a zero, and this would mess up character sync for at least 1 character time. But all UARTs would see the false start bit, and most all other UARTs seem to work fine.
    So, I speculate that, instead, it might be due to the hardware's seeing break characters when my line isn't driven, and this does mess with error flags whether interrupts are enabled or not, according to the Kinetis user's manual. And that same manual says I can't disable break character detection, only adjust its length. (I should experiment and see if continuous 0s produce repeated break characters. I'm guessing they do.)
    I'm hoping someone has a trick up their sleeve.

  4. #4
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    20,559
    Let's talk of the RS485 signals as "A" and "B" according to this diagram.

    Click image for larger version. 

Name:	rs485.jpg 
Views:	42 
Size:	22.6 KB 
ID:	14313
    (click for full size)

    Maybe you could describe the circuit again with "A" and "B"?

  5. #5
    Junior Member
    Join Date
    Jun 2018
    Posts
    8
    Yes, thanks. In addition to the termination resistors across A and B, there's one pull-down on the A line and one pull-up on the B. As you know, an idle serial1--hardware serial--data line is high, and A would be high while B is low. But, here, when no driver is enabled, the pull-down on A and pull-up on B cause the data line to read low. And, rather than idle, this looks like a break, or an all-zeros character with no stop bit.

  6. #6
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    3,070
    if the pins are low power mode disabled on startup, why not use the built in pullup/pulldown when activating the uart pins? this way theres no pullups/pulldowns on startup, and then theres pullups/pulldowns after initializing the uart interface and configuring the pin pull direction

  7. #7
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    20,559
    Ok, I have 2 question for you.

    1: First, have you tried connecting the TTL level input of some other device to the same signal Teensy is actually getting from the RS485 chip? For example, have the chip drive both pin 0 (RX1) on Teensy *and* the input to a FTDI-based USB-serial cable. The important question is whether Teensy really is getting a valid TTL level signal. If the signal is idle at logic low when the (low) start bit begins, then no UART could ever hope to detect the beginning of the start bit and receive the following data bits! I know you've said other devices work and Teensy doesn't, but the important question is whether this test was done with both devices receiving the EXACT same signal.

    2: If Teensy really is having trouble with a signal other devices can receive, how do I go about setting up a test here to get EXACTLY that same signal? I have some of those RS485 chips and plenty of resistors. But getting the EXACT same signal will require connecting something to the transmitter chip when turns on the DE pin and drives the DI pin with the EXACT same relative timing. Again, I'm going to point out that the transmitter *MUST* turn on DE and allow at least a short time before the start bit, because the improper resistors are holding the line in the non-idle state. Any UART, whether Teensy or a USB-Serial cable, requires detection of the beginning of the start bit, which just can't happen with this connection unless DE turns on first and enough time is allowed before the start bit begins. So if I'm going to try to reproduce the problem here, I need to know how to get the exact same DI & DE signals on the transmit side.

  8. #8
    Senior Member
    Join Date
    Dec 2013
    Posts
    225
    I have no experience with RS485 but perhaps you can enable the noise and framing interrupt errors and see if you can detect that situation.
    Not tested but should work I believe.
    Code:
    #define IRQ_ERROR_PRIORITY  48  // 0 = highest priority, 255 = lowest
    
    void setup() {
      delay(1000);
    
      // Frame error and Noise Error Interrupt Enable
      // Set error IRQ priority lower (higher priority) than that of the status IRQ PRIORITY 64,
      NVIC_SET_PRIORITY(IRQ_UART0_ERROR, IRQ_ERROR_PRIORITY); // E PRIORITY 48, 0 = highest priority, 255 = lowest
      // NVIC_SET_PRIORITY(IRQ_UART0_ERROR, NVIC_GET_PRIORITY(IRQ_UART0_STATUS) - 16); // 0 = highest priority, 255 = lowest
      // Enable UART0 interrupt on (Frame Error, Noise Error) and enable IRQ
      UART0_C3 |= UART_C3_FEIE | UART_C3_NEIE; // Framing Error Interrupt Enable // Noise Error Interrupt Enable
      // UART_C3_PEIE    0x01      // Parity Error Interrupt Enable
      // UART_C3_ORIE    0x08      // Overrun Error Interrupt Enable
      NVIC_ENABLE_IRQ(IRQ_UART0_ERROR);
      attachInterruptVector(IRQ_UART0_ERROR, UART0RxError);
    
      //Set up Frame error and Noise Error before calling Serial1.begin(..)
      Serial.begin(9600); // USB is always 12 Mbit/sec
      Serial1.begin(9600); // UART0 RS485
    }
    
    void loop() {
      // put your main code here, to run repeatedly:
      Serial.println("Hello World...");
      delay(2000);  //
    }
    
    void UART0RxError(void)
    {
      uint8_t E;
      if (UART0_S1 & UART_S1_FE) {
        __disable_irq();
        E = UART0_D; // dummy unload
        UART0_CFIFO = UART_CFIFO_RXFLUSH;
        UART0_D = 0; // dummy upload
        UART0_CFIFO = UART_CFIFO_TXFLUSH;
        __enable_irq();
        Serial.print("BUS Frame Error ");
        Serial.println(E);
      }
      if (UART0_S1 & UART_S1_NF) {
        __disable_irq();
        E = UART0_D; // dummy unload
        UART0_CFIFO = UART_CFIFO_RXFLUSH;
        UART0_D = 0; // dummy upload
        UART0_CFIFO = UART_CFIFO_TXFLUSH;
        __enable_irq();
        Serial.print("BUS Noise Flag ");
        Serial.println(E);
      }
    }

  9. #9
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    20,559
    If you have an oscilloscope or logic analyzer, a capture of the signal Teensy really is receiving at RX1 would also really help.

    If I work on investigating this issue (which is contingent on a clear way to reproduce the signal), I'll set up whatever is specified on the transmit side and my very first step will be to capture the real waveform with my scope. To really get to the bottom of what's going wrong here, before guessing what to do about software, we really need to check what waveform is actually arriving at the RX1 pin.

    Again I want to stress asynchronous serial communication fundamentally depends on detection of start bits. The timing between the DE pin and start bit on the DI pin of whatever is transmitting the RS485 signal will be critical, because of the wrong resistors holding the line in its non-idle state. If DE isn't driven (active high) significantly before the beginning of the start bit on DI, so that the idle state appears on the line before the start bit begins, then there's no way any receiving devices, whether Teensy or anything else, could ever hope to see a valid start bit.

    I know you believe there may be a problem unique to Teensy. Indeed that is possible, and if there is I certainly do want to find and fix it. But this particular case of holding the line in it's non-idle state is very unusual and risks creating invalid waveforms. I know you're said you tested where other devices worked and Teensy didn't... but the details of exactly how the tests were done matters greatly. I need very specific details about how to duplicate your test if I'm going to investigate it here.
    Last edited by PaulStoffregen; 07-31-2018 at 11:08 PM.

  10. #10
    Junior Member
    Join Date
    Jun 2018
    Posts
    8
    I appreciate the help you're offering, and thanks, but I need to puzzle it out here. And it isn't worth it, as this is a very unusual situation--very non-standard. It's not a Teensy problem, but almost certainly the Kinetis UART that's so much more capable than I need--and which sees this non-standard bus configuration as an error. It seems the best thing I could do is carefully look at the error bits and the flags set due to break detection and handle them so they don't interfere with the correct processing of what immediately follows. Which I think is what Chris O. was saying. It would be convenient if break detection could be turned off, so I could be sure the issue has nothing to do with UART-vs-break.
    I'm using an RS485-to-USB converter that's high-speed, isolated, and has a Silicon Labs CP2104 UART-to-USB.
    Here's a 'scope shot of the A and B signals, and RX1, while a single ACK is sent: first the driver is initially disabled, then enabled for a about a bit-time, then a start-bit of 0 and data 0:1:1:0:0:0:0:0, a stop bit (1), then idle (1s) for a couple of character-times, then the driver is disabled.
    Click image for larger version. 

Name:	A_B_and_RX1_ACK.png 
Views:	29 
Size:	230.3 KB 
ID:	14321
    As you might be able to see, it's 230,400 baud, and, after the line driver is enabled, there is about 1 bit-time of marking line before the beginning of the start bit. And, yes, the converter gets every character of every message all the time, while, simultaneously, the Teensy 3.5 misses most.
    Of course you're right that it all depends on the start bit. But no start bit, no matter how clean, will be detected if, say, a false start bit precedes it by less than a character-time--if it arrives while the UART is in the middle of assembling a character or break.

  11. #11
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    20,559
    I see what looks like about 1/2 a bit time before the start bit. Do you have control over the DE signal on the transmitter side? Maybe try lengthening the logic high before the start bit.

  12. #12
    Junior Member
    Join Date
    Jun 2018
    Posts
    8
    PaulStoffregen~
    On close inspection, it can be just under a bit time, at its shortest. And, sadly, I do not have control. What you see is comms between modules in an established product.
    But! What I did learn is that breaks (when not in LIN mode) are nothing more than characters with all bits 0, and with a stop-bit of 0, which, of course, produces a framing error (and others maybe.) Starting with Chris O.'s code snippet, I now have (most) messages reading completely and correctly on the T3.5. I'm sure by diving in and understanding in detail the way Teensyduino library handles these errors, I'll be in business in no time.
    My thanks, and sorry for having phrased this issue as if it could be a deficiency in T3.5, when it's entirely my lack of familiarity with my issue and the software that handles it. In fact, I love the T3.5, and I'm happy I'm here and not still with T2.0.
    Chris O.~
    Thanks for the insight. And the code snippet, which worked, and led me down the right path. (I'd bet you understood my issue all along but were too modest to say.)
    ~Jay

  13. #13
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    20,559
    Just a quick update on this old thread. I looked into framing error recovery today. There does indeed seem to be less-than-ideal behavior.

    https://forum.pjrc.com/threads/53850...l=1#post188193

    I'll post followups on that thread. Planning to have this fixed for version 1.45.

  14. #14
    Senior Member
    Join Date
    Apr 2013
    Posts
    138
    Quote Originally Posted by PaulStoffregen View Post
    Just a quick update on this old thread. I looked into framing error recovery today. There does indeed seem to be less-than-ideal behavior.

    https://forum.pjrc.com/threads/53850...l=1#post188193

    I'll post followups on that thread. Planning to have this fixed for version 1.45.
    Hello Paul,

    does the Teensy now has LIN communication support with Linebreak support inside the Lib?

    B.R.
    Markus

Posting Permissions

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