I would like to Implement Low Power Modes in S32K144. I'm running my board in RUN mode at FIRC = 24MHz clock. I want to bring this to VLPS mode at LPO = 1KHz. For every 10s, it has to be back to RUN mode by the LP TMR interrupt. Can anyone please guide me to create this project.
The LPTMR module can work on VLPS but requires the SIRC clock source to work on VLPS. Therefore, the functional clock of LPTMR must be SIRC.
The following example uses LPTMR on VLPS to activate CMP: Example S32K144 CMP Round-robin.
But the CMP module is the one that wakes up, not LPTMR in this case.
Also, try to modify lptmr_periodic_interrupt_s32k144 included in the SDK. It is a good point to start.
B.R.
VaneB
Hi @VaneB ,
Thanks for your suggestion. we can use an LPO clock of frequency 1KHz as a source for LPTMR on VLPS. Can we proceed with LPO clock..?. And can we use LPTMR as wakeup source to switch back the RUN mode..?
Please find the LPTMR interrupt initialization for your reference,
void init_LPTMR(void){
SIM->LPOCLKS = 0x0000000D; /*1KHz LPO clock*/
uint16_t init_ms = 2710; /*10s*/
PCC->PCCn[PCC_LPTMR0_INDEX] = PCC_PCCn_CGC_MASK; /* Enable LPTMR Clock */
LPTMR0->PSR |= LPTMR_PSR_PCS(0b01)|(1<<0); /* LPTMR clk src: 1KHz LPO Bypass Prescaler*/
LPTMR0->CMR = init_ms; /* 10s interrupt */
LPTMR0->CSR |= (1<<6) |(1<<0) ; /* Timer interrupt enabled and Enable Timer */
}
void LPTMR0_IRQHandler(void)
{
if(((LPTMR0->CSR >> LPTMR_CSR_TCF_SHIFT) & 1) == 1)
{
/* Check if TCF flag is set */
LPTMR0->CSR |= (1<<7); /* Clear TCF flag by writing a logic one */
}
}
Please refer to section 40.4.2.2 VLPS/Stop mode exit sequence of the S32K1xx Series Reference Manual, Rev. 13.
Hi @VaneB ,
I implemented the VLPS mode, But the power consumption when LPTMR enabled can be 42uA in VLPS, but my power saving in this mode is only 1mA. I'm attaching the code for your reference. Please check and let me know how to reduce power consumption.
#include "S32K144.h"
#include "Clock_Settings.h"
#include "CAN_Settings.h"
void Peripheral_disable(void)
{
// PCC->PCCn[PCC_PORTD_INDEX] |= PCC_PCCn_CGC_MASK;
// PCC->PCCn[PCC_PORTE_INDEX] |= PCC_PCCn_CGC_MASK; /* Enable clock for PORTE */
// PORTE->PCR[4] |= PORT_PCR_MUX(5); /* Port E4: MUX = ALT5, CAN0_RX */
// PORTE->PCR[5] |= PORT_PCR_MUX(5); /* Port E5: MUX = ALT5, CAN0_TX */
// PCC->PCCn[PCC_PORTD_INDEX ]|=PCC_PCCn_CGC_MASK; /* Enable clock for PORTD */
// PORTD->PCR[14] = 0x00008700;
PCC->PCCn[PCC_PORTA_INDEX] &= ~PCC_PCCn_CGC_MASK;
PCC->PCCn[PCC_PORTB_INDEX] &= ~PCC_PCCn_CGC_MASK;
PCC->PCCn[PCC_PORTC_INDEX] &= ~PCC_PCCn_CGC_MASK;
PCC->PCCn[PCC_PORTD_INDEX] &= ~PCC_PCCn_CGC_MASK;
PCC->PCCn[PCC_PORTE_INDEX] &= ~PCC_PCCn_CGC_MASK;
PCC->PCCn[PCC_FTM0_INDEX] &= ~PCC_PCCn_CGC_MASK;
PCC->PCCn[PCC_FTM1_INDEX] &= ~PCC_PCCn_CGC_MASK;
PCC->PCCn[PCC_FTM2_INDEX] &= ~PCC_PCCn_CGC_MASK;
PCC->PCCn[PCC_FTM3_INDEX] &= ~PCC_PCCn_CGC_MASK;
PCC->PCCn[PCC_ADC0_INDEX] &= ~PCC_PCCn_CGC_MASK;
PCC->PCCn[PCC_ADC1_INDEX] &= ~PCC_PCCn_CGC_MASK;
PCC->PCCn[PCC_LPI2C0_INDEX] &= ~PCC_PCCn_CGC_MASK;
PCC->PCCn[PCC_LPIT_INDEX] &= ~PCC_PCCn_CGC_MASK;
PCC->PCCn[PCC_LPSPI0_INDEX] &= ~PCC_PCCn_CGC_MASK;
PCC->PCCn[PCC_LPSPI1_INDEX] &= ~PCC_PCCn_CGC_MASK;
PCC->PCCn[PCC_LPSPI2_INDEX] &= ~PCC_PCCn_CGC_MASK;
PCC->PCCn[PCC_LPUART0_INDEX] &= ~PCC_PCCn_CGC_MASK;
PCC->PCCn[PCC_LPUART1_INDEX] &= ~PCC_PCCn_CGC_MASK;
PCC->PCCn[PCC_LPUART2_INDEX] &= ~PCC_PCCn_CGC_MASK;
PCC->PCCn[PCC_CMP0_INDEX] &= ~PCC_PCCn_CGC_MASK;
PCC->PCCn[PCC_DMAMUX_INDEX] &= ~PCC_PCCn_CGC_MASK;
PCC->PCCn[PCC_FlexCAN0_INDEX] &= ~PCC_PCCn_CGC_MASK;
PCC->PCCn[PCC_FlexCAN1_INDEX] &= ~PCC_PCCn_CGC_MASK;
PCC->PCCn[PCC_FlexCAN2_INDEX] &= ~PCC_PCCn_CGC_MASK;
PCC->PCCn[PCC_PDB0_INDEX] &= ~PCC_PCCn_CGC_MASK;
PCC->PCCn[PCC_PDB1_INDEX] &= ~PCC_PCCn_CGC_MASK;
PCC->PCCn[PCC_CRC_INDEX] &= ~PCC_PCCn_CGC_MASK;
PCC->PCCn[PCC_RTC_INDEX] &= ~PCC_PCCn_CGC_MASK;
PCC->PCCn[PCC_EWM_INDEX] &= ~PCC_PCCn_CGC_MASK;
PORTx
}
void LPTMR_LPO(void)
{
SIM->LPOCLKS = 0x0000000D; /*1KHz LPO clock*/
uint16_t init_ms = 2710; /*10s*/
PCC->PCCn[PCC_LPTMR0_INDEX] = PCC_PCCn_CGC_MASK; /* Enable LPTMR Clock */
LPTMR0->PSR |= LPTMR_PSR_PCS(0b01)|(1<<0); /* LPTMR clk src: 1KHz LPO Bypass Prescaler*/
LPTMR0->CMR = init_ms; /* 10s interrupt */
LPTMR0->CSR |= (1<<6) |(1<<0) ; /* Timer interrupt enabled and Enable Timer */
}
void NVIC_IRQs(void)
{
S32_NVIC->ICPR[1] = (1 << (58 % 32));
S32_NVIC->ISER[1] = (1 << (58 % 32));
S32_NVIC->IP[58] = 0x10; // Priority level 0
}
int main(void) {
Clock_Initialization();
Peripheral_disable();
LPTMR_LPO();
NVIC_IRQs();
while(1){
S32_SCB->SCR |= 0x16;
// PMC->REGSC |= 0x47;
PMC->REGSC |= (1 << 1)|(1<<0);
// [1] CLKBIASDIS = 1 In VLPS mode, the bias current for SIRC, FIRC, PLL is disabled
// [0]
SMC->PMCTRL |= 0x00000002;
// [2-0] STOPM = Very-Low-Power Stop (VLPS)
SMC->PMPROT |= (1 << 5);
// [5] AVLP = 1 VLPS allowed
// asm("WFI");
STANDBY();
}
return 0;
}
void LPTMR0_IRQHandler(void)
{
LPTMR0->CSR |= LPTMR_CSR_TCF_MASK;
}
Please check the application note Power Management for S32K1xx. In this, you can find the VLPS mode entry and exit sequence, provide use case examples and shows current measurement results for these cases.