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.

TMDS64GPEVM: TMDS64GPEVM [AM6442] EVK MCAN interface

Part Number: TMDS64GPEVM

I am using TMDS64GPEVM and mcu_plus_sdk_am64x_08_00_00_21 for development. I want to implement MCAN interface between MCAN 0 and MCAN1 from the same board, So, I started with Loopback example code from SDK examples and modified it for external communication. I am able to get data from the external pin(Tx line) by removing the loopback configurations but still the transfer(Tx to Rx) is happening internally.

Can anyone tell me how to configure MCAN instances for external communication and how to modify the example code for this application

Thanks in advance

  • Hi,

    Which example project are you using? I see four different projects in <SDK>\examples\drivers\mcan.

    How did you remove the internal loopback setting? I see only one location in mcan_loopback_interrupt_am64x-evm_r5fss0-0_freertos_ti-arm-clang where the internal loopback is enabled:

    144: App_mcanConfig(TRUE);

    Where are you inspecting the Tx/Rx signals on the board? I notice a 2x1 mux which routes the MCAN0/1 signals to either the HSE connector or the MCAN transceivers. The mux select is configured using the I2C IO expander.

    Are you connecting the MCAN0 transceiver pins on J31 and J32?

    Regards,
    Frank

  • Hi Frank,

    I am using mcan_loopback_interrupt nortos example for the current implementation, but the actual application is to communicate from MCAN0 to MCAN1 of the same EVK with a Freertos interrupt example.

    I could find  only one function"MCAN_lpbkModeEnable(gMcanBaseAddr, MCAN_LPBK_MODE_INTERNAL, TRUE);"  related to loopback mode enable so I commented out these lines and observed data from the J9 header Tx and Rx pins using a logic analyzer. I am not sure this method is correct. I got the first packet of data through Tx line and the code is waiting for Tx completion.

    If this approach is wrong could you suggest me how to remove internal loopback from the example code and how enable communication with two MCAN instances from the same EVK.

  • Hi Michael,

    I see you mention the TMDS64GPEVM is the thread title. Just to confirm, is that what you mean by "EVK"?

    Instead of commenting out the MCAN_lpbkModeEnable() call, did you try setting the last argument to "FALSE"?

    The J9 pins are for MCAN0 Tx/Rx, correct? What did you observe on the Rx pin J9.1?

    Do you have something connected the J31 pins? Which pins are connected for your external loopback?

  • TMDS64GPEVM is the AM64x GP EVM development platform for evaluating Sitara AM64x processor, sharing the product link https://www.ti.com/tool/TMDS64GPEVM for more reference.

    As you mentioned I tried setting the last argument as FALSE, and observed first packet of data in J9 Tx and Rx line (In both lines I observed the same data). In this case also the code fails and waiting for Tx completion. I am not sure why we are getting same data on Tx and Rx line without loopback enable code.

    For communicating between both MCAN0 and MCAN1, J31 is externally connected to J32.

  • Michael,

    I'm reaching out to internal experts and will get back with you.

    Regards,
    Frank

  • Hi Micheal,

    Our internal expert told me the MCAN transceivers must be enabled to connect externally, and the tranceivers are enabled via the I2C IO Expander.

    He shared the attached code with me for enabling the tranceivers. It appears I call to test_mcanEnableTransceiver() should be added to the application code. I haven't tried this out, can you please try it out?

    Regards,
    Frank

    test_mcan_transceiver.c
    /*
     *  Copyright (C) 2021 Texas Instruments Incorporated
     *
     *  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.
     */
    
    /* ========================================================================== */
    /*                             Include Files                                  */
    /* ========================================================================== */
    #include <drivers/i2c.h>
    #include "ti_drivers_open_close.h"
    
    /* ========================================================================== */
    /*                           Macros & Typedefs                                */
    /* ========================================================================== */
    #define TCA6424_CMD_AUTO_INC            ((uint8_t) 0x80U)
    
    /* Input status register */
    #define TCA6424_REG_INPUT0              ((UInt8) 0x00U)
    #define TCA6424_REG_INPUT1              ((UInt8) 0x01U)
    #define TCA6424_REG_INPUT2              ((UInt8) 0x02U)
    
    /* Output register to change state of output BIT set to 1, output set HIGH */
    #define TCA6424_REG_OUTPUT0             ((uint8_t) 0x04U)
    #define TCA6424_REG_OUTPUT1             ((uint8_t) 0x05U)
    #define TCA6424_REG_OUTPUT2             ((uint8_t) 0x06U)
    
    /* Configuration register. BIT = '1' sets port to input, BIT = '0' sets
     * port to output */
    #define TCA6424_REG_CONFIG0             ((uint8_t) 0x0CU)
    #define TCA6424_REG_CONFIG1             ((uint8_t) 0x0DU)
    #define TCA6424_REG_CONFIG2             ((uint8_t) 0x0EU)
    
    /* ========================================================================== */
    /*                          Function Declarations                             */
    /* ========================================================================== */
    static void SetupI2CTransfer(I2C_Handle handle,  uint32_t slaveAddr,
                          uint8_t *writeData, uint32_t numWriteBytes,
                          uint8_t *readData,  uint32_t numReadBytes);
    
    void test_mcanEnableTransceiver(void)
    {
        I2C_Handle      i2cHandle;
        uint8_t         dataToSlave[4];
    
        i2cHandle = gI2cHandle[CONFIG_I2C0];
        dataToSlave[0] = TCA6424_REG_CONFIG1 | TCA6424_CMD_AUTO_INC;
        dataToSlave[1] = 0x0U;
        SetupI2CTransfer(i2cHandle, 0x22, &dataToSlave[0], 1, &dataToSlave[1], 1);
        /* set the P10 and P11 to 0 make them output ports. */
        dataToSlave[1] &= ~(0x3U);
        SetupI2CTransfer(i2cHandle, 0x22, &dataToSlave[0], 2, NULL, 0);
    
        /* Get the port values. */
        dataToSlave[0] = TCA6424_REG_INPUT1 | TCA6424_CMD_AUTO_INC;
        dataToSlave[1] = 0x0U;
        SetupI2CTransfer(i2cHandle, 0x22, &dataToSlave[0], 1, &dataToSlave[1], 1);
    
        /* Set P10 and P11 to 0.
         */
        dataToSlave[0] = TCA6424_REG_OUTPUT1 | TCA6424_CMD_AUTO_INC;
        dataToSlave[1] &= ~(0x3);
        SetupI2CTransfer(i2cHandle, 0x22, &dataToSlave[0], 2, NULL, 0);
    }
    
    static void SetupI2CTransfer(I2C_Handle handle,  uint32_t slaveAddr,
                          uint8_t *writeData, uint32_t numWriteBytes,
                          uint8_t *readData,  uint32_t numReadBytes)
    {
        int32_t status;
        I2C_Transaction i2cTransaction;
    
        /* Enable Transceiver */
        I2C_Transaction_init(&i2cTransaction);
        i2cTransaction.slaveAddress = slaveAddr;
        i2cTransaction.writeBuf = (uint8_t *)&writeData[0];
        i2cTransaction.writeCount = numWriteBytes;
        i2cTransaction.readBuf = (uint8_t *)&readData[0];
        i2cTransaction.readCount = numReadBytes;
        status = I2C_transfer(handle, &i2cTransaction);
        DebugP_assert(SystemP_SUCCESS == status);
    }

  • Hi Frank,

    Thank you so much for your help and support.

    I tried the code you provided, unfortunately the build failed with errors. Listing the errors found

    • use of undeclared identifier 'CONFIG_I2C0'
    • use of undeclared identifier 'gI2cHandle'
  • Michael,

    Ok, today I'll figure out how to get the code to build. It looks like an I2C instance is missing from the Sysconfig configuration.

    Regards,
    Frank

  • Hi Michael,

    I was able to add the new code to mcan_loopback_interrupt_am64x-evm_r5fss0-0_nortos_ti-arm-clang as follows:

    • Add source file to project (place file in same directory as other source files)
    • Add I2S instance to example.syscfg, use defaults
    • Add function prototype and call to void test_mcanEnableTransceiver(void) in mcan_loopback_interrupt.c. I added the call just before the binary semaphores are created.

    I haven't tested whether this works, can you please test this on your side?

    Regards,
    Frank

  • Hi Michael,

    I have some additional information on this topic. Please follow these steps:

    • As there is a dependency on I2C, need to configure I2C1 instance in SYSCFG.
    • Need to include uploaded file in their make system and rebuild it.
    • Disable internal loopback.
    • Need to connect CAN_H of MCAN0 to CAN_H to MCAN1, CAN_L of MCAN0 to CAN_L to MCAN1, CAN_GND of MCAN0 to CAN_GND to MCAN1.

    The key new item is the requirement to use I2C1, not I2C0 as I have in the previous post. Please give this a try and let me know if it works.

    Regards,
    Frank