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.

TMS320F280025C: TMS320F280025C - Tx in SCI Mode is blocked approx 900µs after Fram Header

Part Number: TMS320F280025C

Hello support team,

We are testing SCI mode in SCI/LIN module and found following behaviour

we cannot send anything about 900µs after the frame header. Although TXRDY is bit high, the data in SCITD is not sent out.

For a simple description I send a byte 0x55 every 1ms with timer 0 interrupt:

Legend: blue: LIN, red: Tx, yellow: Rx green: test pin after while (! LinaRegs.SCIFLR.bit.TXRDY);

  • Without data on the Rx. All good. Byte 0x55 is sent every 1ms. OK
  • Data on the Rx:
    • In the frame header, TXRDY is high ???, Tx data is not sent (still OK)
    • After the frame header (between 2 cursors / rulers, approx. 950µs) Tx data is also not sent, although the TXRDY bit is already high (on the 1st ruler) ???

 

Code init

EALLOW;

   /* Reset LIN/SCI module */
   LinaRegs.SCIPIO0.bit.RXFUNC = 0u;
   LinaRegs.SCIPIO0.bit.TXFUNC = 0u;
   LinaRegs.SCIGCR0.bit.RESET = 0u;
   LinaRegs.SCIGCR0.bit.RESET = 1u;

   LinaRegs.SCIGCR1.bit.SWnRST = 0u;    /* Enter Software Reset State */

   /* Enable SCI communications mode */
   LinaRegs.SCIGCR1.bit.TIMINGMODE = 1u;
   LinaRegs.SCIGCR1.bit.LINMODE  = 0u;

   LinaRegs.SCIGCR1.bit.COMMMODE  = 0u; /* Idle-line mode is used. */
   LinaRegs.SCIGCR1.bit.STOP  = 0u;     /* 1 Stop bit */
   LinaRegs.SCIGCR1.bit.PARITYENA = 0u; /* Disable parity check */
   LinaRegs.SCIGCR1.bit.MBUFMODE = 0u;  /* Disable multi-buffer mode */
   LinaRegs.SCIGCR1.bit.CONT = 1u;      /* Module set to complete operations when halted by debugger */
   LinaRegs.SCIGCR1.bit.LOOPBACK = 0u;  /* Disable Internal loopback for external communication */

   LinaRegs.SCIFORMAT.bit.CHAR = 7u;    /* Set character length as 8-bits */
   LinaRegs.SCIFORMAT.bit.LENGTH = 0u;   /* Set response field to 1 byte */

   /* Enable TX and RX pin control functionality */
   LinaRegs.SCIPIO0.bit.RXFUNC = 1u;
   LinaRegs.SCIPIO0.bit.TXFUNC = 1u;

   LinaRegs.BRSR.all = (BRSR_P | (BRSR_M << 24uL)); /* Set Baud Rate */

   LinaRegs.SCIGCR1.bit.CLK_MASTER = 1u;  /* Select the internal clock */

   LinaRegs.SCICLEARINT.all = 0xFF0023D2U; /* !< Diasble all interrupts */
   LinaRegs.SCISETINT.bit.SETRXINT = 1u;  /* Enable Rx Int */
   LinaRegs.SCISETINT.bit.SETFEINT = 1u;  /* Set framing-error interrupt */
   LinaRegs.SCISETINT.bit.SETOEINT = 1u;  /* Set overrun-error interrupt */
   LinaRegs.SCISETINT.bit.SETPEINT = 1u;  /* Set parity interrupt */
   LinaRegs.SCISETINT.bit.SETBRKDTINT = 1u;  /* Set break-detect interrupt */

   /* Enable transmit and receive */
   LinaRegs.SCIGCR1.bit.TXENA = 1u;
   LinaRegs.SCIGCR1.bit.RXENA = 1u;

   /* Finally exit SW reset and enter LIN ready state */
   LinaRegs.SCIGCR1.bit.SWnRST = 1u;

   IER |= M_INT8;                        /* Enable CPU which is connected to CPU */
   PieCtrlRegs.PIEIER8.bit.INTx9 = 1u;  /* Enable PIE  Group 8 interrupt 9 */

   PieVectTable.LINA_0_INT = &lin_ISR;  /* Map ISR functions */
   /* Enable global interrupt lines and clear status to known value */
   LinaRegs.LIN_GLB_INT_EN.bit.GLBINT0_EN = 1u;
   LinaRegs.LIN_GLB_INT_CLR.bit.INT0_FLG_CLR = 1u;

   EDIS;

Code Lin Interrupt

  volatile u32 statusReg;
  volatile u16 dummy_data;

  statusReg = LinaRegs.SCIFLR.all;

  dummy_data = (l_u8)LinaRegs.SCIRD.bit.RD;

  // Clear module interrupt flag and global interrupt flag for line 0
  LinaRegs.SCIFLR.all = 0xFFFFFFFFuL;
  LinaRegs.LIN_GLB_INT_CLR.bit.INT0_FLG_CLR = 1u;

  /* Acknowledge this interrupt to receive more interrupts from same group */
  PieCtrlRegs.PIEACK.all = PIEACK_GROUP8;

code timer interrupt

  while(!LinaRegs.SCIFLR.bit.TXRDY);
  GpioDataRegs.GPATOGGLE.bit.GPIO31 = 1;
  LinaRegs.SCITD.bit.TD = 0x55;

  /* Acknowledge this interrupt to receive more interrupts from group 1 */
  PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;

  • Hi,

    On the first picture where there is no delay, why there is no data on RX? What changed between 1st and 2nd picture?

    Also, are there any error flags set? Can you dump SCIFLR register?

    Also is LINTX and LINRX connected to LIN Bus?

    Best Regards,

    Nirav

  • Hi Nirav,

    Tx is not connected to the LIN Transceiver (just Oscilloscope)

    On the 1st picture, I disconnect RX on the board with Rx of LIN Transceiver. => No data on Rx => No LIN Interrupt => Tx is sent without any problem

    On the 2nd picture, I connect RX on the board to Rx of LIN Transceiver. => Data on Rx (LIN Header) => LIN Interrupt during Frame Hader => Tx is blocked about 900µs after Frame Hader

    When Rx is connected to the Transceiver, I can get data and interrupts, I detect a Header, PID, ... Everything is ok there, but after the header I cannot send the response data on Tx. That's why I built a simple example with 1ms timer to show that the Tx data is blocked approx. 900µs after a LIN Frame Header.

    Regards,

    Quy

  • Hi Quy,

    Thanks for your follow up! One thing to note: the second cursor in the image is slightly off. The start of the TX is actually starts exactly on the next 1ms Timer0 cycle.

    This is important because it shows the reason for the issue is actually the interrupts!

    Here's an explanation of why this is happening.

    The LIN RX data is being received, and is being handled by an interrupt ISR.

    The TIMER0 ISR fires, but the LIN RX ISR is still running. Since the LIN RX is still processing, TIMER0 gets skipped till it interrupts again.

    See the images below for a visual explanation:

    LIN RX ISR still processing:

    TIMER0 ISR gets to run on its next cycle since no other interrupts are running:

    So to fix this, you can increase the TIMER0 time, or speed up the LIN transmission speed.

    Regards,

    Vince

  • Hi Vince,

    You ignored the 3rd screenshot in my first post:

    The timer interrupt is not synchronized with LIn Header, the screenshots I posted here are 2 typical cases:

    - 2nd screenshot in my first post: Timer Interrupt happens right after Header (0 Tbit delay9, the response should be sent there => LIN Response space = 0

    - 3nd screenshot in my first post: Timer Interrupt happens within 1ms after Header, the response should also be sent there.

    The LIN response space max = 0.8 Tbyte = 400µs in 20kBaud and 1ms delay is not LIN conformed

    Regards,

    Quy

  • Hi Quy,

    I apologize for the misunderstanding, I see what you are describing now, thank you for clarifying.

    I would like to try two things to help narrow down the possible causes:

    1. Can you try changing the polling while loop to instead poll for "TXEMPTY"? So use something similar to the following: "while(!LinaRegs.SCIFLR.bit.TXEMPTY);". My reasoning for this is to see if the SCITXSHF register is still blocked from the previous transmit being interrupted by the RX ISR (with residual bits). Our typical polling examples use TXEMPTY rather than TXRDY for the check. We can debug this route further for the cause if this ends up resolving the issue.

    2. Can you read the SCIFLR register bits and provide us this information? I would like to see the flags in three locations:

    LIN INTERRUPT (1 read):

      volatile u32 statusReg;
      volatile u16 dummy_data;
    
      statusReg = LinaRegs.SCIFLR.all;
    
      dummy_data = (l_u8)LinaRegs.SCIRD.bit.RD;
    
      // Clear module interrupt flag and global interrupt flag for line 0
      
      //***********************************
      // READ SCIFLR HERE (BEFORE CLEARING)
      //***********************************
      LinaRegs.SCIFLR.all = 0xFFFFFFFFuL;
      LinaRegs.LIN_GLB_INT_CLR.bit.INT0_FLG_CLR = 1u;
    
      /* Acknowledge this interrupt to receive more interrupts from same group */
      PieCtrlRegs.PIEACK.all = PIEACK_GROUP8;

    TIMER0 INTERRUPT (2 reads):

      while(!LinaRegs.SCIFLR.bit.TXRDY);
      
      GpioDataRegs.GPATOGGLE.bit.GPIO31 = 1;
      //******************************************
      // READ SCIFLR HERE (before transmit)
      //******************************************
      LinaRegs.SCITD.bit.TD = 0x55;
      //******************************************
      // READ SCIFLR HERE (after transmit)
      //******************************************
    
      /* Acknowledge this interrupt to receive more interrupts from group 1 */
      PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;

    I would like to have the flag status at these locations to understand if something out of the ordinary is happening with the frame.

    Thanks again for the clarification.

    Regards,

    Vince

  • Hi Vince,

    Sorry for the late response.

    Due to the project’s urgency, we had to switch to LIN mode at this moment. With LIN mode we have no open point currently.

    I will come back to this open point in SCI when I have time.

    Regards,

    Quy