I need to write a function that uses interface functions from other components to get individual values for year, month, day, hour, minute, second, and then pack those values into a 5-byte message payload and provide it to another component by using an unsigned char pointer as function parameter. The payload structure is strictly defined and must look like this:
| | bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0 |
| -------------- | -------------- | -------------- | --------------| --------------| --------------| --------------|-------------- |-------------- |
| byte 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | year |
| byte 1 | year | year | year | year | year | year | month | month |
| byte 2 | month | month | day | day | day | day | day | hour |
| byte 3 | hour | hour | hour | hour | minute | minute | minute | minute |
| byte 4 | minute | minute | second | second | second | second | second | second |
My current approach is:
void prepareDateAndTimePayload(unsigned char * message)
{
unsigned char payload[5] = {0};
unsigned char year = getYear();
unsigned char month = getMonth();
unsigned char day = getDay();
unsigned char hour = getHour();
unsigned char minute = getMinute();
unsigned char second = getSecond();
payload[0] = (year & 0x40) >> 6u; //get 7th bit of year and shift it
payload[1] = ((year & 0x3F) << 2u) | ((month & 0xC) >> 2u); //remaining 6 bits of year and starting with month
payload[2] = ((month & 0x3) << 6u) | ((day & 0x1F) << 1u) | ((hour & 0x10) >> 4u); //...
payload[3] = ((hour & 0xF) << 4u) | ((minute & 0x3C) >> 2u);
payload[4] = ((minute & 0x3) << 6u) | (second & 0x3F); //...
memcpy(message, payload, sizeof(payload));
}
I'm wondering how I should approach extracting the particular bits and packing them into a payload, so they match the required message structure. I find my version with bit masks and bit shifting to be messy and not elegant. Is there any better way to do it?