How can I create a delay of microseconds

ChibiOS public support forum for topics related to the STMicroelectronics SPC56x family of automotive micro-controllers.
GianlucaLaManna
Posts: 25
Joined: Fri Mar 13, 2015 12:12 pm
Location: Palermo, Italy

How can I create a delay of microseconds

Postby GianlucaLaManna » Mon May 11, 2015 5:40 pm

Hello,
I saw this code to create a generator delay in microseconds.

Code: Select all

#include <board.h>
#include <lcd.h>
#include <timer.h>
#include <systick.h>
#include <stdio.h>

static unsigned long loops_per_msec;

/*
 * Loop for the specified no. of times. Used for generating delays.
 */
static void busy_loop(unsigned int nloops)
{
        unsigned int i;
        for (i = 0; i < nloops; i++);
}

/*
 * Calibrate the loop, to find out the no. of loops executed in 1
 * milli-second, and store the result in loops_per_msec.
 */
void udelay_calibrate_loop(void)
{
        timer_t timer;
        ticks_t start;

        loops_per_msec = 1;

        /*
         * Calculate loop count. Use geometrical progression to get a
         * coarse grained value quickly - 1, 2, 4, 8, 16, 32, 64 ...
         */
        while (1) {
                /*
                 * Wait till we are the start of a millisecond.
                 */
                start = systick_get_ticks();
                while (systick_get_ticks() == start);

                /* timer for one milli seconds */
                timer_setup(&timer, 1);
                busy_loop(loops_per_msec);
                if (timer_expired(&timer))
                        break;
                loops_per_msec <<= 1;
        }
        loops_per_msec >>= 1;

        /*
         * Calculate fine grained loop count. Use arithmetic
         * progression to get an accurate value.
         */
        while (1) {
                /* timer for one milli seconds */
                timer_setup(&timer, 1);
                busy_loop(loops_per_msec);
                if (timer_expired(&timer))
                        break;
                loops_per_msec += 1;
        }
}

/*
 * Generate a micro-second delay.
 *
 * The function executes the required no. of delay loops, using the
 * previously calibrated loops_per_msec, to generate the delay.
 */
void udelay_delay(unsigned int usec)
{
        busy_loop((loops_per_msec * usec) / 1000);
}

/*
 * Test code to use the udelay, implementation.
 *
 * Generates a 1 second delay.
 */
int main()
{
        int i;

        board_init();
        timer_init();
        lcd_init();
        board_stdout(LCD_STDOUT);

        udelay_calibrate_loop();
        printf("Loops: [%lu]\n", loops_per_msec);

        printf("Start\n");
        /* Generate a 1 second delay. */
        for (i = 0; i < 1000; i++)
                udelay_delay(1000);
        printf("End");

        return 0;
}


I would do the same thing, but there is a similar function to systic_get_ticks () and time_setup () in chibios? I use the board STMicroelectronics SPC560P-DISP.
I need this function because there is no function osalThreadSleepMicroseconds, but only Milliseconds.
Thanks.

Best regards,
Gianluca.

User avatar
Giovanni
Site Admin
Posts: 14444
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1074 times
Been thanked: 921 times
Contact:

Re: How can I create a delay of microseconds

Postby Giovanni » Mon May 11, 2015 6:22 pm

It is called osalOsGetSystemTimeX() it returns a variable that is increased every millisecond.

Note that you cannot have RELIABLE delays at microsecond resolution because interrupts will add jitter to whatever loop delay code you will write.

Jitter can be in the range of 1uS...10uS (or even more) depending on you application critical zones.

Giovanni


Return to “SPC56x Support”

Who is online

Users browsing this forum: No registered users and 3 guests