« Close

Datasheets and User Guides

App Notes

Software & Driver

 

2.9.1.10 - System Timer Low/High Read (Modes 10 & 11)

The LabJack U6 has a free-running internal 64-bit system timer with a frequency of 4 MHz. Timer modes 10 & 11 return the lower or upper 32-bits of this timer. An FIO line is allocated for these modes like normal, even though they are internal readings and do not require any external connections. This system timer cannot be reset, and is not affected by the timer clock.

If using both modes 10 & 11, read both in the same low-level command and read 10 before 11.

Mode 11, the upper 32 bits of the system timer, is not available for stream reads. Note that when streaming on the U6, the timing is known anyway (elapsed time = scan rate * scan number) and it does not make sense to stream the system timer modes 10 or 11.

7 comments

ElectroLund's picture

Any idea why I might be getting strangely low timer values on occasion?  For the majority of my sys timer value requests, I get good data.  But sometimes, the LOWER value is an order of magnitude suspiciously low.

Here's my init code, run once before timing/counting begins:

int InitSystemTimer(counter_struct* counter)

{

// Configure Timer0 as system timer low

AddRequest(ljHandle, LJ_ioPUT_TIMER_MODE, X123_TLSW, LJ_tmSYSTIMERLOW, 0, 0);

// Configure Timer1 as system timer high

AddRequest(ljHandle, LJ_ioPUT_TIMER_MODE, X123_TMSW, LJ_tmSYSTIMERHIGH, 0, 0);

// now send all the messages

GoOne(ljHandle);

ePut(ljHandle, LJ_ioPUT_COUNTER_RESET, X123_COUNTER, TRUE, 0);

// flush last value

eGet(ljHandle, LJ_ioGET_COUNTER, X123_COUNTER, &counter->counts, 0);

// init the ticks 

GetCountTime(counter);

counter->ticksInit = counter->ticks;

}

And here's my timer function that I run once a second thereafter:

int GetCountTime(counter_struct* counter)

{

// set up counter read

AddRequest(ljHandle, LJ_ioGET_COUNTER, X123_COUNTER, 0, 0, 0);

// set up read of internal system timer low and high words

AddRequest(ljHandle, LJ_ioGET_TIMER, X123_TLSW, 0, 0, 0);

AddRequest(ljHandle, LJ_ioGET_TIMER, X123_TMSW, 0, 0, 0);

// send all requests

GoOne(ljHandle);

// now get the results

GetResult(ljHandle, LJ_ioGET_COUNTER, X123_COUNTER, &counter->counts);

GetResult(ljHandle, LJ_ioGET_TIMER, X123_TLSW, &lower);

GetResult(ljHandle, LJ_ioGET_TIMER, X123_TMSW, &upper);

// combine timer MSW and LSW

counter->ticks = lower + upper * pow(2, 16);

// calculate the delta time

counter->time = (counter->ticks - counter->ticksInit) / LABJACK_SYS_TIMER_CLOCK;

}

LabJack Support's picture

I ran a quick test and did not see any points that looked bad.

At what rate are you reading the timers? And how often do you see the bad readings?

ElectroLund's picture

I should have said that I'm using a U6, with latest firmware.  I'm polling the timers at 1Hz with CVI LabWindows.  I output my structure time value and it shows a very close 1HZ rate most of the time, with LABJACK_SYS_TIMER_CLOCK defined as 4e6.

I'm seeing these bad readings maybe once every 4-5 attempts of a unit test.  In a unit test, there's about 500 timer requests.  So it's pretty rare, but often enough that my unit test gets pretty fouled up.  I'm at such a loss as to why the value would be borked.  My counter structure is made up of all doubles.

typedef struct

{

double counts,

ticks,

ticksInit,

time,

rate;

} counter_struct;

LabJack Support's picture

Can you provide 10 or so scans of raw (uncombined) timer values so we can see good readings and a bad reading.

LabJack Support's picture

I have not been able to reproduce the error, but I think I have found what was causing it. Please send an email so that I can send you a new firmware version to try. The data set requested above may still be useful.

ElectroLund's picture

Before I patch any firmware, I wanted to post my results.  Here is some history of data values, stopped when I get a bad point:

14:28:17: MSW = 19.000000, LSW = 4237101451.000000, combined = 4238346635.000000

14:28:18: MSW = 19.000000, LSW = 4241781934.000000, combined = 4243027118.000000

14:28:19: MSW = 19.000000, LSW = 4246301450.000000, combined = 4247546634.000000

14:28:20: MSW = 19.000000, LSW = 4250902229.000000, combined = 4252147413.000000

14:28:21: MSW = 19.000000, LSW = 4255320215.000000, combined = 4256565399.000000

14:28:22: MSW = 19.000000, LSW = 4259769907.000000, combined = 4261015091.000000

14:28:24: MSW = 19.000000, LSW = 4266328515.000000, combined = 4267573699.000000

14:28:25: MSW = 19.000000, LSW = 4270820926.000000, combined = 4272066110.000000

14:28:26: MSW = 19.000000, LSW = 4275193662.000000, combined = 4276438846.000000

14:28:27: MSW = 19.000000, LSW = 4279701423.000000, combined = 4280946607.000000

14:28:29: MSW = 19.000000, LSW = 4284152707.000000, combined = 4285397891.000000

14:28:30: MSW = 19.000000, LSW = 4288582525.000000, combined = 4289827709.000000

14:28:31: MSW = 19.000000, LSW = 4293062524.000000, combined = 4294307708.000000

14:28:32: MSW = 20.000000, LSW = 2615698.000000, combined = 3926418.000000

As I feared, bad data happens right at an overflow.  The third column is my joined 64-bit number, but as you can see I've got a serious flaw there!  I was shifting my bits only 16 places, rather than the full 32.  Oops!

LabJack Support's picture

If I do the math on the last three lines I get the following:

19, 4288582525 = 85,892,961,149

19, 4293062524 = 85,897,441,148

20, 2615698 = 85,901,961,618

Which looks correct.