PDA

View Full Version : CPUy setting CPUx into Idle - AURIX TC29X



gpyl
Apr 13th, 2016, 07:41 AM
I would like to ask if someone has experience in using Infineon's IfxCpu_setCoreMode API function (In IfxCpu.c) to place a CPU into Idle mode by another CPU?

Calling IfxCpu_setCoreMode(&MODULE_CPU0, IfxCpu_CoreMode_idle); from CPU1 causes CPU0 to reset instead of placing it in Idle.

Any help would be much appreciated.

Note: I read in the AURIX TC29x B-Step User's manual that for the B-step the PMSCSx register is Safety ENDINIT protected. Hence i presume this is why CPUy can't set CPUx (In my case CPUy = CPU1 and CPUx is CPU0) to Idle eventhough initially when CPU0 powers up (CPUs 1 & 2 Halted) I can start CPU1 by calling IfxCpu_setCoreMode(&MODULE_CPU1, IfxCpu_CoreMode_run); after having set CPU1's program counter.

Executing the following code:

password = IfxScuWdt_getSafetyWatchdogPassword();
IfxScuWdt_clearSafetyEndinitInline( password );
SCU_PMCSR[ 0 ].B.REQSLP = 1;
IfxScuWdt_setSafetyEndinit( password );

fails to place CPU0 in Idle but doesn't cause a reset.

darmain
Apr 14th, 2016, 03:50 AM
This is interesting. Indeed within the API setCoreMode function there is a comment that reads -

/* To take care of the Work Around in A step
* In A Step the PMCSR is Cpu Endinit protected
* in B step it is by safety endinit*/

Now referring to the User manual for both the A step and B step versions of the device, both state that to access the PMCSR register requires setting Safety ENDINIT to 0. Therefore this would suggest there was an error in the A step device that has now been corrected.

Note that in the API the function calls -

IfxScuWdt_clearCpuEndinit (password);

not -

IfxScuWdt_clearSafetyEndinit (password);

as you might expect for the B step device.

Could this be your problem?

gpyl
Apr 14th, 2016, 05:24 AM
Thank you for the reply. I am using Safety Endinit but yes, great interpretation of Infineon's comment regarding the setCoreMode function.

Nevertheless, the code executed by Core1:

password = IfxScuWdt_getSafetyWatchdogPassword();
IfxScuWdt_clearSafetyEndinitInline( password );
SCU_PMCSR[ 0 ].B.REQSLP = 1;
IfxScuWdt_setSafetyEndinit( password );

fails to place CPU0 in Idle mode.

darmain
Apr 15th, 2016, 03:09 AM
Hi. It would appear, on the face of it that this should work. Consulting the manual, the app notes and looking at example projects then nothing obvious can be seen that should prevent this from working. Well, unless there is a silicon issue with the B step device that we are unaware of.

gpyl
Apr 15th, 2016, 03:18 AM
Thank you for the reply!! It is interesting that you should mention that it might be a silicon issue.

I have noticed the following:
Cpu0 can place Cpu1 and/or Cpu2 in Idle mode,
Cpu1 can place Cpu2 in idle mode and vice versa but NO Cpu can place Cpu0 in Idle mode!!

Any advice will be much appreciated.

darmain
Apr 15th, 2016, 03:57 AM
That doesn't make sense. I could see an use case where you might want to transfer to the lock-step protected core and put the other two cores to idle, so to give the highest level of predictability. But as the lock-step core is core 1, then if any core would be immune to being put to idle by another core then I would expect it to be this core.

gpyl
Apr 15th, 2016, 05:12 AM
Problem solved!! Thanks to a Hitex (UK) engineer it was spotted that an auto reloading gpt timer interrupt serviced by CPU0 would not allow that CPU to enter Idle.

darmain
Apr 15th, 2016, 05:23 AM
Well, that sort of makes sense because the core should go idle after it has finsihed whatever it is doing. If you have a interupt to service then it'll keep awake. So you disabled interupts to fix this?

gpyl
Apr 15th, 2016, 05:34 AM
Yes, I had global interrupts disabled but apparrently if a core is configured to service such a feature (auto reload timer), having global interrupts disabled doesn't have an affect on this.

Great that it is solved. Thank you for the help.

darmain
Apr 15th, 2016, 06:25 AM
Ah, so the interrupt disable does not prevent the interrupt event from waking the core. Actually that makes sense in a way. I'm guessing you had to change your interrupt router to stop the problem. I'm sure there are several ways this could be avoid. However brilliant news it is solved and well done.