- System Timer Low/High Read (Modes 10 & 11) [U6 Datasheet] | LabJack
« Close

Datasheets and User Guides

App Notes

Software & Driver - System Timer Low/High Read (Modes 10 & 11) [U6 Datasheet]

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.


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


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 


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


// 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,





} 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.

ElectroLund's picture

Is there any reason why I'd be getting nearly duplicate values for the MSB and LSB sys timers?

upper: 3425196060

lower: 3425195997

Clearly, this is really just the lower that output each time, offset by the number of cycles it took to sample each.  And yet my systimer setup looks good:

number of timers = 3

pin offset = 8

base, divisor, etc.

MSB = 1

LSB = 0


btw, in the LJ Control Panel, all is well. So there's just something I'm not getting right.

labjack support's picture

Your timer will be configured for system timer low if its mode is set to 10, or the mode is not set. When not set, the mode defaults to system timer low.

For each timer, make sure its mode is configured before you start reading from it.

If you enable/disable timers or counters, previous timer mode settings are lost and reset to the default mode. Reconfigure timer modes after enabling/disabling timers or counters.

ElectroLund's picture

Ahh, interesting.  Currently in my system timer init function, I am setting the two states, 10 & 11 for lo/hi with a IO Set Config and then I'm also sending a IO Get Config for both, GoOne, then GetResults for both.  In this function, both check correctly. 

So I must be disabling the timers somewhere else by accident.  You said that if any other timers/counters are disabled or enabled, this will result? That's surprising behavior.  In my system, I need one counter and one PWM output timer.  But both are initialized outside of the system timer.

Am I correct in thinking that all of these need to be configured simultaneously with a single GoOne in order to not be disabled inadvertently? 

labjack support's picture

Disabling or enabling any timers or counters, or setting the timer counter pin offset (just double checked that one), will reset timer modes to their defaults. All timer modes need to be configured then. The reason is that those enable and pin offset settings are configured together in their low-level command-response to the U6. Basically after configuring with these UD constants all timer modes need to be configured: LJ_chNUMBER_TIMERS_ENABLED,  LJ_ioPUT_COUNTER_ENABLE,  LJ_chTIMER_COUNTER_PIN_OFFSET .

To prevent inadvertently disabling timer modes, you can configure timer/counter settings and all modes in one GoOne.

Alternatively, you can use the easy timer functions as timer/counter enabling and timer modes are configured together: