On a F28021 I'm testing for COP functionality.
Via an SCI command I force the code into a while(1) loop activating the COP module.
Here's the sequence and problem:
After a power-up I can trip the COP. I also monitored the cop timer via SCI and saw that it was running.
After the code executes a reset from the above COP event I can trip the COP again. Again the cop timer was running prior.
When the code COP resets a second time I cannot trip the COP again. When I look at the cop timer I see that it is not running, it stays at zero!
When I looked at the SCSR and WDCR the values were the same in all instances
Has anyone seen anything like this before?
Any ideas?
Thanks
Here's more info!
The for case where it does not work:
OSC1 -> system clock
OSC2 -> timer2 and the cop
I did get it to function properly this way:
OSC1 -> system clock and cop
OSC2-> timer2
Did I miss something in the documentation that requires the cop and system clock to run off the same oscillator?
Again, Thanks
The documentation says: “Both INTOSC1 and INTOSC2 can be independently chosen for the Watchdog block, core and CPU-Timer 2.” So there should be no problem in sourcing the watchdog from a different oscillator than the core. I am assuming that when you say COP timer, you mean the Watchdog, right?There are some tricky things when setting up the watchdog (there is a key, there is an override bit so you have to be careful when changing the value in SCSR to avoid clearing it, etc). It would be good to see if you can reproduce the behavior when using the watchdog example from controlSUITE (located at: controlSUITE\f2802x\v129\DSP2802x_examples_ccsv4\watchdog). You could even modify this example to source from OSC2 and test it.
Thanks,
I'll modify the watchdog code and see what happens.
I'll report back.
One thing to note, on a COP hit I don't call an interrupt, I let it reset.
I'll modify the example code to reset too.
Got it to happen with modified example code.
I use GPIO19 as an output to tell me where I am in the code.
At power-up it's low waiting for GPIO18 to go low.
In the loop GPIO19 toggles.
When GPIO18 goes high the code goes into a loop pulling GPIO19 high waiting for a COP timeout.
When I use this line:
SysCtrlRegs.CLKCTL.all = 0x601A; // XTAL off, XCLK off, OSC2 on, OSC1 on, OSC2 ->timer2, OSC1->clock & cop
The code always works. I see GPIO19 toggling and then go low waiting for GPIO18 to return low. (GPIO19 goes high for a very short amount of time)
SysCtrlRegs.CLKCTL.all = 0x601E; // XTAL off, XCLK off, OSC2 on, OSC1 on, OSC2 ->timer2 & cop, OSC1->clock
The code will reset twice as described above, the third time I pull GPIO18 high I see GPIO19 go high and stay high indicating no COP activation.
Here's the code
I used F28021.cmd to run out of flash. The code is running stand alone, not connected to an emulator.
#include "DSP28x_Project.h" // Device Headerfile and Examples Include Filevoid main(void){ InitSysCtrl(); DINT; InitPieCtrl(); IER = 0x0000; IFR = 0x0000; InitPieVectTable(); EALLOW; // THIS LINE ONLY ALLOWS TWO RESETS BEFORE COP STOPS WORKING // SysCtrlRegs.CLKCTL.all = 0x601E; // XTAL off, XCLK off, OSC2 on, OSC1 on, OSC2 ->timer2 & cop, OSC1->clock // THIS LINE ALWAYS WORKS SysCtrlRegs.CLKCTL.all = 0x601A; // XTAL off, XCLK off, OSC2 on, OSC1 on, OSC2 ->timer2, OSC1->clock & cop SysCtrlRegs.PCLKCR3.bit.GPIOINENCLK = 1; // Gpio GpioCtrlRegs.GPADIR.bit.GPIO19 = 1; // use gpio19 to toggle GpioDataRegs.GPACLEAR.bit.GPIO19 = 1; // start low EDIS; EINT; EALLOW; SysCtrlRegs.WDCR = 0x00E8; // clear WD flag, off WD EDIS; // wait till GPIO18 goes low while(GpioDataRegs.GPADAT.bit.GPIO18) ServiceDog(); // Enable the watchdog, clear watchdog reset flag EALLOW; SysCtrlRegs.WDCR = 0x0028; EDIS; for(;;) { // toggle GPIO19 to show running in loop GpioDataRegs.GPATOGGLE.bit.GPIO19 = 1; // when GPIO18 goes high, trip COP, show here by setting GPIO19 high if(GpioDataRegs.GPADAT.bit.GPIO18) { while(1) GpioDataRegs.GPASET.bit.GPIO19 = 1; } ServiceDog(); }}
I suspect there is some problem in the code that I cannot see. To run from Flash, I did the following to run the example on my control card with the TMS320F28027 device (http://focus.ti.com/docs/toolsw/folders/print/tmdscncd28027.html):1. Use the Flash code example from: C:\TI\controlSUITE\device_support\f2802x\v129\DSP2802x_examples_ccsv4\flash_f280272. Modified the code to add your code (See attached) and toggle LED2 on GPOI34 on TI control card:6253.Example_2802xFlash.c3. Ran the code with Debugger attached and CCS runningCouple things that were noticed:1. You are running out of flash, but you do not call MemCopy() anywhere – this is something that you should do if you are running from Flash – see the section in the Headerfiles Quickstart Guide (in controlSUITE) on running from Flash. 2. I don't know how to set up the dependency of GPIO18 and the LED toggling, but I don't think that is neccessary to test this simple case, in which we are just looking for the Watchdog to reset the code and toggle the LED more than twice.3. I did not notice any affect of this, but would be good to mention: It may not be best to set the entire CLKCTL register at once. I think you could try setting OSCCLKSRC2SEL before setting WDCLKSRCSEL – on reset OSCCLKSRC2SEL defaults to an external clock source, which you not using and is not turned on.Summary:1. I would request if you try and run the attached code on TI Piccolo controlcard or controlstick. 2. Place a breakpoint at this line and run again and again to see if the breakpoint is hit repeatedly (if the Watchdog resets the device, it should come out of the "for" loop and hit that breakpoint):SysCtrlRegs.CLKCTL.all = 0x601E;3. If this works, then run the code standalone on your own board or on TI control card using a power supply. May be even slow the LED toggle rate (by inserting delays before toggle) to visually see the LED toggle.
I'll look at it tomorrow.
I think I remember if I ran from the emulator it worked properly both ways.
I ran my code again on my system since it's all set up.
If I leave the emulator connected I can cop timeout to my hearts content.
When I disconnect the emulator on the fly like above I can get two resets to occur, the third time the cop will not execute.
MemCopy is only used when you are copying code from one place to another, specifically in the code example case from flash to ram.
Since I'm not running out of ram and I need no code there, there is no reason to call it.
I tried as you suggested by first selecting the internal oscillator 2 clock then switching over the WD clock source to oscillator 2.
Same result, two activations, then no response.
Here's the two lines of code I used:
SysCtrlRegs.CLKCTL.all = 0x601A; SysCtrlRegs.CLKCTL.all = 0x601E;
If you call initflash function, then you need memcopy. The initflash function needs to be copied from flash to ram.You would get an itrap interrupt if you tried to call that function without copying it.
Also, are you doing all this test on your own board or the TI controlcard/controstick? Do you happen to have a controlcard/controlstick with you, just so that the results can be duplicated on the same setup on both our ends?
The exact code I'm running is shown above, I do not use initflash, it just runs at its default wait state settings.
As I noted before it's on our board since I'm in the middle of developing with it and time is tight.
Can you just take the source I have posted above, modfy the i/o and run off a control stick, it's a very small program?
In the mean time I'll see if I can get mine going as time permits.
So far you have assumed that the WDOG not tripping is the cause of the problem. It may well be but it may not be. According to your test runs the system does not pull GPIO19 low but there is a truckload of code before this happens:
Emil Golen InitSysCtrl(); DINT; InitPieCtrl(); IER = 0x0000; IFR = 0x0000; InitPieVectTable(); EALLOW; // THIS LINE ONLY ALLOWS TWO RESETS BEFORE COP STOPS WORKING // SysCtrlRegs.CLKCTL.all = 0x601E; // XTAL off, XCLK off, OSC2 on, OSC1 on, OSC2 ->timer2 & cop, OSC1->clock // THIS LINE ALWAYS WORKS SysCtrlRegs.CLKCTL.all = 0x601A; // XTAL off, XCLK off, OSC2 on, OSC1 on, OSC2 ->timer2, OSC1->clock & cop SysCtrlRegs.PCLKCR3.bit.GPIOINENCLK = 1; // Gpio GpioCtrlRegs.GPADIR.bit.GPIO19 = 1; // use gpio19 to toggle GpioDataRegs.GPACLEAR.bit.GPIO19 = 1; // start low
InitSysCtrl(); DINT; InitPieCtrl(); IER = 0x0000; IFR = 0x0000; InitPieVectTable(); EALLOW; // THIS LINE ONLY ALLOWS TWO RESETS BEFORE COP STOPS WORKING // SysCtrlRegs.CLKCTL.all = 0x601E; // XTAL off, XCLK off, OSC2 on, OSC1 on, OSC2 ->timer2 & cop, OSC1->clock // THIS LINE ALWAYS WORKS SysCtrlRegs.CLKCTL.all = 0x601A; // XTAL off, XCLK off, OSC2 on, OSC1 on, OSC2 ->timer2, OSC1->clock & cop SysCtrlRegs.PCLKCR3.bit.GPIOINENCLK = 1; // Gpio GpioCtrlRegs.GPADIR.bit.GPIO19 = 1; // use gpio19 to toggle GpioDataRegs.GPACLEAR.bit.GPIO19 = 1; // start low
Now for a second assume the WDOG does trip. The code may be getting stuck in the init procedure before the GPIO is tripped. Have a go at placing GPIO indicators further up in the code to check if this may be the case.
I say this because the initialization of the PLL circuit has a number of traps which can stop startup if things go wrong. I am just wondering if they were taken care of. Here is the InitPll() code.
--------------------------------------- First possible break
if (SysCtrlRegs.PLLSTS.bit.MCLKSTS != 0) { EALLOW; // OSCCLKSRC1 failure detected. PLL running in limp mode. // Re-enable missing clock logic. SysCtrlRegs.PLLSTS.bit.MCLKCLR = 1; EDIS; // Replace this line with a call to an appropriate // SystemShutdown(); function. asm(" ESTOP0"); // Uncomment for debugging purposes } // DIVSEL MUST be 0 before PLLCR can be changed from // 0x0000. It is set to 0 by an external reset XRSn // This puts us in 1/4
--------------------------------------------- Potential break as well if (SysCtrlRegs.PLLSTS.bit.DIVSEL != 0) { EALLOW; SysCtrlRegs.PLLSTS.bit.DIVSEL = 0; EDIS; } // Change the PLLCR if (SysCtrlRegs.PLLCR.bit.DIV != val) { EALLOW; // Before setting PLLCR turn off missing clock detect logic SysCtrlRegs.PLLSTS.bit.MCLKOFF = 1; SysCtrlRegs.PLLCR.bit.DIV = val; EDIS; // Optional: Wait for PLL to lock. // During this time the CPU will switch to OSCCLK/2 until // the PLL is stable. Once the PLL is stable the CPU will // switch to the new PLL value. // // This time-to-lock is monitored by a PLL lock counter. // // Code is not required to sit and wait for the PLL to lock. // However, if the code does anything that is timing critical, // and requires the correct clock be locked, then it is best to // wait until this switching has completed. // Wait for the PLL lock bit to be set. // The watchdog should be disabled before this loop, or fed within // the loop via ServiceDog(). // Uncomment to disable the watchdog DisableDog(); while(SysCtrlRegs.PLLSTS.bit.PLLLOCKS != 1) {
----------------------------------------------------- Have you uncommented to service the watchdog here ?? It could be just resetting continually // Uncomment to service the watchdog // ServiceDog(); } EALLOW; SysCtrlRegs.PLLSTS.bit.MCLKOFF = 0; EDIS; }
I guess the main one would be the Watchdog servicing in the PLL locking. The Piccolo could be in an infinite reset loop if this is not taken care of. However it could also behave normally (if the PLL locks fast enough). Maybe you have done this already but its worth mentioning anyway.
Tim
Also just spotted something else which may be contributing. Ideally you should initialize your clocks first. In the InitSysCtrl() function there is a call to IntOsc1Sel(). This is basically doing what you want but with a different config. I would replace this call with your code and have your code pre the PLL init.
Tim,
I'm pretty sure the COP is not hitting for 2 reasons.
GPIO19 has a pull down on it, when the processor does a reset the line tri-states. At this point the line will be pulled low, it does stay high however.
In a previous test in my application I would report the WDCNTR via SCI. I saw when the COP did not activate WDCNTR stayed at zero. If the clock never counts up it can't expire and reset the system.
Harmon,
Can you tell me what hardware you have, I can modify the code for you so you can duplicate my results.
Unfortunately all I have is the High Voltage Motor Controller Board.
Thanks all!
I have the following two kits and the documentation for these can be found in controlSUITE:Controlstick: http://focus.ti.com/docs/toolsw/folders/print/tmds28027usb.htmlControlCARD: http://focus.ti.com/docs/toolsw/folders/print/tmdscncd28027.htmlI was testing on on the controlCARD and toggling GPIO34, because that's what the LED is on.I guess I am a bit lost now in trying to understand this issue from your last message. Questions:1. Do you have an external pull down on GPIO19? GPIO19 does not have an internal pull down as far as I know.2. There is also a NOTE about GPIO19 on pg 8 (section 2.2) of datasheet. Did you see that and does it affect you?3. Do we still think it's a clocking issue with the Watchdog timer issue, if this has some dependency with GPIO19 due to something specific in your application?
I guess I am just trying to understand as to why GPIO is a factor in this test? In my mind, if we want to just test if the Watchdog timer can provide two or more resets when clocked from OSC2 -> timer2 and the cop and OSC1 -> system clock, we set up the following (as psuedo code):1. Initialize system2. Setup to run from Flash3. Setup clocks: OSC2 -> timer2 and the cop and OSC1 -> system clock4. Setup watchdog to reset5. Just toggle a GPIO6. Trap the CPI in a while 1 loop forever, so that after every reset, step 5 above just toggles the GPIOI want to remove the dependency of GPIO19 causing anything here, so we can isolate the issue. Again this may be just a misunderstanding on my end, but if you could help explain what you need in a psuedo code format, like I did above and how is that different from what I am thinking, then may be we can get on the same page to resolve this?