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.

CCS/TMS320F28377S: Delay function for TMS320F28377S

Part Number: TMS320F28377S

Tool/software: Code Composer Studio

Hello,

 There is a delay function in my code, where the smallest step is just one microsecond.Could you Please tell me, how will i define my own delay function for smaller steps.


// Included Files
//
#include "F28x_Project.h"

//
// Defines
//

#define BLINKY_LED_GPIO 12

interrupt void xint1_isr(void);


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

//
// Step 2. Initialize GPIO:
// This example function is found in the F2837xS_Gpio.c file and
// illustrates how to set the GPIO to it's default state.
//
InitGpio();
GPIO_SetupPinMux(BLINKY_LED_GPIO, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(BLINKY_LED_GPIO, GPIO_OUTPUT, GPIO_PUSHPULL);

//
// 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 F2837xS_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 F2837xS_DefaultIsr.c.
// This function is found in F2837xS_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.XINT1_INT = &xint1_isr;
EDIS; // This is needed to disable write to EALLOW protected registers

//


//
// Enable XINT1 and XINT2 in the PIE: Group 1 interrupt 4 & 5
// Enable INT1 which is connected to WAKEINT:
//
PieCtrlRegs.PIECTRL.bit.ENPIE = 1; // Enable the PIE block
PieCtrlRegs.PIEIER1.bit.INTx4 = 1; // Enable PIE Group 1 INT4
PieCtrlRegs.PIEIER1.bit.INTx5 = 1; // Enable PIE Group 1 INT5
IER |= M_INT1; // Enable CPU INT1
EINT; // Enable Global Interrupts

// GPIO14 is inputs
//
EALLOW;
GpioCtrlRegs.GPAMUX1.bit.GPIO14 = 0; // GPIO
GpioCtrlRegs.GPADIR.bit.GPIO14 = 0; // input
GpioCtrlRegs.GPAQSEL1.bit.GPIO14 = 0; // XINT1 Synch to SYSCLKOUT only

EDIS;

//
// GPIO14 is XINT1
//
GPIO_SetupXINT1Gpio(14);

//
// Configure XINT1
//
XintRegs.XINT1CR.bit.POLARITY = 1; // Raising edge interrupt 1
//Falling edge interrupt 0

//
// Enable XINT1
//
XintRegs.XINT1CR.bit.ENABLE = 1; // Enable XINT1

//
//
// 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(;;)
{


}
}

//
// My intrr
//
// xint1_isr - External Interrupt 1 ISR
//

interrupt void xint1_isr(void)

{

//
// Turn on LED
//
GPIO_WritePin(BLINKY_LED_GPIO, 0);

//
// Delay for a bit.
//
DELAY_US(1000*500);

//
// Turn off LED
//
GPIO_WritePin(BLINKY_LED_GPIO, 1);

//
// Delay for a bit.
//
DELAY_US(1000*500);

// Turn on LED
//
GPIO_WritePin(BLINKY_LED_GPIO, 0);

//
// Delay for a bit.
//
DELAY_US(1000*500);

//
// Turn off LED
//
GPIO_WritePin(BLINKY_LED_GPIO, 1);

//
// Delay for a bit.
//
DELAY_US(1000*500);

//

// Acknowledge this interrupt to get more from group 1
//
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;

}
//
// End of file
//

  • Hello,

    Your options depend on how small you want the delay to be. If you're looking to delay for just a few cycles you can use __asm(" NOP) to add a NOP instruction to the code.

    For several repeated NOPs you can use the RPT instruction like __asm(" RPT #100 || NOP"). You'll want to keep in mind that repeat isn't interruptible though.

    Or you can study the DELAY_US() macro in the F2837xS_Example.h file and tweak it to make it work on a smaller unit of time. The current equation is something like this: ((A us * 1000 ns/us) / CPU_RATE ns/cycle) - 9 cycles) / 5 cycles/loop. The 9 and the 5 have to to stay the same because of the nature of the F28x_usDelay() function, but you could adjust some of the other variables.

    Whitney
  • Thank you so much Whitney. I got the delay in ns by changing variable in the following equation.(A us * 1000 ns/us) / CPU_RATE ns/cycle) - 9 cycles) / 5 cycles/loop.
  • Hello,

     Could you please tell me from where can i change the CPU Rate. And Could you please tell me the values to put in the following equation(A us * 1000 ns/us) / CPU_RATE ns/cycle) - 9 cycles) / 5 cycles/loop) to get 5ns delay.I am working on 200MHZ and I need delay of 5ns (nano second).  

  • Hello,

    The F28x_usDelay() function at the core of that macro takes 5 cycles per loop with 9 cycles of overhead. Given that 5ns is a single cycle, you're not going to be able to use the macro even if you change it. Use a NOP instruction instead.

    Whitney

  • Hello,
    I am using this Instruction __asm(" RPT #100 || NOP"). I also changed the value of 100 (from 0 to 120),But the least delay i am getting is 500ns. Is there any problem with frequency?
  • __asm(" RPT #100 || NOP") is 100 NOPs. It makes sense that you'd be seeing a 100 * 5ns delay. You can use a single __asm(" NOP") for a single cycle if that's what you want.

    Whitney
  • By using this function __asm(" NOP") , I am getting 200ns. Should i use timer?
  • How are you measuring the delay? Can you tell me more about why you need such a small delay?

    Whitney
  • I am measuring the delay through osciloscope HDO4104. I am doing double pulse test using 200MHZ for which i need 5ns delay. I am using the following program.


    //
    // Included Files
    //
    #include "F28x_Project.h"

    //
    // Defines
    //

    #define BLINKY_LED_GPIO 12

    interrupt void xint1_isr(void);
    // Global variables for this example

    volatile Uint32 t1 = (10*50);
    volatile Uint32 t2 = (10*50);
    volatile Uint32 t3 = (10*50);




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

    //
    // Step 2. Initialize GPIO:
    // This example function is found in the F2837xS_Gpio.c file and
    // illustrates how to set the GPIO to it's default state.
    //
    InitGpio();
    GPIO_SetupPinMux(BLINKY_LED_GPIO, GPIO_MUX_CPU1, 0);
    GPIO_SetupPinOptions(BLINKY_LED_GPIO, GPIO_OUTPUT, GPIO_PUSHPULL);

    //
    // 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 F2837xS_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 F2837xS_DefaultIsr.c.
    // This function is found in F2837xS_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.XINT1_INT = &xint1_isr;
    EDIS; // This is needed to disable write to EALLOW protected registers

    //


    //
    // Enable XINT1 and XINT2 in the PIE: Group 1 interrupt 4 & 5
    // Enable INT1 which is connected to WAKEINT:
    //
    PieCtrlRegs.PIECTRL.bit.ENPIE = 1; // Enable the PIE block
    PieCtrlRegs.PIEIER1.bit.INTx4 = 1; // Enable PIE Group 1 INT4
    PieCtrlRegs.PIEIER1.bit.INTx5 = 1; // Enable PIE Group 1 INT5
    IER |= M_INT1; // Enable CPU INT1
    EINT; // Enable Global Interrupts

    // GPIO14 is inputs
    //
    EALLOW;
    GpioCtrlRegs.GPAMUX1.bit.GPIO14 = 0; // GPIO
    GpioCtrlRegs.GPADIR.bit.GPIO14 = 0; // input
    GpioCtrlRegs.GPAQSEL1.bit.GPIO14 = 0; // XINT1 Synch to SYSCLKOUT only

    EDIS;

    //
    // GPIO14 is XINT1
    //
    GPIO_SetupXINT1Gpio(14);

    //
    // Configure XINT1
    //
    XintRegs.XINT1CR.bit.POLARITY = 1; // Raising edge interrupt 1
    //Falling edge interrupt 0

    //
    // Enable XINT1
    //
    XintRegs.XINT1CR.bit.ENABLE = 1; // Enable XINT1

    //
    //
    // 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(;;)
    {

    PieCtrlRegs.PIECTRL.bit.ENPIE = 1; // Enable the PIE block
    PieCtrlRegs.PIEIER1.bit.INTx4 = 1; // Enable PIE Group 1 INT4
    PieCtrlRegs.PIEIER1.bit.INTx5 = 1; // Enable PIE Group 1 INT5

    }
    }

    //
    // My intrr
    //
    // xint1_isr - External Interrupt 1 ISR
    //

    interrupt void xint1_isr(void)

    {
    PieCtrlRegs.PIECTRL.bit.ENPIE = 0; // Enable the PIE block
    PieCtrlRegs.PIEIER1.bit.INTx4 = 0; // Enable PIE Group 1 INT4
    PieCtrlRegs.PIEIER1.bit.INTx5 = 0; // Enable PIE Group 1 INT5

    //
    // Turn on LED
    //
    GPIO_WritePin(BLINKY_LED_GPIO, 0);

    //
    // Delay for a bit.
    //
    __asm(" NOP");

    //
    // Turn off LED
    //
    GPIO_WritePin(BLINKY_LED_GPIO, 1);

    //
    // Delay for a bit.
    //
    __asm(" NOP");

    // Turn on LED
    //
    GPIO_WritePin(BLINKY_LED_GPIO, 0);

    //
    // Delay for a bit.
    //
    __asm(" NOP");

    //
    // Turn off LED
    //
    GPIO_WritePin(BLINKY_LED_GPIO, 1);





    // Acknowledge this interrupt to get more from group 1
    //
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;

    }
    //
    // End of file
    //
  • The extra delay you're seeing isn't because the NOP is taking too long. I suspect it's the way you're writing to the GPIOs. There's the overhead of the function call first of all. Then if you look at the function itself, it calculates which register and bit correspond to the pin number parameter and branches depending on whether you're writing a 0 or a 1 all before it even gets to set the SET or CLEAR register.

    This wiki page lists some faster ways to do it:
    processors.wiki.ti.com/.../General_Purpose_IO_(GPIO)_FAQ_for_C2000

    Whitney
  • Could you please tell me from where can i change the clock frequency to 200MHz in LaunchXL-F28377S.
  • Check out the InitSysCtrl() function in F2837xS_SysCtrl.c. There's a call to InitSysPll() where the multipliers and divider get configured.

    Whitney
  • If i use this function __asm(" RPT #100 || NOP"). How will i declare 100 as a variable t1. i am using this syntax __asm(" RPT #t1 || NOP");
    //Global variables for this example

    volatile Uint32 t1 = 100;
    but its not working
  • Hello
    I am using this function __asm(" RPT #100 || NOP"). But i want to declare 100 as a variable. i am using this syntax but its not working.
    __asm(" RPT #t1 || NOP");
    and before void main(void) i define this
    volatile Uint32 t1 = 100;
  • You can't refer to local variables with the __asm() statement:
    downloads.ti.com/.../index.html

    Whitney