This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TMS320F28069M: SCI Break Detection interpreted as Framing Error

Part Number: TMS320F28069M

Hello,

We are posting on behalf of Daniel Rush, who is not able to post his inquiry to this particular forum. Daniel will be notified once this post goes live, so he can join in and continue the discussion.

Post Description:

When a TX-Break signal is sent from my pc, the RXST bits are always set as a framing error. My interrupt resets the status bits after each interrupt but the BKDT flag is never set. I want to use the break detection to reset the processor. I've verified the TX-Break signal with a logic analyzer.


My peripheral setup is as follows:

  • {
        sciA = SCI_init((void*)SCIA_BASE_ADDR, sizeof(SCI_Obj));
      pieHandle = PIE_init((void*)PIE_BASE_ADDR, sizeof(PIE_Obj));
      SCI_enable(sciA);
      // Protocol is 115200 BAUD, 8-N-1.
      sciA->SCIHBAUD = BAUD_115200 >> 8;   // Set Baud rate
      sciA->SCILBAUD = BAUD_115200;        // Set Baud rate
      SCI_disableParity(sciA);
      SCI_setNumStopBits(sciA, SCI_NumStopBits_One);
      SCI_setCharLength(sciA, SCI_CharLength_8_Bits);
      SCI_disableLoopBack(sciA);
     
      // FIFO and Interrupt setup
      SCI_enableTxFifo(sciA);
      SCI_enableRxFifo(sciA);
      SCI_enableRxErrorInt(sciA);
      SCI_enableRxInt(sciA);
      SCI_enableTxInt(sciA);
     
      // Enable interface
      SCI_enableRx(sciA);
      SCI_enableTx(sciA);
     
      // enable peripheral interrupts
      PIE_enableInt(pieHandle, PIE_GroupNumber_9, PIE_InterruptSource_SCIARX);
      PIE_enableInt(pieHandle, PIE_GroupNumber_9, PIE_InterruptSource_SCIATX);
    }
    

  • Daniel,
    Through previous experimentation I have see the BRKDT work. You will always receive a FE before a BRKDT. If you think about it if the bus is pulled low it simply looks like another device is transmitting all "low" characters... It isn't until a stop bit is missed that anything looks wrong(this will trigger the FE).

    Findings:
    When I connect SCIRX to ground I see RXERROR = BRKDT = FE = 1. How long did you force your RX GPIO low? You should need to receive a FE, then after 10 bit times you should receive a BRKDT.


    Note: there is no way to suppress this error flag.

    Regards,
    Cody
  • Hey Cody,

    I have been using miniterm as a serial terminal which allows me to toggle on a tx-break, I can leave it on indefinitely(and verified that this just causes rx line to be low at the micro) with a stream of framing errors but never a BKDT flag. I had figured that after one framing error, and a reset of the flags, that I would recieve a BKDT flag, but it never ends up getting triggered.

    Thanks

    Daniel Rush

  • Daniel,

    please confirm my understanding.

    1. You set the RX line low
    2. You see a FE.
    3. You clear the FE, and RXERROR flags
    4. My guess at this point you get stuck in a loop
      1. Clear the error flags,
      2. Receive another FE flag
      3. Clear again and repeat

    The only way to clear the FE/RXERROR flags is to reset the SCI, this will reset the logic that sets the BRKDT flag. Assuming that you are handling FE flags in a timely manner (less than 10 bit times) then you will reset the SCI module before a BRKDT condition could be detected.

    Are you triggering an interrupt on a FE and resetting the SCI? I would expect this to happen much faster than the BRKDT detection.

    Regards,
    Cody 

  • Cody,

    1. I send a break(RX line low)
    2. Interrupt Triggered
    3. Acknowledge Int
    4. See an FE
    5. Reset SCI
    6. Re-enable SCI
    7. Return to main execution
    8. Subsequent interrupts while line still low are also framing errors.

    Here is a code snippet from my interrupt:

       if(char_index >= MAX_MESSAGE_LEN) {
          char_index = 0;
          memset(CMD_buf[write_index], '\0', MAX_MESSAGE_LEN);
        } else if(sciA->SCIRXST & SCI_SCIRXST_BRKDT_BITS) {
          // Break Detect: Handle Reset when break detected
          sendDebugMsg("Break");
          return;
        } else if(sciA->SCIRXST & SCI_SCIRXST_OE_BITS) {
          // Overrun Error
          // TODO(DJR): This just discarding characters might change this in future
          SCI_reset(sciA);
          SCI_enable(sciA);
          return;
        } else if(sciA->SCIRXST & SCI_SCIRXST_FE_BITS) {
          // Framing Error
          SCI_reset(sciA);
          SCI_enable(sciA);
          // TODO(DJR): This just discarding characters might change this in future
          return;
        } else if(sciA->SCIRXST & SCI_SCIRXST_PE_BITS) {
          // Parity Error
          // TODO(DJR): Discard Char
          SCI_reset(sciA);
          SCI_enable(sciA);
        }
  • Daniel,

    a FE always occurs 10 bit times before a BRKDT. With the way your code is written you will likely reset the SCI with every FE well before you would receive a BRKDT.

    To prove this theory: comment the SCI reset and SCI enable lines in the else if statement for the FE, you should begin to see BRKDT errors.


    Regards,
    Cody 

  • Cody,

    This was one of my thoughts as well. So, after testing this, It does trigger the break detect after 10 bits, but, the reason that the SCI_reset is there is to clear the error bits so that another interrupt can be triggered, if they aren't cleared the first FE error is detected, and serviced, then all subsequent interrupts are ignored. As outlined in the technical reference, the bits are only cleared once a SW_Reset is set.

    When running the debugger, I can step through the interrupt then once it returns to the main code keep stepping through and watching the RXST register, after some time the BKDT goes high but there's no way to know because it's not causing an interrupt. Not sure how I can keep getting interrupts without resetting the interface each time I receive an error.

  • Daniel, 

    yes, you understand correctly. I agree that the implementation is not good for identifying "Break Detects". If you would like to distinguish between FEs and BRKDTs you can setup a CPU timer when a FE is detected. The CPU timer should be configured to trigger an interrupt after more than 10 bit times. In the interrupt you can determine if a BRKDT happened or if only a FE occured, then reset the SCI module and synchronize to your UART transmitter accordingly.

    I would suggest that you implement some sort of checksum for the transmitted data, this will help with robustness.

    One other way around this issue is to define a series of transmission stop packets(instead of inteionally adding a break in communication), this series of packages shouldn't be common in your data.

    As you are finding out one drawback of using UART  is all of the handshaking is left to the application code.


    Hope it helps,
    Cody 

  • Thanks Cody,

    You can mark your reply as the answer! I cannot since it wasn't posted by me.