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.

TMS570LS3137: canUpdateID not working with interrupts

Part Number: TMS570LS3137
Other Parts Discussed in Thread: HALCOGEN

I have can 2 and 3 connected in loopback mode externaly,
* CanREG 2 messageBox 1 is sendig the data R
* CanREG 3 messageBox 1 recieving
* Im using interrupts
Im trying to cange the ID (using extended Id) in CAN register 2 message box 1.
Doing it in HalCoGen is no problem but as soon as i try to do it using the function it gets stuck pending the tx_done interruption.




/** @file sys_main.c 
*   @brief Application main file
*   @date 11-Dec-2018
*   @version 04.07.01
*
*   This file contains an empty main function,
*   which can be used for the application.
*/

/* 
* Copyright (C) 2009-2018 Texas Instruments Incorporated - www.ti.com 
* 
* 
*  Redistribution and use in source and binary forms, with or without 
*  modification, are permitted provided that the following conditions 
*  are met:
*
*    Redistributions of source code must retain the above copyright 
*    notice, this list of conditions and the following disclaimer.
*
*    Redistributions in binary form must reproduce the above copyright
*    notice, this list of conditions and the following disclaimer in the 
*    documentation and/or other materials provided with the   
*    distribution.
*
*    Neither the name of Texas Instruments Incorporated nor the names of
*    its contributors may be used to endorse or promote products derived
*    from this software without specific prior written permission.
*
*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
*  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
*  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
*  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
*  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
*  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
*  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
*  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
*  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/


/* USER CODE BEGIN (0) */
/* Includes */
#include "system.h"
#include "spi.h"
#include "het.h"
#include "gio.h"
#include "reg_pcr.h"
#include "sys_pcr.h"
#include "sys_pmm.h"
#include "reg_vim.h"
#include "sci.h"
#include "string.h"
#include "reg_can.h"
#include "can.h"
#include "sys_common.h"
#include "sys_core.h"
#include "sys_vim.h"
#include "reg_mibspi.h"
#include "reg_can.h"
#include "adc.h"
#include "i2c.h"
#include "esm.h"
/* USER CODE END */

/* Include Files */

#include "sys_common.h"

/* USER CODE BEGIN (1) */
/* USER CODE END */

/** @fn void main(void)
*   @brief Application main function
*   @note This function is empty by default.
*
*   This function is called after startup.
*   The user can use this function to implement the application.
*/

/* USER CODE BEGIN (2) */
/* Globals */

typedef struct qMessage3
{
    uint32_t    id;
    uint8_t     buffer[8];
    uint8_t     interface;
} xMessage3;

uint32 tx_done =0;
xMessage3 rx_data;


void sysInit(void);
void canTest(void);
void dumpSomeData();

/* USER CODE END */

int main(void)
{
/* USER CODE BEGIN (3) */
    sysInit();
    canTest();
    while(1);
/* USER CODE END */

    return 0;
}


/* USER CODE BEGIN (4) */

void canTest()
{
    uint8_t tx_data[8] = {0x03, 0x0A, 0x03, 0x0A, 0x0B, 0x0C, 0x0B, 0x0A};
    uint8 *tx_ptr = &tx_data[0];
    uint32 command = 0x00000ABC;
//    uint32 canId;

    sciSend(scilinREG, 34, (unsigned char *)"\r\n********************************");
    sciSend(scilinREG, 34, (unsigned char *)"\r\n**********  CAN test  **********");
    sciSend(scilinREG, 34, (unsigned char *)"\r\n********************************");
    sciSend(scilinREG, 2,  (unsigned char *)"\r\n");
    sciSend(scilinREG, 12, (unsigned char *)"\r\nDeveloper:");
    sciSend(scilinREG, 26, (unsigned char *)"\r\n           Marco Mecha\r\n");
    sciSend(scilinREG, 2,  (unsigned char *)"\r\n");

    canUpdateID(canREG2, canMESSAGE_BOX1, ((command) & 0x1FFFFFFF) | (1<<29) |(1<<30));

//    canId = canGetID(canREG2, canMESSAGE_BOX1);
//    sciDisplayData(scilinREG, (uint8_t *)&(canId), 4);

    if(!canTransmit(canREG2, canMESSAGE_BOX1, tx_ptr)){
        sciSend(scilinREG, 26, "Error in data transmission");
    }

    sciSend(scilinREG, 13, "Transmitted: ");
    sciDisplayData(scilinREG, tx_ptr, 8);
    sciSend(scilinREG, 2, "\r\n");

    while(!tx_done){};                         /* the code gets stuck here */
    tx_done=0;

    sciSend(scilinREG, 12, "Received:   ");
    sciDisplayData(scilinREG, (uint8_t *)&(rx_data.buffer), 8);
    sciSend(scilinREG, 2, "\r\n");

    sciSend(scilinREG, 4, "Id: ");
    sciDisplayData(scilinREG, (uint8_t *)&(rx_data.id), 4);
    sciSend(scilinREG, 2, "\r\n");
}


void sysInit()
{
    uint8_t generic = 0;

    sciInit();                                      //SCI initialization.
    canInit();                                      //CAN initialization.

    //Enable interrupts:
    _enable_interrupt_();                           //General interrupt flag.

    //Enable SCI interrupt:
    sciEnableNotification(scilinREG,SCI_RX_INT);    //Enable SCI Lin interrupt by Rx.
    sciEnableNotification(sciREG,SCI_RX_INT);       //Enable SCI interrupt by Rx.

    //Enable CAN interrupt:
    canEnableErrorNotification(canREG2);            //Enable canREG2 interrupt.
    canEnableErrorNotification(canREG3);            //Enable canREG3 interrupt.

    sciReceive(scilinREG,1, (unsigned char *)&generic);

    sciSend(scilinREG, 2,  (unsigned char *)"\r\n");
    sciSend(scilinREG, 37, (unsigned char *)"Initializing system. Please wait...\r\n");
    gioInit();                                      //GIO module initialization.
    gioSetDirection(hetPORT1, 1 << 15);             //Enable N2HET1[15] as output. This is the output signal to the external watch-dog.
    gioSetDirection(spiPORT3, 0x11);                //to set the SPI3NCS[0] to output direction. The SPI3NCS[0] is the bit0 of SPIPC1 register.
                                                    //to set the SPI3NCS[4] to output direction. The SPI3NCS[4] is the bit4 of SPIPC1 register.
    gioSetDirection(mibspiPORT5, 0 <<9);
    gioSetDirection(mibspiPORT1, 0 <<1);

    //By default we set the GIO pins for long test as follows:

    gioSetDirection(mibspiPORT1, (0 << 9));         //Set MibSPI1_CLK direction. This is the bit 9 in the SPIPC3 register.
    gioSetDirection(gioPORTA, (0 << 6));            //Set GIOA[6] direction. This is the bit 6 of GIODIRA register.
    gioSetDirection(mibspiPORT1, (1 << 11));        //Set MibSPI1_SOMI[0] direction. This is the bit 11 in the SPIPC3 register.
    gioSetDirection(mibspiPORT1, (1 << 10));        //Set MibSPI1_SIMO[0] direction. This is the bit 10 in the SPIPC3 register.
    gioSetBit(mibspiPORT1, 10, 0);                  //We set the GIOs as logic 0
    gioSetBit(mibspiPORT1, 11, 0);                  //We set the GIOs as logic 0


    gioSetBit(spiPORT3, 0, 1);                      //Disable External memories SPI communication
    gioSetBit(spiPORT3, 4, 1);                      //Disable External memories SPI communication

    sciSend(scilinREG, 27, (unsigned char *)"\t************************\r\n");
    sciSend(scilinREG, 27, (unsigned char *)"\tLabOSat-02 [OBC] OS V1.0\r\n");
    sciSend(scilinREG, 27, (unsigned char *)"\t************************\r\n");
    sciSend(scilinREG, 1, (unsigned char *)"\n");
    sciSend(scilinREG, 14, (unsigned char *)"Developers: \r\n");
    sciSend(scilinREG, 30, (unsigned char *)"\t Gagliardi Leandro Luciano \r\n");
    sciSend(scilinREG, 22, (unsigned char *)"\t Di Nardo Federico \r\n");
    sciSend(scilinREG, 1, (unsigned char *)"\n");
}

/*********************************
 * SCI interrupt service routine *
 *********************************/
void sciNotification(sciBASE_t *sci, unsigned flags)
{
    uint8_t *rxKey = NULL;
    if(sci == scilinREG)
    {
        sciReceive(scilinREG, 1, rxKey);
        sciSend(sci, sizeof(uint8_t), rxKey);
    }
}

/*********************************
 * CAN interrupt service routine *
 *********************************/

void canMessageNotification(canBASE_t *node, uint32 messageBox)
{
    if(node==canREG2)
    {
        tx_done=1; /* confirm transfer request */
    }

    if(node==canREG3)
    {
        while(!canIsRxMessageArrived(canREG3, canMESSAGE_BOX1));
        canGetData(canREG3, canMESSAGE_BOX1, &(rx_data.buffer[0]));
        rx_data.id = canGetID(node, messageBox);
    }
}

/* USER CODE END */

  • Hi Marco,

    I started working on this thread now and will give my update ASAP.

    --
    Thanks & Regards,
    Jagadish.

  • This gets stucked in the same place as before 

    void canTest()
    {
        uint8_t tx_data[8] = {0x03, 0x0A, 0x03, 0x0A, 0x0B, 0x0C, 0x0B, 0x0A};
        uint8 *tx_ptr = &tx_data[0];
    //    uint32 command = 0x00000ABC;
    //    uint32 canId;
        uint32 ArbValue;
    
        sciSend(scilinREG, 34, (unsigned char *)"\r\n********************************");
        sciSend(scilinREG, 34, (unsigned char *)"\r\n**********  CAN test  **********");
        sciSend(scilinREG, 34, (unsigned char *)"\r\n********************************");
        sciSend(scilinREG, 2,  (unsigned char *)"\r\n");
        sciSend(scilinREG, 12, (unsigned char *)"\r\nDeveloper:");
        sciSend(scilinREG, 26, (unsigned char *)"\r\n           Marco Mecha\r\n");
        sciSend(scilinREG, 2,  (unsigned char *)"\r\n");
    
    //    canUpdateID(canREG2, canMESSAGE_BOX1, ((command) & 0x1FFFFFFF) | (1<<29) |(1<<30));
        ArbValue  = canREG2->IF2ARB;
        ArbValue &= 0xE0000000;
        ArbValue |= 0x1FFFFFFF;
        canUpdateID(canREG2, canMESSAGE_BOX1, ArbValue);
    
        if(!canTransmit(canREG2, canMESSAGE_BOX1, tx_ptr)){
            sciSend(scilinREG, 26, "Error in data transmission");
        }
    
        sciSend(scilinREG, 13, "Transmitted: ");
        sciDisplayData(scilinREG, tx_ptr, 8);
        sciSend(scilinREG, 2, "\r\n");
    
        while(!tx_done){};                         /* the code gets stuck here */
        tx_done=0;
    
        sciSend(scilinREG, 12, "Received:   ");
        sciDisplayData(scilinREG, (uint8_t *)&(rx_data.buffer), 8);
        sciSend(scilinREG, 2, "\r\n");
    
        sciSend(scilinREG, 4, "Id: ");
        sciDisplayData(scilinREG, (uint8_t *)&(rx_data.id), 4);
        sciSend(scilinREG, 2, "\r\n");
    }

    It never triggers the interrupt 

    void canMessageNotification(canBASE_t *node, uint32 messageBox)
    {
        if(node==canREG2)
        {
            tx_done=1; /* confirm transfer request */
        }
    
        if(node==canREG3)
        {
            while(!canIsRxMessageArrived(canREG3, canMESSAGE_BOX1));
            canGetData(canREG3, canMESSAGE_BOX1, &(rx_data.buffer[0]));
            rx_data.id = canGetID(node, messageBox);
        }
    }

  • Hi Macro Macha,

    I understood the root cause of the issue.

    Actually, it is a problem with the "canUpdateID" function. There is a small code issue in this function.

    The current process of this function is below:

    1. The below instruction is used to wait until the IF2 is free.

    while ((node->IF2STAT & 0x80U) ==0x80U)
        {
        } /* Wait */

    2. After that, in the below instruction we are setting the WR/RD bit and the Arb bits.

    node->IF2CMD = 0xA0U;

    That means we are telling CAN module that we want to do the write operation to the message object RAM and also, we are telling we want to update the arbitration field (Identifier + Dir + Xtd + MsgVal).

    3. In these two instructions we are updating arbitration field with the new required ID etc.

    node->IF2ARB &= 0x80000000U;
    	node->IF2ARB |= (msgBoxArbitVal & 0x7FFFFFFFU);

    4. As we already updated the new ID into the arbitration field, and now using this instruction we are initiating the actual writing into the message RAM for corresponding message object box.

    node->IF2NO = (uint8) messageBox;

    5. Finally waiting until the updation completion.

     while ((node->IF2STAT & 0x80U) ==0x80U)
        {
        } /* Wait */

    The problem with this process is that we are directly writing into IF2 register and then we are initiating the process right. But this should not be correct because before we are modifying the ID field, we should read the corresponding message number object into the IF2 register and then we should modify it.

    As we are directly modifying IF2 register before reading corresponding message object number, the IF2 register arbitration field will be with the value of 0, so that means MsgVal bit value also will be zero.

    If you verify below two lines we are modifying all the fields in the arbitration register except the MsgVal bit value.

    Here we are keeping just previous value in the MsgVal field, that means MsgVal field will be zero only(That means we are telling that it is not a valid message object).

    That is the reason our data is not transmitting from CAN module.

    The solution for this issue is below:

    Add above highlighted lines in the "canUpdateID" function, these lines will be helpful to read the corresponding message object number into IF2 before it is modifying.

    Note: If we add above lines in the function they might be lost if you regenerate the code from HALCoGen, to eliminate that you can add these lines before you are calling "canUpdateID" function in main itself.

    --

    Thanks & regards,
    Jagadish.

  • doing it like this solves the issue of  getting stuck pending the tx_done interruption.
    but it never riggers the recive interrupt, so it does not read any data.


    typedef struct qMessage3
    {
        uint32_t    id;
        uint8_t     buffer[8];
        uint8_t     interface;
    } xMessage3;
    
    uint32 tx_done =0;
    xMessage3 rx_data;
    
    
    void sysInit(void);
    void canTest(void);
    void dumpSomeData();
    
    /* USER CODE END */
    
    int main(void)
    {
    /* USER CODE BEGIN (3) */
        sysInit();
        canTest();
        while(1);
    /* USER CODE END */
    
        return 0;
    }
    
    
    /* USER CODE BEGIN (4) */
    
    void canTest()
    {
        uint8_t tx_data[8] = {0x03, 0x0A, 0x03, 0x0A, 0x0B, 0x0C, 0x0B, 0x0A};
        uint8 *tx_ptr = &tx_data[0];
        uint32 newCanId = 0x00000234;
        uint32 ArbValue;
    
        sciSend(scilinREG, 34, (unsigned char *)"\r\n********************************");
        sciSend(scilinREG, 34, (unsigned char *)"\r\n**********  CAN test  **********");
        sciSend(scilinREG, 34, (unsigned char *)"\r\n********************************");
        sciSend(scilinREG, 2,  (unsigned char *)"\r\n");
        sciSend(scilinREG, 12, (unsigned char *)"\r\nDeveloper:");
        sciSend(scilinREG, 26, (unsigned char *)"\r\n           Marco Mecha\r\n");
        sciSend(scilinREG, 2,  (unsigned char *)"\r\n");
    
        ArbValue  = canREG2->IF2ARB;
        ArbValue &= 0xE0000000;
        ArbValue |= newCanId;
    
        /*Jagadish*/
        while ((canREG2 -> IF2STAT & 0x80U) == 0x80u){}
    
        canREG2->IF2CMD = 0x20U;
        canREG2->IF2NO = (uint8) canMESSAGE_BOX1;
        /*Jagadish*/
    
        canUpdateID(canREG2, canMESSAGE_BOX1, ArbValue);
    
        if(!canTransmit(canREG2, canMESSAGE_BOX1, tx_ptr)){
            sciSend(scilinREG, 26, "Error in data transmission");
        }
    
        sciSend(scilinREG, 13, "Transmitted: ");
        sciDisplayData(scilinREG, tx_ptr, 8);
        sciSend(scilinREG, 2, "\r\n");
    
        while(!tx_done){};                         /* the code gets stuck here */
        tx_done=0;
    
        sciSend(scilinREG, 12, "Received:   ");
        sciDisplayData(scilinREG, (uint8_t *)&(rx_data.buffer), 8);
        sciSend(scilinREG, 2, "\r\n");
    
        sciSend(scilinREG, 4, "Id: ");
        sciDisplayData(scilinREG, (uint8_t *)&(rx_data.id), 4);
        sciSend(scilinREG, 2, "\r\n");
    }
    
    
    void sysInit()
    {
        uint8_t generic = 0;
    
        sciInit();                                      //SCI initialization.
        canInit();                                      //CAN initialization.
    
        //Enable interrupts:
        _enable_interrupt_();                           //General interrupt flag.
    
        //Enable SCI interrupt:
        sciEnableNotification(scilinREG,SCI_RX_INT);    //Enable SCI Lin interrupt by Rx.
        sciEnableNotification(sciREG,SCI_RX_INT);       //Enable SCI interrupt by Rx.
    
        //Enable CAN interrupt:
        canEnableErrorNotification(canREG2);            //Enable canREG2 interrupt.
        canEnableErrorNotification(canREG3);            //Enable canREG3 interrupt.
    
        sciReceive(scilinREG,1, (unsigned char *)&generic);
    
        sciSend(scilinREG, 2,  (unsigned char *)"\r\n");
        sciSend(scilinREG, 37, (unsigned char *)"Initializing system. Please wait...\r\n");
        gioInit();                                      //GIO module initialization.
        gioSetDirection(hetPORT1, 1 << 15);             //Enable N2HET1[15] as output. This is the output signal to the external watch-dog.
        gioSetDirection(spiPORT3, 0x11);                //to set the SPI3NCS[0] to output direction. The SPI3NCS[0] is the bit0 of SPIPC1 register.
                                                        //to set the SPI3NCS[4] to output direction. The SPI3NCS[4] is the bit4 of SPIPC1 register.
        gioSetDirection(mibspiPORT5, 0 <<9);
        gioSetDirection(mibspiPORT1, 0 <<1);
    
        //By default we set the GIO pins for long test as follows:
    
        gioSetDirection(mibspiPORT1, (0 << 9));         //Set MibSPI1_CLK direction. This is the bit 9 in the SPIPC3 register.
        gioSetDirection(gioPORTA, (0 << 6));            //Set GIOA[6] direction. This is the bit 6 of GIODIRA register.
        gioSetDirection(mibspiPORT1, (1 << 11));        //Set MibSPI1_SOMI[0] direction. This is the bit 11 in the SPIPC3 register.
        gioSetDirection(mibspiPORT1, (1 << 10));        //Set MibSPI1_SIMO[0] direction. This is the bit 10 in the SPIPC3 register.
        gioSetBit(mibspiPORT1, 10, 0);                  //We set the GIOs as logic 0
        gioSetBit(mibspiPORT1, 11, 0);                  //We set the GIOs as logic 0
    
    
        gioSetBit(spiPORT3, 0, 1);                      //Disable External memories SPI communication
        gioSetBit(spiPORT3, 4, 1);                      //Disable External memories SPI communication
    
        sciSend(scilinREG, 27, (unsigned char *)"\t************************\r\n");
        sciSend(scilinREG, 27, (unsigned char *)"\tLabOSat-02 [OBC] OS V1.0\r\n");
        sciSend(scilinREG, 27, (unsigned char *)"\t************************\r\n");
        sciSend(scilinREG, 1, (unsigned char *)"\n");
        sciSend(scilinREG, 14, (unsigned char *)"Developers: \r\n");
        sciSend(scilinREG, 30, (unsigned char *)"\t Gagliardi Leandro Luciano \r\n");
        sciSend(scilinREG, 22, (unsigned char *)"\t Di Nardo Federico \r\n");
        sciSend(scilinREG, 1, (unsigned char *)"\n");
    }
    
    /*********************************
     * SCI interrupt service routine *
     *********************************/
    void sciNotification(sciBASE_t *sci, unsigned flags)
    {
        uint8_t *rxKey = NULL;
        if(sci == scilinREG)
        {
            sciReceive(scilinREG, 1, rxKey);
            sciSend(sci, sizeof(uint8_t), rxKey);
        }
    }
    
    /*********************************
     * CAN interrupt service routine *
     *********************************/
    
    void canMessageNotification(canBASE_t *node, uint32 messageBox)
    {
        if(node==canREG2)
        {
            tx_done=1; /* confirm transfer request */
        }
    
        if(node==canREG3)
        {
            while(!canIsRxMessageArrived(canREG3, canMESSAGE_BOX1));
            canGetData(canREG3, canMESSAGE_BOX1, &(rx_data.buffer[0]));
            rx_data.id = canGetID(node, messageBox);
        }
    }
    
    /* USER CODE END */

  • Hi Marco,

    but it never riggers the recive interrupt, so it does not read any data.

    It should not have any impact on receive data.

    Anyway, i will test and will provide my observations.

    --
    Thanks & Regards,
    Jagadish.

  • Im going to try to solve it in a different way

  • I figured out thet the problem is noot in transmition but in reception.
    I posted this related, cuestiion

  • Let's close this issue as you raised new issue for the interrupt being not work.