dgipling

Missing bytes in messages received over SCI

Discussion created by dgipling on Jul 12, 2012
Latest reply on Mar 14, 2013 by Guest

Hi, I have written an interrupt routine to receive binary messages over SCI for an MC9S08 CPU.  This does not work when the byte 0x00 is included in the message. 

 

The messages all starts with a Start Of Message byte (SOM) equal to 0xAA and ends with a End Of Message byte (EOM) equal to 0x55.  If the SOM or EOM is included in the message as ordinary data they are stuffed with a stuff byte equal to 0x70 and the most significant bit in the byte is inverted. 

 

This works very well in all cases as long as the messages do not include one or more bytes equal to 0x00.  For instance receiving the message “SOM, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, EOM” works as expected.  If I try to receive a message like this: “SOM, 0x10, 0x00, 0x00, EOM” the messages is received as “SOM, 0x10, 0x00, EOM”, one of the 0x00 is not received.  If I try to receive a message like this: “SOM, 0x10, 0x00, 0x55” this is received as “SOM, 0x10, 0x00, 0xd5”.  All testing shows me that the problem is related to receiving messages containing the character 0x00. 

 

The code below shows how the SCI2 is configured in the InitSCI routine.  The interrupt routine itself is also included.  L is a typedef struct declared globally in the project.

 

 

#define SOM   0xaa

#define EOM   0x55

#define STUFF 0x70

 

void InitSCI ( void )

{

    SCI2C2 = 0x00;        

    SCI2C1 = 0x00;        

    SCI2C2 = 0x2C;        

    SCI2C3 = 0x00;        

}

 

__interrupt void isrVsci2rx(void)

{

    UINT8 ucStatus, ucData;

 

    ucStatus = SCI2S1;

    ucData = SCI2D;

 

    if ( L.WaitForSOM == TRUE )

    {

        if ( ucData == SOM )

        {

            L.WaitForSOM = FALSE;

            g_ucRxUART2ReadIndex = 0;

            L.MsgReceivedLen = 0;

            L.StuffReceived = FALSE;

        }

    }

    else

    {

        switch ( ucData )

        {

            case 0x2a:         //SOM with inverted most significant bit

            case 0xd5:         //EOM with inverted most significant bit

            case 0xf0:         //STUFF with inverted most significant bit

                if ( L.StuffReceived == TRUE )

                {

                    g_ucRxUART2Buffer [g_ucRxUART2ReadIndex++] = ucData ^ 0x80;

                    L.MsgReceivedLen++;

                    L.StuffReceived = FALSE;

                }

                else

                {

                    g_ucRxUART2Buffer [g_ucRxUART2ReadIndex++] = ucData;

                    L.MsgReceivedLen++;

                }

                break;

 

            case STUFF:

                if ( L.StuffReceived == TRUE )

                {

                    g_ucRxUART2Buffer [g_ucRxUART2ReadIndex++] = ucData;

                    L.MsgReceivedLen++;

                    L.StuffReceived = FALSE;

                }

                else

                {

                    L.StuffReceived = TRUE;

                }

                break;

 

            case EOM:

                if ( L.StuffReceived == TRUE )

                {

                    g_ucRxUART2Buffer [g_ucRxUART2ReadIndex++] = ucData;

                    L.MsgReceivedLen++;

                    L.StuffReceived = FALSE;

                }

                else

                {

                    g_ucRxUART2Buffer [g_ucRxUART2ReadIndex] = ucData;

                    L.WaitForSTX = TRUE;

                    L.MsgReceived = TRUE;

                }

                break;

 

            default:

                g_ucRxUART2Buffer [g_ucRxUART2ReadIndex++] = ucData;

                L.MsgReceivedLen++;

                L.StuffReceived = FALSE;

        }

    }

}

Outcomes