I/O Register Organization Change

The ATmega4809 organizes I/O registers by module and puts all the registers in C structures. The older AVR microcontrollers have a flat organization. For instance, take the Data Direction register for port B. In the ATmega328P this is simply defined:

#define DDRB _SFR_IO8(0x04)

This puts the register at location 0x04.

In the ATmega4809, all the registers of PORTB are defined as an instance of structure PORT_t at location 0x0400:

#define PORTB                (*(PORT_t *) 0x0420) /* I/O Ports */

But this structure contains multiple registers, of course. The structure is defined:

typedef struct PORT_struct
 {
     register8_t DIR;  /* Data Direction */
     register8_t DIRSET;  /* Data Direction Set */
     register8_t DIRCLR;  /* Data Direction Clear */
     register8_t DIRTGL;  /* Data Direction Toggle *
... 27 registers omitted for clarity ...
     register8_t reserved_0x1F;
 } PORT_t;

So instead of writing DDRB |= 1<<2; one would write PORTB.DIR |= 1<<2;

However, I would guess as a concession to the traditionalists, they have also defined:

#define PORTB_DIR  _SFR_MEM8(0x0420)

So you can avoid the structure (but why?) and write PORTB_DIR |= 1<<2;

In this particular case we would probably use the Virtual Port feature which allows us to set the direction using a lower address, which generates smaller and faster code. VPORTB.DIR |= 1<<2;

Instead we could eliminate the need for a read-modify-write of the register, which would not be an atomic operation for PORTB (it would be for VPORTB) by using the DIRSET register. They have cleverly added what I call virtual registers that are write only and modify an existing register. DIRSET will set bits in the DIR register eliminating the need to read the register first. So PORTB.DIRSET = 1<<2;

I’ve revised the Pins library provided in Far Inside The Arduino to handle the new structure of the ATmega4809. Using this library we can still write ddr.digital_5 = 1; to change digital pin 5 (Port B bit 2 on the Arduino Nano Every) to be an output pin.