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.

TMS320F28384D: SCI interrupt frame Mismatch gets struck

Part Number: TMS320F28384D
Other Parts Discussed in Thread: C2000WARE, SFRA

Dear Team,

We have our custom board using TMS320F28384D, We are receiving data from an external HMI through  SCIA_BASE using FIFO RX ISR.

If the frame match  it is working properly. otherwise if frame mismatch  program get struck and we restart the board.

for example

WORKING properly:

This is our Frame In an array of 0 to 16

001 002 015 000 000 000 000 000 000 000 000 000 000 000 000 000 018

002 002 015 000 000 000 000 000 000 000 000 000 000 000 000 000 018

Not Working(Program stuck)

000 000 00 000 000 000 000 000 000 000 000 000 000 000 000 000 000

000

FF

123

Please find below snippier code..

void initSCIAFIFO()
  {

           Interrupt_register(INT_SCIA_RX, sciaRXFIFOISR);

           SCI_setConfig(SCIA_BASE, DEVICE_LSPCLK_FREQ,115200, (SCI_CONFIG_WLEN_8 |
                                                                  SCI_CONFIG_STOP_ONE |
                                                                  SCI_CONFIG_PAR_NONE));
           SCI_enableModule(SCIA_BASE);
           SCI_resetChannels(SCIA_BASE);
           SCI_enableFIFO(SCIA_BASE);
           Interrupt_enable(INT_SCIA_RX);
           SCI_enableInterrupt(SCIA_BASE, SCI_INT_RXFF );
           SCI_disableInterrupt(SCIA_BASE, SCI_INT_RXERR);
           SCI_setFIFOInterruptLevel(SCIA_BASE, SCI_FIFO_TX1, SCI_FIFO_RX1);
           SCI_performSoftwareReset(SCIA_BASE);
           SCI_resetRxFIFO(SCIA_BASE);
           Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);

  }


//
// sciaRXFIFOISR - SCIA Receive FIFO ISR
//
__interrupt void sciaRXFIFOISR(void)
{


    postTransmission1();
    Recipe==6 ?SCI_readCharArray(SCIA_BASE,( uint16_t *) (Display_RX_Buf),86): SCI_readCharArray(SCIA_BASE,( uint16_t *) (Display_RX_Buf),16);
    Recipe =Display_RX_Buf[1];

     if((Display_RX_Buf[0]==Spid[1] && Spid[1]!=0)||(Display_RX_Buf[0]==Spid[2] && Spid[2]!=0)||(Display_RX_Buf[0]==Spid[3] && Spid[3]!=0)||(Display_RX_Buf[0]==Spid[4] && Spid[4]!=0))
         {
       Check_Setting();
         }
    SCI_resetRxFIFO(SCIA_BASE);                                       //clear RxFIFO
    SCI_resetTxFIFO(SCIA_BASE);                                      //clear TxFIFO
    SCI_clearOverflowStatus(SCIA_BASE);                              // Clear overflowstatus
    SCI_clearInterruptStatus(SCIA_BASE, SCI_INT_RXFF|SCI_INT_RXERR); // Clear Interrupt RX status
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);                   // Clear interrupt

}

For mismatch frame we implemented below code to clear interrupt and base and Receiver buffer variable(Display_RX_Buf[1])..i.e if function code in Display_RX_Buf mismatch we clear interrupt.

but still the program gets struck.  kindly guide us for this problem.. thanks in advance for your guidance..


    if((Display_RX_Buf[1]==0 && Display_RX_Buf[0]==0)||( Display_RX_Buf[0]>=20 && Display_RX_Buf[1]>=20) )
    {
        SCI_clearInterruptStatus(SCIA_BASE, SCI_INT_RXFF|SCI_INT_RXERR); // Clear Interrupt RX status
        SCI_resetRxFIFO(SCIA_BASE);
        Reset_Display_TX_Buf();
        SCI_resetTxFIFO(SCIA_BASE);
        SCI_clearOverflowStatus(SCIA_BASE);                              // Clear overflowstatus
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);
        Reset_Display_RX_Buf();
    }

Rgds

Sunil Raj

  • Hi Sunil,


    Thanks for your question!

    I have written a FAQ thread for similar issues that may help to narrow down the issue to either hardware/software/config/etc.

    https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1031947/faq-my-c2000-sci-is-not-transmitting-and-or-receiving-data-correctly-how-do-i-fix-this

    If you could walk through this and let me know which of the issues seems most similar, and provide screenshots during the error scenario, this will allow me to provide the quickest support.

    I look forward to your response!

    Regards,

    Vince

  • Hi Vince,

    We figure out issue while power on or some unknown raw data from  HMI send FF or 00 or different size ,, during that time its get struck.

    Main Problem is we found through debug.. 

    if array  size mismatch.."SCI_readCharArray(uint32_t base, uint16_t * const array, uint16_t length)"

    we send from HMI array size of 16 or 86 bytes and slave return 12 bytes..

    suppose board  receive 11 or 2 or 1 byte or 12 bytes in network... processor get struck...

    this our snipper code..

    Recipe==6 ?SCI_readCharArray(SCIA_BASE,( uint16_t *) (Display_RX_Buf),86): SCI_readCharArray(SCIA_BASE,( uint16_t *) (Display_RX_Buf),5); //

    we found its struck in below section , kindly guide us how over come from array size mismatch issue,,,

    //*****************************************************************************
    //
    // SCI_readCharArray
    //
    //*****************************************************************************
    void
    SCI_readCharArray(uint32_t base, uint16_t * const array, uint16_t length)
    {
    //
    // Check the arguments.
    //
    ASSERT(SCI_isBaseValid(base));

    uint16_t i;
    //
    // Check if FIFO enhancement is enabled.
    //
    if(SCI_isFIFOEnabled(base))
    {
    //
    // FIFO is enabled.
    // For loop to read (Blocking) 'length' number of characters
    //
    for(i = 0U; i < length; i++)
    {
    //
    // Wait until a character is available in the receive FIFO.
    //
    while(SCI_getRxFIFOStatus(base) == SCI_FIFO_RX0)
    {
    }

    //
    // Return the character from the receive buffer.
    //
    array[i] = (uint16_t)
    (HWREGH(base + SCI_O_RXBUF) & SCI_RXBUF_SAR_M);
    }
    }
    else
    {
    //
    // FIFO is not enabled.
    // For loop to read (Blocking) 'length' number of characters
    //
    for(i = 0U; i < length; i++)
    {
    //
    // Wait until a character is available in the receive buffer.
    //
    while(!SCI_isDataAvailableNonFIFO(base))
    {
    }

    //
    // Return the character from the receive buffer.
    //
    array[i] = (uint16_t)
    (HWREGH(base + SCI_O_RXBUF) & SCI_RXBUF_SAR_M);
    }
    }
    }

     

    Rgds

    Sunil

  • Please find error in excel sheet..


    Docklight serial software to board rs485.xlsx

     

    Rgds

    Sunil

  • Hi vince,

         As I mentioned earlier ,we connect  two slaves with HMI .

        we are using  SCI_readCharArray(SCIA_BASE,( uint16_t *) (Display_RX_Buf),16); driverlib API function  to read caharaters 16bytes from HMI.the problem gets strucks . we also Oberseved that in receive status register RX_WAKE DETECT FLAG =1 at every time we send.

    1. we send 8 adress for 2 slaves we the problem didn't struck

    2.when we receive a single byte or error byte that  not match 16bytes,the readchar array functions  waits for the buffer to fill.

    3.Next to it when we send that the 16 bytes afer a single byte ,that single byte fdidnot overwrites rest of the array is filled with 16byte it getting mismatched.

    In this case we observed in Receiver status regsister RX_ERROR,FRAME ERROR,BRK_DT  flag are high.

    kindly help me to reslove this issue ,will send scope waveforms in the next reply.

    Thanks& Regards,

    Ajay S 

  • Hi Ajay,

    If you have a scenario where you have an uncertain number of bytes that can be received, then the "SCI_readCharArray" should not be used without FIFO. It will hang in that loop until the entire number of bytes is received (if "length" variable is set to 100 for example, then it will not exit the read until 100 bytes are read).

    To get around this, please instead see the "sci_ex2_loopback_interrupts.c" example within C2000Ware driverlib, under:

    C2000Ware_VERSION#\driverlib\f2838x\examples\c28x\sci\sci_ex2_loopback_interrupts.c

    Note how the FIFO is used, and anytime the FIFO gets filled up, the interrupt triggers.

    The main issue here is if you have variable number of bytes (16-to-18 bytes for example). For this, I would recommend just using standard interrupts (no FIFO) and every time there is an interrupt from a new byte, do "SCI_readCharBlockingNonFIFO".

    Regards,

    Vince

  • Hi Vince,

    As you suggest on previous reply, we have change code,, code struck issue we not face till now,, but instead of 16 or 86 byte,, 5 byte or 3  byte or 18byte  array from doclight.. in the case .here i am clear  array Display_RX_Buf[16] if my SPID=!1;


        if (Display_RX_Buf[0] !=spid)
                       {
                         rxsize=0;

                         //  reset_base=1;
                           memset(Display_RX_Buf,0,16);
                           SCI_resetChannels(SCIA_BASE);
                               // If break detected or serialport times out, reset SCI
                               //--- Needed by some serialports when code is run with an emulator
                               //
                               SCI_performSoftwareReset(SCIA_BASE);
                               reset_base=0;
                       }}

    Like wise ,   if (Display_RX_Buf[0] !=spid) (reset ) if id not match i reset everything , like wise 255 025 225 or 005 002 015 000 000 000 000... if send from docklight , need clear sci buffer. in Display_RX_Buf.. first it loading 255 025 225 in first set and then 005 002 015 000 000 000 000..

    may be junk will come during poweron HMI..we noticed junk is coming... how to clear all receive buffer SCIA base...

  • Hi Ajay,

    Thanks for the follow up. I agree that it sounds then like that junk data may be coming from the HMI power-on. You can verify this by using an oscilloscope if possible to view the HMI TX/RX during power-up.

    To clear the buffer from SCI, it is required to:

    1. Read the SCI buffer.

    2. (If FIFO is used) Continue reading the buffer till the FIFO is empty to clear out the FIFO.

    3. Clear all SCI errors that were flagged

    4. (Optional) Could be good to do an SCI SW reset, just to really ensure fresh start again.

    Let me know if any questions with the above steps.

    Regards,

    Vince

  • Hi Vince,

    Now  everything is working fine after your suggestion SCI_readCharBlockingNonFIFO(SCIA_BASE);
    as per your guidance We implemented in code like  number interrupt count as array size entered and if is match with our required array size and  ID, function code or else we clear everything..

    We have using multiple Model HMI in same Manufacture , one of the model we analyze in serial software always send "00" while power on based on SCI_readCharBlockingNonFIFO(SCIA_BASE), we clear everything as mentioned above..

    thanks for your valuable time and support hence our problem solved and closing this query..

    Thanks and Regards

    Ajay S

  • Hi Vince,

    Again we face new issue, when we communicate with two slave board (TMS320F28384D) with our hmi,
    Every one second we requesting status of slave board status..

    we have same code with different addressing..

    Initially HMI communicate with 2 slave boards. After sometimes only one board is communicate properly, second one is after 3 to 4 interrupt in sci.. later its not accepting interrupt. we noticed in timer counter is working .. problematic slave is not accepting interrupt ..

    Suppose Slave 2 board communicate first,, its working good update status to hmi, then if slave one is communicate second.. after  3 to 4 interrupt .. communication stop ..

    we am using crystal 20mhz oscillator and Baud rate 115200.. please find init file

    void init_int()
    {

    SCI_performSoftwareReset(SCIA_BASE);


    SCI_setConfig(SCIA_BASE, DEVICE_LSPCLK_FREQ, 115200, (SCI_CONFIG_WLEN_8 |
    SCI_CONFIG_STOP_TWO |
    SCI_CONFIG_PAR_NONE));
    SCI_resetChannels(SCIA_BASE);
    SCI_clearInterruptStatus(SCIA_BASE, SCI_INT_RXRDY_BRKDT);
    SCI_enableModule(SCIA_BASE);
    SCI_performSoftwareReset(SCIA_BASE);
    SCI_enableInterrupt(SCIA_BASE, SCI_INT_TXRDY | SCI_INT_RXRDY_BRKDT);

    Interrupt_enable(INT_SCIA_RX);
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);

    EINT;

    }

    based on other forum we changed 
    device.h file -->

    #define DEVICE_OSCSRC_FREQ 20000000U

    //
    // Define to pass to SysCtl_setClock(). Will configure the clock as follows:
    // PLLSYSCLK = 20MHz (XTAL_OSC) * 40 (IMULT) / (2 (REFDIV) * 2 (ODIV) * 1(SYSDIV))
    //
    #define DEVICE_SETCLOCK_CFG (SYSCTL_OSCSRC_XTAL | SYSCTL_IMULT(40) | \
    SYSCTL_REFDIV(2) | SYSCTL_ODIV(2) | \
    SYSCTL_SYSDIV(1) | SYSCTL_PLL_ENABLE | \
    SYSCTL_DCC_BASE_1)

    //
    // 200MHz SYSCLK frequency based on the above DEVICE_SETCLOCK_CFG. Update the
    // code below if a different clock configuration is used!
    //
    #define DEVICE_SYSCLK_FREQ ((DEVICE_OSCSRC_FREQ * 40) / (2 * 2 * 1))

    //
    // 50MHz LSPCLK frequency based on the above DEVICE_SYSCLK_FREQ and a default
    // low speed peripheral clock divider of 4. Update the code below if a
    // different LSPCLK divider is used!
    //
    #define DEVICE_LSPCLK_FREQ (DEVICE_SYSCLK_FREQ / 1)

    //
    // Define to pass to SysCtl_setAuxClock(). Will configure the clock as follows:
    // AUXPLLCLK = 20MHz (XTAL_OSC) * 50 (IMULT) / (2 (REFDIV) * 4 (ODIV) * 1(AUXPLLDIV) )
    //
    #define DEVICE_AUXSETCLOCK_CFG (SYSCTL_AUXPLL_OSCSRC_XTAL | SYSCTL_AUXPLL_IMULT(50) | \
    SYSCTL_REFDIV(2U) | SYSCTL_ODIV(4U) | \
    SYSCTL_AUXPLL_DIV_1 | SYSCTL_AUXPLL_ENABLE | \
    SYSCTL_DCC_BASE_0)

    //
    // 125MHz AUXCLK frequency based on the above DEVICE_AUXSETCLOCK_CFG. Update
    // the code below if a different clock configuration is used!
    //
    #define DEVICE_AUXCLK_FREQ ((DEVICE_OSCSRC_FREQ * 50) / (2 * 4 * 1))

    based on other forum we changed 
    device.c file -->

    SysCtl_setLowSpeedClock(SYSCTL_LSPCLK_PRESCALE_1);

    Kindly guide me if any configuration is wrong and solution for  above problem mentioned...

    Thanks in advance for guidance..

    Rgds

    Ajay S

  • Hi Ajay,

    Could you provide a scope capture of the data received by C2000 when the device is not interrupting? Basically, a scope capture of the RX line when the problem is occurring. This will allow the debug to move much faster (as we'll be able to determine what is wrong with the configuration). The configuration you provided could work perfectly, but only for certain types of data packets received.

    Regards,

    Vince

  • Hi, Vince,

    now its working, Problem sort out by adding below code while its enter SCI interrupt and we clear all buffer variable,,  previous we did software reset when number bytes enter and store in array , if not match we clear software  reset.  but now once SCI interrupt  call , we check  the error immediately clearing everything please find below ..

    uint16_t scistatusbit = SCI_getRxStatus(SCIA_BASE);
    if ((scistatusbit & SCI_RXSTATUS_ERROR)!=0)
    {
    scicount=0;
    SCI_performSoftwareReset(SCIA_BASE);
    memset(Display_RX_Buf_temp,0,105);
    memset(Display_RX_Buf,0,105);
    read_flag=0;
    reset_base=0;
    rxsize=0;
    }

    we have tested 5 hours now communication between  HMI and Board working and status update successful

    But please confirm that, In initialization we implemented "SCI_enableInterrupt(SCIA_BASE, SCI_INT_RXRDY_BRKDT);"" 

    but in sci isr we clear  SCI_clearInterruptStatus(SCIA_BASE, SCI_INT_RXFF); 

     kindly confirm its correct that  clear  #define SCI_INT_RXFF           0x10U  //!< RX FIFO level interrupt

    __interrupt void sciaRXFIFOISR(void)
    {
    iamhere123=22;
    postTransmission1();
    recive_data();
    if((Display_RX_Buf[0]==Spid[1] && Spid[1]!=0)||(Display_RX_Buf[0]==Spid[2] && Spid[2]!=0)||(Display_RX_Buf[0]==Spid[3] && Spid[3]!=0)||(Display_RX_Buf[0]==Spid[4] && Spid[4]!=0))
    {
    Check_Setting();
    }
    SCI_clearOverflowStatus(SCIA_BASE);
    SCI_clearInterruptStatus(SCIA_BASE, SCI_INT_RXFF);
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);
    }

    Rgds

    Ajay S

  • Hi Ajay,

    Please let me know if I am understanding your question correctly, but "SCI_clearInterruptStatus(SCIA_BASE, SCI_INT_RXFF)" will clear SCI_INT_RXFF.

    Regards,

    Vince

  • Hi Vince,

    Yes,,  in initialization we dint enable SCI_enableInterrupt(SCIA_BASE, SCI_INT_RXFF); but while clearing  SCI_clearInterruptStatus(SCIA_BASE, SCI_INT_RXFF) ..

    whether its right??

    In our code in initialization we enable SCI_enableInterrupt(SCIA_BASE, SCI_INT_RXRDY_BRKDT);

     but while clearing  SCI_clearInterruptStatus(SCIA_BASE, SCI_INT_RXRDY_BRKDT)  SCI communication  not working later..

    1..kindly confirm whether we should clear SCI_INT_RXRDY_BRKDT or Only interrupt  enable is enough?? and 

    2..  For SCI_readCharBlockingNonFIFO(SCIA_BASE); we have to enable SCI_enableInterrupt(SCIA_BASE, SCI_INT_RXFF ); or not ??

    Please find SCI communication initialization and ISR :- 


    void initSCIAFIFO()
    {
    SCI_performSoftwareReset(SCIA_BASE);
    Interrupt_register(INT_SCIA_RX, sciaRXFIFOISR);
    // Baud rate 115200 8 Bit data 1 Bit stop No parity bit
    SCI_setConfig(SCIA_BASE, DEVICE_LSPCLK_FREQ, 115200, (SCI_CONFIG_WLEN_8 |
    SCI_CONFIG_STOP_TWO |
    SCI_CONFIG_PAR_NONE));
    SCI_resetChannels(SCIA_BASE);
    SCI_clearInterruptStatus(SCIA_BASE, SCI_INT_RXRDY_BRKDT);
    SCI_enableModule(SCIA_BASE);
    SCI_performSoftwareReset(SCIA_BASE);
    SCI_enableInterrupt(SCIA_BASE, SCI_INT_RXRDY_BRKDT);

    /*#ifdef AUTOBAUD
    //
    // Perform an autobaud lock.
    // SCI expects an 'a' or 'A' to lock the baud rate.
    //
    SCI_lockAutobaud(SCIA_BASE);
    #endif*/
    Interrupt_enable(INT_SCIA_RX);
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);
    EINT;
    }

    Interrupt isr:- 

    __interrupt void sciaRXFIFOISR(void)
    {
    iamhere123=22;
    postTransmission1();
    recive_data();
    if((Display_RX_Buf[0]==Spid[1] && Spid[1]!=0)||(Display_RX_Buf[0]==Spid[2] && Spid[2]!=0)||(Display_RX_Buf[0]==Spid[3] && Spid[3]!=0)||(Display_RX_Buf[0]==Spid[4] && Spid[4]!=0))
    {
    Check_Setting();
    }
    SCI_clearOverflowStatus(SCIA_BASE);
    SCI_clearInterruptStatus(SCIA_BASE, SCI_INT_RXFF);
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);
    }

  • Hi, answers below:

    1. Yes, all interrupts should be cleared on interrupt exit. 
    2. RXFF interrupt is not needed when not using FIFO

  • Hi Vince, 

    Thanks you for your valuable support and time.. We clear in timer 1sec..like Texas instruments servo reference code sfra gui interface.. Now everthing fine.. 

    Have nice day and weekend.. 

    Rgds

    Ajay S