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.

TMS320F2806 Timer0 not running

Other Parts Discussed in Thread: CONTROLSUITE

I have tried everything I can thing of but this simple step of setting an 80 millisecond timer is absolutely stumping me.  I got the ADC and IQmathLib stuff all working (except my timer never stopped, so my running DFT's were not finishing...

I started with the simple configure timer and start timer functions from the examples, but the timer never ran, so I started loading registers by hand.  I have stripped the code down to nothing and I am still absolutely perplexed. 

The project is a clean slate.  The board is proprietary but fully functional.  20MHz clock in and 100 MHz system clock.  I am using CCS5.3, c2000 compiler 6.1.  I have tried hardware reboot, XDS510USB reboot, closing CCS, ...

Looking at the watch windows, I see that TIM.all and TIM.half.xxx are completely unrelated.

CpuTimer0Regs.TCR.bit.TIF  0 

 CpuTimer0Regs.TCR.bit.TSS  0

CpuTimer0Regs.TIM.half.LSW 4608

CpuTimer0Regs.TIM.half.MSW 122 

 CpuTimer0Regs.TIM.all  8000000 

 

 

Code - pretty much all of it at that...

No matter how many times I run the 1000 increment loop none of the clock variables change in the watch window and TIF never sets. 

 

 

 

#include "DSP280x_Device.h"    

#define PLLCR_VALUE  0x000A     // SYSCLKOUT = (OSCLK*10)/2

int main(void)

 {

        int i;

        if (SysCtrlRegs.PLLSTS.bit.MCLKSTS != 1)   {.../*standard PLL stuff*/}

        //InitCpuTimers();   

        // Initialize timer control register:

        CpuTimer0Regs.TCR.bit.TSS = 1;      // 1 = Stop timer, 0 = Start/Restart Timer

        CpuTimer0Regs.PRD.all  = 0xFFFFFFFF; // why?

        CpuTimer0Regs.TCR.bit.TRB = 1;      // 1 = reload timer

        CpuTimer0Regs.TCR.bit.TIE = 0;      // 0 = Disable/ 1 = Enable Timer Interrupt

        CpuTimer0Regs.TCR.bit.SOFT = 1;

        CpuTimer0Regs.TCR.bit.FREE = 1;     // Timer Free Run

        CpuTimer0Regs.TCR.bit.TIF = 0;      // Clear Timer Interrupt Flag

        // Set pre-scale counter to divide by 1 (SYSCLKOUT):

       CpuTimer0Regs.TPR.all  = 0;

        CpuTimer0Regs.TPRH.all  = 0;

        // Initialize timer period in ticks at 100 MHz

        CpuTimer0Regs.PRD.all  = (long) (100 * 80000);

        //CpuTimer0Regs.TIM.all = CpuTimer0Regs.PRD.all;

        // Reload all counter register with period value:

        CpuTimer0Regs.TCR.bit.TSS = 0;      // 1 = Stop timer, 0 = Start/Restart Timer

        CpuTimer0Regs.TCR.bit.TRB = 1;

        while (!CpuTimer0Regs.TCR.bit.TIF)

       {

           for (i=0;i<1000;i++);

           i--; // just to keep a line for a breakpoint

        }

       return 0;

}

  • Hi,

    Did you try implementing the timer example available in controlSuite first? What was your observation?

    Regards,

    Gautam

  • No.  First, this is part of a much broader project.  By this, you seem to suggest that I should use yet another layer of software abstraction to test if this works.  But a timer is about as simple as mcu hw gets.  The standard 280x_cputimers driver works in other apps (other developer, ccs3.3, source code not available right now) on the same board. 

     Second, I tried the simple device examples, although admittedly I have not yet backed all the way off to simply running the example project itself.  These are used in the final app that I am writing a new module for...   I would do that before trying yet another set of drivers.  

    It seems to me that if the PLL locks, there is SYSCLK, and if i appear to be following what resolved previous issues, there is no value in this test.  Is there a reason you suggest it?

    thanks.

  • Jeff,

    Can you describe what you mean by "not running"? Are you able to modify the CPUTimer0 Control Registers? Are all of the settings going throigh, but it just never triggers?

    In your code, you have this line:

      if (SysCtrlRegs.PLLSTS.bit.MCLKSTS != 1)   {.../*standard PLL stuff*/}

    I am curious if you have enabled the clock to the Cputimer0 module inside of  the highlighted brakcets. If you look In the Example_2806xCpuTimer.c  file inside of Control suite. There is a call to the InitSysCtrl() function which then calls InitPeripheralClocks() which enables the clock to the module. The clock to cputimer0 can be enabled with this code:

    EALLOW;

    SysCtrlRegs.PCLKCR3.bit.CPUTIMER0ENCLK = 1; // CPU Timer 0

    EDIS;

    You said that you started with a larger example and took things out trying to make it work. Since you have pulled the PLL Initialization into your main you may have missed the clock enable code.

    Please let me know if this helps.

    Thanks, 

    Mark

  • Mark,

    Yes I mean that the clock registers can be set but the TSS start does not being decrementing the counter. 

    I looked for that last night, feeling sure there was something like that.  You have nailed the missing setting, alas in the files I am working from it is MISSING.  DSP280x_SysCtrl.h from the file set I am working with does not have this field.  InitPeripheralClocks also does not set it in the DSP280x_SysCtrl.c source.  I guess I need to look at a better set of headers!

    I'll go look for newer heards and drivers.  Unfortunately when I send my snippet back for integration into the main code, it might cause problems...  But, if my snippet works, integration is someone else's problem.

     

    Thanks!

     

     (Headers and drivers from this source

    Thank you for trying C28x Software Collateral.

    V1.70 of the C280x/C2801x C/C++ Header Files and Peripheral

    By default, the software will be installed in the

    following directory:

       C:\tidcs\c28\dsp280x\v170

     

    C2000 APPLICATIONS.

    Texas Instruments Incorporated

    )

    //---------------------------------------------------------------------------
    // System Control Register File:
    //
    struct SYS_CTRL_REGS {
       union   XCLK_REG    XCLK;      // 0
       union   PLLSTS_REG  PLLSTS;    // 1
       Uint16              rsvd1[8];  // 2-9
       union   HISPCP_REG  HISPCP;    // 10: High-speed peripheral clock pre-scaler
       union   LOSPCP_REG  LOSPCP;    // 11: Low-speed peripheral clock pre-scaler
       union   PCLKCR0_REG PCLKCR0;   // 12: Peripheral clock control register
       union   PCLKCR1_REG PCLKCR1;   // 13: Peripheral clock control register
       union   LPMCR0_REG  LPMCR0;    // 14: Low-power mode control register 0
       Uint16              rsvd2;     // 15: reserved
       Uint16              rsvd3;     // 16: reserved
       union   PLLCR_REG   PLLCR;     // 17: PLL control register
       // No bit definitions are defined for SCSR because
       // a read-modify-write instruction can clear the WDOVERRIDE bit
       Uint16              SCSR;      // 18: System control and status register
       Uint16              WDCNTR;    // 19: WD counter register
       Uint16              rsvd4;     // 20
       Uint16              WDKEY;     // 21: WD reset key register
       Uint16              rsvd5[3];  // 22-24
       // No bit definitions are defined for WDCR because
       // the proper value must be written to the WDCHK field
       // whenever writing to this register.
       Uint16              WDCR;      // 25: WD timer control register
       Uint16              rsvd6[6];  // 26-31
    };
    

     

     

     
     
     
    void InitPeripheralClocks(void)
    {
       EALLOW;
    
    // HISPCP/LOSPCP prescale register settings, normally it will be set to default values
       SysCtrlRegs.HISPCP.all = 0x0001;
       SysCtrlRegs.LOSPCP.all = 0x0002;
    
    // XCLKOUT to SYSCLKOUT ratio.  By default XCLKOUT = 1/4 SYSCLKOUT
       SysCtrlRegs.XCLK.bit.XCLKOUTDIV=2;
    
    // Peripheral clock enables set for the selected peripherals.
    // If you are not using a peripheral leave the clock off
    // to save on power.
    //
    // Note: not all peripherals are available on all 280x derivates.
    // Refer to the datasheet for your particular device.
    //
    // This function is not written to be an example of efficient code.
    
       SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1;    // ADC
       SysCtrlRegs.PCLKCR0.bit.I2CAENCLK = 1;   // I2C
       SysCtrlRegs.PCLKCR1.bit.ECAP1ENCLK = 1;  // eCAP1
       SysCtrlRegs.PCLKCR1.bit.ECAP2ENCLK = 1;  // eCAP2
       SysCtrlRegs.PCLKCR1.bit.EPWM1ENCLK = 1;  // ePWM1
       SysCtrlRegs.PCLKCR1.bit.EPWM2ENCLK = 1;  // ePWM2
       SysCtrlRegs.PCLKCR1.bit.EPWM3ENCLK = 1;  // ePWM3
       SysCtrlRegs.PCLKCR0.bit.SCIAENCLK = 1;   // SCI-A
       SysCtrlRegs.PCLKCR0.bit.SPIAENCLK = 1;   // SPI-A
    
       if(DevEmuRegs.PARTID.bit.PARTNO != PARTNO_28015 &&
          DevEmuRegs.PARTID.bit.PARTNO != PARTNO_28016)
       {
          SysCtrlRegs.PCLKCR1.bit.EQEP1ENCLK = 1;  // eQEP1
          SysCtrlRegs.PCLKCR0.bit.SPIBENCLK = 1;   // SPI-B
       }
    
       if(DevEmuRegs.PARTID.bit.PARTNO != PARTNO_2801 &&
          DevEmuRegs.PARTID.bit.PARTNO != PARTNO_2802)
       {
    	   SysCtrlRegs.PCLKCR1.bit.EPWM4ENCLK = 1;  // ePWM4
       }
    
       if(DevEmuRegs.PARTID.bit.PARTNO != PARTNO_28015)
       {
          SysCtrlRegs.PCLKCR0.bit.ECANAENCLK=1;    // eCAN-A
       }
    
       if(DevEmuRegs.PARTID.bit.PARTNO == PARTNO_2809 ||
          DevEmuRegs.PARTID.bit.PARTNO == PARTNO_2808 ||
          DevEmuRegs.PARTID.bit.PARTNO == PARTNO_2806 )
       {
    	   SysCtrlRegs.PCLKCR1.bit.ECAP3ENCLK = 1;  // eCAP3
    	   SysCtrlRegs.PCLKCR1.bit.ECAP4ENCLK = 1;  // eCAP4
    	   SysCtrlRegs.PCLKCR1.bit.EPWM5ENCLK = 1;  // ePWM5
    	   SysCtrlRegs.PCLKCR1.bit.EPWM6ENCLK = 1;  // ePWM6
    	   SysCtrlRegs.PCLKCR0.bit.SCIBENCLK = 1;   // SCI-B
    	   SysCtrlRegs.PCLKCR0.bit.SPICENCLK = 1;   // SPI-C
    	   SysCtrlRegs.PCLKCR0.bit.SPIDENCLK = 1;   // SPI-D
    	   SysCtrlRegs.PCLKCR1.bit.EQEP2ENCLK = 1;  // eQEP2
    
       }
       if(DevEmuRegs.PARTID.bit.PARTNO == PARTNO_2808 ||
          DevEmuRegs.PARTID.bit.PARTNO == PARTNO_2809)
       {
    	   SysCtrlRegs.PCLKCR0.bit.ECANBENCLK=1;    // eCAN-B
       }
    
       SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;       // Enable TBCLK within the ePWM
    
       EDIS;
    }
    

     

     

  • Jeff,

    Can you please clarify for me which device you are using?

    http://www.ti.com/product/tms320f2806 Digital Signal Controller (F280x devices)

    or

    http://www.ti.com/product/tms320f28069 Piccolo Device (F28806x devices)

    I may have misinterpreted which you are using.

     

    Thanks,

    Mark

  • Mark,

     

    TMS3202806 (board can take 2808 or 2809 but has 2806 on it) C2000 fixed point DSP...

     

    Thanks!

  • Thanks, that is what I thought. I originally gave you information for the F2806x device. please disregard that information.

    Looking through the code that you have posted, in line 18 please write a 1 to the TIF bit to clear the flag, as all writes of 0 are ignored to the TIF bit.(per page 61 of spru712h.pdf)

            CpuTimer0Regs.TCR.bit.TIF = 1;      // Clear Timer Interrupt Flag
     
    Also I would swap lines 28 and 29. You want to reload your period before you start the timer again.
     
    If this does not work, please try Running the cpu_timer example that was provided with th headers and let me know if that example works. You should just be able to import the project into CCS, build it, then run it without any modification. The example uses interrupts, but it will give us a base of whether or not the Timer is working in the first place. The project should be located here:
    C:\tidcs\c28\DSP280x\v170\DSP280x_examples_ccsv4\cpu_timer
     
    Thanks,
    Mark
  • Mark,

     

    It looks like I need to take an educational detour... I imported the example and eliminated references to XDAIS (not on my system).  It compiles but when I go to debug I get this error.  I now get it in all my projects (before I imported).  I assume I need to make sure the cmd files are all present and all for this chip?

     

    C28xx: Loader: One or more sections of your program falls into a memory region that is not writable.  These regions will not actually be written to the target.  Check your linker configuration and/or memory map.

    C28xx: AutoRun: Target not run as breakpoint could not be set: Error programming AET Job: ANA_ENABLE Register write failed

  • Mark,

     

    I did not have the file, DSP280x_Headers_nonBIOS.cmd, included so I may have been editing a structure, but apparently it was not the device register file.

    My only annoyance is that the timer state progresses while I am on a breakpoint.  Even setting FREE to 0, it appears runs to completion.  My experience is with Microchip parts and the peripherals can be set to pause during breakpoints.  Can I do that here?

  • Jeff,

    Yes, the DSP280x_Headers_nonBIOS.cmd is a pretty important file :).

    If you look at bit description for the TIMERxCTR register decriptions for the FREE and SOFT bits, Both need to be set to 0 for the timer to stop at the breakpoint. Just setting FREE to 0 will let the Timer run to completion to stop (soft stop mode)

     

    Here is the link in case the picture is too small: http://www.ti.com/litv/pdf/spru712h. (page 61)

    Thanls,

    Mark

  • does it resume when I resume from the breakpoint?  I guess I misread that.

     

    In any case, I have moved on to ADC code that I had working and now is not...  I am sure it's another cmd file conflict, but I just got pulled of the R&D to troubleshoot a different problem.

     

    Thanks again.