Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Micro Second delay/clock implementation with an i960 proceesor

79 views
Skip to first unread message

Leonid Rosenboim

unread,
Aug 12, 2002, 1:40:37 PM8/12/02
to
Raja,

I have faced a similar problem when writing Flash memory drivers a few years
back, where the delay needs not be accurate, but must be larger than a
specified time, e.g. > 6 microsec for byte/word write command.

The was we did this was to write a loop that accesses the Flash memory
(assumed to be non-cached) multiple times, while the loop count was set to a
value perviously determined by a measured loop. During initialization, the
Calibration function would run the loop for a full system clock period, i.e.
it would start counting when the tickGet() value changes 1st time, and stops
counting with vxTicks changes the second time. Knowing the time length of
this period we would scale the loop count per microsecond.

If we needed accurate pulses, then during the coutining all interrupts would
be locked out (which is OK for a few microseconds), but if it would be
acceptable for the pulses to be "longer then X usec", we would leave
interrupts and scheduling turned on.


"Raja" <amr...@hotmail.com> wrote in message
news:7da11b7d.02080...@posting.google.com...
> Hi
> I need to implement a microsecond clock or any timer that can provide
> me delay in the order of micro seconds. I tried using system clock
> which gives me a clock rate of 60 ticks per second only. I tried to
> get the clock rate of the auxiliary clock and it seems to be the same
> 60 ticks per second.
>
> I would highly appreciate if you could let me know of any ideas
> regarding this.
>
> Note: I am using VME board (VMETRO - Power Midas 1200s )that has an an
> i960 processor and am running in Tornado 2.0 IDE( for i960 )
>
> Thank you,
> Raja.


Bill Pringlemeir

unread,
Aug 12, 2002, 3:00:11 PM8/12/02
to

"Raja" <amr...@hotmail.com> wrote in message
news:7da11b7d.02080...@posting.google.com...
> Hi
> I need to implement a microsecond clock or any timer that can provide
> me delay in the order of micro seconds. I tried using system clock
> which gives me a clock rate of 60 ticks per second only. I tried to
> get the clock rate of the auxiliary clock and it seems to be the same
> 60 ticks per second.


Leonid> The was we did this was to write a loop that accesses the
Leonid> Flash memory (assumed to be non-cached) multiple times, while
Leonid> the loop count was set to a value perviously determined by a
Leonid> measured loop. During initialization, the Calibration

[snip]

This is a modified version of code posted on comp.os.vxworks
previously. I have modified it to add assembler code to the delay
loop. This increases the precision. People could add assembler code
for the other processors.

I think the original author is "espin".... Ah it is in the FAQ under,
"http://www.xs4all.nl/~borkhuis/vxworks/vxw_pt6.html#6.1-A".

The author is Geoffrey Espin. Now you have two versions...

hth,
Bill Pringlemeir.

/* delayLib.c - hard delay routines */

/*
* DESCRIPTION
* This module provides "hard" delay routines for micro and millisecond
* periods.
*
* EXAMPLE .CS
* -> delayCalibrate(); /@ call used for calibration @/
* -> timexN delayMsec, 10
* timex: 75 reps, time per rep = 10209 +/- 222 (2%) microsecs
* value = 59 = 0x3b = ';'
* -> .CE
*
* The routines sysClkRateGet() and tickGet() are used to calibrate
* the timing loop. Therefore, the first call is much longer than
* requested if delayCalibrate is not called. If the system clock
* rate is changed, a new calibration must be explicitly made.
*
*
* The calibration should be done with interrupts off. This will
* guarantee that the delays are at least the specified time period.
* Calls to delayUsec and delayMsec maybe of a longer period due to
* interrupt delays.
*
*/
#include "vxWorks.h"
#include "tickLib.h"
#include "sysLib.h"
#include "delayLib.h"

#ifdef DEBUG
# include <stdio.h>
# define INFO_PRINT printf
int unsigned delayLoop = 0;
#else
# define INFO_PRINT(s...) /* nothing. */
static unsigned int delayLoop = 0;
#endif

/*****************************************************************************
*
* delayCalibrate - calibrate hard delay loops.
*
* RETURNS: N/A
*/
void delayCalibrate(void)
{
unsigned int maxLoop;
int start = 0;
int stop = 0;
unsigned int mpt = (1000 * 1000) / sysClkRateGet (); /* usecs per tick */

/* Course calculation of delay, up to twelve iterations */
for (delayLoop = 1; delayLoop < 0x1000 && stop == start; delayLoop<<=1)
{
/* wait for clock turn over */
stop = start = tickGet ();
while(start == stop)
start = tickGet ();

delayUsec (mpt);

stop = tickGet ();
}

start = stop = 0;
delayLoop = max(delayLoop, 4);
maxLoop = delayLoop/2; /* loop above overshoots */

INFO_PRINT("maxLoop = %d\n", maxLoop);

/* Find `delayLoop' to match tick interval. Start at 1/4 course */
for (delayLoop /= 4; delayLoop < maxLoop && stop == start; delayLoop++)
{
/* wait for clock turn over */
stop = start = tickGet ();
while(start == stop)
{
start = tickGet ();
}

delayUsec (mpt);

stop = tickGet ();
}

INFO_PRINT("delayLoop = %d\n", delayLoop);
}

#if CPU_FAMILY == ARM
/*****************************************************************************
*
* delayUsec - hard delay for <u> microseconds
*
* Notes: this routine is in assembler not to make the "delay fast", but
* to improve the resolution of the timer loop. It is doubles the precision
* of a `C' compiler loop.
*
* RETURNS: N/A
*/
void delayUsec(unsigned int u) /* # of microsecs */
{
__asm__ volatile (
" cmp %1,#0 \n" /* Set delayLoop > 0 */
" moveq %1,#1 \n"
"20: mov r1,%1 \n"
"10: subs r1,r1,#1 \n" /* Inner loop counts delayLoop */
" bne 10b \n"
" subs %0,%0,#1 \n" /* Outer loop counts `u'. */
" bne 20b \n"
: /* No outputs */
: "r" (u), "r" (delayLoop) /* %0 is u, %1 is delayLoop */
: "1"); /* trashes r1. */
}

#else
/* Equivalent `C' of above function version for reference. */
void delayUsec(unsigned int u)
{
unsigned int i;

for (; u; u--)
{
for (i = delayLoop; i; i--);
}
}
#endif

/*****************************************************************************
*
* delayMsec - hard delay for <m> milliseconds
*
* RETURNS: N/A
*/
void delayMsec(unsigned int m) /* # of millisecs */
{
delayUsec (m * 1000);
}

/* delayLib.h - self-calibrating hard delay routines header file */

/*
modification history
--------------------
27Mar96,espin written.
*/

#ifndef __INCdelayLibh
#define __INCdelayLibh

#ifdef __cplusplus
extern "C"
{
#endif

extern void delayCalibrate(void);
extern void delayUsec (unsigned int u);
extern void delayMsec (unsigned int m);

#ifdef __cplusplus
}
#endif

#endif /* __INCdelayLibh */

--
I want EARS! I want two ROUND BLACK EARS to make me feel warm 'n
secure!!

0 new messages