Search code examples
c++cavr

Preprocessor directive for certain address space


Lets say I wanted to define a directive that could take an int8_t and store it to a specified memory location say 0x0071. How would I do this?

I know I could say

#define DDRA 0xAA

And that would make DDRA = 0xAA, but how do I make it so that typing

DDRA = 0xBB;

will write 0xBB in address location 0x0071?


Solution

  • The AVR-GCC headers define I/O ports using the internal _SFR_IO8 macro, e.g. in <avr/iom328p.h>:

    #define PORTB _SFR_IO8(0x05)
    

    This macro is defined in <avr/srf_defs.h> as:

    #define _SFR_IO8(io_addr) _MMIO_BYTE((io_addr) + __SFR_OFFSET)
    

    Which, in turn, is resolved by the _MMIO_BYTE macro in the same file:

    #define _MMIO_BYTE(mem_addr) (*(volatile uint8_t *)(mem_addr))
    

    The definition of __SFR_OFFSET is… a little obscure. It has to do with the 32-byte offset between the AVR I/O space and the start of memory.

    TL;DR: #define DDRA _SFR_IO8(0x71), but the standard headers for your part should be doing this already if it's actually a standard I/O port.