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.

F28335, CPU Timer , Change time period during run time

Other Parts Discussed in Thread: TMS320F28335, CONTROLSUITE

Dear all,

I am using the TMS320F28335 Delfino Experimental kit.

I am using the CPU timer0 for generating 100us interrupt. I simply used the
command ConfigCpuTimer(&CpuTimer0, 150, 100);  all working fine.

Now I want to change the Period of the timer depending upon the input
frequency of my signal. I was using PWM earlier but my application requires me
to use all the 6 PWM as a result I have to use to CPU Timer0 for the 100us and
also generate a trigger for SOC of ADC signals.

I tried ConfigCpuTimer(&CpuTimer0, 150, Timer_Duration); and update the
Timer_Duration value but it doesn't work.

I also tried CpuTimer0.PeriodInUSec= Timer_Duration; then called the
ConfigCpuTimer,

I read the SPRUFB0D and tried the following, but didn't know what value to
put in the PRD register for a period in us.

CpuTimer0Regs.TCR.bit.TRB=1; 

CpuTimer0Regs.PRD.all=0x3A98; // Value observed in the Register for a period of 100us

Can you point me in the right direction?

What is the sequence of commands to be used for continuously changing the period of the CPU timer0, during run time?

Best Regards,

Pankaj

  • Hi Pankaj,

    What is the sequence of commands to be used for continuously changing the period of the CPU timer0, during run time?

    I guess the above won't be possible (I've not tried it personally though). Here are the steps for configuring normal timer interrupt:

    EALLOW;  
    PieVectTable.TINT0 = &cpu_timer0_isr;
    EDIS; 
    
    InitCpuTimers(); 
    
    ConfigCpuTimer(&CpuTimer0, 150, 1000000);
    
    CpuTimer0Regs.TCR.all = 0x4001;
    IER |= M_INT1;
    PieCtrlRegs.PIEIER1.bit.INTx7 = 1;
    EINT;   // Enable Global interrupt INTM
    ERTM;   // Enable Global realtime interrupt DBGM

    So changing the timer value, is not as simple as modifying the value in ConfigCpuTimer function.

    Regards,

    Gautam

  • Hello Pankaj,

    Here's what you need to do:

    CpuTimerX.RegsAddr->PRD.all = Period.

    X = 0,1 or 2

    The period will be Period/150e6 seconds, i.e. Period = 150 is 1us (assuming you are using a uP clock frequency of 150MHz.

    Stephen

  • Dear Stephen,

    Yes I am using a clock frequency of 150Mhz.

    I actually did something different to what you suggested.

    I tried 150M/10K =15000, //10K for 100us period then convert 15000 to hex 3A98 and load it into PRD.

    But in the end I am using ConfigCpuTimer, as its simpler.

    For anyone's future reference the code is as below and the sequence of command is really important too.

    My code in the ISR is as follows

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


    ConfigCpuTimer(&CpuTimer0, 150, 150); // Period = 150Us


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


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


    CpuTimer0Regs.TCR.all = 0x4001; // TIE=1 The CPU-Timer interrupt is enabled, TSS = 0 = Start/Restart Timer

    Thank you

    Best Regards,

    Pankaj

  • Great work, Pankaj!

  • HI Gautam/Pankaj

    Can You please help me understand that when we are changing the period from 1us to 150us or to 400us or 500ms or what ever value,Are we also changing the value in PRD register in configCpuTimer also???

    From what I understood from the program the PRD register is loaded with a value temp = Freq * Period.But what Pankaj is telling 150M/10K I did not get it..

    Say I want a period of 200us,then temp = 150M*200us = 30K so now what id the value with which PRD register should be loaded 7530 h??

    Thanks

    Sneha

  • HI Pankaj

    Thanks for the reply.

    I have control suite installed and I know the easiest method is by using PWM. But I have asked to start from scratch and not use these inbuilt advantages.

    I have already referred multiday workshop slides.

    I just want to know How do we adjust the Timer period of CPU timer interrupts and adjust the SYSCLOCK output.When we are doing it with PWM we have the option of TBRD register in PWM. But what without it?

    Thanks

    Sneha

    ........................................................................................................................................................................................

    Dear Sneha,

    If you don't want to use any of the features and just use basic commands then you can toggle a GPIO pin and add a "for loop" (or a NOP or similar) for the required time period. This will generate a pwm signal.

    I suggested you to have a look and understand example in the ControlSuite as there are valuable comments which explain everything.

    I understand in the beginning it seem difficult to understand (For my project I started from scratch too, to reduce the program size!!) but try using the  step-wise execution to see how the program flows. It will show you how the SYSCLOCK frequency is set, etc. You need to take it slowly and understand the basic, then the fun part begins.

    Like how to change CPU interrupt time. There is an initialisation part in which you write the interrupt time in usec(microseconds), updating the value in that location you change the time for the CPU interrupt.

     

    Best Regards,

    Pankaj Kadam

  • Hi Pankaj

    Thanks for the suggestions.I understood what you are trying to say.I am working in that direction only.

    I am attaching here a text document for a program to generate pulse using CPUtimers.

    5670.cpu_timer_pulse.txt
    //###########################################################################
    //
    // FILE:    Example_2833xLedBlink.c
    //
    // TITLE:   DSP2833x eZdsp LED Blink Getting Started Program.
    //
    // ASSUMPTIONS:
    //
    //    This program requires the DSP2833x header files.
    //
    //
    //    As supplied, this project is configured for "boot to SARAM"
    //    operation.  The 2833x 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:
    //
    //         GPIO87   GPIO86     GPIO85   GPIO84
    //          XA15     XA14       XA13     XA12
    //           PU       PU         PU       PU
    //        ==========================================
    //            1        1          1        1    Jump to Flash
    //            1        1          1        0    SCI-A boot
    //            1        1          0        1    SPI-A boot
    //            1        1          0        0    I2C-A boot
    //            1        0          1        1    eCAN-A boot
    //            1        0          1        0    McBSP-A boot
    //            1        0          0        1    Jump to XINTF x16
    //            1        0          0        0    Jump to XINTF x32
    //            0        1          1        1    Jump to OTP
    //            0        1          1        0    Parallel GPIO I/O boot
    //            0        1          0        1    Parallel XINTF boot
    //            0        1          0        0    Jump to SARAM	    <- "boot to SARAM"
    //            0        0          1        1    Branch to check boot mode
    //            0        0          1        0    Boot to flash, bypass ADC cal
    //            0        0          0        1    Boot to SARAM, bypass ADC cal
    //            0        0          0        0    Boot to SCI-A, bypass ADC cal
    //                                              Boot_Table_End$
    //
    // DESCRIPTION:
    //
    //    This example configures CPU Timer0 for a period, and sets and clears the GPIO31
    //    LED on the 2833x eZdsp once per interrupt. For testing purposes, this example
    //    also increments a counter each time the timer asserts an interrupt.
    //
    //       Watch Variables:
    //          CpuTimer0.InterruptCount
    //
    //       Monitor the GPIO31 LED blink on (for GPASET) and off (for GPACLEAR) on the 2833x eZdsp.
    //
    //###########################################################################
    // $TI Release: 2833x/2823x Header Files and Peripheral Examples V133 $
    // $Release Date: June 8, 2012 $
    //###########################################################################
    
    #include "DSP28x_Project.h"     // Device Headerfile and Examples Include File
    #include <math.h>
    // Prototype statements for functions found within this file.
    interrupt void cpu_timer0_isr(void);
    float d,t;
    
    void main(void)
    {
    
    // Step 1. Initialize System Control:
    // PLL, WatchDog, enable Peripheral Clocks
    // This example function is found in the DSP2833x_SysCtrl.c file.
       InitSysCtrl();
    
    // Step 2. Initalize GPIO:
    // This example function is found in the DSP2833x_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 DSP2833x_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 DSP2833x_DefaultIsr.c.
    // This function is found in DSP2833x_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.TINT0 = &cpu_timer0_isr;
    
       EDIS;    // This is needed to disable write to EALLOW protected registers
    
    // Step 4. Initialize the Device Peripheral. This function can be
    //         found in DSP2833x_CpuTimers.c
       InitCpuTimers();   // For this example, only initialize the Cpu Timers
    
    #if (CPU_FRQ_150MHZ)
    // Configure CPU-Timer 0 to interrupt every 1s:
    // 150MHz CPU Freq, Period is in uSeconds
       ConfigCpuTimer(&CpuTimer0, 150, 1000000);
    
    #endif
    
    // To ensure precise timing, use write-only instructions to write to the entire register. Therefore, if any
    // of the configuration bits are changed in ConfigCpuTimer and InitCpuTimers (in DSP2833x_CpuTimers.h), the
    // below settings must also be updated.
    
       CpuTimer0Regs.TCR.all = 0x4001; // Use write-only instruction to set TSS bit = 0
    
    // Step 5. User specific code, enable interrupts:
    
    // Configure GPIO32 as a GPIO output pin
       EALLOW;
       GpioCtrlRegs.GPAMUX2.bit.GPIO31 = 0;
       GpioCtrlRegs.GPADIR.bit.GPIO31 = 1;
         EDIS;
    
    // Enable CPU INT1 which is connected to CPU-Timer 0:
       IER |= M_INT1;
    
    
    // Enable TINT0 in the PIE: Group 1 interrupt 7
       PieCtrlRegs.PIEIER1.bit.INTx7 = 1;
    
    // 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):
    for(;;);
    }
    
    void delay_loop()
    {
       volatile long i;
      for (i = 0; i <= t; i++) {}
    
    }
    
    		interrupt void cpu_timer0_isr(void)
    		{
    			CpuTimer0.InterruptCount++;
    			   GpioDataRegs.GPADAT.bit.GPIO31 = 1; // Sets the GPIO31 to high once per interrupt for the time t provided by delay loop.
    			   delay_loop();
    			  GpioDataRegs.GPADAT.bit.GPIO31 = 0;// clears the GPIO31 to low once per interrupt after delay loop is over and stays there till interrupt is encountered again.
    
    			   PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;// Acknowledge this interrupt to receive more interrupts from group 1
    
    		}
    
    	//===========================================================================
    // No more.
    //===========================================================================
    

    Can you please suggest how can I set the variable 't' in the delay loop in microseconds? Untill and unless this varibale 't' is not in the same scale as that of CPUtimer interrupt period ,I would not get the correct turn-on time for my pulse.

    Waiting for your reply.

    Thanks

    Sneha