Reducing power consumption in MPC577x MCU

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

Reducing power consumption in MPC577x MCU

Jump to solution
866 Views
kanhu96
Contributor II

Hi,

I'm currently working on MPC5775B/E MCU. Our project is currently on bare metal code. I was wondering what are provisions available in the MCU to lower power consumption.

 

1. Can we put MCU code to sleep/halt program execution until next (any configured) interrupt occurs?

Currently in our project, MCU runs on while loop checking for milliseconds elapsed to execution functions.

 

Please let us know if any there's any better solution to reduce the power consumption of the MCU.

 

Thanks.

0 Kudos
1 Solution
483 Views
lukaszadrapa
NXP TechSupport
NXP TechSupport

Hi @kanhu96 
you are right, I was wrong. I'm sorry, I tested this long time ago and it got mixed up in my head.
My wrong expectation was that everything starts by executing of wait instruction and ends by an interrupt which wakes everything up. Actually, this is correct only for cores, not for peripherals. The key point is that you can halt peripherals regardless of cores and wait instruction. So, a peripheral is halted when setting corresponding bit in SIU_HLTn register (and when confirmed by corresponding bit in SIU_HLTACKn register). The peripheral is then halted until you clear the bit in SIU_HLTn.
In case of cores, it's connected to the wait instruction - core is halted by wait instruction and woken up by an interrupt. Therefore it's not necessary to clear halt bits for cores. But it's necessary to clear halt bits for peripehrals once you need them working again.
I'm sorry for the confusion again.
Regards,
Lukas

View solution in original post

13 Replies
852 Views
lukaszadrapa
NXP TechSupport
NXP TechSupport

Hi @kanhu96 

this device supports STOP mode only. You can configure which cores and which peripherals are supposed to be stopped using SIU_HLT1 register (see please description of this register in the reference manual for details) and then execute WAIT instruction. An interrupt will wake up the device.

Another option is to slow down the clocks when high performance is not needed. The current consumption is usually almost linearly dependent on the system frequency.

Regards,

Lukas

0 Kudos
850 Views
kanhu96
Contributor II

Hi @lukaszadrapa,

Thanks for your response.

Please advise on the following:
1. Can any configured interrupt automatically wake up the cores (E.G. PIT or flexCAN etc) or do we have to configure which interrupts can?

 

2. Are you referring to __asm__ ("wait") execution?

If so, will the chosen peripherals require reinitialization, after core wake up? 

 

3. To decrease power consumption related to peripherals, what strategy would you recommend?

Especially when our system needs to go into "Sleep" state, should we disable the clock or deinit all peripherals?

 

 

Regarding your suggestion of slowing down system frequency, during run time of the MCU, if we adopt that method we'll have to reinitialize all peripherals clocks whenever we want to switch to high performance mode, right?

 

Thanks.

Kanhu

 

 

0 Kudos
828 Views
lukaszadrapa
NXP TechSupport
NXP TechSupport

1. Yes, any interrupt will cause wake up.
2. Yes, I mean this asm wait instruction. No reinitialization is needed. Wait instruction will just stop the clocks, it won't cut the power to core/peripherals, so the content of registers is not lost.
3. Deinitialization of peripherals won't help. It's sufficient to stop the clocks.

And yes, clock reinitialization could be needed in this case but it depends on your application what is needed exactly. Stop mode will be probably better solution.

Regards,
Lukas

791 Views
kanhu96
Contributor II

Hi @lukaszadrapa ,

Thanks for your response.

I'm running into few issues while trying to halt core0.

I'm using the following snippet of code:

uint32_t *SIU_HLT1 ;

SIU_HLT1 = (uint32_t *)(0xC3F90000 + 0x000009A4);
*SIU_HLT1 |= (uint32_t)0xC0000000;
 __asm__ ("wait");

 

The above code resides inside a while(true) loop and relies on the PIT timer interrupt for waking up the core0.

 

1. Does the core0 halt bit need to be cleared after wake instruction?

2. If any other peripherals are halted, do their halt bits are supposed to be cleared after wake instruction?

 

Please let me know if there's any sample code or example project.

Thanks.

Kanhu

 

 

0 Kudos
721 Views
lukaszadrapa
NXP TechSupport
NXP TechSupport

Hi @kanhu96 

I'm sorry for delayed response, I just got back from vacation.

It's not necessary to clear the bits in SIU_HLT1 register after wake up.

What kind of issues can you see? Notice that it's usually better to test low power modes without a debugger.

I can't find such example. But it should be enough to set the SIU_HLT1 register and execute wait instruction. Nothing else is needed.

Regards,

Lukas

0 Kudos
719 Views
kanhu96
Contributor II

@lukaszadrapa 

Can you please clarify whether that applies to peripherals?

As in if I have halted another peripheral as well, does the CPU (after waking up from halt mode by an interrupt) need to clear the corresponding bit for waking up the peripheral?

Because I'm confused how other peripherals are supposed to wake up.

The CPU wakes up by the interrupt. But does that apply to other halted peripheral too?

 

Kanhu

 

0 Kudos
685 Views
lukaszadrapa
NXP TechSupport
NXP TechSupport

An interrupt will wake up everything what was halted. It's not selective and it's not necessary to clear the bits in SIU_HLT1 register.

One more thing - there are some errata, not sure if you are aware of that. Please check ERR008368, ERR008367 and ERR010610.

https://www.nxp.com/docs/en/errata/MPC5777C_3N45H.pdf

Regards,

Lukas

0 Kudos
530 Views
kanhu96
Contributor II

hI @lukaszadrapa ,

I have been trying the following block of code:

uint32_t *SIU_HLT1 ;
SIU_HLT1 = (uint32_t *)(0xC3F90000 + 0x000009A4);
*SIU_HLT1 = (uint32_t)0xC000FFBF; //Core0 : 0x80000000, Core1: 0x40000000, PIT: 0x00040000,
__asm__ ("wait");

 

But the MCU seems to halt completely without recovering. Note that I have not halted the PIT timer responsible for tick_ms.

I have tried different combination of other peripheral halting, but any attempt to halt PIT, FlexCAN or DSPI results in halt without recovery.

 

To check what could be the reason, when I enter debugging mode, after MCU comes to complete halt (after wait instruction), if I pause the MCU, it shows that "No source for SWT1_IRQHandler".

 

When I defined "SWT1_IRQHandler", it gave error as no source for "SWT0_IRQHandler".

 

Please help with diagnosis of the problem.

 

0 Kudos
516 Views
lukaszadrapa
NXP TechSupport
NXP TechSupport

Hi @kanhu96 

one common mistake is that the wait instruction is executed in interrupt handler while the MSR[EE] bit is 0. In this case, interrupts are masked, so next PIT interrupt will not wake up the device. Isn't this the root cause?

Regards,

Lukas

0 Kudos
513 Views
kanhu96
Contributor II

Hi @lukaszadrapa ,

I'm not sure how that can happen as the wait instruction can only be executed after the interrupt handlers are completed right?

I'm not using wait instruction inside any interrupt handler.

 

Can you please elaborate how that situation can happen?

Can you suggest a way to avoid the situation you described ?

 

Thanks.

Kanhu

0 Kudos
502 Views
lukaszadrapa
NXP TechSupport
NXP TechSupport

Well, an interrupt can wake up the device only if:

- an interrupt flag is set (for example TIF in PIT)

AND

- interrupts are enabled by MSR[EE] = 1

AND

- current priority is lower than priority of an interrupt which is supposed to wake up the device.

So, that's the typical case when wait is executed in interrupt handler. Even if nested interrupts are enabled (MSR[EE] is enabled in prologue), the same interrupt won't wake up the device because the priority of the same interrupt won't be higher than current priority. It would be necessary to use another interrupt with higher priority.

Regards,

Lukas

492 Views
kanhu96
Contributor II

Hi @lukaszadrapa ,

I didn't find any root cause in-regards to interrupt handlers.

One part of the problem was compiler optimisation which was fixed by using volatile data type.

What finally solved my issue is to restore the SIU_HLT1 value after wait instruction. What I observed is that the bits of HLT1 register were not being cleared automatically. Is there any reason behind this?

 

The following block of code seems to work (although marginal power reduction):

volatile uint32_t *SIU_HLT1, *SIU_HLT2, *SIU_HLTACK1, *SIU_HLTACK2;
SIU_HLT1 = (uint32_t *)(0xC3F90000 + 0x000009A4);
SIU_HLT2 = (uint32_t *)(0xC3F90000 + 0x000009BC);
 
uint32_t backUp_HLT1 = *SIU_HLT1;
uint32_t backUp_HLT2 = *SIU_HLT2;
 
*SIU_HLT1 |= (uint32_t)0xC0000000;
*SIU_HLT2 |= (uint32_t)0x00000000;
 
__asm__ ("wait");
 
*SIU_HLT1 = backUp_HLT1;
*SIU_HLT2 = backUp_HLT2;

 

 

 

0 Kudos
484 Views
lukaszadrapa
NXP TechSupport
NXP TechSupport

Hi @kanhu96 
you are right, I was wrong. I'm sorry, I tested this long time ago and it got mixed up in my head.
My wrong expectation was that everything starts by executing of wait instruction and ends by an interrupt which wakes everything up. Actually, this is correct only for cores, not for peripherals. The key point is that you can halt peripherals regardless of cores and wait instruction. So, a peripheral is halted when setting corresponding bit in SIU_HLTn register (and when confirmed by corresponding bit in SIU_HLTACKn register). The peripheral is then halted until you clear the bit in SIU_HLTn.
In case of cores, it's connected to the wait instruction - core is halted by wait instruction and woken up by an interrupt. Therefore it's not necessary to clear halt bits for cores. But it's necessary to clear halt bits for peripehrals once you need them working again.
I'm sorry for the confusion again.
Regards,
Lukas