Part Number: TMS570LC4357
Following this issue, trying to put the flash banks to sleep when getting the device to sleep (following the sequence described in section 2.4.3.1 of the reference manual) triggers prefetch errors on wakeup interrupts, ultimately keeping the VDDIO current around 30mA (~100mW) during sleep to keep one flash bank powered, which is too high for our application.
We tried to adapt the code from the TMS570LS0714PZ_LPMs_Wakeup repository to the TMS570LC device we are using, but did not meet the expected results, as the TMS570LC device lacks registers FBFALLBACK and FPAC2 to control flash bank fallback power mode, and only allows to change the current mode through the FBPWRMODE register.
Placing the shutdown / wakeup sequence and GIO interrupt handler in ram (section .ramTEXT) does not change the outcome.
Are we missing some configuration to put the flash to sleep while in sleep mode?
Here is our shutodwn / wakeup sequence:
#pragma SET_CODE_SECTION(".ramTEXT")
void systemPowerDown(uint32 mode)
{
uint32_t flashFbPwrMode;
uint32_t clkTest, csdis, cddis, ghvsrc, pllctl1, pllctl2, pllctl3;
flashFbPwrMode = flashWREG->FBPWRMODE; // Save configuration to restore it on wakeup
clkTest = systemREG1->CLKTEST;
csdis = systemREG1->CSDIS;
cddis = systemREG1->CDDIS;
pllctl1 = systemREG1->PLLCTL1;
pllctl2 = systemREG1->PLLCTL2;
pllctl3 = systemREG2->PLLCTL3;
ghvsrc = systemREG1->GHVSRC;
systemREG1->CLKTEST = (clkTest & ~(1 << 25)) | (1 << 24); // disable range detection
pmmTurnOFFLogicPowerDomain(PMM_LOGICPD4);
pmmTurnOFFLogicPowerDomain(PMM_LOGICPD5);
while (flashWREG->FBBUSY & ((1U << 7) | (1U << 1) | (1U << 0))); // wait for all flash banks to be idle
flashWREG->FBAC = (0x00 << 16) //OTP programming is disabled
| (0x0F); //VREAD setup for wakeup
flashWREG->FPAC1 &= ~1U; // charge pump fallback power mode = sleep
flashWREG->FBPWRMODE = (3U << (0 * 2)) // flash bank 0 power mode (0: sleep, 1: standby, 3: active)
| (0U << (1 * 2)) // flash bank 1 power mode (0: sleep, 1: standby, 3: active)
| (0U << (7 * 2));// flash bank 7 power mode (0: sleep, 1: standby, 3: active)
// Disable clock sources and domains
systemREG1->CSDISSET = mode & 0x000000FFU;
systemREG1->CDDIS = (mode >> 8U) & 0x00000FFFU;
/* Idle CPU */
asm volatile (
" WFI \n" // Wait-For-Interrupt instruction
" nop \n" // 4 nopes to flush the pipeline
" nop \n"
" nop \n"
" nop \n"
);
flashWREG->FBPWRMODE = flashFbPwrMode; //wake up flash
systemREG1->CSDISCLR = (~csdis) & 0x31; // enable LF LPO, HF LPO and oscillator first
if (mode & ~csdis & (1U << 1U)) // if LP mode disabled pll1
{
systemREG1->PLLCTL1 = (0U << 31U) // no reset on slip
| (1U << 29U) // bypass on slip enabled
| (0x1F << 24U) // output divider to max before lock
| (pllctl1 & 0x00FFFFFF);
systemREG1->PLLCTL2 = (0U << 31U) // disable freq. modulation
| (pllctl2 & 0x7FFFFFFF);
}
if (mode & ~csdis & (1U << 6U)) // if LP mode disabled pll2
{
systemREG2->PLLCTL3 = (7U << 29U) // output divider to max before lock
| (pllctl3 & 0x1FFFFFFF);
}
systemREG1->CSDIS = csdis;
systemREG1->CDDIS = cddis;
// Wait until clocks are locked, then restore remaining pll parameters
while ((systemREG1->CSVSTAT & (~csdis) & 0xFF) != ((~csdis) & 0xFF));
systemREG1->PLLCTL1 = pllctl1;
systemREG1->PLLCTL2 = pllctl2;
systemREG1->GHVSRC = ghvsrc;
// Resume oscillator monitoring
systemREG1->CLKTEST = clkTest;
pmmTurnONLogicPowerDomain(PMM_LOGICPD4);
pmmTurnONLogicPowerDomain(PMM_LOGICPD5);
gioInit();
}
#pragma SET_CODE_SECTION()