Reading hardware register in C program

Asam Padeh picture Asam Padeh · Dec 20, 2013 · Viewed 8.1k times · Source

Let say there is a 32 bits register defined as TIMER and its 32 bits address TIMER_ADDR in the memory (DDRAM).

uint32_t TIMER_ADDR; // 32 bits address declared as uint32_t

The layout of TIMER is defined as:

struct timer {
    uint32_t start:1;
    uint32_t mode: 3;
    uint32_t init: 4;
    uint32_t value:24
}

Later I defined a local var loc_timer as:

struct timer loc_timer;

How can I to read this register to a local register in the program so I can modify the content

loc_timer.mode = 4;
loc_timer.init = 10;

and write it back to register TIMER ?

something like

(*(uint32_t *))&loc_timer = (*((uint32_t *)(TIMER_ADDR))); // read
(*((uint32_t *)(TIMER_ADDR))) = (*(uint32_t *))&loc_timer; // write

but it does not work :-(

Answer

Paul R picture Paul R · Dec 20, 2013

Like this:

struct timer loc_timer = *(struct timer *)TIMER_ADDR; // read register
loc_timer.mode = 4;                                   // modify fields
loc_timer.init = 10;
*(struct timer *)TIMER_ADDR = loc_timer;              // write register back again

Note that since this is a memory-mapped register you should treat it as volatile, e.g.

volatile struct_timer * const timer = (struct timer *)TIMER_ADDR;
struct timer loc_timer = *timer;                      // read register
loc_timer.mode = 4;                                   // modify fields
loc_timer.init = 10;
*timer = loc_timer;                                   // write register back again