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.

TCAN4550: Transmission and reception is not working at the same time.

Part Number: TCAN4550

Hi,

We are using sllc469 for development of CANFD transmission and reception.

We are setting Nominal baud rate to 500kbps and Data baudrate to 2Mbps;

Case 1: 

We are setting following values

MRAMConfiguration_before.SIDNumElements = 4; // Standard ID number of elements
MRAMConfiguration_before.XIDNumElements = 3; // Extended ID number of elements
MRAMConfiguration_before.Rx0NumElements = 2; // RX0 Number of elements
MRAMConfiguration_before.Rx0ElementSize = 0x07; // RX0 data payload size
MRAMConfiguration_before.Rx1NumElements = 2; // RX1 number of elements
MRAMConfiguration_before.Rx1ElementSize = 0x07; // RX1 data payload size
MRAMConfiguration_before.RxBufNumElements = 0; // RX buffer number of elements
MRAMConfiguration_before.RxBufElementSize = 0x07; // RX buffer data payload size
MRAMConfiguration_before.TxEventFIFONumElements = 0; // TX Event FIFO number of elements
MRAMConfiguration_before.TxBufferNumElements = 0; // TX buffer number of elements
MRAMConfiguration_before.TxBufferElementSize = 0x07;
TCAN4x5x_MRAM_Configure(&MRAMConfiguration_before); // Set up the applicable registers related to MRAM configuration

and we are enabling RXFIFO0 receive interrupt and RXFIFO1 receive interrupt

TCAN4x5x_MCAN_ConfigureInterruptEnable(0x00000011);

We are able to get nINT interrupt.

Expected data is received.

Case 2: 

MRAMConfiguration_before.SIDNumElements = 0; // Standard ID number of elements
MRAMConfiguration_before.XIDNumElements = 0; // Extended ID number of elements
MRAMConfiguration_before.Rx0NumElements = 0; // RX0 Number of elements
MRAMConfiguration_before.Rx0ElementSize = 0; // RX0 data payload size
MRAMConfiguration_before.Rx1NumElements = 0; // RX1 number of elements
MRAMConfiguration_before.Rx1ElementSize = 0; // RX1 data payload size
MRAMConfiguration_before.RxBufNumElements = 0; // RX buffer number of elements
MRAMConfiguration_before.RxBufElementSize = 0; // RX buffer data payload size
MRAMConfiguration_before.TxEventFIFONumElements = 0; // TX Event FIFO number of elements
MRAMConfiguration_before.TxBufferNumElements = 2; // TX buffer number of elements
MRAMConfiguration_before.TxBufferElementSize = 0x07;
TCAN4x5x_MRAM_Configure(&MRAMConfiguration_before);

and disable all interrupt TCAN4x5x_MCAN_ConfigureInterruptEnable(0x00000000);

and sending data after every 15 msec

header.DLC = MCAN_DLC_64B; // Set the DLC to be equal to or less than the data payload (it is ok to pass a 64 byte data array into the WriteTXFIFO function if your DLC is 8 bytes, only the first 8 bytes will be read)
header.ID = 0x055; // Set the ID
header.FDF = 1; // CAN FD frame enabled
header.BRS = 1; // Bit rate switch enabled
header.EFC = 0;
header.MM = 0;
header.RTR = 0;
header.XTD = 0; // We are not using an extended ID in this example
header.ESI = 0;

if((MODE_PINS_AFTER & (REG_BITS_DEVICE_MODE_DEVICEMODE_NORMAL|REG_BITS_DEVICE_MODE_WD_CLK_40MHZ)) == (REG_BITS_DEVICE_MODE_DEVICEMODE_NORMAL|REG_BITS_DEVICE_MODE_WD_CLK_40MHZ))
{
    
   TCAN4x5x_MCAN_WriteTXBuffer(1, &header, send_data); // This function actually writes the header and data payload to the specified TX Fifo number. It returns the bit necessary to write to TXBAR,
 
   TCAN_BURST_READ(0X8158,&test_read,18);
    
   TCAN4x5x_MCAN_TransmitBufferContents(1);


}

Case 3:

MRAMConfiguration_before.SIDNumElements = 4; // Standard ID number of elements
MRAMConfiguration_before.XIDNumElements = 3; // Extended ID number of elements
MRAMConfiguration_before.Rx0NumElements = 2; // RX0 Number of elements
MRAMConfiguration_before.Rx0ElementSize = 0x07; // RX0 data payload size
MRAMConfiguration_before.Rx1NumElements = 2; // RX1 number of elements
MRAMConfiguration_before.Rx1ElementSize = 0x07; // RX1 data payload size
MRAMConfiguration_before.RxBufNumElements = 0; // RX buffer number of elements
MRAMConfiguration_before.RxBufElementSize = 0x07; // RX buffer data payload size
MRAMConfiguration_before.TxEventFIFONumElements = 0; // TX Event FIFO number of elements
MRAMConfiguration_before.TxBufferNumElements = 2; // TX buffer number of elements
MRAMConfiguration_before.TxBufferElementSize = 0x07;
TCAN4x5x_MRAM_Configure(&MRAMConfiguration_before); // Set up the applicable registers related to MRAM configuration

TCAN4x5x_MCAN_ConfigureInterruptEnable(0x00000011);

If I place only Reception logic it works properly. If I add transmission logic, Data of all configure message IDs are receive once and then nINT interrupt is not coming, and data is not transmitting.

Thanks and regards 

Vikas Gavhane 

  • Hi Vikas,

    Thanks for providing the details on your software configuration.  We will be able to look through this in detail on Monday once our team returns from our US holiday.  I wanted to clarify on your last statement, though.  When you say all configured message IDs are received once, do you mean that all the messages that had previously been written to the TX buffer are received?  If so, this would be expected.  After that, though, are you able to re-write to the TX buffer and send more frames to the CAN bus?

    Regards,
    Max

  • Hi MAX,

    We are using TCAN4550 in  Normal mode not in test mode, 

    We have configured the nINT interrupt for "Rx FIFO 0 New Message" and "Rx FIFO 1 New Message".

    cases:

    1.standalone Transmission program is working in polling method.

    2.standalone reception program is working fine with interrupt logic, interrupts are generated on every configured trigger.

    3.when we try to integrate both implementations. transmission and reception are working properly but we are not able to get interrupt for reception triggers as we were getting in the standalone configuration..

      Thank you in advance

  • Vikas,

    In the third case where the nINT is not triggering, how is the proper reception in RX FIFOx being verified? Since you've seen the nINT trigger previously, I'll assume your software configuration is correct and besides adding the transmission logic, nothing else is changing from case 1 to case 3. Is that correct?

    Regards,

  • Hi Eric,

    1. We are contineously reading "MRAM Interrupt Status register" [TCAN4x5x_MCAN_Interrupts] and checking whether "FIFO has new element" [RF0N] bit.

    RF0N Bit is getting set but interrupt is not triggering.  SO when we are getting bit status as set we are reading from FIFO and we are getting updated data as per transmitted messages.

    2. yes,There is no change apart from adding transmission configuration.

    observation for case3: we are getting nINT interrupt until we start transmission. as soon as we start transmission the nINT intr is not generating, but we can see the values changing in polling logic

  • Vikas,

    Thank you for this information, it helps. So you are seeing the interrupt bit itself toggle along with nINT in case 1 where reception is correctly occurring. But in case 3 once transmission is added, the interrupt bit itself is still toggling, but nINT is no longer toggling. It's strange that you're seeing the interrupt indication function correctly until you add the transmission logic.

    My first thought is that the interrupt enable bit is getting overwritten when you write the transmission logic. While in case 3, is it possible to verify the correct interrupts are enabled after all the reception and transmission logic is written and the procedure is executed? And I saw the order of commands you showed in previous posts, is this the chronological order that happens in the code? 

    Another experiment to try would be to assign the interrupts to m_can_int0 and m_can_int1, and have them output on GPIO1 or GPO2 to see if they work on those outputs. A step-by-step procedure can be found here on post number 4.

    Please let me know if you have any questions or if this doesn't make sense.

    Regards,

  • Hi Eric,

    We have performed the experiment suggested by you, observations as per below

    Configuration 1:

    We have configured the registers as per following:


    register address and values


    0x0800 = 0x08400080 //configure GPO2 as mcan_int0
    0x105c = 0x00000001 //enable mcan_int0
    0x1054 = 0x00000001 //enable RF0NE interrupt
    0x1058 = 0x00000000 //Assign RF0NE to mcan_int0

    We configured 7 filter to RXFIFO0

    Case 1: Code has only reception logic

    We continuously get nINT interrupt, We were able to read received data.
    GPO2 pin is toggling(Checked on DSO).

    Read the Configuration register in nINT interrupt logic


    register address and values

    0x0800  = 0x08400080
    0x105c = 0x00000001
    0x1054 = 0x00000001
    0x1058 = 0x00000000

    Case 2: Code with Transmission and reception logic
    We are successfully able to transmit data, Able to read received data in polling mode.
    GPO2 pin is toggling but nINT interrupt is not triggering.

    Read the Configuration register after sending data
    register address and values


    0x0800 = 0x08400080
    0x105c = 0x00000001
    0x1054 = 0x00000001
    0x1058 = 0x00000000



    Configuration 2:

    We have configured the registers as per below


    0x0800 = 0x08400480 //configure GPO2 as mcan_int0 and GPIO1 as a mcan_int1
    0x105c = 0x00000003 //enable mcan_int0 and mcan_int1
    0x1054 = 0x00000011 //enable RF0NE and RF1NE interrupt
    0x1058 = 0x00000010 //Assign RF0NE to mcan_int0 and RF1NE to mcan_int1

    We configured the 4 filter to RXFIFO0 and 3 filters to RXFIFO1

    Case 1: Code has only reception logic

    We continuously get the nINT interrupt, We were able to read received data.
    GPO2 and GPOI1 pins are toggling(Checked on DSO).

    Read the Configuration register in nINT interrupt logic
    register address and values


    0x0800 = 0x08400480
    0x105c = 0x00000003
    0x1054 = 0x00000011
    0x1058 = 0x00000010

    Case 2: code with Transmission and reception logic
    We were successfully able to transmit data, Able to read received data in polling mode.
    GPO2 and GPIO1 pins are toggling but nINT interrupt is not triggering.

    Read the Configuration register after sending data
    Register address and values


    0x0800 = 0x08400480
    0x105c = 0x00000003
    0x1054 = 0x00000011
    0x1058 = 0x00000010


    Thank You

    Vikas Gavhane

  • Hello Vikas,

    Eric is currently out of the office so I will try to help you while he is out.  I have read through the thread and I have a couple of questions.  You have provided the MCAN Interrupt register values, but I didn't see the values of registers 0x0820 (Interrupts), 0x0824 (MCAN Interrupts), and 0x0830 (Interrupt Enables) reported for your test cases.  Could you tell me what those values are as well?

    It sounds to me that there is another interrupt bit being set as a result of the transmission code being added that is not part of the MCAN Interrupt bits you are enabling.  You mention that the "nINT interrupt is not triggering" but I don't know if this pin is stuck high or stuck low.  Could you tell me the logic High/Low level of the nINT pin when it is not triggering as you expect it to?  I suspect it is Low, and if so, there is another interrupt bit holding it low that is preventing it from toggling.  If so, clearing that interrupt bit should allow the RX FIFO interrupts to be reflected on the nINT pin as well.  We should be able to determine this from the values of 0x0820, 0x0824, and 0x0830.

    The nINT pin is active low and is the logical OR of all faults in registers0x0820 and 0x0824 that are not masked in 0x0830. The default value for 0x0830 is hFFFFFFF which means every bit is enabled including non-MCAN related interrupt bits. 

    If any of these are being set there may be a hardware issue, or they could be left over from initialization and you can simply add the code to clear them as part of your initialization before trying to send and receive data.

    Regards,

    Jonathan Nerger

    Texas Instruments | INT-TRX| Applications Engineer

  • Hi Jonathan,

    we did the tests as per you specified. below are the observation.

    While we are checking the integrated logic we read the status registers
    Register Address and values
    0x0830 = 0x809628ff
    0x0820 = 0x8A or 0x88 (showing M_CAN global INT and SPI Error)
    0x0824 = 0x01 or 0x05 (Expected value as per mcan interrupt configuration)


    SPI status register
    0x000C = 0x0804000E (Write underflow and Internal error log write)

    for SPI error :'Read_overflow' is occurring sometimes and  at that instance 'Write underflow' is not present
    0x000C = 0x2000A


    as per the observation it looks like issue in SPI TX/RX code.
    please suggest what additional things needs to be done for removing SPI related Error.

    
    /*******************************************************************************************************************************/
    
    uint32_t TCAN_READ(uint16_t Add_int16) 
    {
    
        uint8_t Addr_byte = 0x00;
        uint8_t error_mst;
        uint8_t readData;
        uint8_t readData1;
        uint8_t readData2;
        uint8_t readData3;
        
        uint32_t returnData = 0x00000000;
        
    
        //MAKE THE CHIP SELECT LOW
        CANFD_SS_Pin_PutVal(0);   
    
       
        error_mst |= TCAN_Send_Char(AHB_READ_OPCODE);  
         
        Addr_byte = (uint8_t)(Add_int16>>8);
        error_mst |= TCAN_Send_Char(Addr_byte);
        Addr_byte = (uint8_t)(Add_int16);
        error_mst |= TCAN_Send_Char(Addr_byte);
        
        error_mst |= TCAN_Send_Char(0x01);
       
        ///////////////////////////ACTUAL READ HAPPENS HERE  
       
        //error_mst |= TCAN_Recv_Char(&Read_Data);
        error_mst |= TCAN_Recv_Char(&Read_Data);
        readData = Read_Data; //1st byte
        error_mst |= TCAN_Recv_Char(&Read_Data);
        readData1 = Read_Data; //2nd byte
        error_mst |= TCAN_Recv_Char(&Read_Data);
        readData2 = Read_Data;    //3rd byte
        error_mst |= TCAN_Recv_Char(&Read_Data);
        readData3 = Read_Data;       //4th byte
        returnData = (((uint32_t)readData) << 24) | (((uint32_t)readData1 << 16)) | (((uint32_t)readData2) << 8) | readData3;
    
    
         delay();
        //MAKE THE CHIP SELECT HIGH
        CANFD_SS_Pin_PutVal(1);    
    
        return  returnData;
    }
    /*******************************************************************************************************************************/
    
    uint8_t TCAN_WRITE(uint16_t Add_int16,uint32_t data_32) 
    {
     
      uint8_t status;
      uint8_t error_mst;
      uint8_t Addr_byte;
      uint8_t Data_byte;
      status = ERR_OK; 
      
      CANFD_SS_Pin_PutVal(0); 
     
      
      error_mst |= TCAN_Send_Char(AHB_WRITE_OPCODE);
      
      Addr_byte = (uint8_t)(Add_int16>>8);
      error_mst |= TCAN_Send_Char(Addr_byte);  
      Addr_byte = (uint8_t)(Add_int16);  
      error_mst |= TCAN_Send_Char(Addr_byte);
      
      
      error_mst |= TCAN_Send_Char(0x01);
     
      ///////////////////////////ACTUAL WRITE HAPPENS HERE  
    
      Data_byte = (uint8_t)(data_32>>24);
      error_mst |= TCAN_Send_Char(Data_byte);
      
      Data_byte = (uint8_t)(data_32>>16);
      error_mst |= TCAN_Send_Char(Data_byte); 
      
      Data_byte = (uint8_t)(data_32>>8);
      error_mst |= TCAN_Send_Char(Data_byte);
       
      
      Data_byte = (uint8_t)(data_32);
      error_mst |= TCAN_Send_Char(Data_byte);
       
      delay();
       //MAKE THE CHIP SELECT HIGH
     
      CANFD_SS_Pin_PutVal(1);   
      
    
      status = error_mst;
      return status ; 
       
    }
    /*******************************************************************************************************************************/
    
    uint8_t TCAN_BURST_READ(uint16_t Add_int16,uint32_t *data_32, uint8_t No_Of_Words) 
    {
      uint8_t status;
      uint8_t word_count;
      uint8_t error_mst;
      uint8_t Addr_byte;
      uint8_t readData;
      uint8_t readData1;
      uint8_t readData2;
      uint8_t readData3;
      
      status = ERR_OK;
      word_count = 0; 
      
          //MAKE THE CHIP SELECT LOW
      CANFD_SS_Pin_PutVal(0);
      
      error_mst = TCAN_Send_Char(AHB_READ_OPCODE);
       
      Addr_byte = (uint8_t)(Add_int16>>8);  
      error_mst = TCAN_Send_Char(Addr_byte);  
      Addr_byte = (uint8_t)(Add_int16);
      error_mst = TCAN_Send_Char(Addr_byte);
      
      error_mst = TCAN_Send_Char(No_Of_Words);
      
      ///////////////////////////ACTUAL WRITE HAPPENS HERE  
      for(word_count=0; word_count<No_Of_Words; word_count++)
      {
        
                 ///////////////////////////ACTUAL READ HAPPENS HERE       
              error_mst |= TCAN_Recv_Char(&Read_Data);
              readData = Read_Data; //1st byte
                     
              error_mst |= TCAN_Recv_Char(&Read_Data);
              readData1 = Read_Data; //2nd byte
               
              error_mst |= TCAN_Recv_Char(&Read_Data);
              readData2 = Read_Data;    //3rd byte       
               
              error_mst |= TCAN_Recv_Char(&Read_Data);
              readData3 = Read_Data;       //4th byte
               
              *data_32 = (((uint32_t)readData) << 24) | (((uint32_t)readData1 << 16)) | (((uint32_t)readData2) << 8) | readData3;
              data_32++;
      }
      delay();
       //MAKE THE CHIP SELECT HIGH  
      CANFD_SS_Pin_PutVal(1); 
    
      status = error_mst;
      return status ; 
       
    }
    /*******************************************************************************************************************************/
    
    uint8_t TCAN_BURST_WRITE(uint16_t Add_int16,uint32_t *data_32, uint8_t No_Of_Words) 
    {
       uint8_t status;
       uint8_t word_count;
       uint8_t error_mst;
       uint8_t Addr_byte;
       
       
      status = ERR_OK;
      word_count = 0; 
     
      CANFD_SS_Pin_PutVal(0); 
      
      error_mst |= TCAN_Send_Char(AHB_WRITE_OPCODE);
      
       
      Addr_byte  = (uint8_t)((uint16_t)Add_int16>>8);
      error_mst |= TCAN_Send_Char(Addr_byte);   
      Addr_byte  = (uint8_t)(Add_int16);
      error_mst |= TCAN_Send_Char(Addr_byte);
      
      
      error_mst |= TCAN_Send_Char(No_Of_Words);
      
     
        ///////////////////////////ACTUAL WRITE HAPPENS HERE  
      for(word_count=0; word_count<No_Of_Words; word_count++)
      {     
          
            Data_byte = (uint8_t)(*data_32 >> 24);
            error_mst |= TCAN_Send_Char(Data_byte);
      
            Data_byte = (uint8_t)(*data_32 >> 16);
            error_mst |= TCAN_Send_Char(Data_byte); 
      
            Data_byte = (uint8_t)(*data_32 >> 8);
            error_mst |= TCAN_Send_Char(Data_byte);     
      
            Data_byte = (uint8_t)(*data_32);
            error_mst |= TCAN_Send_Char(Data_byte);
             data_32++;
      
    
      }
      
      delay();
         
      CANFD_SS_Pin_PutVal(1); 
    
      status = error_mst;
      return status ; 
       
    }
    /*******************************************************************************************************************************/
    
    
    uint8_t TCAN_Send_Char(uint8_t Send_data)
    {
        uint8_t dummy_data;
        uint8_t SPI0_error;
        
        SPI0_error |= CANFD_SendChar(Send_data);
    
        //while(SPI0SR_SPTEF == 0); //wait till transmission complete
       
        while(SPI0SR_SPIF == 0); //wait till data received complete
        
        SPI0_error |= CANFD_RecvChar(&Read_Data);
        return SPI0_error;                  
       
    }
    
    
    /*******************************************************************************************************************************/
    
    
    uint8_t TCAN_Recv_Char(uint8_t *Receive_data)
    {
        uint8_t dummy_data =0x00;
        uint8_t SPI0_error;
        
        SPI0_error |=CANFD_SendChar(dummy_data);
        
        //while(SPI0SR_SPTEF == 0); //wait till transmission complete
       
        while(SPI0SR_SPIF == 0); //wait till data received complete  
        
        SPI0_error |= CANFD_RecvChar(Receive_data);                
        return SPI0_error;
                             
    }
    
    /*******************************************************************************************************************************/
    
    void delay(void) 
    {
      uint8_t  count = 0;
       
      for(count = 0;count<100;count++) 
      {
       
        __asm("NOP");
     
      }
    }
    

    the routines used in our code for SPI data exchange are attached in the FILE

    NOTE: We are using NXP MC9S12xep100 micro for project

  • Hi Vikas,

    I had our firmware expert on this device look over your code and he didn't see anything obvious in your code and it appears to work.  I am suspecting there might be a SPI signal integrity issue with either noisy or marginal SPI signals.  If so you could be getting a variety of errors, but this is normally a result that the transaction doesn't end on a byte boundary as a result of it seeing an incorrect number of clock pulses.  The TCAN4550 checks that the SPI transaction contains exactly a multiple of 32 bits is received, otherwise it assumes an error occurred and sets the interrupt pin to signal the MCU that the last SPI transaction could contain an error and to re-send (if your code implements this function).

    I suggest that you look at the signals with a scope to help determine if there may be an integrity issue. Is it possible to look at the SPI signals in your setup?

    But you can also do a simple test:

    Do a while(1) loop until error/interrupt and keep reading MCAN_ENDN register (0x1004) until unexpected value or interrupt.  Value should always be 0x87654321. 

    There is also always a scratchpad register that you can use as a test and repeatedly write and read this register and compare the values and looking for differences. 

    If you are having no reliability issues with single word read/writes, then you may be having a problem with bulk reads and writes.  In this case you could move the testing to a random unused portion of MRAM (location 0x8000 to 0x87FF) to test the SPI reliability with repeated reads and writes.

    Are you using the TCAN4550 EVM, or have you built your own board for this evaluation?  Also, what is your SPI data rate?

    Regards,

    Jonathan

  • Hi Jonathan,
    Using DSO We check transmission of data on SPI and reception of data on SPI, it showing expected result.

    We read the register as per your suggestion
    Register and Values
    0x1004 = 0x87654321 (We contineously read the register we are getting this value only)

    We were able to successfully write in the MRAM transmit buffer.
    (We read the data from transmit buffer before sending the message on CAN, data is same as written.)

    We are using TCAN4550EVM.
    SPI configuration: data rate is 10Mhz.
    (Note: today's test is done on 5Mhz and 1Mhz it showing same result as 10Mhz).
    Clock Edge = Falling edge
    Clock Idle polarity = low


    Still nINT interrupt is not toggling(It is stuck to low due to SPI error).

    Thank you
    Vikas

  • Hi Vikas,

    The SPIERR is really only generated as a result of an incorrect number of clock cycles compared with how many bytes/words of data you are telling the device it is expecting.  If you have verified that the signal integrity of the SPI is good, then I believe the issue will probably come down to something related to the number of clock cycles received during the transaction. 

    You gave me one additional piece of information in your last post that I find as very useful.  You told me that the Clock Edge you are using for the SPI is the Falling Edge.  The TCAN4550 uses both edges of the clock for shifting data into and out of the device.  Section 8.5.1 of the datasheet discusses this in more detail. 

    The SPI input data on SDI is sampled on the low to high edge of the SCLK.  The SPI output data on SDO is changed on the high to low edge of SCLK. 

    From the Microcontroller side, I believe you need to be using the Rising Edge for your SPI communication into and out of the TCAN4550.  For example, data will be shifted out of the MCU on the rising edge and will be held at that value until the following rising edge.  This will make the data stable for the TCAN4550 to sample on the Falling Edge.  Likewise, the TCAN4550 will shift data out on the Falling Edge where it will hold that value to make it stable for the MCU to sample on the Rising Edge.

    The SDO/SDI sample and hold relationship with the SCLK may allow for the data to be sampled correctly.  But my suspicion is that as a result of using the incorrect clock edge, there may be a missing or extra clock edge seen by the TCAN4550 at the end of the transaction that is causing it to set the SPI Error Flag. 

    The other cause could be a result of telling the TCAN4550 that you are going to send it more words of data as part of the packet header than what you are actually sending it.  Make sure you are only telling it to expect one word of data if you are writing one word.  If you are telling it to expect 2 or more words, but only sending one word before changing the chip select pin, then this will also flag an error.

    Try to change the clock polarity too rising edge on the MCU and check to make sure there is exactly the correct number of clock edges in the transaction using a scope and in the code.  Also check that you are setting the correct number of words in the SPI header and see if either of those settings makes a difference.  If you would like I could contact you through email and we could exchange more detailed information such as screenshots, that are not as easy to do through e2e.  If you would like that, just let me know and I will look you up in the system and send you an email.

    Regards,

    Jonathan

  • Hello Jonathan,

    We have changed the SPI configuration to rising edge and there is some improvement in operation.
    Now, nInt intr is occurring when we transmit and receive at the same time using polling architecture.

    when we use the interrupt logic i.e in ISR we are implementing below code

    void CANFD_nINT_OnInterrupt(void)
    {
         //read status registers
         dev_ir_before.WORD_CONFIG.WORD = TCAN_READ(REG_DEV_IR);
         TCAN_WRITE(REG_DEV_IR, 0xFFFFFFFF);
         mcan_ir.WORD_CONFIG.WORD = TCAN_READ(REG_DEV_MRAM_IR);
         TCAN_WRITE(REG_MCAN_IR, 0xFFFFFFFF);
    }

    then nInt is occurring , but as we try to read the data in ISR then the same issue is repeating (nInt stuck low in SPI Error)

    One more thing we tried is,
    we did not do ant action in ISR (just flag activation) and we read the REGISTER - cleared the register - read the data operation in main loop, taking just flag activation from ISR.

    In the above case the logic is working fine and we are able to get continuous nInt.

    we want to know is ther any rule/ interlock to operate Register/ data after receiving nInt.

    last case: in standalone reception code (where I am not transmitting any data) then I am able to read data in ISR routine successful and nInt also working OK.

    Thank You!!

  • Hi Vikas,

    I am glad to hear that changing the clock polarity from falling to rising edge improved your operation.  I think we are very close to resolving all of your difficulties. 

    To answer your last question "we want to know is there any rule/ interlock to operate Register/ data after receiving nInt," the answer is no, there is no rule.  You can read this data whenever you would like, or not at all.  The TCAN4550 device does not care.  However, you WILL want to read this data before your buffers and FIFOs fill up with so many new messages that you will either lose new incoming data or overwrite data you have yet to read (depending on how you configure your device).  As long as you read the data fast enough to prevent lost CAN messages, you have no other limitations.

    Now, regarding your problems with the SPI Error.  I think I now know what the problem is and it should be a fairly easy fix.  Looking at your ISR code, you are performing SPI Reads and Writes within the ISR itself.  This is a big problem and you should avoid doing any form of SPI activity within the ISR itself.  The reason for this is that you are most likely receiving an interrupt request while you are in the middle of a SPI transaction from your main loop.  If you are in the middle of the transaction when the ISR starts, then it will restart a new SPI transaction and the TCAN4550 will not have received the correct number of bits from the previous SPI transaction that got interrupted and therefore result in a SPI Error. 

    This is probably one of the reasons why you worked with just the "receive" code enabled and not the "transmit."  When you added the transmit code you were doing SPI transactions for both sending data and for reading the incoming messages which were part of the ISR and you were interrupting and corrupting yourself.

    Instead, you should make the ISR very simple and simply set a flag that you received an interrupt that needs to be serviced.  Then in your Main code, you should check for that flag and if your ISR set the flag, then your Main loop should go read the register data through the SPI bus.  This way, if you are in the middle of a SPI transaction and the ISR is triggered, it will simply set a flag and return to the main code where it will complete the SPI transaction currently in progress without any error.

    I hope this is clear.  Let me know if it is not.

    Regards,

    Jonathan

  • Hi Jonathan,

    Last post clear my doubts.

    Thank you for support, we resolved the issue.

    Regards,

    Vikas

  • Hi Vikas,

    I am glad I was able to help you resolve your issues.  Please feel free to reach back out to us if you have any additional issues that need our support.

    Regards,

    Jonathan