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.

TMS320F28388D: Read 512 bytes of data using SCI RX interrupt

Part Number: TMS320F28388D
Other Parts Discussed in Thread: C2000WARE

Hi,

I am trying to develop a communication protocol using SCI in TMS320F28388. Maximum 512 bytes of data can come through this SCI and the controller should be able to store the data using RX interrupt method.

Below  is the code I am using for SCI configuration.

GPIO_setPinConfig(GPIO_19_SCIB_RX);
GPIO_setPinConfig(GPIO_18_SCIB_TX);


//
// Interrupts that are used in this example are re-mapped to
// ISR functions found within this file.
//
Interrupt_register(INT_SCIB_RX, sciaRXFIFOISR);

SCI_performSoftwareReset(SCIB_BASE);

//
// Configure SCIA for echoback.
//
SCI_setConfig(SCIB_BASE, DEVICE_LSPCLK_FREQ, 9600, (SCI_CONFIG_WLEN_8 |
SCI_CONFIG_STOP_ONE |
SCI_CONFIG_PAR_NONE));
SCI_resetChannels(SCIB_BASE);
SCI_enableModule(SCIB_BASE);
SCI_performSoftwareReset(SCIB_BASE);
SCI_enableFIFO(SCIB_BASE);

//
// RX FIFO Interrupts Enabled
//
SCI_enableInterrupt(SCIB_BASE, SCI_INT_RXFF);
SCI_disableInterrupt(SCIB_BASE, SCI_INT_RXERR);

//
// The transmit FIFO generates an interrupt when FIFO status
// bits are less than or equal to 2 out of 16 words
// The receive FIFO generates an interrupt when FIFO status
// bits are greater than equal to 2 out of 16 words
//
SCI_setFIFOInterruptLevel(SCIB_BASE, SCI_FIFO_TX2, SCI_FIFO_RX2);
SCI_performSoftwareReset(SCIB_BASE);

SCI_resetRxFIFO(SCIB_BASE);

Interrupt_enable(INT_SCIB_RX);
Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);

 Below is the code in the ISR to read the data.

uint16_t flags;
uint16_t chr;
uint16_t words;


if (ReceiveBufferLen != 0) // if buffer is busy
return;


do // until TerminationChar received or rcv buf is empty
{


flags = SCI_getRxStatus(SCIB_BASE);
if (NumCharsReceived >= RX_BUFF_SIZE)
{
ErrorCode = SerialRxBuffTooSmall; // ReceiveBuffer too small
ReceiveBufferLen = RX_BUFF_SIZE; // inform the user a partial packet is available
break;
}
//
if (SCI_getRxFIFOStatus(SCIB_BASE))
{
chr = SCI_readCharBlockingFIFO(SCIB_BASE);
//
// // If no data is available, break
//
((uint16_t*) &ReceiveBuffer)[NumCharsReceived++] = chr;
if (((((uint16_t) (ReceiveBuffer[1]) << 8) & 0xFF00u)
| ((uint16_t) (ReceiveBuffer[0] & 0x00FFu)))
== NumCharsReceived)
{
ReceiveBufferLen = NumCharsReceived; // inform the user a packet is available
//break;
}

} while (!SCI_isDataAvailableNonFIFO(SCIB_BASE));

SCI_clearOverflowStatus(SCIB_BASE);

SCI_clearInterruptStatus(SCIB_BASE, SCI_INT_RXFF);


//
// Issue PIE ack
//
Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);

Using this code I am able to read only 2 bytes of data.

Can any one help me to get some idea on this to read multiple bytes of data through SCI Rx using interrupt method.

Thanks in advance

Regards

Dipin

  • Hi Dipin,

      

    Thanks for your quesiton. I have updated your post to use code blocks instead of raw text. In the future, please use "Insert->Code" to properly format code in your posts.

      

    Can you pause the debugger and see where the code is getting stuck? I believe that once the code is read one time, the code may be getting stuck in the "readCharBlockingFIFO" line.

      

    I think part of the issue is:

    * You are triggering the interrupt every 2 bytes (FIFO level set to 2 bytes)

    -BUT-

    * You still put an if statement to see if there's data using getRxFIFOStatus:

      

    The "if statement" should not be necessary. If the code gets into the ISR, then that means there was 2 bytes -OR- an error. The error should be checked first, and then that means there is only possibility of data arrival.

      

    Regards,

    Vince

  • Hi Vince,

    Thanks for your reply.

    I actually my code is not getting stuck anywhere. It does not reading all the data what I am sending. Even though I am sending more than 16 bytes of data its getting only first two bytes and rest data is lost.

    For receiving all the data what is the FIFO interrupt level I have to set? Please suggest any SCI configuration change.

    Which condition I should check to make sure complete data is received?

    Can you help me solve these doubts? I have added my latest Rx ISR code for reference

    Thanks

    	uint16_t flags;
    	uint16_t chr;
    	uint16_t words;
    
    
    	if (ReceiveBufferLen != 0) // if  buffer is busy
    		return;
    
    
    	do  // until TerminationChar received or rcv buf is empty
    	{
    
    	   flags =  SCI_getRxStatus(SCIB_BASE);
    		if (NumCharsReceived >= RX_BUFF_SIZE)
    		{
    			ErrorCode = SerialRxBuffTooSmall;  // ReceiveBuffer too small
    			ReceiveBufferLen = RX_BUFF_SIZE; // inform the user a partial packet is available
    			break;
    		}
    //			// If data is available, read
    		    chr = SCI_readCharBlockingFIFO(SCIB_BASE);
    //
    //			// If no data is available, break
    //
    			((uint16_t*) &ReceiveBuffer)[NumCharsReceived++] = chr;
    			if (((((uint16_t) (ReceiveBuffer[1]) << 8) & 0xFF00u)
    					| ((uint16_t) (ReceiveBuffer[0] & 0x00FFu)))
    				    == NumCharsReceived)
    			{
    				ReceiveBufferLen = NumCharsReceived; // inform the user a packet is available
    				//break;
    			}
    	} while (SCI_getRxFIFOStatus(SCIB_BASE)!=0);
    
    		    SCI_clearOverflowStatus(SCIB_BASE);
    
    		    SCI_clearInterruptStatus(SCIB_BASE, SCI_INT_RXFF);
    
    
    		    //
    		    // Issue PIE ack
    		    //
    		    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);
    
    }

    Dipin

  • Hi Dipin,

    As mentioned previously, it is difficult to determine where the issue is unless the debug window is used to find where the code is stopped. Can you provide the location where the code is after the first 2 bytes are received?

    Regards,

    Vince

  • Hi Vince,

    After receiving two bytes of data while reading SCI_getRxFIFOStatus it will give 0. Then it will come out of the loop.

    while (SCI_getRxFIFOStatus(SCIB_BASE)!=0); (line number 33) this is the condition I am talking about. After two bytes, this condition will give value as 0.

    I am not understanding where is my rest data ?

    I have set my FIFO interrupt level to 2 in the previous SCI configuration. 

    Regards

    Dipin

  • Hi Dipin,

    As mentioned, you should not do a while loop inside an ISR like this. This prevents further interrupts from triggering. Please remove the while loop.

    Regards,

    Vince

  • Hi Vince,

    I will try that. Do you have any example code to share with me for receiving sequence of data (512 bytes) through SCI?

    Regards

    Dipin

  • Dipin,

    The "echoback" and "interrupts" SCI examples in C2000Ware are a good starting point for this. They are both capable of theoretically unlimited data reception, and need only slight modification to do what you are attempting to do (basically just change FIFO depth).

    One thing to keep in mind: ensure data received has 2 stop bits. This will prevent any issues with reception over large packets of data (provides the interrupt sufficient processing time).

    Regards,

    Vince

  • Can you please look into this issue

  • Can you please tell me the FIFO depth required for reading sequence of data. Actually my code is still not working as expected. Can you please share the code which you have for unlimited data  reception

    Regards

    Dipin

  • Dipin,

    Any FIFO depth will suffice for a simple read of multiple data bytes.

    To assist in debug, please try to replicate the issue when using one of the basic examples, unmodified. For example: please run the SCI echoback example and see if the example ever has issues receiving 512 bytes. Please attempt to use that example and see if the issue persists.

    Regards,

    Vince