M0 doesn't always come out of reset

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

M0 doesn't always come out of reset

3,494 Views
gregorydavies
Contributor II

I have an application running on an LPC4357, that uses both the M4 and M0 cores, which works almost all of the time. One of the features we use is being able to control which application the M0 is running, so we can do different types of acquisition, or reset the internal state of the application we're running.

The problem I'm seeing is that about 1 out of every 200 times, the M0 doesn't come out of reset. I can repeat the issue reliably by continually resetting the M0, until eventually it stops exhibiting its normal behaviour (writing to shared memory, and sending event interrupts to the M4).

Our M0 reset code looks like this (uses NXP BSP library) :

// Make sure the M0 core is being held in reset via the RGU
Chip_RGU_TriggerReset(RGU_M0APP_RST);
// clear out the memory
memset((void*)M0_APP_LOCATION, 0, M0_APP_MAX_SIZE);
memset((void*)M0_MEM_LOCATION, 0, M0_MEM_SIZE);
// Copy image to execution location
memcpy((void*)M0_APP_LOCATION, (const void*)pimage->start, size);
// Verify
if(memcmp((void*)M0_APP_LOCATION, (void*)pimage->start, size))
{
 DEBUGSTR("* Verification Failed - Aborting\n");
}
else
{
 Chip_Clock_Enable(CLK_M4_M0APP);

 /* Keep in mind the M0 image must be aligned on a 4K boundary */
 Chip_CREG_SetM0AppMemMap(M0_APP_LOCATION); // Location is 0x20000000

 // release from reset
 Chip_RGU_ClearReset(RGU_M0APP_RST);
 
 DEBUGSTR("* M0 released from reset\n");
}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

After resetting the M0 until it doesn't work, I can stop the M4 in the debugger, and I see the following values on these related RGU registers:

RESET_STATUS3: 0x55575555

RESET_ACTIVE_STATUS1: 0xffffffff

RESET_EXT_STAT56: 0x0

According to these, the M4 should assume that the M0 core is out of reset, and running.

Once it fails to come out of reset, subsequent commands don't cause it to recover. I also can't connect to the M0 over JTAG once it fails. I checked the errata, and RESET.1 and RESET.2 seem similar to the problem I'm seeing, but don't mention this M0 behaviour.

I've never noticed this issue when the processor first starts up and runs our default M0 appliation. It's only after we stop and start the M0 that it fails.

Labels (1)
0 Kudos
Reply
8 Replies

3,048 Views
FelipeGarcia
NXP Employee
NXP Employee

Hi Greg,

 

I don't think this is a problem related to the errata RESET.1 and RESET.2, in those cases the resets do not work at all. In your case M0APP_RST works most of the time.

 

My best guess is that you are trying to reset the application before the last reset has finished and the memory gets corrupted.

 

Also, could you try resetting using M0SUB_RST?

 

Best regards,

Felipe

0 Kudos
Reply

3,049 Views
gregorydavies
Contributor II

Hi Filepe,

On the 2nd and 3rd line of the code snippet above, we clear the memory of both the the code and data before writing the application to RAM and taking it out of reset. I have to assume the RGU takes care of resetting the M0 registers, since these are inaccessible from the M4. If the RGU is not clearing all registers and interrupts, I would expect to see the behaviour I'm seeing.

I tested M0SUB_RST, but get identical results. What is the difference between these resets? The user manual doesn't outline what the differences are, and uses them interchangeably in Fig. 29.

0 Kudos
Reply

3,049 Views
FelipeGarcia
NXP Employee
NXP Employee

Hi Greg,

 

The LPC4370 includes an ARM Cortex-M0 coprocessor and an ARM Cortex-M0 subsystem for managing peripherals.

 

M0SUB_RST resets ARM Cortex-M0 subsystem core and M0APP_RST resets ARM Cortex-M0 co-processor.

 

Have a great day,

Felipe

0 Kudos
Reply

3,049 Views
gregorydavies
Contributor II

Hi Felipe,

I still didn't understand the difference after your description, so I looked into it further. I looks like M0APP is the M0 core that's available on all LPC43XX parts, and M0SUB is a second M0 core available on LPC4370 parts. I'm using an LPC4357, so none of the M0SUB stuff applies to my situation.

We've also done some experiments where we repeatedly reset the M4 core, and wait for it to come back, and that has similar issues, which points again in the direction of the RGU.

0 Kudos
Reply

3,049 Views
quex
Contributor I

Hello Greg,

since you mention the behavior with M4 core, it seems to me I might have a similar problem.
A 3rd party device started restarting my device repeatedly.

(reset command is sent via communication and the M0 core resets the whole MCU using Chip_RGU_TriggerReset(RGU_CORE_RST); I am using LPC4357 with LPCopen 2.12)

That did not seem to be my problem until it did not come back after one of the restarts.

I can replicate the behavior. It takes between several to hundreds of restarts.

The M4 core ends up in hard fault. The problem happens during setting of clock, usually in the call of Chip_Clock_SetupMainPLLMult()

When I reset from the application and connect through JTAG after the crash, I can't get any relevant information from the VECTPC register. If I reset it through LPCXpresso, it shows where the hard fault handler was called.

How do you perform the M4 reset?

Do you have any idea what caused the fault?

0 Kudos
Reply

3,049 Views
gregorydavies
Contributor II

Hi quex,

It sounds like you are seeing the same problem I'm seeing. Your description matches what I was seeing exactly. I did the M4 resets with the same TriggerReset() call as you, initiated through a communication channel. I'm not sure what version of LPCCore I'm using, my version.txt says: ECHO is off. Thu 05/15/2014.

I still have no idea what is causing the fault. My best guess is still that it has something to do with the RGU, possibly interacting with interrupts. Maybe an interrupt arrives after interrupt handling is reset, but before the interrupt enable is reset? The NXP support person seem to still be talking past me, and not understanding what I'm describing, so I've given up on that. 

Ultimately I had to just work around the problem. The reason we were resetting the M0 was to reset the filtering on our acquisition. I had to add additional code to reset the filters, without resetting the whole processor. However, the system that uses it is still stuck with the old release, using the M0 reset. For its workaround, it will reset the M4 if the M0 doesn't come back (M0 state is relayed to the communication channels by the M4). If the M4 latches up too, the external watchdog chip will give it a hard reset, and everything will come back normally.

0 Kudos
Reply

3,049 Views
quex
Contributor I

Hello Greg,

thank you for the reply. Good that you found a workaround, unfortunately I can't use that approach.

I created a new thread.

https://community.nxp.com/thread/509527 

0 Kudos
Reply

3,049 Views
FelipeGarcia
NXP Employee
NXP Employee

Hi Greg,

 

You could probably try reading RESET_ACTIVE_STATUSn first and make sure M0 is not in reset when writing to RESET_CTRLn.

 

Also could you please take a look to the following dual core examples:

https://community.nxp.com/docs/DOC-330811 

Regards,

Felipe

0 Kudos
Reply