91 lines
3.6 KiB
C
91 lines
3.6 KiB
C
#include <assert.h>
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
// #define SET_BIT(BF, N) BF |= ((uint64_t)0x1 << N)
|
|
// #define CLEAR_BIT(BF, N) BF &= ~((uint64_t)0x1 << N)
|
|
// #define IS_BIT_SET(BF, N) ((BF >> N) & 0x1)
|
|
// #define SET_BIT(BF, N) ((BF) |= ((typeof(BF))1 << (N)))
|
|
// #define CLEAR_BIT(BF, N) ((BF) &= ~((typeof(BF))1 << (N)))
|
|
// #define IS_BIT_SET(BF, N) (((BF) >> (N)) & (typeof(BF))1)
|
|
|
|
#define UINT_CAST(x) \
|
|
_Generic((x), \
|
|
uint8_t: (uint8_t)1, \
|
|
uint16_t: (uint16_t)1, \
|
|
uint32_t: (uint32_t)1, \
|
|
uint64_t: (uint64_t)1, \
|
|
default: (x) /* fallback */ \
|
|
)
|
|
|
|
#define SET_BIT(BF, N) ((BF) |= (UINT_CAST(BF) << (N)))
|
|
#define CLEAR_BIT(BF, N) ((BF) &= ~(UINT_CAST(BF) << (N)))
|
|
#define IS_BIT_SET(BF, N) (((BF) >> (N)) & UINT_CAST(BF))
|
|
|
|
typedef enum : char {
|
|
BRIGHTNESS_SET_INSTANT, //!< Set instantly with no delay
|
|
BRIGHTNESS_CMD_TRY_SET, //!< Set brightness, ignored if setpoint already exists
|
|
BRIGHTNESS_CMD_QUEUE, //!< Set brightness, queued if setpoint already exists
|
|
BRIGHTNESS_CMD_FORCE, //!< Force set brightness target
|
|
BRIGHTNESS_CMD_HOLD, //!< Force set brightness target to current brightness
|
|
} brightness_cmd_t;
|
|
|
|
typedef struct {
|
|
uint8_t type : 8;
|
|
uint32_t value : 24;
|
|
} brightness_cmd;
|
|
|
|
int main(void) {
|
|
assert(sizeof(brightness_cmd) == 4);
|
|
assert(sizeof(brightness_cmd_t) == 1);
|
|
|
|
// Examples
|
|
brightness_cmd cmd1 = {.type = BRIGHTNESS_CMD_FORCE, .value = 100};
|
|
brightness_cmd cmd2 = {.type = BRIGHTNESS_CMD_TRY_SET, .value = 50};
|
|
brightness_cmd cmd3 = {.type = BRIGHTNESS_CMD_QUEUE, .value = (1 << 23)};
|
|
|
|
// For readout comparisons later
|
|
brightness_cmd read1 = cmd1;
|
|
brightness_cmd read2 = cmd2;
|
|
brightness_cmd read3 = cmd3;
|
|
|
|
SET_BIT(*(int *)&read1, 10);
|
|
|
|
// In this case, our command structure fits neatly into a 32 bit integer
|
|
// so we can simply cast it directly:
|
|
uint32_t int_cmd = *(uint32_t *)&cmd1;
|
|
assert(memcmp(&int_cmd, &cmd1, 4) == 0);
|
|
|
|
// To buffer
|
|
char buf[12];
|
|
|
|
*(uint32_t *)&buf[0] = *(uint32_t *)&cmd1;
|
|
*(uint32_t *)&buf[4] = *(uint32_t *)&cmd2;
|
|
*(uint32_t *)&buf[8] = *(uint32_t *)&cmd3;
|
|
|
|
// Wipe these so we can read them back from the buffer
|
|
memset(&cmd1, 0, 4);
|
|
memset(&cmd2, 0, 4);
|
|
memset(&cmd3, 0, 4);
|
|
|
|
// Note that these are neq's
|
|
assert(memcmp(&cmd1, &read1, 4) != 0);
|
|
assert(memcmp(&cmd2, &read2, 4) != 0);
|
|
assert(memcmp(&cmd3, &read3, 4) != 0);
|
|
|
|
cmd1 = *(brightness_cmd *)&buf[0];
|
|
cmd2 = *(brightness_cmd *)&buf[4];
|
|
cmd3 = *(brightness_cmd *)&buf[8];
|
|
|
|
assert(memcmp(&cmd1, &read1, 4) == 0);
|
|
assert(memcmp(&cmd2, &read2, 4) == 0);
|
|
assert(memcmp(&cmd3, &read3, 4) == 0);
|
|
|
|
brightness_cmd casted = *(brightness_cmd *)&read1;
|
|
assert(memcmp(&read1, &casted, 4) == 0);
|
|
|
|
printf("Sizeof(brightness_cmd) = %ld\n", sizeof(brightness_cmd));
|
|
printf("Sizeof(brightness_cmd_t) = %ld\n", sizeof(brightness_cmd));
|
|
printf("All is well!\n");
|
|
}
|