I am trying to make write a code for i2c communication with a device (ADS1115). The communication uses different arrays of bits for commands and sending data back, in which most bits or group of bits have different meanings. So, I did the natural thing that came to my mind and wrote enum classes like this:
enum class latching_comparator : bool
{
non_latching= false, //default
latching = true
};
enum class comparator_polarity : bool
{
low = false, //default
high= true
};
I know I can derive my enum class from uint8_t and uint16_t for 8 and 16 bit entities but I don't need them. What I need instead are 2 and 3 bit entities. However, I can't do this:
typedef std::bitset<2> twobits;
enum class comperator : twobits
{
...
}
Is there a way I can group bits like this and make it easy to write further codes using this? Is there a way to combine and get back bits/groups of bits this way?
Suggestions for any other method of doing this is also welcome.
You can use bit fields in a struct to accomplish this. Depending on what you are doing, you may need to use
#pragma packwhich will fix alignment issues.This says that each enum in the struct uses only 1 bit. The test member uses 3 bits, which could be a 3 bit value or flag member, just as an example. This will only use one byte for both enums. Technically it only uses 5 bits, but 8 bit arch technically can't go lower, so you always use at least 8. If you use 9 bits in the struct, it will use 2 bytes since you move into another byte for bit 9.
Will print
1because it only uses one byte to accomplish this.I didn't read the documentation on the hardware you're interfacing with, but it would be best to design the entire struct around the registers you're configuring. The bit sizes will vary for each configuration in that register, but generally I write one struct for each register, manipulate the struct, then i just output the bytes of the struct straight into the communication interface, no need to hassle with bit shifting etc.
Edit: I'm feeling generous today, so here is some of the code to work with the config register of that chip (reading or writing). The register has more configurations in it, so you still need to finish it, but it gives you a direct example of what I'm talking about.