Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 3 of 3

Thread: Register Addressing

  1. #1

    Register Addressing

    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

  2. #2
    Senior Member+ MichaelMeissner's Avatar
    Join Date
    Nov 2012
    Location
    Ayer Massachussetts
    Posts
    3,252

    Cool

    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 by MichaelMeissner; 05-15-2014 at 04:23 AM.

  3. #3
    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

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •