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.

[FAQ] TDA4VM: How to enable power for a module (CAN, ADC, etc..) from remote core firmware?

Part Number: TDA4VM

I am using the MCAN examples from the SDK and I am integrating this firmware along with Linux on A72. I see my firmware crashing when configuring the CAN module. How can I resolve the issue?

  • If your firmware is crashing after loading from u-boot then there could be one of the two issues:

    1. The module you are trying to use is already in use by Linux. See https://e2e.ti.com/support/processors-group/processors/f/processors-forum/931992/faq-tda4vm-application-in-the-psdkra-runs-standalone-from-sbl-but-doesn-t-run-alongside-linux for more details.
    2. The module you are trying to access in not powered on by the firmware itself or the bootloader.

    Sometime the applications rely on the bootloader for some initializations and when the bootloader changes (SPL from SBL) then this dependency might not be met. The best and the cleanest way to tackle this is to keep the SW blocks modular and do the initialization of the peripherals, being used by the core, inside the firmware itself.

    Before that, to check if the real reason for the crash is the module not being enabled - you can dump the peripheral registers from the u-boot prompt (or CCS) using the "md" command.

    Now to add the code to initialize the module use the below patch:

    +/* Local API for enabling clocks.
    +   Copied from board library.
    + */
    +int32_t local_moduleClockEnable(uint32_t moduleId)
    +{
    +    int32_t retVal = 0;
    +    int32_t status = -1;
    +    uint32_t moduleState = 0U;
    +    uint32_t resetState = 0U;
    +    uint32_t contextLossState = 0U;
    +
    +    /* Get the module state.
    +       No need to change the module state if it
    +       is already ON
    +     */
    +    status = Sciclient_pmGetModuleState(moduleId,
    +                                        &moduleState,
    +                                        &resetState,
    +                                        &contextLossState,
    +                                        SCICLIENT_SERVICE_WAIT_FOREVER);
    +    if(moduleState == TISCI_MSG_VALUE_DEVICE_HW_STATE_OFF)
    +    {
    +        status = Sciclient_pmSetModuleState(moduleId,
    +                                            TISCI_MSG_VALUE_DEVICE_SW_STATE_ON,
    +                                            (TISCI_MSG_FLAG_AOP |
    +                                             TISCI_MSG_FLAG_DEVICE_RESET_ISO),
    +                                             SCICLIENT_SERVICE_WAIT_FOREVER);
    +        if (status == 0)
    +        {
    +            status = Sciclient_pmSetModuleRst (moduleId,
    +                                               0x0U,
    +                                               SCICLIENT_SERVICE_WAIT_FOREVER);
    +            if (status != 0)
    +            {
    +                retVal = -1;
    +            }
    +        }
    +        else
    +        {
    +            retVal = -1;
    +        }
    +    }
    +
    +    return retVal;
    +}
    You will need the header file for this:
    
    +#include <ti/drv/sciclient/sciclient.h>
    In the main() add the following:
    
    +    /* Enable MCU ADCs */
    +    local_moduleClockEnable(TISCI_DEV_MCU_ADC0);
    +    local_moduleClockEnable(TISCI_DEV_MCU_ADC1);
    +    /* Enable MCAN clocks */
    +    local_moduleClockEnable(TISCI_DEV_MCAN0);
    +    local_moduleClockEnable(TISCI_DEV_MCAN4);
    +    local_moduleClockEnable(TISCI_DEV_MCAN9);
    +    local_moduleClockEnable(TISCI_DEV_MCAN11);

    For device IDs refer TISCI user guide: https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/j721e/devices.html 

    Regards,

    Karan