Tuesday, March 4, 2014

Access Memory Mapped Registers


woaahh I hear you, chill bro!!
To get the feel of it, first get rid of the outer most bracket and the asterisk at the left:
((volatile unsigned long *)0x12345678)
looks easy now?

Whats happening here is that we made a pointer that points to the address 0x12345678 in the memory(RAM).
In other (pro)words we type-casted 0x12345678 to a volatile unsigned long pointer.

The volatile keyword here makes sure that you will get the current value from the address 0x12345678.
For more information on volatile kindly see this shit.

so
((volatile unsigned long *)0x12345678) is a pointer

Now when we de-reference it with the asterisk on the left like so
((volatile unsigned long *)0x12345678)
 to access the value stored at this location.

EXAMPLE:
This technique is used to read write IO mapped registers among other things.
 
a) Reading
Suppose in an SoC the output of an ADC is stored in a register which is mapped to location 0xDEADBABE.
We will always want the updated value of ADC in mission critical systems hence we will use the volatile keyword.

#define     ADC    (*((volatile unsigned long *)0x12345678))

then in code to read the value of ADC in a variable temp we simply do:
temp = ADC; // cool ryt? 

b) Writing
The same technique can be use to write the value to a memory mapped register.
Suppose we have a 32 bit output port called LEDBANK located at 0xCAFEC0DE then

#define     LEDBANK    (*((volatile unsigned long *)0xCAFEC0DE))
LEDBANK = 0xDECAFBAD

and 0xDECAFBAD will be transferred to LEDBANK

If you need more help, kindly leave a comment below :)