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.

TMS320F28P650DK: How do I set the timer period to 100ns?

Part Number: TMS320F28P650DK

Tool/software:

Hello everyone,


how can I change the timer period to get a timer interrupt every 100ns?

Unfortunately I can only set a minimum of 2us.

My current code:

//#############################################################################
//
// FILE:   timer_ex1_cputimers.c

//
// Included Files
//
#include "driverlib.h"
#include "device.h"

//
// Function Prototypes
//
__interrupt void cpuTimer0ISR(void);
void initCPUTimers(void);
void configCPUTimer(uint32_t, float, float);

//
// Main
//
void main(void)
{
    //
    // Initializes device clock and peripherals
    //
    Device_init();

    Device_initGPIO();

    //
    // Initializes PIE and clears PIE registers. Disables CPU interrupts.
    //
    Interrupt_initModule();

    //
    // Initializes the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    //
    Interrupt_initVectorTable();

    //
    // ISRs for each CPU Timer interrupt
    //
    Interrupt_register(INT_TIMER0, &cpuTimer0ISR);

    //
    // Initializes the Device Peripheral. For this example, only initialize the
    // Cpu Timers.
    //
    initCPUTimers();

    //
    // Configure CPU-Timer 0 to interrupt every ... seconds:
    // 1 Period respectively (in uSeconds)
    //
    configCPUTimer(CPUTIMER0_BASE, DEVICE_SYSCLK_FREQ, 0.2);

    //
    // 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, the below settings must also
    // be updated.
    //
    CPUTimer_enableInterrupt(CPUTIMER0_BASE);

    //
    // Enables CPU int1 which are connected to CPU-Timer 0, respectively.
    // Enable TINT0 in the PIE: Group 1 interrupt 7
    //
    Interrupt_enable(INT_TIMER0);

    //
    // Starts CPU-Timer 0.
    //
    CPUTimer_startTimer(CPUTIMER0_BASE);

    //
    // Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
    //
    EINT;
    ERTM;

    GPIO_writePin(0, 1);
    GPIO_setPinConfig(GPIO_0_GPIO0);
    GPIO_setDirectionMode(0, GPIO_DIR_MODE_OUT);

    //
    // IDLE loop. Just sit and loop forever (optional)
    //
    while (1)
    {
    }
}

//
// initCPUTimers - This function initializes all three CPU timers
// to a known state.
//
void initCPUTimers(void)
{
    //
    // Initialize timer period to maximum
    //
    CPUTimer_setPeriod(CPUTIMER0_BASE, 0xFFFFFFFF);

    //
    // Initialize pre-scale counter to divide by 1 (SYSCLKOUT)
    //
    CPUTimer_setPreScaler(CPUTIMER0_BASE, 0);

    //
    // Make sure timer is stopped
    //
    CPUTimer_stopTimer(CPUTIMER0_BASE);

    //
    // Reload all counter register with period value
    //
    CPUTimer_reloadTimerCounter(CPUTIMER0_BASE);


}

//
// configCPUTimer - This function initializes the selected timer to the
// period specified by the "freq" and "period" parameters. The "freq" is
// entered as Hz and the period in uSeconds. The timer is held in the stopped
// state after configuration.
//
void configCPUTimer(uint32_t cpuTimer, float freq, float period)
{
    uint32_t temp;

    //
    // Initialize timer period:
    //
    temp = (uint32_t) ((freq / 1000000) * period);
    CPUTimer_setPeriod(cpuTimer, temp - 1);

    //
    // Set pre-scale counter to divide by 1 (SYSCLKOUT):
    //
    CPUTimer_setPreScaler(cpuTimer, 0);

    //
    // Initializes timer control register. The timer is stopped, reloaded,
    // free run disabled, and interrupt enabled.
    // Additionally, the free and soft bits are set
    //
    CPUTimer_stopTimer(cpuTimer);
    CPUTimer_reloadTimerCounter(cpuTimer);
    CPUTimer_setEmulationMode(cpuTimer,
                              CPUTIMER_EMULATIONMODE_STOPAFTERNEXTDECREMENT);
    CPUTimer_enableInterrupt(cpuTimer);

}

//
// cpuTimer0ISR
//
__interrupt void cpuTimer0ISR(void)
{
    GPIO_writePin(0, 1);
    GPIO_writePin(0, 0);

    //
    // Acknowledge this interrupt to receive more interrupts from group 1
    //
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP1);
}



//
// End of File
//


Kind regards

  • Hello,

    That frequency should be possible with the CPU timer module on this device. 

    If you call the configCPUTimer() function and pass in a period value of 0.2 (like you have shown), this will result in an interrupt every 0.2 us:

    0.0000002 us = 0.0002 ms = 0.2 us = 200 ns

    To achieve a CPU timer interrupt every 100 ns, you should pass 0.1 into the configCPUTimer() function. Let me know if you run into any issues when passing this value in. It would be best to verify the achieved frequency on a scope using a GPIO that gets toggled in every CPU timer ISR.

    Best Regards,

    Delaney

  • Unfortunately it doesn't work if I specify a smaller period. Suddenly I no longer measure a signal

  • Hello,

    I apologize for the delay. If you step through the configuration code using a value of 0.1 passed in, do you see the CPU timer registers being written to the correct values in the Expressions view? Can you also try putting a breakpoint in the ISR and seeing if the CCS debugger ever hits it?

    Best Regards,

    Delaney

  • Hi,
    In which register should which value be? (Unfortunately I clicked on "This resolved my issue" by mistake)

  • Hello,

    For a 100ns period and SYSCLK of 200MHz:

    -The SYSCLK will tick every 5ns = 5 x (10^-9) seconds

    -A period of 20 SYSCLK ticks would be needed to achieve an interrupt every 200ns since 100ns/5ns = 20

    So, you can verify that the PRD register is being written with the value 20 (the LSW should be 0x14 and the MSW should be 0x00. If you see different values, please attach a screenshot of all the Timer counter register values.

    Best Regards,

    Delaney