6
\$\begingroup\$

I'm curious? A watchdog timer could do this, but I would like to do it manually.

\$\endgroup\$
5
\$\begingroup\$

From a quick look at the datasheet, I believe that the watchdog is the only way to reset under software control.

Reset has two sources on the LPC2101/02/03: the RST pin and watchdog reset. The RST pin is a Schmitt trigger input pin with an additional glitch filter. Assertion of chip reset by any source starts the wake-up timer (see wake-up timer description below), causing the internal chip reset to remain asserted until the external reset is de-asserted, the oscillator is running, a fixed number of clocks have passed, and the on-chip flash controller has completed its initialization.

To do a software reset, start the watchdog with a small timeout value, then go into an infinite loop.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ This is exactly what I did a few years ago on the LPC2148, worked like a charm. \$\endgroup\$ – Radian Jul 12 '10 at 13:41
  • \$\begingroup\$ It might be possible to arrange some other kind of suicide reset with external logic, but if you already have a WD.. Just make sure you know what way it behaves when it comes back out of WDR so you won't be in a reset loop or such. \$\endgroup\$ – XTL Jul 12 '10 at 14:50
  • \$\begingroup\$ Yes, the watchdog is how I did it with an LPC2148 application, as well. \$\endgroup\$ – Leon Heller Jul 12 '10 at 16:42
  • \$\begingroup\$ The watchdog timer here is mislabeled. ARM documentation as well as Atmel and TI/Stellaris implementations of the ARM7TDMI (for starters) all refer to this interrupt as Reset, not 'Watchdog' as NXP does. Use it like you'd use a reset interrupt. \$\endgroup\$ – Kevin Vermeer Jul 20 '10 at 12:26
6
\$\begingroup\$

reemrevnivek has the right idea, but there's a better way.

WDTC = 1024;              // short timeout; we don't care (won't be using it)
WDMOD = WDEN | WDRESET;   // watchdog resets CPU
WDFEED = 0xAA;            // start ...
WDFEED = 0x55;            // ... watchdog.
WDFEED = 0xAA;            // start ...
WDFEED = 0x00;            // ... invalid WDFEED sequence causes instant reset.

That will give you an immediate reset without the need for waiting.

Note that simply jumping to location 0 isn't the same as a real reset. Jumping to 0 doesn't reset any peripherals nor does it reset the ARM core's state. It may sound like I'm nitpicking here, but you can run into some very unusual and difficult to debug issues if you are expecting a reset and don't actually get one.

| improve this answer | |
\$\endgroup\$
3
\$\begingroup\$

Don't run interrupts by starting the timers with a small value - Write directly to the interrupt flag! Leon's post wants you to run the interrupt as defined in the user manual, page 219:

WDTC = 1024;              // short timeout - WASTEFUL!
WDMOD = WDEN | WDRESET;   // watchdog resets CPU
WDFEED = 0xAA;            // start ...
WDFEED = 0x55;            // ... watchdog.

Instead, do the timer's job for it - Write to the WDINT bit (Which triggers the watchdog interrupt) of the WDMOD register directly, instead of waiting for the timer:

WDMOD = WDEN;       // Enable interrupt
WDMOD |= WDINT;     // Trigger interrupt

The datasheet says that it's read-only, which is a surprise to me, but the TI and Atmel processors I've used usually have writable interrupt triggers. Give it a try, and see what happens.

The more portable alternative is a software interrupt. I haven't worked with NXP processors, but the ARM7TDMI family (of which the LPC2100 is a member) can be reset by branching to 0x00000000. Interestingly, NXP refers to this address as the watchdog interrupt. You should be able to branch to zero with code like:

void (*reset)(void); // Declare function to call
reset = 0x00000000;  // Address in memory of reset ISR 
                     // (See Table 2-4 of ARM7TDMI TRM or 
                     // Table 2 of NXP UM10161)
reset();             // Call your new function

Alternatively, use:

asm volatile ("mov pc, #0\n");

to accomplish the same thing.

There might be a few housekeeping things left to do, but this code will basically do the same thing as the watchdog timer, which is to start your program over from the beginning. This code will also work across a wide number of microcontrollers.

| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.