Page 1 of 1

MOD54415 CWT reset using PIT

Posted: Wed Jul 02, 2014 7:54 am
by jediengineer
Hi all,

I'm trying to get my CWT to reset properly but just can't seem to get it right. It's set up to trigger every 1.8 seconds, and I have a PIT running that loads 0x55 and 0xAA into the CWSR consecutively every full second (PIT interrupt routine handles that). Somehow, it's not working. The interrupt routine is configured at the moment to interrupt every second, and the only function it has is to reset the CWT before it trips, send an interrupt count number to the serial port, and to reset the PIT. By itself, the PIT is working just fine. with the CWT enabled, I get through the first interrupt routine, and the CWT starts barking at me (consistent reset). The CWT is set to trigger after 1.8 seconds, and I've tried it set to 3.7 seconds as well (0x19 and 0x1A respectively) but it just goes into an instant reset loop. Any ideas why?

Current CWT settings:

Code: Select all

    unsigned short settings = 0;											// simple masking variable for CWCR

    settings |= 0x8000;														// sets CWCR as read-only - bit 15
    settings |= 0x0019;														// sets timeout to 3.7 seconds - bits 4-0
    settings |= 0x00C0;														// bit 7 = enable, bits 6-5 = generate system reset on timeout

    sim2.scm.cwcr = settings;												// load CWCR - starts WDT immediately 
PIT interrupt function:

Code: Select all

INTERRUPT(exPitISR, 0x2400)
{
    static WORD counter = 0;
    sim2.scm.cwsr = 0x55;
    sim2.scm.cwsr = 0xAA;
    sim2.pit[1].pcsr |= 0x0004;  											// clear the PIT IRQ flag 
    SETUP_PIT1_ISR( exPitISR, 4 );										// setup PIT to trigger ISR
    sim2.pit[1].pmr = 0xEE6B; 											// set count to 61035
    sim2.pit[1].pcsr = 0x0B1B; 							 				// set prescale = 2048, rld, and enable
    if (!release) iprintf("Timer 2 Reset. Count = %d \r\n", counter);
    counter++;
}

Re: MOD54415 CWT reset using PIT

Posted: Wed Jul 02, 2014 8:40 am
by ecasey
For starters: Take the iprintf() out of the ISR.
That might fix the reset problem.

Re: MOD54415 CWT reset using PIT

Posted: Wed Jul 02, 2014 8:58 am
by jediengineer
ecasey wrote:For starters: Take the iprintf() out of the ISR.
That might fix the reset problem.
Tried that already. Doesn't affect it. Especially if I have 1.86 seconds to reset the CWT, and a PIT interrupting to reset it every 1.0 seconds. It resets on the first interrupt from the PIT.

Re: MOD54415 CWT reset using PIT

Posted: Wed Jul 02, 2014 9:00 am
by dciliske
ARRRGGGHHH!!!! NEVER USE ANY CALL IN AN INTERRUPT THAT MAY TRIGGER AN OS PEND!

Sorry, now that that's out of the way... basically, printf functions call 'write' on the currently assigned file descriptor for stdout. In said write routine, at some point or another there is almost always* a possibility of the call scheduling out the task via an OSPend of some form (if the output file descriptor doesn't have space for the data being sent). If you pend in an interrupt, the system is royally screwed, and all behaviour after it is undefined (aka, probably never going to return from the interrupt, or schedule in another task). So, the fact that you're trying to service a watchdog and then reseting from this... means that the watchdog works :)

Does this clarify why your application seems to work and then randomly hand grenades? It probably would works fine up until the serial driver output becomes full, and then you explode. You can check the reset status register to confirm that it was the watchdog triggering the reset as well.

-Dan

Re: MOD54415 CWT reset using PIT

Posted: Wed Jul 02, 2014 9:04 am
by dciliske
Also, what are you doing with the call to 'SETUP_PIT1_ISR' in your isr? That function is used for registering the ISR in the vector table, not clearing an IRQ bit.

Re: MOD54415 CWT reset using PIT

Posted: Wed Jul 02, 2014 9:21 am
by jediengineer
Sorry Dan, I know that I'm making you pull out your hair... The SETUP_PIT_ISR was removed from the interrupt for the PIT - I realize that was an error... Also, I originally had it setup without the iprintf statement - that was implemented to test if the interrupt was working... this was the original code:

Code: Select all

INTERRUPT (exPitISR, 0x2400)
{
    sim2.scm.cwsr = 0x55;                                 // service watchdog
    sim2.scm.cwsr = 0xAA;
    sim2.pit[1].pcsr |= 0x0004;                         // clear the PIT IRQ flag
    OSSemPost(&timerSEM);
    sim2.pit[1].pmr = 0xEE6B;
    sim2.pit[1].pcsr = 0x0B1B;
}

And yes, it blows up right after the iprintf was called. I tried it without it, and got the same thing.  The current ISR omits the semaphore posting. I'm assuming a direct register write does not cause an OS Pend...?

Re: MOD54415 CWT reset using PIT

Posted: Wed Jul 02, 2014 11:20 am
by rnixon
Comment out all the wdog stuff and just run the pit. Add some code in user main to print out a counter value for how many times your pit isr got called every 10 seconds. Calculate what that count should be and that will verify your pit is running properly.