Using Register Class with G30

Hello,

I’m hoping someone can explain what I am misunderstanding here.

Why does this code:

Register timer2CTRL = new Register(0x40000000);
timer2CTRL.SetBits( 1 << 0);
Debug.Print(timer2CTRL.Value.ToString());

Produce the output : 0 ?

I have tried other methods of writing to the register as well like … = new Register(0x40000000, 0x01) but no dice.

What am I missing here? I want to enable timer2 on the G30 and read its CNT register from time to time.

Thanks

@ jwizard93 - are you sure you have the register address correct? I did a quick scan through a cortex m4 manual, and the control registers begin with hex E. Where did you get the address you are using?

1 Like

@ Mike - I bet you are correct. The all 000000 also look suspicious.

Thanks everyone,

I found the image I attached in the reference guide, and used the Address Offset of 0x0 from the description of the timer registers in the same reference. I think CyberHome is correct I remember seeing “peripheral base” only I thought I was on the right track.

@ Mike - Could you link me to that reference? So far I have a datasheet and the reference manual and I can’t seem to find what I’m looking for. I feel you are correct because other examples start with 0xE as well.

I Googled Cortex M4 and found several manuals. For example, this one http://infocenter.arm.com/help/topic/com.arm.doc.dui0553a/DUI0553A_cortex_m4_dgug.pdf

Hmmmmm.

Looks like TIM2 may be in the 0x4… range. But, it appears that TIM2 memory mapped area is 0x3ff bytes long. You need to find exactly within that range where the register you need is located. I have to admit that I could not easily find it.

I was able to find several C examples. Worse case, you can try to find the C headers for the Cortex M4, which have the values for the registers you need.

1 Like

Looking at the datasheet for the STM32F401RE which I believe the G30 is based on, TIM2 CR1 is located at 0x40000000.
TIM2 is located at 0x40000000-0x400003ff
CR1 is located at offset 0x0

CR1 definition can be found in Section 13.4.1 of the associated reference manual.

@ mike - Yeah I glanced through the link you supplied, thank you for it, but it’s quite similar if not identical to the others. I’m afraid I just don’t understand how to extract what I need. I spent the better part of this morning downloading SDKs and pouring through header files. Like I originally tried, and like you and @ trapperbob have seen it does appear as the control register is at precisely 0x40000000. However, like @ cyber_h0me was getting at (I think) the peripheral base must first be enabled through some other register not in the 0x40000000-0x4000003fff register boundary. Alas, half the day is gone and I’m still where I started. I will just use some managed tickCount thing or something until I have time to sort out the right registers.

Is there a good Milliseconds_since_startup class to hold me over?

I’m using

long start = DateTime.Now.Ticks;
int millis = (int) (DateTime.Now.Ticks) - start) / 10000;

But I beleive someone with some fancy measurements would discover discrepancies between the units listed in my GUI and the actual operation of my motor, that is why I want to use a low level timer and the register class seems to be a valid option in getting high accuracy while maintaining the awesomeness that is developing in netmf.

@ jwizard93 - The managed method you used should work, if the resultant accuracy is sufficient. If you are using threading, you might get a bit of jitter due to context switching and/or garbage collection.

1 Like

@ Mike - Ahhh I figured as much. That would explain the somewhat rare case of a slightly different than average response. It’s mostly unnoticeable. I can occasionally hear some whining when the slider is at its end. I assume another thread is active at these times and the instructions to change direction have yet to execute. I made the critical thread HighestPriority but that’s all I currently know how to do and not even sure if it’s effective.

I suppose the register access method would suffer the same?

Can the framework allow an interrupt from a timer if i were able to figure out the register access method?

Otherwise I think I will learn more about threading and see if I can pause the other threads at just the right time to ensure my motor isn’t wasting power pushing against a wall and the other threads still appear as “real-time” to the user. The critical window is really only 10 or so milliseconds if it were running on its own processor.

You can not handle a timer interrupt you set up in managed code. The G30 does not support RLP, which could be used on other boards to handle such an interrupt.

To minimize GC you should look at how you allocate new objects, such as strings. If you are careful, and minimize creating new objects, then GC will not occur very often. In embedded systems, it is good practice to allocate as many objects as possible at startup time. Look at the debug output in the console window. It should tell you how often GC is run.

You should know that a thread will hold the processor for up to 20ms, before it is taken away (timeslice). If you have long processing loops, then you might want to insert Thread.Sleep(0) statements, which will release the CPU to a waiting thread of equal or higher priority.

Alas, NETMF is not real-time. Deterministic timing does not exist with NETMF.

1 Like

Thank you everyone, especially @ Mike, for your assistance. I was able to get the maximum delay (seen so far) between motor commands down to ~1.4ms which will do for now if not forever. I made every little variable static and global and added Thread.Sleep to some key culprits.

I’ll be sure to update if anything interesting arises with the register class and the low level timer to make this thread more relevant to its topic.

1 Like

Can you maybe use the RTC-Alarm somehow?
It’s used e.g. for wakeup here:
https://www.ghielectronics.com/docs/141/low-power