System time in RLP on G120

How can I get something like system time in RLP on a G120.
It should have microseconds resolution, or at least better than milliseconds.
The actuall value does not matter, all I need is the time between two events.

I tried clock() from time.h already, but it always Returns FF FF FF FF :frowning:


You should be able to use on of the timer registers in counting mode. Easy code, after reading the chip manual

1 Like

Can’t I access the RTC somehow?
this should be readable from some Register already I guess.

@ Reinhard Ostermeier -

Using RTC register is harder than the register which Mike talking about.

1 Like

Is the Counter Mike is talking about already Setup and I just Need to read the Register, or do I have to Setup the Counter.
If I have to set it up, how can I be sure to not mess up something Setup by the Firmware already?

@ Reinhard Ostermeier -

if timer0 then just read it, other than that you may need to set it up.

1 Like

Thank you both, will try it tomorrow

I managed to get a time value from timer 0 by reading

I wonder now what the exact scaling of this value is.
When I set up an RLP Task with 100000µsec. the Delta jitters around 3.600.000 and 3.700.000.
This would mean something around 36 ticks per µsec.
I wonder if this is corect, because this would be a factor of 3.3333 to the 120MHz CPU frequency.
So 40 ticks/µsec. would make more sens, but I can’t imageine that the RLP Task is that much off, actually too fast (in kernel mode) :think:

I could read the Registers for scaling, but it’s hard for me to find the correct documentation on that.

I nailed it down to that the timer is incremented every PCLK tick divided by (PR+1)
PR seems to be set to 0, means my timer is incremented at the PCLK frequency.
But what is the PCLK frequency on a G120?
1st I thought PCLK would be 120MHz, and PR would propably be set to 3 or something.
But it isn’t.
I also saw that some PWM’s use TIM0, and PWM’s are documented to work up to 30MHz.
Also this frequency could be changed.
Does that mean PCLK can Change over runtime, or is it PR that is variable?
I currently do not use any PWM’s so all Settings related to them should be at boot up default.

I did some more Tests:
I set up an RLP function that only sets up an Task with delays between 100µsec and 1000000 µsec.
Each one multiple times, 50 measurements in total.
in the Task callback the 1st Thing I do was scheduling the next one.
Then I wrote the current time from TIM0 into an Array.
Dividing the TIM0 difference between two calls with the actual scheduled time gives me a value just above 60, means for me I have 60 ticks per µsec + some overhead.
When I assume that 60 is my actual factor and take the difference between the delay I wanted between two Task callback calls and the time I meassured, I get the each call is delayed by 785 Counts in average, which would be 13 µsec.
This is what I also found out in an earlier reserch with RLP Tasks.
if you schedule a delayed Task from within the Task callback (in 1st line) the next Task comes actually 12 or 13 µsec too late.

What is strange now is that my 1st test would have given me about 40 ticks per µsec. but this might be that case because the next Task in this callback is scheduled at the end of the function.

Final question:
What is now the ticks/µSec for TIM0, is it constant over runtime. If not: can I calculate it at any given time???

@ cyberh0me i know I will not get hard real time, but that’s not really the goal here. I just Need a Task schedule taht is faster and has less jitter than in CLR.

What I Need is a valid and reliable time Delta in RLP.

@ GHI:
I have a really bad Feeling about timer0 and/or the RLP Task Scheduler.

As long as I keep the CLR busy, everything works fine. I get constant values from TIM0 of 60 x t [µsec] + 785+/-
But as soon as I send all managed threads to sleep, it starts to get cracy.
The main thread has an Thread.Sleep(-1).
The sleep in the thread that monitors the RLP data was changed form nothing (everything works fine) to 10 (still fine, at least that Long that I could not see something bad) to 100 or 200 ms, time delta values get way to small.

The delta of TIM0 between the task callbacks gets lower, sometimes the delta is only 50% of what it should be.
I can think of 3 possible reasons for this:

  1. The RLP task scheduler speeds up and calls the callback early
  2. The prescaler (PR) of TIM0 gets increased and set back to normal in the meantime
  3. the PCLK clock frequency goes down as if the CPU would support Intel® SpeedStep™

Does any thing above makes sens to you?

@ Reinhard Ostermeier -

Hopefully this will help you:

 #include "RLP.h"

 #define UINT32 unsigned int
 #define UINT64 unsigned long long
 #define TIMER0_TIMECOUNTER (0x40004000 + 0x00000008)

UINT32 RLP_Timer0(void **args)
	UINT64 *currentTick = (UINT64*)args[0];
	UINT64 *currentMircosec = (UINT64*)args[1];
	UINT64 *currentMilisec = (UINT64*)args[2];
	UINT64 *lastReadValue = (UINT64*)args[3];
	UINT32 *reg_tc = (UINT32*)(TIMER0_TIMECOUNTER);
	UINT32 resHigh = (UINT32)(*lastReadValue >> 32);
    UINT32 resLow  = (UINT32)(*lastReadValue & 0xFFFFFFFF);

    UINT32 value = *reg_tc;

    if(value <= resLow)
        resHigh += 1;
    *lastReadValue = (UINT64)resHigh << 32 | value;
	*currentTick = *lastReadValue;
	*currentTick *= (10000000               /1000000);
    *currentTick /= ((120000000/2)/1000000);
	*currentMircosec = *currentTick/10;
	*currentMilisec = *currentTick/10000;

    return 1;

In Managed code, you can check by:

 binfile = Resources.GetBytes(Resources.BinaryResources.G120RLP);
            var elfImage = new RuntimeLoadableProcedures.ElfImage(binfile);
            var RLP_readTimer = elfImage.FindFunction("RLP_Timer0");
            long[] time_ms = new long[1] {0};
            long[] time_us = new long[1] { 0 };
            long[] time_tick = new long[1] { 0 };
            long[] last_read = new long[1] { 0 };

            while (true)
                long last_tick = time_tick[0];
                long last_us = time_us[0];
                long last_ms = time_ms[0];
                RLP_readTimer.Invoke(time_tick, time_us, time_ms, last_read);

                Debug.Print(" time_tick = " + time_tick[0] + ", diff= " + (time_tick[0] - last_tick));
                Debug.Print(" time_us = " + time_us[0] + ", diff= " + (time_us[0] - last_us));
                Debug.Print(" time_ms = " + time_ms[0] + ", diff= " + (time_ms[0] - last_ms));  


@ Dat - thank you for the sample.
If I read it right, then this confirms that timer0 has 60 ticks per µsec.

But I still have the strange issue that the timer0 Counter value increases to slow when read in an sereies of RLP Tasks, and the managed Code is at sleep.

I will prepare a simple demo tomorrow and post it here.

@ Reinhard Ostermeier -

Those are should not effect to timer counter, I think.
Just after few minutes 32 bit is run out so your program may run incorrectly. Use the test above can correct that.

I’ll post a sample tomorrow. The overrung is no Problem, since it can easily detected.

I have nailed it down:
The networking (ENC28 on G120) interfiers with the RLP Task Scheduler.
As soon as I have networking initialized and a network cable is connected (no active Connection), the RLP Task calbback is called early.

How did I verify this:
I removed one pice of Code from my program until the time intervalls where as expected and constant (more or less).
The final pice of code was the Network initialization.
Then I not only monitored the time deltas between two task callbacks, but also the number of calls to it in a specific time from manged Code.
In a Loop with one RLP call and a 100ms sleep I got relatively stable 12 or 13 calls to the callback.

Then I added the network initialization back in and I got shorter time deltas and up to 23 calls in the same time span.
The I disconnected the network cable, and everything looks fine again.
Network cable back in, wrong timing.

When you let it run for a while (without networking) you still see shorter time deltas from time to time.
But with initialized networking and pluged in cable between 50% and 80% of the scheduled tasks are called early.

b.t.w. I still use FW V4.3.6, and I havn’t tried it with a newer FW so far.

Actually, now that I know that the time value is correct, and the only issue is that the callback is called early, (and not too late) I can write a workaround.
If the callback is called early. I simply reschedule it with the remaining time. This should work I think.
But it would be interesting what the cause for this is.
Any shared Interrupts?

@ cyberh0me - Well I have prooven that the timer works correctly.
Also I tried timer1, which was not initialized, and I don’t want to mess around with too many Registers in RLP, beacuse I don’t know on what NETMF and the GHI FW relies on.

@ cyberh0me - This thread is for sure not about the G120, they talking abou 18MHz, but on G120 timer 0 runs at 60MHz.
The only Thing that might Change that is the prescaler, which i can read, and as Long as it does not get above 60 i’m fine.

The G120 docs say that timer0 and timer1 are used for PWM.