I happen to be working on a C++ BitFields library for microcontrollers and I'm starting with AVR and the ATmega328P.
Here's an example - this will be part of a header file specific to the ATmega328P - see:
https://bitbucket.org/owebeeone/ardoinus/src/master/ardOinus/src/sys/mcu/avr/ardo_supplemental_atmega328p_dev.hThis is a snippet from that file:
/**
* Controls for timer output compare register modes.
*/
enum class EnumCOMn : unsigned char {
disconnect = 0b00,
toggle = 0b01, // Reserved for Fast PWM mode on COM2A
clear = 0b10,
set = 0b11
};
/**
* Bit field definitions for the COMnA and COMnB fields.
*/
using BitsCOM0A = setl::BitsRW<
setl::SemanticType<setl::hash("COM0A"), EnumCOMn>, ccCOM0A1, ccCOM0A0>;
using BitsCOM0B = setl::BitsRW<
setl::SemanticType<setl::hash("COM0B"), EnumCOMn>, ccCOM0B1, ccCOM0B0>;
...
// Define register TCCR0AB.
using FieldsTCCR0AB = setl::BitFields<
BitsCOM0A, BitsCOM0B,
BitsWGM0_210,
BitsFOC0A_16, BitsFOC0B_16,
BitsCS01_16>;
using rrTCCR0AB = rrTCCR0A::ForType<std::uint16_t>;
using RegisterTCCR0AB = Register<FieldsTCCR0AB, rrTCCR0AB>;
So not you can set and get all the bitfields of interest in one read or ReadModifyWrite cycle.
e.g.
RegisterTCCR0AB::ReadModifyWrite(BitsCS01_16{ EnumCS0::clk8}, BitsWGM_16{ EnumWGM::fast_pwm_icr });
or
BitsCOM0A com0a;
BitsWGM0_210 wgm;
Assign(com0a, wgm) = RegisterTCCR0AB::Read();
Will write the CS and WGM bits in a single RMW operation. (although this is actually defined as a 16 bit register so its happening as a 2 8 bit reads followed by 2 8 bit writes).
It also allows the creation of a selection of registers where you can simply write all the values you want to write in one statement and the bitfield library will find the corresponding registers and write all the values to corresponding to the value types given.
It's still a work in progress when it comes to the AVR interfaces, I've only done the GPIO and and most of the timers interfaces, however the bitfield library I think is mostly done and generic so it should work on anything with C++14 and higher language support.
In theory, user/application code will never do anything with the bitfields interface, that should all be done in the MCU support library so all this bitfield madness is to make that code more easily reusable across different processors. Hence I'll be ripping out the generic bits of ardo_supplemental_atmega328p_dev.h into another file soon..ish.