Skip to content

Instantly share code, notes, and snippets.

@jlennox
Last active June 2, 2021 17:37
Show Gist options
  • Save jlennox/5b20cd1164f072aeb31eb72f9bcca72c to your computer and use it in GitHub Desktop.
Save jlennox/5b20cd1164f072aeb31eb72f9bcca72c to your computer and use it in GitHub Desktop.
Bit twiddling PORT optimizations on AVR 1/0 series (attiny, atmega)
  • PORTB.DIR |= 0b010 is 5 instructions.
  • PORTB.DIRSET = 0b010 is 2 instructions, one of which is double width (2 tick?).
  • VPORTB.DIR |= 0b010 is optimized by the compiler to 1 instruction.

The magic sauce is that VPORTB is mapped to 0x0000 (PORTB is mapped to 0x0400), the chips have instructions to bit twiddle in a single instruction but only on addresses 0x00 to 0x1F. The higher mapping has extra costs on an 8bit CPU.

// PORTB.DIR |= PIN3_bm;
80a:	e0 e2       	ldi	r30, 0x20	; 32
80c:	f4 e0       	ldi	r31, 0x04	; 4
80e:	80 81       	ld	r24, Z
810:	88 60       	ori	r24, 0x08	; 8
812:	80 83       	st	Z, r24

// PORTB.DIRSET = PIN3_bm;
80a:	88 e0       	ldi	r24, 0x08	; 8
80c:	80 93 21 04 	sts	0x0421, r24	; 0x800421 <font_data+0x7f721a>

// VPORTB.DIR |= PIN3_bm;
80a:	23 9a       	sbi	0x04, 3	; 4
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment