The static "Register" class

Although not documented, the Register.Read and Register.Write seemed reasonably self explanatory after studying the code.

So I am puzzled by why a Read, followed by a Write and another Read, shows that the value seems unaffected by the Write.

var ior = Register.Read(0x4000_0000);

Register.Write(0x4000_0000, 0x0007);

ior = Register.Read(0x4000_0000);

Each read into ior is zero, both before and after the write. Am I misunderstanding something? This is of course attempting to modify the TIM2_CR1 register.

Some registers allow write or read only, some after read the value is set to zero, some allow write/read only after enabled the special or peripheral clock… many rules…

I guess you need to enable timer peripheral clock first,

Ah yes, it could be as simple as that, many thanks. I’ve been coding these devices in C on an STM32F407 board and of course the periph needs its clock enabling.

1 Like

OK this is a whole different ball game to “ordinary” MCU devices. It’s becoming clear that these MP devices pretty much presume there’s an OS running and that plays a large part in all this.

Clearly if there’s an OS running then that will in some way or other have some oversight of peripherals or certain essential resources.

I’ve been thinking of these devices as more or less comparable to an STM32 MCU and that the principles used in those are “portable” to this MPU device, it doesn’t look like that’s a valid way to look at things.

Accessing and modifying hardware registers when there’s an OS running is obviously something that must be done with great discipline so I’m now thinking this isn’t a very useful thing to try with these devices (even if there was a performance benefit).

I was toying with the idea of creating a library that supported stuff like this (register level manipulation) that embraces newer C# language features (life ref returns and so on) to facilitate very fast access to hardware from C#, but I think there is far more involved than I assumed initially!

I did get a small useful basic library running, one where we create a disposable “mapping” object that we can work from and eventually dispose, until it gets disposed the mapping remain mapped and so there’s no open/map/unmap/close sequence on each register access, just an open/map, a bunch of register operations directly manipulating register storage, as many as needed and then an eventual unmap/close. The registers are accessed through a ref that is created from the raw register address and means one can work directly with these registers without using unsafe code.

It works well but the complexity of the MPU/OS seems daunting now.

Example

                using var mp = Peripherals.MapPageRegion(0x4000_0000, 1);

                var tp = mp.GetPeripheralRef<TimerGeneral, APB1>(APB1.Tim2Ofx);

                Console.WriteLine($"CEN:  {tp.TIM_CR1.CEN}");
                Console.WriteLine($"UDIS: {tp.TIM_CR1.UDIS}");
                Console.WriteLine($"URS:  {tp.TIM_CR1.URS}");
                Console.WriteLine($"COPM: {tp.TIM_CR1.COPM}");
                Console.WriteLine($"DIR:  {tp.TIM_CR1.DIR}");

                tp.TIM_CR1.CEN = true;
                tp.TIM_CR1.DIR = true;

                Console.WriteLine($"CEN:  {tp.TIM_CR1.CEN}");
                Console.WriteLine($"UDIS: {tp.TIM_CR1.UDIS}");
                Console.WriteLine($"URS:  {tp.TIM_CR1.URS}");
                Console.WriteLine($"COPM: {tp.TIM_CR1.COPM}");
                Console.WriteLine($"DIR:  {tp.TIM_CR1.DIR}");