How to enter VLPS (SLEEP) mode

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

How to enter VLPS (SLEEP) mode

Jump to solution
1,456 Views
Oido
Contributor I
I'm using a s32k144w and want to get this into VLPS.
I'm running the motor using ADC, CAN FD, timer, PWM and I don't know what to do.
I've seen an example called POWER MODE SWITCH but I want to solve it by declaring the register. Request help. And AN5425.PDF was also referenced.
 
void Sleep(void)
{
PMC->REGSC = PMC_REGSC_BIASEN_MASK;
SCG->FIRCCSR = SCG_FIRCCSR_FIRCEN(0);
SCG->SPLLCSR = SCG_SPLLCSR_SPLLEN(0);
SCG->SOSCCSR = SCG_SOSCCSR_SOSCEN(0);
S32_SCB ->SCR = S32_SCB_SCR_SLEEPDEEP_MASK;
SMC->PMPROT = SMC_PMPROT_AVLP_MASK; // VLPS 허용
SMC->PMCTRL = SMC_PMCTRL_RUNM(2)|SMC_PMCTRL_STOPM(2); // VLPR 동작, VLPS
if(SMC->PMSTAT == 1){
__WFI(); //
}
}
void Wake(void)
{
SCG->SIRCCSR = SCG_SIRCCSR_SISCEN(0);
SOSC_init_8MHz();
    SPLL_init_160MHz();
    NormalRUNmode_40MHz();
}
 
int main(void)
{
    SOSC_init_8MHz();
    SPLL_init_160MHz();
    NormalRUNmode_40MHz();
    CAN0_Init();
    PWM_Init(); // PWM주파수, 클럭, 분주비 등 설정
    TIMER_Init();//주파수, 클럭, 분주비 등 설정
    ADC_Init();//채널, 트리거, 평균값, 분주비, 비트 등 설정
    BoardInit(); //핀 및 클럭
    NVIC_EnableIRQ(FTM1_Ovf_Reload_IRQn); // 오버플로우 인터럽트 활성화
    NVIC_EnableIRQ(PORTC_IRQn);
 
    while(1)
    {
}
0 Kudos
Reply
1 Solution
1,277 Views
danielmartynek
NXP TechSupport
NXP TechSupport

Hi @Oido,

You really need to do it step by step.

1. Disable all the peripherals that are not used in VLPS.

2. Switch the system clock to SIRC (measure BUS_CLK at CLKOUIT)

3. Disable all the other clock sources.

4. Enabled wakeup interrupt

5. Enter VLPS.

 

I would strongly recommended testing the VLPS entry/exit using a new simple project that does not use PLL / Motor control routines / any periperals except a GPIO wakeup interrupt.

I have already linked a few example that provide you with all you need.

 

Once you have such a simple project and still have problems, attach the complete project here so that I can test it.

 

Regards,

Daniel

 

View solution in original post

0 Kudos
Reply
8 Replies
1,441 Views
danielmartynek
NXP TechSupport
NXP TechSupport

Hello @Oido,

Refer to this example:

https://community.nxp.com/t5/S32K-Knowledge-Base/Example-S32K144-RTC-VLPS/ta-p/1119655

You need to disable all the peripherals that are not active in VLPS, then, change the system clock to SIRC and disable FIRC, SOSC and SPLL.

On wakeup, enable all the clocks and peripherals.

 

Regards,

Dnaiel

1,432 Views
Oido
Contributor I

First of all, thank you for your answer.

But even after posting this question, I referred to the example you provided and failed.

I can't check if it's vlps mode and I can't even get it back on. If you have any additional information, please do.

0 Kudos
Reply
1,361 Views
Oido
Contributor I
void Sleep(void)
{
PTC->PSOR |= (1<<6); //MCU CAN off
PTA->PSOR |= (1<<10)|(1<<11);//A3922 reset, A3922 ENABLE off
    NVIC_DisableIRQ(LPIT0_Ch0_IRQn);//저전력 타이머 슬립모드 관련 지어야 할듯 LPIT가 맞나 LPTMR이 맞나..15초 후 슬립모드 가는거면 LPTMR이 나을듯TMR할거면 2.2예제
NVIC_DisableIRQ(FTM1_Ovf_Reload_IRQn); // 오버플로우 인터럽트 끄기 ISR OFF
NVIC_DisableIRQ(PORTC_IRQn); //PORTC 인터럽트 홀카운트 끄기
FTM0->SC &= ~FTM_SC_CLKS_MASK;//FTM끄기
FTM1->SC &= ~FTM_SC_CLKS_MASK;//FTM끄기
    CAN0->MCR |= CAN_MCR_MDIS_MASK;//CAN OFF
    ADC0->SC1[0] = ADC_SC1_AIEN(0); //ADC OFF 채널4,5 활성화
 
    init_SIRC();//4MHz
    SCG->RCCR = SCG_RCCR_SCS(2); // SIRC를 시스템 클럭으로 선택
    //while(SCG->CSR & SCG_CSR_SCS_MASK); // 클럭 스위칭이 완료될 때까지 대기
    SCG->SPLLCSR = SCG_SPLLCSR_SPLLEN(0);
    SCG->FIRCCSR = SCG_FIRCCSR_FIRCEN(0);
 
    SCG->SOSCCSR = SCG_SOSCCSR_SOSCEN(0);
    SCG->CLKOUTCNFG = SCG_CLKOUTCNFG_CLKOUTSEL(2);
 
S32_SCB->SCR = S32_SCB_SCR_SLEEPDEEP_MASK;
PMC->REGSC = PMC_REGSC_BIASEN(1) | PMC_REGSC_CLKBIASDIS(1)|PMC_REGSC_LPODIS(1);
SMC->PMPROT = SMC_PMPROT_AVLP_MASK; // VLPS 허용
SMC->PMCTRL = SMC_PMCTRL_STOPM(2); // VLPR 동작, VLPS SMC_PMCTRL_RUNM(2)|
SCG->VCCR = SCG_VCCR_SCS(2); // SIRC를 시스템 클럭으로 선택
__ASM volatile ("wfi"); //인터럽트 대기
}
 
 
 
CAN, FTM, ADC, IRQ, etc. used in this way have been disabled, but 40mA comes out.
We used a digital multimeter to measure the power supply by connecting + and -. Is this the right method? The current goes nowhere
0 Kudos
Reply
1,345 Views
danielmartynek
NXP TechSupport
NXP TechSupport

Hello @Oido,

The example I linked here before have these functions that can be used directly, or slightly modifies if it goes from RUN straight to VLPS.

init_VLPR(),  switch_to_SIRC_in_RUN(), disable_FIRC_in_RUN(), enter_VLPR(), enter_VLPS()

When you change the system clock to SIRC, wait until the system clock is clocked by SIRC before other clocks get disabled, which is something you don't do in the code you posted.

Also, the example uses CLKOUT, which is something I would recommend using to confirm that the clock was correcly switch to SIRC, and that the MCU is VLPS.

There is also this example:

https://community.nxp.com/t5/S32K-Knowledge-Base/Example-S32K144-CMP-Round-robin-S32DS2-0/ta-p/11007...

And the AN5425 that you mentioned come with SW:

https://www.nxp.com/webapp/Download?colCode=AN5425SW&docLang=en

 

If you have the S32K14W-Q064 Evaluation Board, there is J16 for current measurements.

danielmartynek_0-1708349520964.png

You need to measure the just MCU consumption, not the consuption of other devices on the board.

Also, make sure you don't drive any load with the MCU outputs.

The outputs retain their states in VLPS set in the RUN mode.

 

Regards,

Daniel

 

 

0 Kudos
Reply
1,323 Views
Oido
Contributor I
Thank you for your reply.
I tried many things, but I failed.
I'm using a personal pcb, not a pcb of nxp.
I'm still a trainee, but I think I should let this go. It's hard because the current doesn't decrease and I don't wake up. MCU died twice during the attempt. Thank you so much.
If you have time later, please give me your last advice.
I'll leave some but not all of them.
 
void Sleep(void)
{
PTC->PSOR |= (1<<6); //MCU CAN off
PTA->PSOR |= (1<<10)|(1<<11);//A3922 reset, A3922 ENABLE off
    NVIC_DisableIRQ(LPIT0_Ch0_IRQn);//저전력 타이머 슬립모드 관련 지어야 할듯 LPIT가 맞나 LPTMR이 맞나..15초 후 슬립모드 가는거면 LPTMR이 나을듯TMR할거면 2.2예제
NVIC_DisableIRQ(FTM1_Ovf_Reload_IRQn); // 오버플로우 인터럽트 끄기 ISR OFF
NVIC_DisableIRQ(PORTC_IRQn); //PORTC 인터럽트 홀카운트 끄기
FTM0->SC &= ~FTM_SC_CLKS_MASK;//FTM끄기
FTM1->SC &= ~FTM_SC_CLKS_MASK;//FTM끄기
    CAN0->MCR |= CAN_MCR_MDIS_MASK;//CAN OFF
    PCC->PCCn[PCC_FTM0_INDEX] = PCC_PCCn_PCS(0) | PCC_PCCn_CGC(0); //클럭활성화, FTM0 활성화
    PCC->PCCn[PCC_FTM1_INDEX] = PCC_PCCn_PCS(0) | PCC_PCCn_CGC(0); // 클럭활성화, FTM1 활성화
    PCC->PCCn[PCC_ADC0_INDEX] = PCC_PCCn_PCS(0) | PCC_PCCn_CGC(0); // ADC0에 출력
    //ADC0->SC1[0] = ADC_SC1_AIEN(0); //ADC OFF 채널4,5 활성화
    init_SIRC();//1MHz
    SCG->RCCR = SCG_RCCR_SCS(2); // SIRC를 시스템 클럭으로 선택
    //while(SCG->CSR & SCG_CSR_SCS_MASK); // 클럭 스위칭이 완료될 때까지 대기
    //SCG->SPLLCSR = SCG_SPLLCSR_SPLLEN(0);
    //SCG->FIRCCSR = SCG_FIRCCSR_FIRCEN(0);
    //SCG->SOSCCSR = SCG_SOSCCSR_SOSCEN(0);
 
S32_SCB->SCR = S32_SCB_SCR_SLEEPDEEP_MASK;
SMC->PMPROT = SMC_PMPROT_AVLP_MASK; // VLPS 허용
SMC->PMCTRL = SMC_PMCTRL_STOPM(2); // VLPR 동작, VLPS SMC_PMCTRL_RUNM(2)|
PMC->REGSC = PMC_REGSC_BIASEN(1) | PMC_REGSC_CLKBIASDIS(1)|PMC_REGSC_LPODIS(1);
//SCG->VCCR=SCG_VCCR_SCS(2);   //SIRC사용 8Mhz
 
STANDBY(); //인터럽트 대기
}
void wake(void)
{
    //SCG->SPLLCSR = SCG_SPLLCSR_SPLLEN(1);
    //SCG->FIRCCSR = SCG_FIRCCSR_FIRCEN(1);
    //SCG->SOSCCSR = SCG_SOSCCSR_SOSCEN(1);
    SCG->RCCR = SCG_RCCR_SCS(6); // SIRC를 시스템 클럭으로 선택
    while(SCG->CSR & SCG_CSR_SCS_MASK); // 클럭 스위칭이 완료될 때까지 대기
 
    NVIC_EnableIRQ(LPIT0_Ch0_IRQn);//저전력 타이머 슬립모드 관련 지어야 할듯 LPIT가 맞나 LPTMR이 맞나..15초 후 슬립모드 가는거면 LPTMR이 나을듯TMR할거면 2.2예제
NVIC_EnableIRQ(FTM1_Ovf_Reload_IRQn); // 오버플로우 인터럽트 끄기 ISR OFF
NVIC_EnableIRQ(PORTC_IRQn); //PORTC 인터럽트 홀카운트 끄기
FTM0->SC |= FTM_SC_CLKS(3);//FTM끄기
FTM1->SC |= FTM_SC_CLKS(3);//FTM끄기
    CAN0->MCR &= ~CAN_MCR_MDIS_MASK;//CAN OFF
//PCC->PCCn[PCC_FlexCAN0_INDEX] |= PCC_PCCn_CGC_MASK; //CAN0 활성화
PCC->PCCn[PCC_FTM0_INDEX] = PCC_PCCn_PCS(1) | PCC_PCCn_CGC_MASK; //클럭활성화, FTM0 활성화
PCC->PCCn[PCC_FTM1_INDEX] = PCC_PCCn_PCS(1) | PCC_PCCn_CGC_MASK; // 클럭활성화, FTM1 활성화
PCC->PCCn[PCC_ADC0_INDEX] = PCC_PCCn_PCS(1) | PCC_PCCn_CGC_MASK; // ADC0에 출력
PTC->PCOR |= (1<<6); //MCU CAN
PTA->PCOR |= (1<<10)|(1<<11);//A3922 리셋 A3922 ENABLE
}
 
void BoardInit(void)
{
PCC->PCCn[PCC_PORTA_INDEX] = PCC_PCCn_CGC_MASK; //포트A에 클럭 출력
PCC->PCCn[PCC_PORTB_INDEX] = PCC_PCCn_CGC_MASK; //포트B에 클럭 출력
PCC->PCCn[PCC_PORTC_INDEX] = PCC_PCCn_CGC_MASK; //포트C에 클럭 출력
//PCC->PCCn[PCC_PORTD_INDEX] = PCC_PCCn_CGC_MASK; //포트D에 클럭 출력
PCC->PCCn[PCC_PORTE_INDEX] = PCC_PCCn_CGC_MASK; //포트E에 클럭 출력
 
PTA->PDDR = (0<<0)|(0<<1)|(1<<10)|(1<<11)|(0<<13); //PTA0 입력(IGN),PTA1 입력(스위치),PTA10은 A3922리셋,PTA11은 A3922EN,13은 언락스위치
PTB->PDDR = (1<<5); //PTB2 출력 크리스탈 타이머 / PTB4 출력 CCW / PTB5 출력 CW/ PTB6 입력 크리스탈/ PTB7 출력 크리스탈 |(0<<6)|(1<<7) (1<<2)|
PTC->PDDR = (1<<1)|(0<<3)|(1<<6); //PTC3번은 홀센서 인풋, PTC6은 MCU CAN
//PTD->PDDR = (1<<0)|(1<<1)|(1<<2)|(1<<3); //게이트 드라이버 시리얼 머시기 인데 보류
 
 
PTA->PCOR = (1<<10)|(1<<11);
PTC->PCOR = (1<<6); //MCU CAN
 
PORTA->PCR[0] = PORT_PCR_MUX(1);//|PORT_PCR_ISF(1)|PORT_PCR_IRQC(9); //PTA1번 GPIO로 설정 (IGN스위치)
PORTA->PCR[1] = PORT_PCR_MUX(1); //PTA1번 GPIO로 설정 (CS스위치)
PORTA->PCR[13] = PORT_PCR_MUX(1); //PTA13번 GPIO로 설정 (UL스위치)
//PORTB->PCR[2] = PORT_PCR_MUX(1); //PTB2번 GPIO로 설정 (타이머)
 
PORTA->PCR[10] = PORT_PCR_MUX(1);
PORTA->PCR[11] = PORT_PCR_MUX(1);
PORTB->PCR[4] = PORT_PCR_MUX(2); //PTB4번 PWM로 설정
PORTB->PCR[5] = PORT_PCR_MUX(1); //PTB5번 GPIO로 설정
 
PORTE->PCR[8] = PORT_PCR_MUX(2); //PTE8번 PWM로 설정
PORTC->PCR[1] = PORT_PCR_MUX(1); //PTC1번 GPIO로 설정
 
PORTC->PCR[6] = PORT_PCR_MUX(1); //PTC6 MCU CAN
PORTE->PCR[4] = PORT_PCR_MUX(5); //PTE4 CAN RX
PORTE->PCR[5] = PORT_PCR_MUX(5); //PTE5 CAN TX
//-----------SDI PTD1 CS PTD3 SDO PTD2 SCK PTD0
 
PORTC->PCR[3] = PORT_PCR_MUX(1)|PORT_PCR_ISF(1)|PORT_PCR_IRQC(9); //홀센서 PTC3번 GPIO, 인터럽트, 라이징
 
}
 
 
int main(void)
{
SOSC_init_8MHz();
    SPLL_init_160MHz();
    NormalRUNmode_40MHz();
    CAN0_Init();//CAN 설정
PWM_Init(); // PWM주파수, 클럭, 분주비 등 설정
TIMER_Init();//주파수, 클럭, 분주비 등 설정
LPIT_Init(); //저전력 타이머
ADC_Init();//채널, 트리거, 평균값, 분주비, 비트 등 설정
    BoardInit(); //핀 및 클럭
    NVIC_EnableIRQ(LPIT0_Ch0_IRQn);//저전력 타이머 슬립모드 관련 지어야 할듯 LPIT가 맞나 LPTMR이 맞나..15초 후 슬립모드 가는거면 LPTMR이 나을듯TMR할거면 2.2예제
NVIC_EnableIRQ(FTM1_Ovf_Reload_IRQn); // 오버플로우 인터럽트 활성화
NVIC_EnableIRQ(PORTA_IRQn); //PORTC 인터럽트 홀카운트 관련
NVIC_EnableIRQ(PORTC_IRQn); //PORTC 인터럽트 홀카운트 관련
//Sleep();
    while(1)
    {
    CAN0RX();
ADC0->SC1[0] = ADC_SC1_ADCH(4); // ADC0 채널4번 활성화
while(((ADC0->SC1[0] & ADC_SC1_COCO_MASK)>>ADC_SC1_COCO_SHIFT) == 0); // 변환이 완료되어 SC1_COCO가 1로 설정 될 때 까지 대기
ADC_Result_Channel4 = ADC0->R[0]; // ADC0 R(A)의 값을 저장
 
ADC0->SC1[0] = ADC_SC1_ADCH(5); // ADC0 채널5번 활성화
while(((ADC0->SC1[0] & ADC_SC1_COCO_MASK)>>ADC_SC1_COCO_SHIFT) == 0); // 변환이 완료되어 SC1_COCO가 1로 설정 될 때 까지 대기
ADC_Result_Channel5 = ADC0->R[0]; // ADC0 R(A)의 값을 저장
ADC_Current = (ADC_Result_Channel4/140)-0.1; // 게이트 드라이버 전류센서 기존과 변경 값 달라서 보류
ADC_Voltage = (((float)ADC_Result_Channel5 * 5) / 4095)*4+0.5;
if(UnderVoltage<=ADC_Voltage && ADC_Voltage<=OverVoltage){ // 약 11V<전압<13V 내에서만 동작 수치 조정 가능
if(Direction==0){ // 정지
ST();
}
if(Direction==1){ // 정방향
CW();
}
if(Direction==2){ // 역방향
CCW();
}
}
else
{
ST();//전압 범위에서 벗어날 경우 정지
}
}
}
0 Kudos
Reply
1,278 Views
danielmartynek
NXP TechSupport
NXP TechSupport

Hi @Oido,

You really need to do it step by step.

1. Disable all the peripherals that are not used in VLPS.

2. Switch the system clock to SIRC (measure BUS_CLK at CLKOUIT)

3. Disable all the other clock sources.

4. Enabled wakeup interrupt

5. Enter VLPS.

 

I would strongly recommended testing the VLPS entry/exit using a new simple project that does not use PLL / Motor control routines / any periperals except a GPIO wakeup interrupt.

I have already linked a few example that provide you with all you need.

 

Once you have such a simple project and still have problems, attach the complete project here so that I can test it.

 

Regards,

Daniel

 

0 Kudos
Reply
1,413 Views
danielmartynek
NXP TechSupport
NXP TechSupport

There are many issues in the code you posted.

You need to first switch the system clock to SIRC before you can disable all the other clock sources.

Also, in the wakeup interrupt, the system clock should be changed from SIRC before SIRC can be disabled.

Use CLKOUT as shown in the example to monitor the power modes, in VLPS the system clock is turned off. You should also measure the power consumption at VDD.

If you have any probelems with that, please elaborate,

 

Thank you,

BR, Daniel

 

 

0 Kudos
Reply
1,383 Views
Oido
Contributor I

Hello, Daniel

Which register should I look at that can change the system clock to SIRC?

SCG->FIRCCSR = SCG_FIRCCSR_FIRCEN(0);
SCG->SPLLCSR = SCG_SPLLCSR_SPLLEN(0);
SCG->SOSCCSR = SCG_SOSCCSR_SOSCEN(0);
I wonder if it is right for the rest of the clock except SIRC to be deactivated with the registers below.
 
Although the clock was not properly deactivated, the current decreased from 80 mA to 30 mA due to deactivating the CAN or motor gate driver, but it is still high, so it is very important to solve the clock problem. However, I haven't been able to find a way for days.
 
I'm using FTM0,1 as SOC 8Mhz
CAN0 is being used at 40Mhz using SPL.
I tried to deactivate it, but the motor made a strange noise and I quickly stopped it.
 
I feel like I'm gaining experience, but I'm using my time so much that I'm having a headache, can I help?
0 Kudos
Reply