problem with reception and transmission of CAN messages using the same FlexCAN_0 interface

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

problem with reception and transmission of CAN messages using the same FlexCAN_0 interface

987 Views
némethgábor
Contributor I

I am using eclipse and diab compiler to develope a bootloader code for S32R247 flash programming over CAN interface. Actually i have a problem with the reception and transmission of CAN messges, when message buffer interrupt is used.

Any time if I am sending CAN messages from the host to the bootloader then an interrupt flag going to be active, this is fine and works fine. After recognising an interrupt arrived and handled, I am reading the message out from the buffer and send a response back to the host.
Here comes the trouble! The answer what I sent back is causing the problem because it is reflected somehow to the receive messge buffer and causing interruption again. Therefore the sent message will be transmited all over and over again

do you have any ide how could I disable this reflection?

I am using to receive and transmit FlexCAN_0
 - receive message to message buffer 0
 - transmit message from message buffer 15
 
 here is a snippet of code I am using to initialize the CAN interface

additionally a question would be: why I can only enable  CAN_0.IMASK1.B.BUF31TO0M = 1; interrupt for all message buffers. I want to enable interrupt ! only ! for message buffer 0

void FlexCAN0_Init( void )
{
    int i = 0;

    /*Module enable*/
    CAN_0.MCR.B.MDIS = 0;

    /* Freeze ON */
    CAN_0.MCR.B.FRZ = 1;

    /*Source clk is oscillator clock (40MHz)*/
    CAN_0.CTRL1.B.CLKSRC = 0;

    /*Error correction configuration register enable*/
    CAN_0.CTRL2.B.ECRWRE = 1;

    /*Enable unrestricted write access to FlexCAN memory*/
    CAN_0.CTRL2.B.WRMFRZ = 1;

    /*Error configuration register write enable*/
    CAN_0.MECR.B.ECRWRDIS = 0;

    /*Disable memory error correction*/
    CAN_0.MECR.B.ECCDIS = 1;

    /*Keep normal operation*/
    CAN_0.MECR.B.NCEFAFRZ = 0;

    /*Error configuration register write disable*/
    CAN_0.MECR.B.ECRWRDIS = 1;

    /*Disable unrestricted write access to FlexCAN memory*/
    CAN_0.CTRL2.B.WRMFRZ = 0;

    /*Error correction configuration register disable*/
    CAN_0.CTRL2.B.ECRWRE = 0;

    /* Loop back mode Disabled */
    CAN_0.CTRL1.B.LPB = 0;

    /*Enable individual RX masking*/
    CAN_0.MCR.B.IRMQ = 1;

    /* ADDED TO EVADE SELF RECEPTION */
    CAN_0.MCR.B.SRXDIS = 1;

    //Sclock frequency = PE clock frequency / (PRESDIV + 1)
    // Bit Rate = f_CANCLK / (PRESDIV + 1) x (PROP_SEG + PSEG1 + PSEG2 + 4)
//    /*CAN bit timing - 40MHz oscillator, 100kbps bitrate,*/
//    CAN_0.CTRL1.B.PRESDIV = 39;
//    CAN_0.CTRL1.B.PROPSEG = 0;
//    CAN_0.CTRL1.B.PSEG1 = 3;
//    CAN_0.CTRL1.B.PSEG2 = 3;
//    CAN_0.CTRL1.B.RJW = 3;

    /*CAN bit timing - 40MHz oscillator, 500kbps bitrate,*/
    CAN_0.CTRL1.B.PRESDIV = 4;
    CAN_0.CTRL1.B.PROPSEG = 2;
    CAN_0.CTRL1.B.PSEG1 = 5;
    CAN_0.CTRL1.B.PSEG2 = 5;
    CAN_0.CTRL1.B.RJW = 1;

    /*CAN bit timing - 40MHz oscillator, 1000kbps bitrate,*/
//    CAN_0.CTRL1.B.PRESDIV = 3;
//    CAN_0.CTRL1.B.PROPSEG = 4;
//    CAN_0.CTRL1.B.PSEG1 = 1;
//    CAN_0.CTRL1.B.PSEG2 = 1;
//    CAN_0.CTRL1.B.RJW = 0;

    /*enable interrupt for MB0*/
    CAN_0.IMASK1.B.BUF31TO0M = 1;

    /*Clear all RX individual Mask Registers The corresponding bit in the
     * filter is "don't care."*/
    for(i = 0; i < 64; i++)
    {
        CAN_0.RXIMR[i].R = 0xFFFFFFFF;
    }

    /*Set all message buffers RX inactive*/
    for(i = 0; i <64; i++)
    {
        CAN_0.MB[i].CS.R = 0x0000;
    }

    CAN_0.RXMGMASK.R = 0x00000001;

    /* Freeze OFF */
    CAN_0.MCR.B.FRZ = 0;

    /*No freeze mode request*/
    CAN_0.MCR.B.HALT = 0;
}

void ConfigureRXMessageBuffer(void)
{
    CAN_0.MB[0].CS.B.CODE = 0x0;              //MB inactive
    CAN_0.MB[0].CS.B.IDE = 0;
    CAN_0.MB[0].ID.R = 0;          //set standard ID
    CAN_0.MB[0].DATA.W[1] = 0x00000000;        //data1 set (optional)
    CAN_0.MB[0].DATA.W[0] = 0x00000000;        //data0 set (optional)
    CAN_0.MB[0].CS.B.CODE = 0x4;            //MB empty - ready for receive
}

void transmitMessage(int MB, int ID, unsigned char* pbData, unsigned char bLen)
{
    uint32 dwTemp;
    if (CAN_0.MB[MB].CS.B.CODE != 0xC)
    {
        CAN_0.MB[MB].CS.B.CODE = 0x8;         // MB TX inactive
        CAN_0.MB[MB].CS.B.IDE = 1;              // extended bit enabled
        CAN_0.MB[MB].ID.R = ID;                  // set message STD ID
        //    CAN_0.MB[MB].DATA.W[0] = 0x12345678;  // data0 set
        //    CAN_0.MB[MB].DATA.W[1] = 0x90ABCDEF;  // data1 set
        if (bLen >= 1)
        {
            CAN_0.MB[MB].DATA.W[0]  = ((*pbData++) << 24);  // data0 set
            if (bLen >= 2)
            {
                CAN_0.MB[MB].DATA.W[0] += ((*pbData++) << 16);
                if (bLen >= 3)
                {
                    CAN_0.MB[MB].DATA.W[0] += ((*pbData++) << 8);
                    if (bLen >= 4)
                    {
                        CAN_0.MB[MB].DATA.W[0] += ((*pbData++));
                        if (bLen >= 5)
                        {
                            CAN_0.MB[MB].DATA.W[1]  = ((*pbData++) << 24);   // data1 set
                            if (bLen >= 6)
                            {
                                CAN_0.MB[MB].DATA.W[1] += ((*pbData++) << 16);
                                if (bLen >= 7)
                                {
                                    CAN_0.MB[MB].DATA.W[1] += ((*pbData++) << 8);
                                    if (bLen == 8)
                                    {
                                        CAN_0.MB[MB].DATA.W[1] += ((*pbData));
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        CAN_0.MB[MB].CS.B.DLC = bLen;         // message length max 8 bytes
        CAN_0.MB[MB].CS.B.RTR = 0;              // remote frame disable
        CAN_0.MB[MB].CS.B.SRR = 1;              // used with STD_ID
        CAN_0.MB[MB].CS.B.CODE = 0xC;          // MB once transmit data
        dwTemp = CAN_0.TIMER.R;

        //mandatory to wait until the message is not shifted out completely
        //do{
        //    kickWDT();
        //}while(CAN_0.ESR1.B.IDLE == 0);
    }
}

int frameworkCheckInterrupt( void )
{
    uint32 dwTemp;
    //check interrupt flag and sign it if something is received
    if (CAN_0.IFLAG1.R & 0x00000001)
    {
        CAN_0.MB[0].ID.R = 0;

        fw.status = RECEIVED;
        dwTemp = CAN_0.IFLAG1.R;
        CAN_0.IFLAG1.R = dwTemp;

        /* mandatory - read control/status word - lock the MB */
        dwTemp = CAN_0.MB[0].CS.R;

        canReadBuffer(fw.fBuffer);
        fw.task = fw.fBuffer[0];
        //used when user cmd is used as task
        fw.subTask = fw.fBuffer[1];
    }
    else
      fw.status = IDLE;
    return fw.status;
}

3 Replies

715 Views
némethgábor
Contributor I

Hi,

Yes somehow the self reception is active and I cannot switch it off. Therefore I just made a workaround and ignoring the self received messages, differentiating based on the can id field.
I cannot really debug it because I'm downloading my bootloader over an other bootloader, what needs to trigger external wdt and so on.

It really seems that my transmitt is also causing interrupt in that message buffer where from I sent data. I'm using 15th MB to transmit data and any time I'm transmitting something the interrupt flag going to be 1 on MB 15.

anyway thanks your feedback,

G

0 Kudos

715 Views
hcontigiani
Contributor II

I have the same issue, somehow the self reception is active and I cannot switch it off. I try with:

base->MCR |= CAN_MCR_SRXDIS(1);

I have noticed that the instruction takes effect only if I debug the program step by step at the point of the instruction execution of self reception off.

0 Kudos

715 Views
PetrS
NXP TechSupport
NXP TechSupport

Hi,

it looks the Self reception is still enabled. Check with the debugger that the MCR[SRXDIS] is really set.

The  CAN_0.IMASK1.B.BUF31TO0M = 1; and  CAN_0.IMASK1.R = 1; do the same; MB0 interrupt is only enabled.

BR, Petr