This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

COP issue?

Other Parts Discussed in Thread: CONTROLSUITE, TMS320F28027

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)

    When I use this line:

        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 File

    void 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_f28027
    2. Modified the code to add your code (See attached) and toggle LED2 on GPOI34 on TI control card:

    // TI File $Revision: /main/1 $
    // Checkin $Date: July 13, 2009   10:09:34 $
    //###########################################################################
    //
    // FILE:    Example_2802xFlash.c
    //
    // TITLE:   DSP2802x EPwm Timer Interrupt From Flash Example.
    //
    // ASSUMPTIONS:
    //
    //    This program requires the DSP2802x header files.
    //
    //    As supplied, this project is configured for "boot to FLASH"
    //    operation.  The 2802x Boot Mode table is shown below.
    //    For information on configuring the boot mode of an eZdsp,
    //    please refer to the documentation included with the eZdsp,
    //
    //    $Boot_Table
    //    While an emulator is connected to your device, the TRSTn pin = 1,
    //    which sets the device into EMU_BOOT boot mode. In this mode, the
    //    peripheral boot modes are as follows:
    //
    //      Boot Mode:   EMU_KEY        EMU_BMODE
    //                   (0xD00)         (0xD01)
    //      ---------------------------------------
    //      Wait         !=0x55AA        X
    //      I/O          0x55AA          0x0000
    //      SCI          0x55AA          0x0001
    //      Wait         0x55AA          0x0002
    //      Get_Mode     0x55AA          0x0003
    //      SPI          0x55AA          0x0004
    //      I2C          0x55AA          0x0005
    //      OTP          0x55AA          0x0006
    //      Wait         0x55AA          0x0007
    //      Wait         0x55AA          0x0008
    //      SARAM        0x55AA          0x000A
    //      Flash        0x55AA          0x000B   <-- "Boot to Flash"
    //      Wait         0x55AA          Other
    //
    //   Write EMU_KEY to 0xD00 and EMU_BMODE to 0xD01 via the debugger
    //   according to the Boot Mode Table above. Build/Load project,
    //   Reset the device, and Run example
    //
    //   $End_Boot_Table
    //
    //    The program must first be compiled and then programmed into the
    //    flash.
    //
    //
    // DESCRIPTION:
    //
    //    This example runs the EPwm interrupt example from flash.
    //
    //    1) Build the project
    //    2) Flash the .out file into the device.
    //    3) Set the hardware jumpers to boot to Flash
    //    4) Use the included GEL file to load the project, symbols
    //       defined within the project and the variables into the watch
    //       window.
    //
    //    Steps that were taken to convert the EPwm example from RAM
    //    to Flash execution:
    //
    //    - Change the linker cmd file to reflect the flash memory map.
    //    - Make sure any initialized sections are mapped to Flash.
    //      In SDFlash utility this can be checked by the View->Coff/Hex
    //      status utility. Any section marked as "load" should be
    //      allocated to Flash.
    //    - Make sure there is a branch instruction from the entry to Flash
    //      at 0x3F7FF6 to the beginning of code execution. This example
    //      uses the DSP0x_CodeStartBranch.asm file to accomplish this.
    //    - Set boot mode Jumpers to "boot to Flash"
    //    - For best performance from the flash, modify the waitstates
    //      and enable the flash pipeline as shown in this example.
    //      Note: any code that manipulates the flash waitstate and pipeline
    //      control must be run from RAM. Thus these functions are located
    //      in their own memory section called ramfuncs.
    //
    //
    //    EPwm1 Interrupt will run from RAM and puts the flash into sleep mode
    //    EPwm2 Interrupt will run from RAM and puts the flash into standby mode
    //    EPwm3 Interrupt will run from FLASH
    //
    //    As supplied:
    //
    //    All timers have the same period
    //    The timers are started sync'ed
    //    An interrupt is taken on a zero event for each EPwm timer
    //
    //       EPwm1: takes an interrupt every event
    //       EPwm2: takes an interrupt every 2nd event
    //       EPwm3: takes an interrupt every 3rd event
    //
    //    Thus the Interrupt count for EPwm1, EPwm4-EPwm6 should be equal
    //    The interrupt count for EPwm2 should be about half that of EPwm1
    //    and the interrupt count for EPwm3 should be about 1/3 that of EPwm1
    //
    //          Watch Variables:
    //                 EPwm1TimerIntCount
    //                 EPwm2TimerIntCount
    //                 EPwm3TimerIntCount
    //
    //                 Toggle GPIO34 while in the background loop.
    //
    //###########################################################################
    // $TI Release: DSP2802x C/C++ Header Files V1.10 $
    // $Release Date: July 27, 2009 $
    //###########################################################################
    
    #include "DSP28x_Project.h"     // Device Headerfile and Examples Include File
    
    // Configure which EPwm timer interrupts are enabled at the PIE level:
    // 1 = enabled,  0 = disabled
    /*#define PWM1_INT_ENABLE  1
    #define PWM2_INT_ENABLE  1
    #define PWM3_INT_ENABLE  1
    
    // Configure the period for each timer
    #define PWM1_TIMER_TBPRD   0x1FFF
    #define PWM2_TIMER_TBPRD   0x1FFF
    #define PWM3_TIMER_TBPRD   0x1FFF
    
    // Make this long enough so that we can see an LED toggle
    #define DELAY 1000000L
    
    // Functions that will be run from RAM need to be assigned to
    // a different section.  This section will then be mapped using
    // the linker cmd file.
    #pragma CODE_SECTION(EPwm1_timer_isr, "ramfuncs");
    #pragma CODE_SECTION(EPwm2_timer_isr, "ramfuncs");
    
    // Prototype statements for functions found within this file.
    interrupt void EPwm1_timer_isr(void);
    interrupt void EPwm2_timer_isr(void);
    interrupt void EPwm3_timer_isr(void);
    void InitEPwmTimer(void);
    
    // Global variables used in this example
    Uint32  EPwm1TimerIntCount;
    Uint32  EPwm2TimerIntCount;
    Uint32  EPwm3TimerIntCount;
    Uint32  LoopCount;*/
    
    // These are defined by the linker (see F2808.cmd)
    extern Uint16 RamfuncsLoadStart;
    extern Uint16 RamfuncsLoadEnd;
    extern Uint16 RamfuncsRunStart;
    
    void main(void)
    {
    
    // Step 1. Initialize System Control:
    // PLL, WatchDog, enable Peripheral Clocks
    // This example function is found in the DSP2802x_SysCtrl.c file.
       InitSysCtrl();
    
    // Step 2. Initalize GPIO:
    // This example function is found in the DSP2802x_Gpio.c file and
    // illustrates how to set the GPIO to it's default state.
    // InitGpio();  // Skipped for this example
    
    // Step 3. Clear all interrupts and initialize PIE vector table:
    // Disable CPU interrupts
       DINT;
    
    // Initialize the PIE control registers to their default state.
    // The default state is all PIE interrupts disabled and flags
    // are cleared.
    // This function is found in the DSP2802x_PieCtrl.c file.
       InitPieCtrl();
    
    // Disable CPU interrupts and clear all CPU interrupt flags:
       IER = 0x0000;
       IFR = 0x0000;
    
    // Initialize the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    // This will populate the entire table, even if the interrupt
    // is not used in this example.  This is useful for debug purposes.
    // The shell ISR routines are found in DSP2802x_DefaultIsr.c.
    // This function is found in DSP2802x_PieVect.c.
       InitPieVectTable();
    
    // Interrupts that are used in this example are re-mapped to
    // ISR functions found within this file.
    /*   EALLOW;  // This is needed to write to EALLOW protected registers
       PieVectTable.EPWM1_INT = &EPwm1_timer_isr;
       PieVectTable.EPWM2_INT = &EPwm2_timer_isr;
       PieVectTable.EPWM3_INT = &EPwm3_timer_isr;
       EDIS;    // This is needed to disable write to EALLOW protected registers*/
    
    // Step 4. Initialize all the Device Peripherals:
    // This function is found in DSP2802x_InitPeripherals.c
    // InitPeripherals();  // Not required for this example
     //  InitEPwmTimer();    // For this example, only initialize the EPwm Timers
    
    // Step 5. User specific code, enable interrupts:
    
    // Copy time critical code and Flash setup code to RAM
    // This includes the following ISR functions: EPwm1_timer_isr(), EPwm2_timer_isr()
    // EPwm3_timer_isr and and InitFlash();
    // The  RamfuncsLoadStart, RamfuncsLoadEnd, and RamfuncsRunStart
    // symbols are created by the linker. Refer to the F2808.cmd file.
       MemCopy(&RamfuncsLoadStart, &RamfuncsLoadEnd, &RamfuncsRunStart);
    
    // Call Flash Initialization to setup flash waitstates
    // This function must reside in RAM
       InitFlash();
    
    // Initalize counters:
     /*  EPwm1TimerIntCount = 0;
       EPwm2TimerIntCount = 0;
       EPwm3TimerIntCount = 0;
       LoopCount = 0;
    
    // Enable CPU INT3 which is connected to EPwm1-3 INT:
       IER |= M_INT3;
    
    // Enable EPwm INTn in the PIE: Group 3 interrupt 1-3
       PieCtrlRegs.PIEIER3.bit.INTx1 = PWM1_INT_ENABLE;
       PieCtrlRegs.PIEIER3.bit.INTx2 = PWM2_INT_ENABLE;
       PieCtrlRegs.PIEIER3.bit.INTx3 = PWM3_INT_ENABLE;*/
    
    // Enable global Interrupts and higher priority real-time debug events:
     //  EINT;   // Enable Global interrupt INTM
     //  ERTM;   // Enable Global realtime interrupt DBGM
    
    // Step 6. IDLE loop. Just sit and loop forever (optional):
       EALLOW;
       GpioCtrlRegs.GPBMUX1.bit.GPIO34 = 0;
       GpioCtrlRegs.GPBDIR.bit.GPIO34 = 1;
       EDIS;
    
    // 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.GPBCLEAR.bit.GPIO34 = 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.GPBTOGGLE.bit.GPIO34 = 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();                              
               }*/
    
    
    }
    
    /*void InitEPwmTimer()
    {
    
       EALLOW;
       SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;      // Stop all the TB clocks
       EDIS;
    
       InitEPwm1Gpio();
       InitEPwm2Gpio();
       InitEPwm3Gpio();
    
       // Setup Sync
       EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;  // Pass through
       EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;  // Pass through
       EPwm3Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;  // Pass through
    
       // Allow each timer to be sync'ed
    
       EPwm1Regs.TBCTL.bit.PHSEN = TB_ENABLE;
       EPwm2Regs.TBCTL.bit.PHSEN = TB_ENABLE;
       EPwm3Regs.TBCTL.bit.PHSEN = TB_ENABLE;
    
       EPwm1Regs.TBPHS.half.TBPHS = 100;
       EPwm2Regs.TBPHS.half.TBPHS = 200;
       EPwm3Regs.TBPHS.half.TBPHS = 300;
    
       EPwm1Regs.TBPRD = PWM1_TIMER_TBPRD;
       EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP;    // Count up
       EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO;     // Select INT on Zero event
       EPwm1Regs.ETSEL.bit.INTEN = PWM1_INT_ENABLE;  // Enable INT
       EPwm1Regs.ETPS.bit.INTPRD = ET_1ST;           // Generate INT on 1st event
    
    
       EPwm2Regs.TBPRD = PWM2_TIMER_TBPRD;
       EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP;     // Count up
       EPwm2Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO;      // Enable INT on Zero event
       EPwm2Regs.ETSEL.bit.INTEN = PWM2_INT_ENABLE;   // Enable INT
       EPwm2Regs.ETPS.bit.INTPRD = ET_2ND;            // Generate INT on 2nd event
    
    
       EPwm3Regs.TBPRD = PWM3_TIMER_TBPRD;
       EPwm3Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP;     // Count up
       EPwm3Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO;      // Enable INT on Zero event
       EPwm3Regs.ETSEL.bit.INTEN = PWM3_INT_ENABLE;   // Enable INT
       EPwm3Regs.ETPS.bit.INTPRD = ET_3RD;            // Generate INT on 3rd event
    
       EPwm1Regs.CMPA.half.CMPA = PWM1_TIMER_TBPRD/2;
       EPwm1Regs.AQCTLA.bit.PRD = AQ_SET;
       EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR;
       EPwm1Regs.AQCTLB.bit.PRD = AQ_SET;
       EPwm1Regs.AQCTLB.bit.CAU = AQ_CLEAR;
    
       EPwm2Regs.CMPA.half.CMPA = PWM2_TIMER_TBPRD/2;
       EPwm2Regs.AQCTLA.bit.PRD = AQ_SET;
       EPwm2Regs.AQCTLA.bit.CAU = AQ_CLEAR;
       EPwm2Regs.AQCTLB.bit.PRD = AQ_SET;
       EPwm2Regs.AQCTLB.bit.CAU = AQ_CLEAR;
    
       EPwm3Regs.CMPA.half.CMPA = PWM3_TIMER_TBPRD/2;
       EPwm3Regs.AQCTLA.bit.PRD = AQ_SET;
       EPwm3Regs.AQCTLA.bit.CAU = AQ_CLEAR;
       EPwm3Regs.AQCTLB.bit.PRD = AQ_SET;
       EPwm3Regs.AQCTLB.bit.CAU = AQ_CLEAR;
    
       EALLOW;
       SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;         // Start all the timers synced
       EDIS;
    
    }
    
    // This ISR MUST be executed from RAM as it will put the Flash into Sleep
    // Interrupt routines uses in this example:
    interrupt void EPwm1_timer_isr(void)
    {
    
       // Put the Flash to sleep
       FlashRegs.FPWR.bit.PWR = FLASH_SLEEP;
    
       EPwm1TimerIntCount++;
    
       // Clear INT flag for this timer
       EPwm1Regs.ETCLR.bit.INT = 1;
    
       // Acknowledge this interrupt to receive more interrupts from group 3
       PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
    }
    
    // This ISR MUST be executed from RAM as it will put the Flash into Standby
    interrupt void EPwm2_timer_isr(void)
    {
       EPwm2TimerIntCount++;
    
        // Put the Flash into standby
        FlashRegs.FPWR.bit.PWR = FLASH_STANDBY;
    
       // Clear INT flag for this timer
       EPwm2Regs.ETCLR.bit.INT = 1;
    
       // Acknowledge this interrupt to receive more interrupts from group 3
       PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
    }
    
    interrupt void EPwm3_timer_isr(void)
    {
       Uint16 i;
    
       EPwm3TimerIntCount++;
    
        // Short Delay to simulate some ISR Code
        for(i = 1; i < 0x01FF; i++) {}
    
       // Clear INT flag for this timer
       EPwm3Regs.ETCLR.bit.INT = 1;
    
       // Acknowledge this interrupt to receive more interrupts from group 3
       PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
    }*/
    
    //===========================================================================
    // No more.
    //===========================================================================
    

    3. Ran the code with Debugger attached and CCS running

    Couple 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.

    Thanks

  • 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.

    Thanks

     

  • 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 said:

        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

  • 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.html
    ControlCARD: http://focus.ti.com/docs/toolsw/folders/print/tmdscncd28027.html
    I 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 system
    2. Setup to run from Flash
    3. Setup clocks: OSC2 -> timer2 and the cop and OSC1 -> system clock
    4. Setup watchdog to reset
    5. Just toggle a GPIO
    6. Trap the CPI in a while 1 loop forever, so that after every reset, step 5 above just toggles the GPIO

    I 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?

     

  • Harman said:

    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?

    I'm testing on my target board.

    Harman said:

    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?

    Yes, I still see a problem. I use GPIO19 as a convenient way for me to monitor where the code is actually running since I'm not using the emulator.

    Harman said:

    I guess I am just trying to understand as to why GPIO is a factor in this test?

    GPIO is used as a state monitor.

    When it's toggling I know code is running in the main loop.

    When it's low I know the code is at or before the while(GpioDataRegs.GPADAT.bit.GPIO18); loop.

    When it's high I know the code is waiting for the COP to timeout.

    Harman said:

     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 system
    2. Setup to run from Flash
    3. Setup clocks: OSC2 -> timer2 and the cop and OSC1 -> system clock
    4. Setup watchdog to reset
    5. Just toggle a GPIO
    6. Trap the CPI in a while 1 loop forever, so that after every reset, step 5 above just toggles the GPIO

    I 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?

     

    Again I used my method since it was the easiest for me to implement, I'm sure many different methods can be devised to show the same result.

    I'll look at the documentation on the board you have and give you code to run on it.

    Thanks

  • I think you are referring to this High Voltage Motor control kit:
    http://focus.ti.com/docs/toolsw/folders/print/tmdshvmtrpfckit.html

    This also comes with a Piccolo control card. Can you please it on that controlCARD also (using the kit as a docking station), if you have one? This way we can be both be atleast on some sort of common platform to duplicate this.

  • I tried getting your board working but I'm missing something so it's not working properly.

    Here's a very simplified version of the code, you should have no trouble incorporating it into a simple template project.

    I use GPIO19 as my output, change it to whatever you have on your board.

    It's setup in two lines and exercised in two lines.

    When it's functioning correctly with 0x601A it will basically stay high for 12ms and go low for a short time when it's going through it's reset.

    When it's not functioning correctly with 0x601E it will operate as described above twice then curiously stay high for 96ms then go low and stay low.

    The last time when the COP is not functioning and is going to fail the test, the cpu clock seems to be running 1/8 the speed it should!

    Here's the code:

    void main(void)
    {
    int x;

        // watchdog disabled on entry
        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 clock
        GpioCtrlRegs.GPBDIR.bit.GPIO19 = 1;            // use gpio19 to toggle
        GpioDataRegs.GPBCLEAR.bit.GPIO19 = 1;        // start off           

        // reset watchdog   
        SysCtrlRegs.WDKEY = 0x0055;
        SysCtrlRegs.WDKEY = 0x00AA;
        // enable the watchdog, clear watchdog reset flag
        SysCtrlRegs.WDCR = 0x0028;
        EDIS;

        GpioDataRegs.GPBTOGGLE.bit.GPIO19 = 1;
        for(x=30000;x;x--);                            // delay to show led   
        GpioDataRegs.GPBTOGGLE.bit.GPIO19 = 1;
               
        while(1);
       
    }

     

  • Any progress?

    Thanks!

  • I was able to duplicate the issue with the following code:

    //
    // FILE:    Example_2802xFlash.c
    //
    // ASSUMPTIONS:
    //
    //    This program requires the DSP2802x header files.
    //
    //    As supplied, this project is configured for "boot to FLASH"
    //    operation.  The 2802x Boot Mode table is shown below.
    //    For information on configuring the boot mode of an eZdsp,
    //    please refer to the documentation included with the eZdsp,
    //
    //    $Boot_Table
    //    While an emulator is connected to your device, the TRSTn pin = 1,
    //    which sets the device into EMU_BOOT boot mode. In this mode, the
    //    peripheral boot modes are as follows:
    //
    //      Boot Mode:   EMU_KEY        EMU_BMODE
    //                   (0xD00)         (0xD01)
    //      ---------------------------------------
    //      Wait         !=0x55AA        X
    //      I/O          0x55AA          0x0000
    //      SCI          0x55AA          0x0001
    //      Wait         0x55AA          0x0002
    //      Get_Mode     0x55AA          0x0003
    //      SPI          0x55AA          0x0004
    //      I2C          0x55AA          0x0005
    //      OTP          0x55AA          0x0006
    //      Wait         0x55AA          0x0007
    //      Wait         0x55AA          0x0008
    //      SARAM        0x55AA          0x000A
    //      Flash        0x55AA          0x000B   <-- "Boot to Flash"
    //      Wait         0x55AA          Other
    //
    //   Write EMU_KEY to 0xD00 and EMU_BMODE to 0xD01 via the debugger
    //   according to the Boot Mode Table above. Build/Load project,
    //   Reset the device, and Run example
    //
    //   $End_Boot_Table
    //
    //    The program must first be compiled and then programmed into the
    //    flash.
    //
    //
    // DESCRIPTION:
    //
    
    #include "DSP28x_Project.h"     // Device Headerfile and Examples Include File
    
    void main(void)
    {
    	volatile unsigned int x;
    
    // Step 1. Initialize System Control:
    // PLL, WatchDog, enable Peripheral Clocks
    // This example function is found in the DSP2802x_SysCtrl.c file.
       InitSysCtrl();
    
    // Step 3. Clear all interrupts and initialize PIE vector table:
    // Disable CPU interrupts
       DINT;
    
    // Initialize the PIE control registers to their default state.
    // The default state is all PIE interrupts disabled and flags
    // are cleared.
    // This function is found in the DSP2802x_PieCtrl.c file.
       InitPieCtrl();
    
    // Disable CPU interrupts and clear all CPU interrupt flags:
       IER = 0x0000;
       IFR = 0x0000;
    
    // Initialize the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    // This will populate the entire table, even if the interrupt
    // is not used in this example.  This is useful for debug purposes.
    // The shell ISR routines are found in DSP2802x_DefaultIsr.c.
    // This function is found in DSP2802x_PieVect.c.
       InitPieVectTable();
    
       for(x=60000;x;x--);                            // delay to show led
    
       EALLOW;
       GpioCtrlRegs.GPBMUX1.bit.GPIO34 = 0;
       GpioCtrlRegs.GPBDIR.bit.GPIO34 = 1;
    // 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 clock
        GpioDataRegs.GPBCLEAR.bit.GPIO34 = 1;        // start low             
    
        // reset watchdog    
        SysCtrlRegs.WDKEY = 0x0055;
        SysCtrlRegs.WDKEY = 0x00AA;
        // enable the watchdog, clear watchdog reset flag
        SysCtrlRegs.WDCR = 0x0028;
        EDIS;
    
        GpioDataRegs.GPBTOGGLE.bit.GPIO34 = 1;
        GpioDataRegs.GPBTOGGLE.bit.GPIO34 = 1;
                
        while(1);
    
    
    }
    
    

    The only differences that I found in my test results are as follows:
    1. In the failing condition, the reset happens more than just two times, but eventually fails with the emulator connected, but code freely running without breakpoints.
    2. When I put a breakpoint in the code before the while(1) line, it run the code to breakpoint, it always passes. I am not sure when you mentioned earlier that the code always works when emulator is connected, if you meant using breakpoints. I can duplicate the failure with the emulator connected to my docking station/controlCARD.

    I will forward this info to the product team to see if they can chase the root cause of this issue.
    Thank you for your help and patience.

  • When I said with the emulator (XDS510 USB) I just meant hooked to the JTAG port but not doing anything else, no breakpoints.

    May I suggest you try one more thing.

    Put the delay in between the GPIO34 toggles and run it without the emulator with both CLKCTL configurations.

    When working correctly you'll basically see the led on.

    When not working correctly the led will light for just a short time and then go off and stay off.

    Just looking for a workaround.

    Thanks for your help!

    Emil

     

     

  • There seems to be an issue in design due to which the WD may not work as expected if it's clocked by OSCCLKSRC2. We are going to issue following errata for the same.

    Advisory Watchdog: Incorrect operation of CPU watchdog when WDCLK source is OSCCLKSRC2

    Revision(s) Affected 0,A

    Details When OSCCLKSRC2 is used as the clock source for CPU watchdog, the watchdog may fail to generate a device reset intermittently.

    Workaround WDCLK should be sourced only from OSCCLKSRC1(INTOSC1). The CPU may be sourced from OSCCLKSRC2.

  • Thank You,

    I'll give it a try.

    Emil

  • Harman,

    Unfortunately this does not work.

    It seems the issue is with internal oscillator #2.

    Here's the code:

    SysCtrlRegs.CLKCTL.all = 0x6000; // XTAL off, XCLK off

     SysCtrlRegs.CLKCTL.all = 0x6002; // OSC2 internal

     SysCtrlRegs.CLKCTL.all = 0x6013; // OSC1 ->timer2 & cop, OSC2->clock

    This will work properly a few times.

    When it fails it fails right after I switch the clock to OSC2, the chip will reset after 42ms.

     

  • Emil:
    I thought when you reported this issue, you mentioned the following 2 cases:
    (Passing Condition): WDT resets the code every time when:
    OSC1 -> system clock and Watchdog
    OSC2-> timer2
    Line of code: SysCtrlRegs.CLKCTL.all = 0x601A;

    (Failing condition): WDT resets the code only a few times and then stops running when:
    OSC1 -> system clock
    OSC2 -> timer2 and the Watchdog
    Line of Code: SysCtrlRegs.CLKCTL.all = 0x601E;

    So now you are reporting the following:
    (Failing Condition): What happens in the failing condition here? It was not clear from the message above.
    OSC1 -> timer2 and Watchdog
    OSC2-> system clock
    Line of Code: SysCtrlRegs.CLKCTL.all = 0x6013;

    Please clarify as to what happens in the above condition.

  • Harman

    As orginally reported and verified by you and various Ti support groups the first two cases illustrated an issue.

    When implementing the workaround I discovered this issue.

    The similarity with the original is again OSC2, the cop would not run from OSC2 after a few cop resets originally.

    Now the cpu running off of OSC2 seems to not run after a few cop resets, it gets stuck resetting itself as soon as the cpu gets switched to OSC2.

    Has this workaround been tested and verified to work after multiple cop resets?

    Time permitting I'll come up with some test code to illustrate the issue.

  • Harman,

    You can recreate the issue by slightly modifying the test code we used in the past, I'll paste it in.

     

    #include "DSP28x_Project.h"     // Device Headerfile and Examples Include File

    void main(void)
    {
        volatile unsigned int x;

    // Step 1. Initialize System Control:
    // PLL, WatchDog, enable Peripheral Clocks
    // This example function is found in the DSP2802x_SysCtrl.c file.
       InitSysCtrl();

    // Step 3. Clear all interrupts and initialize PIE vector table:
    // Disable CPU interrupts
       DINT;

    // Initialize the PIE control registers to their default state.
    // The default state is all PIE interrupts disabled and flags
    // are cleared.
    // This function is found in the DSP2802x_PieCtrl.c file.
       InitPieCtrl();

    // Disable CPU interrupts and clear all CPU interrupt flags:
       IER = 0x0000;
       IFR = 0x0000;

    // Initialize the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    // This will populate the entire table, even if the interrupt
    // is not used in this example.  This is useful for debug purposes.
    // The shell ISR routines are found in DSP2802x_DefaultIsr.c.
    // This function is found in DSP2802x_PieVect.c.
       InitPieVectTable();

       for(x=60000;x;x--);                            // delay to show led

       EALLOW;
       GpioCtrlRegs.GPBMUX1.bit.GPIO34 = 0;
       GpioCtrlRegs.GPBDIR.bit.GPIO34 = 1;
      
    //-----------------------------------------------------------------------------------------------------------------------  
    /* PREVIOUS TESTING
    // 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
    */
    //-----------------------------------------------------------------------------------------------------------------------  
    // NEW ISSUE
        // below required when changing cpu from OSC1 to OSC2 w/o any xtal or xclock   
        SysCtrlRegs.CLKCTL.all = 0x6002;        // XTAL off, XCLK off, OSC2 internal
    // THIS LINE ALWAYS WORKS
    //    SysCtrlRegs.CLKCTL.all = 0x6012;        // OSC1 ->timer2 & cop & clock
    // THIS LINE ONLY ALLOWS TWO RESETS BEFORE RESETTING WHEN CHANGING CPU CLOCK TO OSC2   
        SysCtrlRegs.CLKCTL.all = 0x6013;        // OSC1 ->timer2 & cop, OSC2->clock
       
    // AFTER TWO RESETS THE CODE SEEMS TO RESET RIGHT AFTER THE GPIO WRITE BELOW
    // IT NEVER EXECUTES THE TWO TOGGLES
    // FOR ME IT ALWAYS RUNS CORRECTLY IN EITHER OF THE ABOVE CASES WITH THE JTAG XDS510 USB CONNECTED

    //-----------------------------------------------------------------------------------------------------------------------       
      
    // THIS DELAY LOOP RUNS CORRECTLY EVERY TIME, YOU CAN EVEN TAKE IT OUT.  
        for(x=10000;x;x--);  
       
        SysCtrlRegs.PCLKCR3.bit.GPIOINENCLK = 1;    // gpio clock
        GpioDataRegs.GPBCLEAR.bit.GPIO34 = 1;        // start low
    // SEEMS TO RESET RIGHT HERE AFTER THE SECOND TIME  WHEN CPU IS RUN OFF OF OSC2
           
        // reset watchdog   
        SysCtrlRegs.WDKEY = 0x0055;
        SysCtrlRegs.WDKEY = 0x00AA;
        // enable the watchdog, clear watchdog reset flag
        SysCtrlRegs.WDCR = 0x0028;
      
        EDIS;

        GpioDataRegs.GPBTOGGLE.bit.GPIO34 = 1;
        GpioDataRegs.GPBTOGGLE.bit.GPIO34 = 1;
                
        while(1);
    }

     

    From my testing the reset issue seems to somehow be related to a GPIO write.

    I have the code commented so you can recreate the problem.

    If you have any questions, please post them.

    Thanks,

    Emil

  • I'll look into this. Just for my clarification, you are saying that in the new failing condition, after two resets, the CPU just stays in reset when clocked from OSC2 or is the program counter just lost somewhere in the weeds?

  • The CPU does a reset and starts running from the start, it gets to where it's re-configured to OSC2 then right after a GPIO write, it resets and starts over again.

    It repeats this indefinitely.

    Thanks!

  • We have done some testing and potentially see the issue that you are reporting with OSC2 clocking the CPU or the Watchdog.

    The test code has been cleaned up and attached. Also attached is the Excel sheet explaining each of the test case. LED is on GPIO34 on our TI Target board (F28027 controlCARD).

    //
    // FILE:    Example_2802xFlash.c
    //
    // ASSUMPTIONS:
    //
    //    This program requires the DSP2802x header files.
    //
    //    As supplied, this project is configured for "boot to FLASH"
    //    operation.  The 2802x Boot Mode table is shown below.
    //    For information on configuring the boot mode of an eZdsp,
    //    please refer to the documentation included with the eZdsp,
    //
    //    $Boot_Table
    //    While an emulator is connected to your device, the TRSTn pin = 1,
    //    which sets the device into EMU_BOOT boot mode. In this mode, the
    //    peripheral boot modes are as follows:
    //
    //      Boot Mode:   EMU_KEY        EMU_BMODE
    //                   (0xD00)         (0xD01)
    //      ---------------------------------------
    //      Wait         !=0x55AA        X
    //      I/O          0x55AA          0x0000
    //      SCI          0x55AA          0x0001
    //      Wait         0x55AA          0x0002
    //      Get_Mode     0x55AA          0x0003
    //      SPI          0x55AA          0x0004
    //      I2C          0x55AA          0x0005
    //      OTP          0x55AA          0x0006
    //      Wait         0x55AA          0x0007
    //      Wait         0x55AA          0x0008
    //      SARAM        0x55AA          0x000A
    //      Flash        0x55AA          0x000B   <-- "Boot to Flash"
    //      Wait         0x55AA          Other
    //
    //   Write EMU_KEY to 0xD00 and EMU_BMODE to 0xD01 via the debugger
    //   according to the Boot Mode Table above. Build/Load project,
    //   Reset the device, and Run example
    //
    //   $End_Boot_Table
    //
    //    The program must first be compiled and then programmed into the
    //    flash.
    //
    //
    // DESCRIPTION:
    //
    
    #include "DSP28x_Project.h"     // Device Headerfile and Examples Include File
    
    void main(void)
    {
    	volatile unsigned int x;
    
    // Step 1. Initialize System Control:
    // PLL, WatchDog, enable Peripheral Clocks
    // This example function is found in the DSP2802x_SysCtrl.c file.
       InitSysCtrl();
    
    // Step 3. Clear all interrupts and initialize PIE vector table:
    // Disable CPU interrupts
       DINT;
    
    // Initialize the PIE control registers to their default state.
    // The default state is all PIE interrupts disabled and flags
    // are cleared.
    // This function is found in the DSP2802x_PieCtrl.c file.
       InitPieCtrl();
    
    // Disable CPU interrupts and clear all CPU interrupt flags:
       IER = 0x0000;
       IFR = 0x0000;
    
    // Initialize the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    // This will populate the entire table, even if the interrupt
    // is not used in this example.  This is useful for debug purposes.
    // The shell ISR routines are found in DSP2802x_DefaultIsr.c.
    // This function is found in DSP2802x_PieVect.c.
       InitPieVectTable();
    
       for(x=60000;x;x--);                            // delay to show led
    
       EALLOW;
       GpioCtrlRegs.GPBMUX1.bit.GPIO34 = 0;
       GpioCtrlRegs.GPBDIR.bit.GPIO34 = 1;	//LED turns on here
       
       //CASE 1: WDT = OSC1, CPU = OSC1, Timer = OSC1 (Bright LED blink - Success)
       SysCtrlRegs.CLKCTL.all = 0x6012;
       
       //CASE 2: WDT = OSC1, CPU = OSC1, Timer = OSC2 (Bright LED blink - Success)
       //SysCtrlRegs.CLKCTL.all = 0x601A; 
       
       //CASE 3: WDT = OSC2, CPU = OSC1, Timer = OSC2 (Bright LED blink ~2-3 times, then Stops at solid LED ON - Failure) 
       //SysCtrlRegs.CLKCTL.all = 0x601E;
    
       //CASE 4: WDT = OSC1, CPU = OSC2, Timer = OSC1 (Bright LED blink ~2-3 times, then dim LED blink - Failure) 
       // below required when changing cpu from OSC1 to OSC2 w/o any xtal or xclock
       //SysCtrlRegs.CLKCTL.all = 0x6002;        // XTAL off, XCLK off, OSC2 internal
       //SysCtrlRegs.CLKCTL.all = 0x6013;
        
       //CASE 5: WDT = OSC1, CPU = OSC2, Timer = OSC1 (Bright LED blink ~2-3 times, then dim LED blink - Failure) 
       // below required when changing cpu from OSC1 to OSC2 w/o any xtal or xclock
       //SysCtrlRegs.CLKCTL.all = 0x6002;        // XTAL off, XCLK off, OSC2 internal
       //SysCtrlRegs.CLKCTL.all = 0x6017;
         
        SysCtrlRegs.PCLKCR3.bit.GPIOINENCLK = 1;    // gpio clock          
    
        // reset watchdog    
        SysCtrlRegs.WDKEY = 0x0055;
        SysCtrlRegs.WDKEY = 0x00AA;
        // enable the watchdog, clear watchdog reset flag
        SysCtrlRegs.WDCR = 0x0028;
        EDIS;
                
        while(1);
    
    }
    
    


    0741.OSC2 failure chart.xls

    I will take this back to our product team and take a closer look at OSC2.

  • Thanks,

    May I suggest when they do come up with a workaround that they verify that it works correctly.

    It would save us a lot of work and also turnaround time.

    Emil

  • Emil,
    Here is the update that I received just now.
    We have found the cause and also a workaround for this issue. We will update our advisory on this next week, but this is what needs to be done:

    1. Run the Watchdog from OSC1 source and run the CPU from OSC2 source (on chip OSC or external, doesn't matter). You cannot run the Watchdog from OSC2 source.

    2. When you need to switch clocks to OSC2 Source, you need to pulse the XCLKINOFF and XTALOSCOFF bits a couple of times to unfreeze the mechanism that is causing the issue:

    XTALOSCOFF = 1, XCLKINOFF=1

    XTALOSCOFF = 0, XCLKINOFF=0

    XTALOSCOFF = 1, XCLKINOFF=1

    XTALOSCOFF = 0, XCLKINOFF=0

    XTALOSCOFF = 1, XCLKINOFF=1

    Now perform the clock switch and it should work every time.

    Let us know if the above fixes the problem.

  • Harman,

    This works!
    Here's what I implemented:

            // Internal Oscillator 1 for timer2 and cop, 2 as Clock Source
            SysCtrlRegs.CLKCTL.all = 0x6002;                // XTAL off, XCLK off, OSC2 internal
            SysCtrlRegs.CLKCTL.all = 0x0002;                // multiple set/unset to unfreeze
            SysCtrlRegs.CLKCTL.all = 0x6002;                //
            SysCtrlRegs.CLKCTL.all = 0x0002;                //
            SysCtrlRegs.CLKCTL.all = 0x6002;                //
            SysCtrlRegs.CLKCTL.all = 0x6013;                // OSC1 ->timer2 & cop, OSC2->clock

    Thank you so much.

    Emil

     

    (Tried to respond yesterday but for some reason the e-mail didn't get delivered, I didn't realize it till today)