From ba2d7f9f1cbc230b354fddab1dc444d82ec44cee Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Fri, 3 Mar 2017 20:01:50 -0800 Subject: LPM mode working --- .../low_power_demo/armgcc/CMakeLists.txt | 2 + .../imx7_colibri_m4/low_power_demo/hardware_init.c | 5 ++- .../imx7_colibri_m4/low_power_demo/lpm_mcore.c | 6 ++- .../imx7_colibri_m4/low_power_demo/lpm_mcore.h | 12 ++++-- examples/imx7_colibri_m4/low_power_demo/main.c | 45 ++++++++++++++++++++-- 5 files changed, 60 insertions(+), 10 deletions(-) diff --git a/examples/imx7_colibri_m4/low_power_demo/armgcc/CMakeLists.txt b/examples/imx7_colibri_m4/low_power_demo/armgcc/CMakeLists.txt index ebe868a..0b18ea5 100644 --- a/examples/imx7_colibri_m4/low_power_demo/armgcc/CMakeLists.txt +++ b/examples/imx7_colibri_m4/low_power_demo/armgcc/CMakeLists.txt @@ -107,6 +107,8 @@ ADD_EXECUTABLE(low_power_demo "${BspRootDirPath}/platform/drivers/src/wdog_imx.c" "${BspRootDirPath}/platform/drivers/src/ecspi.c" "${BspRootDirPath}/platform/drivers/inc/ecspi.h" + "${BspRootDirPath}/platform/drivers/src/mu_imx.c" + "${BspRootDirPath}/platform/drivers/inc/mu_imx.h" "${BspRootDirPath}/rtos/FreeRTOS/Source/include/croutine.h" "${BspRootDirPath}/rtos/FreeRTOS/Source/include/event_groups.h" "${BspRootDirPath}/rtos/FreeRTOS/Source/include/FreeRTOS.h" diff --git a/examples/imx7_colibri_m4/low_power_demo/hardware_init.c b/examples/imx7_colibri_m4/low_power_demo/hardware_init.c index aa077b5..a15b4e2 100644 --- a/examples/imx7_colibri_m4/low_power_demo/hardware_init.c +++ b/examples/imx7_colibri_m4/low_power_demo/hardware_init.c @@ -44,7 +44,7 @@ void hardware_init(void) /* * In order to wakeup M4 from LPM, some PLLCTRLs need to be set to "NeededRun" - */ + *//* CCM_BASE_PTR->PLL_CTRL[0].PLL_CTRL = ccmClockNeededRun; CCM_BASE_PTR->PLL_CTRL[6].PLL_CTRL = ccmClockNeededRun; CCM_BASE_PTR->PLL_CTRL[7].PLL_CTRL = ccmClockNeededRun; @@ -56,6 +56,7 @@ void hardware_init(void) CCM_BASE_PTR->PLL_CTRL[13].PLL_CTRL = ccmClockNeededRun; CCM_BASE_PTR->PLL_CTRL[14].PLL_CTRL = ccmClockNeededRun; CCM_BASE_PTR->PLL_CTRL[15].PLL_CTRL = ccmClockNeededRun; +*/ /* Enable clock gate for wakeup mix*/ CCM_ControlGate(CCM, BOARD_SIM_WAKEUP_CCGR, ccmClockNeededAll); @@ -78,6 +79,8 @@ void hardware_init(void) /* Configure ecspi pin IOMUX */ configure_ecspi_pins(BOARD_ECSPI_BASEADDR); + /* RDC MU*/ + RDC_SetPdapAccess(RDC, BOARD_MU_RDC_PDAP, 3 << (BOARD_DOMAIN_ID * 2), false, false); /* Enable MU clock*/ CCM_ControlGate(CCM, BOARD_MU_CCM_CCGR, ccmClockNeededAll); } diff --git a/examples/imx7_colibri_m4/low_power_demo/lpm_mcore.c b/examples/imx7_colibri_m4/low_power_demo/lpm_mcore.c index 96857b8..0b912c7 100644 --- a/examples/imx7_colibri_m4/low_power_demo/lpm_mcore.c +++ b/examples/imx7_colibri_m4/low_power_demo/lpm_mcore.c @@ -49,7 +49,7 @@ static P_WAKEUP_INT_ELE g_wakeup_int_list; /* * Send Message to A7 */ -static void LPM_MCORE_SendMessage(uint32_t msg) +void LPM_MCORE_SendMessage(uint32_t msg) { while (0 == (MUB_SR & MU_SR_TEn(0x8 >> LPM_MCORE_MU_CHANNEL))); MUB->TR[LPM_MCORE_MU_CHANNEL] = msg; @@ -226,9 +226,13 @@ void LPM_MCORE_ChangeM4Clock(LPM_M4_CLOCK_SPEED target) #endif CCM_SetRootMux(CCM, ccmRootM4, ccmRootmuxM4Osc24m); } + CCM_ControlGate(CCM, ccmPllGateSys, ccmClockNotNeeded); + CCM_ControlGate(CCM, ccmPllGateSysDiv2, ccmClockNotNeeded); configCPU_CLOCK_HZ = 24000000ul; break; case LPM_M4_HIGH_FREQ: + CCM_ControlGate(CCM, ccmPllGateSys, ccmClockNeededRun); + CCM_ControlGate(CCM, ccmPllGateSysDiv2, ccmClockNeededRun); if (CCM_GetRootMux(CCM, ccmRootM4) != ccmRootmuxM4SysPllDiv2) { #if (defined(LPM_MCORE_PRINT_DEBUG_INFO) && (LPM_MCORE_PRINT_DEBUG_INFO)) PRINTF("Change M4 clock freq to SysPLL Div2 (240M)\r\n"); diff --git a/examples/imx7_colibri_m4/low_power_demo/lpm_mcore.h b/examples/imx7_colibri_m4/low_power_demo/lpm_mcore.h index 8e72585..407228e 100644 --- a/examples/imx7_colibri_m4/low_power_demo/lpm_mcore.h +++ b/examples/imx7_colibri_m4/low_power_demo/lpm_mcore.h @@ -49,10 +49,12 @@ #define MSG_LPM_M4_WAIT 0x5A5A0002 #define MSG_LPM_M4_STOP 0x5A5A0003 -#define MSG_LPM_M4_REQUEST_HIGHBUS 0x2222CCCC -#define MSG_LPM_M4_RELEASE_HIGHBUS 0x2222BBBB - -#define MSG_LPM_A7_HIGHBUS_READY 0xFFFF6666 +#define MU_LPM_M4_LPM_READY 0xFFFF4444 +#define MU_LPM_M4_LPM_SLEEP 0xFFFF5555 +#define MU_LPM_BUS_HIGH_READY_FOR_M4 0xFFFF6666 +#define MU_LPM_M4_FREQ_CHANGE_READY 0xFFFF7777 +#define MU_LPM_M4_REQUEST_HIGH_BUS 0x2222CCCC +#define MU_LPM_M4_RELEASE_HIGH_BUS 0x2222BBBB #define GPC_SYNC_DELAY_CNT 65536 @@ -99,6 +101,8 @@ LPM_POWER_STATUS_M4 LPM_MCORE_GetPowerStatus(GPC_Type * base); */ void LPM_MCORE_SetPowerStatus(GPC_Type * base, LPM_POWER_STATUS_M4 m4_next_lpm); +void LPM_MCORE_SendMessage(uint32_t msg); + /* * provide readable information of current m4 core lpm state */ diff --git a/examples/imx7_colibri_m4/low_power_demo/main.c b/examples/imx7_colibri_m4/low_power_demo/main.c index 2ccac97..9029272 100644 --- a/examples/imx7_colibri_m4/low_power_demo/main.c +++ b/examples/imx7_colibri_m4/low_power_demo/main.c @@ -39,6 +39,7 @@ #include "gpio_imx.h" #include "ugui/ugui.h" #include "lpm_mcore.h" +#include "mu_imx.h" TaskHandle_t xLcdTaskHandle; @@ -215,6 +216,37 @@ void LCD_SetPixel(UG_S16 x, UG_S16 y, UG_COLOR c) fb[128 * page + x] |= bit; } +void mu_handle_message(uint32_t msg) +{ + static bool firstready = true; + switch(msg) { + case MU_LPM_M4_LPM_READY: + if (firstready) + LPM_MCORE_SendMessage(MU_LPM_M4_RELEASE_HIGH_BUS); + firstready = false; + + PRINTF("\n\rA7 ready\n\r"); + break; + case MU_LPM_M4_LPM_SLEEP: + PRINTF("\n\rA7 asleep\n\r"); + break; + default: + PRINTF("MSG %08x, \n\r", msg); + break; + } +} + +void MU_M4_Handler(void) +{ + uint32_t msg; + + if (MU_TryReceiveMsg(MUB, 0, &msg) == kStatus_MU_Success) + mu_handle_message(msg); + + + return; +} + UG_GUI gui; void LCD_Task(void *pvParameters) @@ -295,12 +327,13 @@ void LCD_Task(void *pvParameters) vTaskDelay(5000); PRINTF("done"); - PRINTF("\r\nCPU spinning, press any character: "); + PRINTF("\r\nCPU spinning, press any character (s sends msg): "); control_char = GETCHAR(); - PRINTF("%c", control_char);/* + PRINTF("%c", control_char); if ((control_char == 's') || (control_char == 'S')) { - break; - }*/ + PRINTF("\r\nSending msg to A7..."); + LPM_MCORE_SendMessage(MSG_LPM_M4_WAIT); + } } /* uint8_t page[128]; @@ -349,6 +382,10 @@ int main(void) LPM_MCORE_ChangeM4Clock(LPM_M4_LOW_FREQ); PRINTF("\n\r=> Low Power Demo\n\r"); + NVIC_SetPriority(MU_M4_IRQn, 3); + NVIC_EnableIRQ(MU_M4_IRQn); + MU_EnableRxFullInt(MUB, 0); + xTaskCreate(LCD_Task, "LCD Task", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY+1, &xLcdTaskHandle); -- cgit v1.2.3