Register Addressing

Status
Not open for further replies.

tlb

Well-known member
For Teensy 3, in mk20dx128.h, there is:

Code:
#define FTM1_CNT		*(volatile uint32_t *)0x40039004 // Counter
and
Code:
#define FTM2_CNT		*(volatile uint32_t *)0x400B8004 // Counter

so one can write statements such as

Code:
Posn=FTM1_CNT;

without having to worry about pointer details.

Is there any way to set up a variable FTM_CNT, such that it will behave as FTM1_CNT or FTM2_CNT depending on a selection variable? Behave such that pointer de-referencing is done automatically as with the existing FTM1_CNT and FTM2_CNT?

Explicitly de-referencing all the register accesses is by no means the end of the world, but I thought I would check if there is some C++ trick that I don't know about.

I want to set up a class that uses the same functions instantiated with either FTM1 or FTM2.

Thanks,

TLB
 
The simplest thing would be to use a pointer, possibly being set by a reference:

Code:
class Foo {
private:
  volatile uint32_t *addr;
public:

  Foo (void)
  {
    addr = &FMT1_CNT;
  }

  Foo (volatile uint32_t &x)
  {
    addr = &x;
  }

  ~Foo (void)
  {
  }

  uint32_t value (void)
  {
    return *addr;
  }

  void set (uint32_t x)
  {
    *addr = x;
  }
};

static Foo x;
static Foo y (FMT2_CNT);

uint32_t callee (uint32_t a, uint32_t b)
{
  uint32_t sum;

  sum = x.value () + y.value ();
  x.set (a);
  y.set (b);
  return sum;
}

Note, unless x and y are defined as local variables, where the compiler can optimize the addresses, it will need to load addr into a register before de-registering it.
 
Last edited:
Hi Michael,

Thanks for the pointer (hate to use that term, but couldn't think of a better one).

This is a post that it took a while to figure out the answer and reply.

I decided I did need two pieces of code at the implementation level, and I just wanted one algorithm at the development level. So the answer was templates.

I have:

Code:
template <int N>    // Valid values are 1 or 2 to set up as FTM1 or FTM2
class QuadDecode{
    private:
    ...

// Setup address as FTM1 or FTM2 depending on template number

	volatile uint32_t * const pCNT = 
	    reinterpret_cast<volatile uint32_t*>((N<2) ? 
		    0x40039004:0x400B8004);
	volatile uint32_t &FTM_CNT=*pCNT;	// Counter

      ...

     uint16_t get_posn() {return FTM_CNT};

       ...

So now in my algorithm I can refer to FTM_CNT and have it compile as either FMT1_CNT or FTM2_CNT depending on the template number.

-Trudy
 
Status
Not open for further replies.
Back
Top