Compare commits
No commits in common. "1c7d6984d0106b4751d899eca3290389fd58d421" and "12e5f2292945b3461c083a62eb4a8e536d9265a9" have entirely different histories.
1c7d6984d0
...
12e5f22929
8 changed files with 2 additions and 321 deletions
91
brightness.c
91
brightness.c
|
|
@ -1,91 +0,0 @@
|
||||||
#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");
|
|
||||||
}
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
CC ?= gcc
|
|
||||||
CFLAGS ?= -Wall -O2 -lcjson
|
|
||||||
|
|
||||||
TARGET = main.elf
|
|
||||||
SRC = main.c
|
|
||||||
|
|
||||||
$(TARGET): $(SRC)
|
|
||||||
@echo CC $@
|
|
||||||
@$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -f $(TARGET)
|
|
||||||
|
|
@ -6,10 +6,9 @@ char *build_set_level_command(int level) {
|
||||||
cJSON_AddStringToObject(root, "cmd", "set_level");
|
cJSON_AddStringToObject(root, "cmd", "set_level");
|
||||||
cJSON_AddNumberToObject(root, "level", level);
|
cJSON_AddNumberToObject(root, "level", level);
|
||||||
|
|
||||||
// char *message = cJSON_PrintUnformatted(root);
|
char *message = cJSON_PrintUnformatted(root);
|
||||||
char *msg2 = cJSON_Print(root);
|
|
||||||
cJSON_Delete(root);
|
cJSON_Delete(root);
|
||||||
return msg2; // Remember to free this when done!
|
return message; // Remember to free this when done!
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
|
|
@ -23,9 +23,7 @@ uint32_t murmur3_32(const uint8_t* key, size_t len, uint32_t seed) {
|
||||||
k = 0;
|
k = 0;
|
||||||
switch (len & 3) {
|
switch (len & 3) {
|
||||||
case 3: k ^= key[i + 2] << 16;
|
case 3: k ^= key[i + 2] << 16;
|
||||||
/* fall through */
|
|
||||||
case 2: k ^= key[i + 1] << 8;
|
case 2: k ^= key[i + 1] << 8;
|
||||||
/* fall through */
|
|
||||||
case 1: k ^= key[i + 0];
|
case 1: k ^= key[i + 0];
|
||||||
k *= c1; k = (k << 15) | (k >> (32 - 15)); k *= c2; h ^= k;
|
k *= c1; k = (k << 15) | (k >> (32 - 15)); k *= c2; h ^= k;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
# Language: C
|
|
||||||
BasedOnStyle: LLVM
|
|
||||||
IndentWidth: 4 # Use 4 spaces for indentation
|
|
||||||
TabWidth: 4 # Tab width is also 4 spaces
|
|
||||||
UseTab: Never # Always use spaces instead of tabs
|
|
||||||
ColumnLimit: 80 # Wrap lines after 80 characters
|
|
||||||
AllowShortLoopsOnASingleLine: true
|
|
||||||
|
|
@ -1,126 +0,0 @@
|
||||||
#include <malloc.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
/* See: https://8dcc.github.io/programming/pool-allocator.html */
|
|
||||||
/* See: https://github.com/8dcc/libpool */
|
|
||||||
|
|
||||||
#define CHUNK_SIZE 64
|
|
||||||
|
|
||||||
typedef union Chunk Chunk;
|
|
||||||
union Chunk {
|
|
||||||
Chunk *next; // When not null, it is used
|
|
||||||
char arr[CHUNK_SIZE];
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct LinkedPtr LinkedPtr;
|
|
||||||
struct LinkedPtr {
|
|
||||||
Chunk *ptr;
|
|
||||||
LinkedPtr *next;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct Pool Pool;
|
|
||||||
struct Pool {
|
|
||||||
Chunk *free_chunk; // Pointer to a linked list of free chunks
|
|
||||||
LinkedPtr *array_starts;
|
|
||||||
};
|
|
||||||
|
|
||||||
Pool *pool_new(size_t pool_size) {
|
|
||||||
Pool *pool = malloc(sizeof(Pool));
|
|
||||||
|
|
||||||
if (pool == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
Chunk *arr = pool->free_chunk = malloc(pool_size * sizeof(Chunk));
|
|
||||||
if (arr == NULL) {
|
|
||||||
free(pool);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (size_t i = 0; i < pool_size - 1; i++) arr[i].next = &arr[i + 1];
|
|
||||||
arr[pool_size - 1].next = NULL;
|
|
||||||
|
|
||||||
pool->array_starts = malloc(sizeof(LinkedPtr));
|
|
||||||
if (pool->array_starts == NULL) {
|
|
||||||
/* Allocation failed */
|
|
||||||
free(arr);
|
|
||||||
free(pool);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
pool->array_starts->next = NULL;
|
|
||||||
pool->array_starts->ptr = arr;
|
|
||||||
|
|
||||||
return pool;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *pool_alloc(Pool *pool) {
|
|
||||||
if (pool == NULL || pool->free_chunk == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
// Pop a new one from the free list
|
|
||||||
Chunk *result = pool->free_chunk;
|
|
||||||
pool->free_chunk = pool->free_chunk->next;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void pool_free(Pool *pool, void *ptr) {
|
|
||||||
if (pool == NULL || ptr == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// This can be done withuot an intermediate ptr
|
|
||||||
Chunk *freed = ptr;
|
|
||||||
freed->next = pool->free_chunk;
|
|
||||||
pool->free_chunk = freed;
|
|
||||||
}
|
|
||||||
|
|
||||||
void pool_close(Pool *pool) {
|
|
||||||
if (pool == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
LinkedPtr *lptr = pool->array_starts;
|
|
||||||
while (lptr != NULL) {
|
|
||||||
LinkedPtr *next = lptr->next;
|
|
||||||
free(lptr->ptr);
|
|
||||||
free(lptr);
|
|
||||||
lptr = next;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(pool);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool pool_resize(Pool *pool, size_t extra_chunk_num) {
|
|
||||||
if (pool == NULL || extra_chunk_num == 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Allocate the array of extra chunks that we are trying to add to the pool.
|
|
||||||
Chunk *extra_chunk_arr = malloc(extra_chunk_num * sizeof(Chunk));
|
|
||||||
if (extra_chunk_arr == NULL)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Link the new chunks together, just like we did when creating the pool.
|
|
||||||
for (size_t i = 0; i < extra_chunk_num - 1; i++)
|
|
||||||
extra_chunk_arr[i].next = &extra_chunk_arr[i + 1];
|
|
||||||
|
|
||||||
// Prepend the array of extra chunks to the “free chunks” list, just like we
|
|
||||||
// did when freeing chunks.
|
|
||||||
extra_chunk_arr[extra_chunk_num - 1].next = pool->free_chunk;
|
|
||||||
pool->free_chunk = extra_chunk_arr;
|
|
||||||
|
|
||||||
// Allocate a new LinkedPtr structure, and store the start of the new chunk
|
|
||||||
// array in it.
|
|
||||||
LinkedPtr *array_start = malloc(sizeof(LinkedPtr));
|
|
||||||
if (array_start == NULL) {
|
|
||||||
free(extra_chunk_arr);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prepend this new LinkedPtr structure to the linked list of “array
|
|
||||||
// starts”, stored inside the Pool structure.
|
|
||||||
array_start->ptr = extra_chunk_arr;
|
|
||||||
array_start->next = pool->array_starts;
|
|
||||||
pool->array_starts = array_start;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
@ -1,47 +0,0 @@
|
||||||
#include <malloc.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
/* See: https://8dcc.github.io/programming/pool-allocator.html */
|
|
||||||
|
|
||||||
#define CHUNK_SIZE 64
|
|
||||||
|
|
||||||
typedef union Chunk Chunk;
|
|
||||||
union Chunk {
|
|
||||||
Chunk *next; // When not null, it is used
|
|
||||||
char arr[CHUNK_SIZE];
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct Pool Pool;
|
|
||||||
struct Pool {
|
|
||||||
Chunk *free_chunk; // Pointer to a linked list of free chunks
|
|
||||||
Chunk *chunk_arr;
|
|
||||||
};
|
|
||||||
|
|
||||||
void *pool_alloc(Pool *pool) {
|
|
||||||
if (pool == NULL || pool->free_chunk == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
// Pop a new one from the free list
|
|
||||||
Chunk *result = pool->free_chunk;
|
|
||||||
pool->free_chunk = pool->free_chunk->next;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void pool_free(Pool *pool, void *ptr) {
|
|
||||||
if (pool == NULL || ptr == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// This can be done withuot an intermediate ptr
|
|
||||||
Chunk *freed = ptr;
|
|
||||||
freed->next = pool->free_chunk;
|
|
||||||
pool->free_chunk = freed;
|
|
||||||
}
|
|
||||||
|
|
||||||
void pool_close(Pool *pool) {
|
|
||||||
if (pool == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
free(pool->chunk_arr);
|
|
||||||
free(pool);
|
|
||||||
}
|
|
||||||
|
|
@ -1,33 +0,0 @@
|
||||||
#!/usr/bin/env lua
|
|
||||||
|
|
||||||
local m = {}
|
|
||||||
|
|
||||||
print("Hello")
|
|
||||||
os.execute("echo $SHELL")
|
|
||||||
|
|
||||||
m.abc = {
|
|
||||||
kek = 10,
|
|
||||||
}
|
|
||||||
|
|
||||||
function m:print()
|
|
||||||
print(m.abc.kek)
|
|
||||||
end
|
|
||||||
|
|
||||||
function os.getName()
|
|
||||||
local osname
|
|
||||||
-- ask LuaJIT first
|
|
||||||
if jit then
|
|
||||||
return jit.os
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Unix, Linux variants
|
|
||||||
local fh, _ = assert(io.popen("uname -o 2>/dev/null", "r"))
|
|
||||||
if fh then
|
|
||||||
osname = fh:read()
|
|
||||||
end
|
|
||||||
|
|
||||||
return osname or "Windows"
|
|
||||||
end
|
|
||||||
|
|
||||||
m:print()
|
|
||||||
print(os.getName())
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue