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.

Uart communication error on 6678



Hi, I have a weird problem with Uart on 6678 Evm. 

Firstly, I configure the interrupt controller and uart in 115200 baud rate with no parity-1 stop bit. I simply use a timer in CCS and I transmit 100 byte with a rate of 50 Hz. When i connect a serial communication application (CommOperator) on PC, I can observe all the bytes sent. Everything (counters in the ISR) seems to be okay. But when I send 100 byte from PC to Evm continuously by press the send button, after some time, interrupt machanism collapsed. I stop the program and I observe that there is no changing in ISR counters meaning that program does not jump into the ISR. Also I noticed that "Overrun error" indicator bit is 1. Although I enabled the ELSI interrupt, this does not create a line status interrupt. After this point I cannot regain the ISR routine.

If someone has a suggestion I am very happy. 

As a final note, I connect rx and tx pins from rs232 cable, everthing works good. I mean it is okay for loopback connection.

  • I think all the UART events share the same interrupt input to CPU and trigger the same ISR.

    Do you check the IIR status in ISR to record which interrupt being triggered every time please?

    Is it possible the last one is the "overrun error" which has not been cleared and blocked the other events?

    The overrun error could be cleared by reading line status register (LSR) as mentioned in table 3-6 in UART user guide. Maybe you can try to clear overrun error in ISR if it happens.

  • I use the following ISR routine. Also I cannot obtain ISR functioanlity again after "overrun error". What is the steps? Reading LSR register is not enough.

    Also I try to sent 50x100=5000 bytes per second, and try to receive 50x100 bytes per second, is there any mistake at this scenario??

    static void uart_isr_handler ()
    {
      Uint32 rawStatus; 
      uint8_t buf;
      Uint32 IntIdentity;
      UInt32 IIRReg;
      Uint32 UseRxTxFIFO;
      volatile Uint32 LSRReg;

      IIRReg=((CSL_UartRegsOvly) CSL_UART_REGS)->IIR;
      IntIdentity=IIRReg&0xE;
      UseRxTxFIFO=IIRReg&0xC0;

      rawStatus = ((CSL_CPINTC_RegsOvly)handleCIC0)->RAW_STATUS_REG[SYSTEM_INTERRUPT_UART/32];

      if ((rawStatus&0x00100000) == 0x00100000)
      {
        isrCounter++;
        if (IntIdentity==0x6) //receiver line status
       {
          ErrorIntCounter++;
          LSRReg=((CSL_UartRegsOvly) CSL_UART_REGS)->LSR;
       }

       else if (IntIdentity==0x4)
       {
         RecIntCounter++;
         while (CSL_UART_LSR_DR_READY==(CSL_FEXT(((CSL_UartRegsOvly)CSL_UART_REGS)->LSR, UART_LSR_DR)))
         {
           buf=(((CSL_UartRegsOvly) CSL_UART_REGS)->RBR & 0xFF);
           if (UARTRecStatus.DataLength<MAX_UART_DATA_LENGTH)
           {
               UARTRecStatus.Buf[UARTRecStatus.DataLength]=buf;
               UARTRecStatus.DataLength++;
           }
           else
           {
           }
        }
      }
      else if (IntIdentity==0xC)
      {
      RecCTIIntCounter++;
        while (CSL_UART_LSR_DR_READY==(CSL_FEXT(((CSL_UartRegsOvly)CSL_UART_REGS)->LSR, UART_LSR_DR)))
        {
          buf=(((CSL_UartRegsOvly) CSL_UART_REGS)->RBR & 0xFF);
          if (UARTRecStatus.DataLength<MAX_UART_DATA_LENGTH)
          {
            UARTRecStatus.Buf[UARTRecStatus.DataLength]=buf;
            UARTRecStatus.DataLength++;
          }
          else
          {
          }
        }
      }
      else if (IntIdentity==0x2)

      {
        THRIntCounter++;
        unsigned int cnt;
        if (UseRxTxFIFO==0xC0)
        {
            if ((UARTSendStatus.DataLength>0))
            {
              if (UARTSendStatus.DataLength<17)
              {
                   while (UARTSendStatus.DataLength>0)
                   {
                        ((CSL_UartRegsOvly) CSL_UART_REGS)->THR=UARTSendStatus.Buf[UARTSendStatus.DataLength-1];
                        UARTSendStatus.DataLength--;
                   }
               }
               else
               {
                  for ( cnt=0 ; cnt<16 ; cnt++)
                  {
                     ((CSL_UartRegsOvly) CSL_UART_REGS)->THR=UARTSendStatus.Buf[UARTSendStatus.DataLength-1];
                     UARTSendStatus.DataLength--;
                  }
              }
          }
        }
        else
       {
             if (UARTSendStatus.DataLength>0)
             {
                 ((CSL_UartRegsOvly) CSL_UART_REGS)->THR=UARTSendStatus.Buf[UARTSendStatus.DataLength-1];
                  UARTSendStatus.DataLength--;
             }
          }
        }
        else
        {
          undefInt++;
        }

        CSL_CPINTC_clearSysInterrupt(handleCIC0, SYSTEM_INTERRUPT_UART);
      }

    }

  • I am wondering if you spend too many cycles in the ISR that there is another interrupt event coming before clearing the previous event.

    Could you please refer to the ISR example in CIC user guide and add the CIC host interrupt disable/enable on top and bottom of your ISR please?

    {

    /* Disable the CIC0 host interrupt output */
    CSL_CPINTC_disableHostInterrupt(cphnd, host_event);
    /* Clear the CIC0 system interrupt */
    CSL_CPINTC_clearSysInterrupt(cphnd, sys_event);
    ......
    (service the interrupt at source)
    (clear the source interrupt flag is typically the first step in the service)

    ......
    /* Clear the CorePac interrupt */
    CSL_intcHwControl(hIntc,CSL_INTC_CMD_EVTCLEAR,NULL);
    /* Enable the CIC0 host interrupt output */
    CSL_CPINTC_enableHostInterrupt(cphnd, host_event);

    }

    By adding the enable/disable routine, the additional event happened inside ISR is supposed to trigger the interrupt again after we exist ISR.

    And there are some other threads talking about UART interrupt, such as the following one which has an example using MCSDK platform library:

    http://e2e.ti.com/support/dsp/c6000_multi-core_dsps/f/639/t/205473.aspx

    The ISR may need to be updated as above but it could be a reference for the platform API usage. Hope it could help.

  • Dear Steven,

    I add your suggestions but the result is not changed. I reduce the setup. There is a PC program only sends 100 bytes every 20ms. In the EVM side, there are an ISR routine and a task pends a semaphore which is posted by a 20ms timer. Whenever semaphore is released task only sends 100 bytes at all. In the ISR routine, every received byte are taken from RBR register as before, and received byte is not copied anywhere.  This is very simple scenario. Send 100 byte every 20ms, and consume all the received bytes by ISR. Even at this configuration, after 10-20 seconds ISR routine become inactive. When I stop the program I see the following from Memory Browser:

    And after that point I cannot make ISR routine active again. Also I want to take notice that if I stop the transfering of 100 bytes for one direction, the error does not occured.  

    When 2 directions become active it appears.. Is there any concept about dublex or half dublex behavior of uart??

    If someone has an argue about that I will be very happy..

  • Also I want to add an interesting note: If I disable the tx interrupt and send 100 byte by polling and receiving 100 bytes by ISR there is no problem. whenever I enable the tx interrupt, ISR will be inactive a little time later.. ??

    Is there a problem tx and rx of data by ISR at the same time?

    Alpaslan