[C++] Operations on I/O registers and I/O port pins

1 post / 0 new
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I've updated avrIO to allow operations on multiple pins and also actions on registers and its respective bits.


MCUCR = (MCUCR & ~(1<<SM0)) | (1<<SM1) | (1<<SE);


The statement can be rewritten using a more concise and type safe solution that doesn't add any overhead to the generated code:

mcucr = (mcucr & ~sm0) | sm1 | se;


The same operation has an alternative approach that is more concise and expressive. The generated code is the same as the one generated to the first statement using macros and bitwise operators:

set(sm0(off), sm1, se);


Generated code with -mmcu=attiny13a -Os and avr-gcc 10.2:
in     r24, 0x35
andi   r24, 0xC7
ori    r24, 0x30
out    0x35, r24


Integers can still be assigned to registers:

portb = 0x07;


Something more expressive that doesn't use bitwise operators can be used:

portb = {pb2, pb1, pb0};


Try to mix bits from different registers generates a compile error:

portb = pb0 | pc1; //compile error


But the byte value can be obtained to bypass the type system:

portb = pb0 | pc1.bv();


All operations on I/O port pins can now be used with multiple pins, for example:
//input mode with pull-up resistor enabled to pb2 and pb1
auto [swA, swB] = in(pullup, pb2, pb1);

//output mode to pb0 and pb4
auto [ledA, ledB] = out(pb0, pb4);


Generated code with -mmcu=attiny13a -Os and avr-gcc 10.2:
cbi    0x17, 2
cbi    0x17, 1
sbi    0x18, 2
sbi    0x18, 1
sbi    0x17, 0
sbi    0x17, 4




Let me know if you would like to use this work with a MCU that isn't supported right now.



avrIO: Operation of I/O port pins and I/O registers.

Last Edited: Sat. Mar 27, 2021 - 12:16 AM