// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md #include "EnterSleepMode.h" #include #include extern char __sdram_start; // Defined in linker script /* This function needs to be compiled either as a C code, or as a C++ code with * exception handling disabled (-fno-exceptions), otherwise it is not possible to relocate * its code into OCRAM. Rationale: * https://stackoverflow.com/questions/52637962/arm-cortex-m7-long-branch-get-error-relocation-truncated-to-fit-r-arm-prel31 * * As compiling single C++ file with exception handling disabled seems to be impossible * using CMake and selectively disabling exceptions using #pragmas looks ugly, I've decided * to just put it in a separate .c file. */ WFI_CODE_SECTION(void enterSleepMode(void)) { /* Wait until SDRAM operations done and switch to self-refresh mode */ __DSB(); while ((SEMC->STS0 & SEMC_STS0_IDLE_MASK) == 0) {} // Wait until SEMC idle __ISB(); SEMC_SendIPCommand(SEMC, kSEMC_MemType_SDRAM, (uint32_t)&__sdram_start, kSEMC_SDRAMCM_SelfRefresh, 0, NULL); /* Go to sleep */ __WFI(); __ISB(); }