Search code examples
c++pointersavr

Passing hardware register pointer


I'm poking around with xMega AVR microcontroller, and having trouble passing the hardware register as a pointer. Pretty sure this is pointer magic, but after a long day can't understand what's wrong.

PORTA is defined (in GCC-AVR toolchain) as follows:

#define PORTA (*(PORT_t *) 0x0600)

This works:

int main(void)
{
    // This will set GPIO high
    PORTA.DIRSET = 1 << 1;
    PORTA.OUTSET = 1 << 1;

    while(1) {};
}

And this won't work:

void gpio_output_set(PORT_t * port, unsigned char pin)
{
    // This will *NOT* set GPIO high
    port->DIRSET = 1 << pin;
    port->OUTSET = 1 << pin;
}

int main(void)
{
    gpio_output_set(&PORTA, 1);

    while(1) {};
}

Why?


Solution

  • I think it should work.

    Essentially it the same as

    PORT_t* pPort = &*(PORT_t*)0x0600;
    pPort->DIRSET = 0x01;
    

    So why should this be a problem? The Atmel Software Framework libraries use this as well:

    void PORT_ConfigureInterrupt0(PORT_t* port, PORT_INT0LVL_t intLevel, uint8_t pinMask);
    
    PORT_ConfigureInterrupt0(&PORTC, PORT_INT0LVL_MED_gc, 0x01);