Tool/software:
My goal is to use the MCU to turn off the MAIN domain power. I do not need to turn MAIN back on, only off. I also have a requirement of using the generic U-Boot development boot flow. I cannot use the BootApp tertiary boot flow. This is why I didn't try using the LPM demo (which requires the BootApp boot flow) and tried using another demo instead.
I tried using the IPC demo FreeRTOS on the MCU1_0 as a starting point and then tried modifying it to call the necessary PMIC functions from the LPM demo. I have pasted the code for my modified demo. I had to make some makefile changes as well as some other minor modifications to be able to include and link the necessary functions.
My code change is extremely simple. All I did was create a new RTOS task and call the following functions:
Here is my full code:
/* * Copyright (c) Texas Instruments Incorporated 2018-2023 * All rights reserved. * * 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. */ /** * \file main_tirtos.c * * \brief Main file for TI-RTOS build */ /* ========================================================================== */ /* Include Files */ /* ========================================================================== */ #include <stdio.h> #include <stdint.h> #include <string.h> #include <ti/drv/ipc/examples/common/src/ipc_setup.h> #include <ti/osal/osal.h> #include <ti/osal/TaskP.h> #include "ipc_utils.h" #include <ti/csl/csl_types.h> #if defined (BUILD_C7X) #include <ti/csl/soc.h> #include <ti/csl/csl_clec.h> #include <ti/csl/arch/csl_arch.h> #include <ti/osal/soc/osal_soc.h> #if (defined (FREERTOS)) #include "Hwi.h" #include "Mmu.h" #elif (defined (SAFERTOS)) #include "Mmu.h" #endif #endif #include <ti/drv/sciclient/sciclient.h> #include <ti/board/board.h> #if (defined (BUILD_MCU1_0) && (defined (SOC_J721E) || defined (SOC_J7200) || defined (SOC_J721S2) || defined (SOC_J784S4))) #include <ti/drv/sciclient/src/sciclient/sciclient_priv.h> #include <ti/drv/sciclient/sciserver_tirtos.h> #endif /* This needs to be enabled only for negative test cases */ #ifdef IPC_NEGATIVE_TEST #include <ti/drv/ipc/examples/rtos/ipc_negative_test/ipc_neg_setup.h> #endif /* This needs to be enabled only for extended test cases */ #ifdef IPC_EXTENDED_TEST #include <ti/drv/ipc/examples/rtos/ipc_extended_test.h> #endif // new 11/8 // #include <ti/drv/lpm/lpm.h> #include <ti/drv/lpm/include/lpm_pmic.h> /* ========================================================================== */ /* Macros & Typedefs */ /* ========================================================================== */ #define APP_TSK_STACK_MAIN (32U * 1024U) /**< Test application stack size */ #if (defined (BUILD_MCU1_0) && (defined (SOC_J721E) || defined (SOC_J7200) || defined (SOC_J721S2) || defined (SOC_J784S4))) /**< SCI Server Init Task stack size */ #define APP_SCISERVER_INIT_TSK_STACK (32U * 1024U) /* SCI Server Init Task Priority - must be higher than High priority Sciserver task */ #define IPC_INIT_SCISERVER_TASK_PRI (6) #endif /* High Priority for SCI Server - must be higher than Low priority task */ #define IPC_SETUP_SCISERVER_TASK_PRI_HIGH (5) /* * Low Priority for SCI Server - must be higher than IPC echo test tasks * to prevent delay in handling Sciserver requests when test is performing * multicore ping/pong. */ #define IPC_SETUP_SCISERVER_TASK_PRI_LOW (4) // new 11/8 #define TEST_SHUTDOWN_TASK_PRIORITY (3) #define TEST_SHUTDOWN_STACK_SIZE (64U * 1024U) /* ========================================================================== */ /* Structure Declarations */ /* ========================================================================== */ /* None */ /* ========================================================================== */ /* Function Declarations */ /* ========================================================================== */ static void taskFxn(void* a0, void* a1); // new 11/8 static void TestShutdown(void *arg0, void *arg1); volatile uint8_t sci_init_done = false; #if (defined (BUILD_MCU1_0) && (defined (SOC_J721E) || defined (SOC_J7200) || defined (SOC_J721S2) || defined (SOC_J784S4))) void Ipc_setupSciServer(void *arg0, void *arg1); /**< Initialize SCI Server, to process RM/PM Requests by other cores */ #endif /* ========================================================================== */ /* Global Variables */ /* ========================================================================== */ /* Test application stack */ /* For SafeRTOS on R5F with FFI Support, task stack should be aligned to the stack size */ #if defined(SAFERTOS) && defined (BUILD_MCU) static uint8_t gAppTskStackMain[APP_TSK_STACK_MAIN] __attribute__ ((aligned(APP_TSK_STACK_MAIN))); #else static uint8_t gAppTskStackMain[APP_TSK_STACK_MAIN] __attribute__ ((aligned(8192))); #endif /* Variable to check if ipc_boardInit has completed or not*/ uint8_t gBoardinit=0; #if (defined (BUILD_MCU1_0) && (defined (SOC_J721E) || defined (SOC_J7200) || defined (SOC_J721S2) || defined (SOC_J784S4))) /* Sciserver Init TAsk stack */ #if defined(SAFERTOS) static uint8_t gSciserverInitTskStack[APP_SCISERVER_INIT_TSK_STACK] __attribute__ ((aligned(APP_SCISERVER_INIT_TSK_STACK))); #else static uint8_t gSciserverInitTskStack[APP_SCISERVER_INIT_TSK_STACK] __attribute__ ((aligned(8192))); #endif extern Sciclient_ServiceHandle_t gSciclientHandle; #endif // new 11/8 static uint8_t gTestShutdownStack[TEST_SHUTDOWN_STACK_SIZE] __attribute__((aligned(32))); /* ========================================================================== */ /* Function Definitions */ /* ========================================================================== */ void ipc_initSciclient() { int32_t ret = CSL_PASS; Sciclient_ConfigPrms_t config; /* Now reinitialize it as default parameter */ ret = Sciclient_configPrmsInit(&config); if (ret != CSL_PASS) { App_printf("Sciclient_configPrmsInit Failed\n"); } #if (defined (BUILD_MCU1_0) && (defined (SOC_J721E) || defined (SOC_J7200) || defined (SOC_J721S2) || defined (SOC_J784S4))) if (ret == CSL_PASS) { ret = Sciclient_boardCfgParseHeader( (uint8_t *)SCISERVER_COMMON_X509_HEADER_ADDR, &config.inPmPrms, &config.inRmPrms); if (ret != CSL_PASS) { App_printf("Sciclient_boardCfgParseHeader Failed\n"); } } #endif if (ret == CSL_PASS) { ret = Sciclient_init(&config); if (ret != CSL_PASS) { App_printf("Sciclient_init Failed\n"); } #if (defined (BUILD_MCU1_0) && (defined (SOC_J721E) || defined (SOC_J7200) || defined (SOC_J721S2) || defined (SOC_J784S4))) if (gSciclientHandle.rmBoardConfigComplete == SCICLIENT_FT_PASS) { App_printf("Sciclient_boardCfgRm init Passed\n"); } else { App_printf("Sciclient_boardCfgRm init FAILED!\n"); } #endif } } void ipc_boardInit() { Board_initCfg boardCfg; boardCfg = BOARD_INIT_UART_STDIO; #if defined(A72_LINUX_OS) /* Configure UART TX pinmux only. Linux doesn't support full pinmux config */ Board_uartTxPinmuxConfig(); #else boardCfg |= BOARD_INIT_PINMUX_CONFIG; #endif Board_init(boardCfg); /* Mark Board_init() has been called */ gBoardinit = 1; } int main(void) { TaskP_Handle task; TaskP_Params taskParams; #if defined ECHO_TEST_BTCM && defined FREERTOS && defined BUILD_MCU /* Relocate FreeRTOS Reset Vectors from BTCM*/ void _freertosresetvectors (void); memcpy((void *)0x0, (void *)_freertosresetvectors, 0x40); #endif #if defined ECHO_TEST_BTCM && defined SAFERTOS && defined BUILD_MCU /* Relocate FreeRTOS Reset Vectors from BTCM*/ void _axSafeRTOSresetVectors (void); memcpy((void *)0x0, (void *)_axSafeRTOSresetVectors, 0x40); #endif /* This should be called before any other OS calls (like Task creation, OS_start, etc..) */ OS_init(); /* Initialize the task params */ TaskP_Params_init(&taskParams); /* Set the task priority higher than the default priority (1) */ taskParams.priority = 2; taskParams.stack = gAppTskStackMain; taskParams.stacksize = sizeof (gAppTskStackMain); task = TaskP_create(&taskFxn, &taskParams); if(NULL == task) { OS_stop(); } // new 11/8 /* Configure and create the TestShutdown task */ TaskP_Params_init(&taskParams); taskParams.priority = TEST_SHUTDOWN_TASK_PRIORITY; taskParams.stack = gTestShutdownStack; taskParams.stacksize = sizeof (gTestShutdownStack); task = TaskP_create(&TestShutdown, &taskParams); if(NULL == task) { OS_stop(); } OS_start(); /* does not return */ return(0); } static void taskFxn(void* a0, void* a1) { /* Initialize SCI Client - It must be called before board init */ ipc_initSciclient(); /* IPC Board Init should be done only for MCU1_0 for Linux, * unconditionally for RTOS */ #if defined(A72_LINUX_OS) && defined(BUILD_MCU1_0) ipc_boardInit(); #elif !defined(A72_LINUX_OS) ipc_boardInit(); #endif #if (defined (BUILD_MCU1_0) && (defined (SOC_J721E) || defined (SOC_J7200) || defined (SOC_J721S2) || defined (SOC_J784S4))) TaskP_Handle sciserverInitTask; TaskP_Params sciserverInitTaskParams; /* Initialize SCI Client Server */ TaskP_Params_init(&sciserverInitTaskParams); sciserverInitTaskParams.priority = IPC_INIT_SCISERVER_TASK_PRI; sciserverInitTaskParams.stack = gSciserverInitTskStack; sciserverInitTaskParams.stacksize = sizeof (gSciserverInitTskStack); sciserverInitTask = TaskP_create(&Ipc_setupSciServer, &sciserverInitTaskParams); if(NULL == sciserverInitTask) { OS_stop(); } #endif #if defined (_TMS320C6X) #if defined (FREERTOS) || defined (SAFERTOS) ipc_cacheMarInit(); #endif #endif #if defined IPC_NEGATIVE_TEST Ipc_echo_neg_test(); #elif IPC_EXTENDED_TEST IpcApp_echoExtTest(); #else Ipc_echo_test(); #endif // TaskP_Handle task; // TaskP_Params taskParams; // /* Configure and create the TestShutdown task */ // TaskP_Params_init(&taskParams); // taskParams.priority = TEST_SHUTDOWN_TASK_PRIORITY; // taskParams.stack = gTestShutdownStack; // taskParams.stacksize = sizeof (gTestShutdownStack); // task = TaskP_create(&TestShutdown, &taskParams); // if(NULL == task) // { // OS_stop(); // } } #if defined(BUILD_C7X) void InitMmu(void) { IpcInitMmu(FALSE); IpcInitMmu(TRUE); OsalCfgClecAccessCtrl(false); } #endif #if defined(BUILD_MPU) extern void Osal_initMmuDefault(void); void InitMmu(void) { Osal_initMmuDefault(); } #endif #if (defined (BUILD_MCU1_0) && (defined (SOC_J721E) || defined (SOC_J7200) || defined (SOC_J721S2) || defined (SOC_J784S4))) void Ipc_setupSciServer(void *arg0, void *arg1) { Sciserver_TirtosCfgPrms_t appPrms; int32_t ret = CSL_PASS; char *version_str = NULL; char *rmpmhal_version_str = NULL; ret = Sciserver_tirtosInitPrms_Init(&appPrms); appPrms.taskPriority[SCISERVER_TASK_USER_LO] = IPC_SETUP_SCISERVER_TASK_PRI_LOW; appPrms.taskPriority[SCISERVER_TASK_USER_HI] = IPC_SETUP_SCISERVER_TASK_PRI_HIGH; if (ret == CSL_PASS) { ret = Sciserver_tirtosInit(&appPrms); } version_str = Sciserver_getVersionStr(); rmpmhal_version_str = Sciserver_getRmPmHalVersionStr(); App_printf("DM Built On: %s %s\n", __DATE__, __TIME__); // new App_printf("Amazon Test"); App_printf("Sciserver Version: %s\n", version_str); App_printf("RM_PM_HAL Version: %s\n", rmpmhal_version_str); if (ret == CSL_PASS) { App_printf("Starting Sciserver..... PASSED\n"); } else { App_printf("Starting Sciserver..... FAILED\n"); } // TODO: added sci_init_done = true; return; } #endif // new 11/8 void TestShutdown(void *arg0, void *arg1) { while(!sci_init_done) { // do nothing TaskP_sleep(10); } //TaskP_sleep(10000); Lpm_pmicInit(); App_printf("PMIC Init done.\n"); uint32_t status = 0; /* Before entering MCU_ONLY mode we need to disable all VTM temp sensors in the MAIN domain - VTM_TMPSENS1-4 */ /* Disabling the VTM MAXT_OUTRG_ALERT_THR */ Lpm_vtmMaxOutrgAlertDisableForTmpSens1to4(); App_printf("Temp sensors disabled.\n"); TaskP_sleepInMsecs(1000); /* Change state from ACTIVE to MCU ONLY */ if (0 == status) { App_printf("ACTIVE -> MCU ONLY MODE\n"); /* The status is dummy currently */ status = Lpm_activeToMcuSwitch(); App_printf("ACTIVE -> MCU ONLY MODE DONE\n"); } else { App_printf(">> ERROR :: Status not correct!!!\n"); } App_printf("STATE INFO :: NOW IN MCU ONLY MODE!\n"); }
I thought that this would be enough to get it to work but the code does not function as expected. It runs as expected until Lpm_activeToMcuSwitch() and then it hangs at that function call. I tried to look into it and it seems that it's hanging on a specific I2C command inside lpm_pmic.c
/* Clear INT_STARTUP */
dataToSlave[0] = 0x65;
dataToSlave[1] = 0x02;
Lpm_setupI2CTransfer(gLpmPmicI2cHandle, 0x48, dataToSlave, 2, NULL, 0);
Is it possible to run these LPM demo commands from the IPC demo? Thank you.