From 105afca3d95adffc0448826e3a7540461073154d Mon Sep 17 00:00:00 2001 From: Kuba Birecki Date: Sat, 4 Dec 2021 17:22:13 +0100 Subject: [PATCH] Clean up the main animation module --- app/src/animation/animation.c | 91 ++++++++++++----------------------- 1 file changed, 31 insertions(+), 60 deletions(-) diff --git a/app/src/animation/animation.c b/app/src/animation/animation.c index c34dd9e2..e9c572f8 100644 --- a/app/src/animation/animation.c +++ b/app/src/animation/animation.c @@ -20,26 +20,31 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); -#define PHANDLE_TO_DEVICE(node_id, prop, idx) \ +// Zephyr 2.7.0 comes with DT_INST_FOREACH_PROP_ELEM +// that we can't use quite yet as we're still on 2.5.* +#define ZMK_DT_INST_FOREACH_PROP_ELEM(inst, prop, fn) \ + UTIL_LISTIFY(DT_INST_PROP_LEN(inst, prop), fn, DT_DRV_INST(inst), prop) + +#define PHANDLE_TO_DEVICE(idx, node_id, prop) \ DEVICE_DT_GET(DT_PHANDLE_BY_IDX(node_id, prop, idx)), -#define PHANDLE_TO_CHAIN_LENGTH(node_id, prop, idx) \ +#define PHANDLE_TO_CHAIN_LENGTH(idx, node_id, prop) \ DT_PROP_BY_PHANDLE_IDX(node_id, prop, idx, chain_length), -#define PHANDLE_TO_PIXEL(node_id, prop, idx) \ - { \ - .animation = DEVICE_DT_GET(DT_PHA_BY_IDX(node_id, prop, idx, animation)), \ - .position = { \ - .x = DT_PHA_BY_IDX(node_id, prop, idx, position_x), \ - .y = DT_PHA_BY_IDX(node_id, prop, idx, position_y), \ - }, \ +#define PHANDLE_TO_PIXEL(idx, node_id, prop) \ + { \ + .animation = PHANDLE_TO_DEVICE(idx, node_id, prop) \ + .position = { \ + .x = DT_PHA_BY_IDX(node_id, prop, idx, position_x),\ + .y = DT_PHA_BY_IDX(node_id, prop, idx, position_y),\ + }, \ }, /** * LED Driver device pointers. */ static const struct device *drivers[] = { - DT_INST_FOREACH_PROP_ELEM(0, drivers, PHANDLE_TO_DEVICE) + ZMK_DT_INST_FOREACH_PROP_ELEM(0, drivers, PHANDLE_TO_DEVICE) }; /** @@ -51,14 +56,14 @@ static const size_t drivers_size = DT_INST_PROP_LEN(0, drivers); * Array containing the number of LEDs handled by each device. */ static const uint8_t pixels_per_driver[] = { - DT_INST_FOREACH_PROP_ELEM(0, drivers, PHANDLE_TO_CHAIN_LENGTH) + ZMK_DT_INST_FOREACH_PROP_ELEM(0, drivers, PHANDLE_TO_CHAIN_LENGTH) }; /** * Pointers to all active animation devices. */ static const struct device *animations[] = { - DT_INST_FOREACH_PROP_ELEM(0, animations, PHANDLE_TO_DEVICE) + ZMK_DT_INST_FOREACH_PROP_ELEM(0, animations, PHANDLE_TO_DEVICE) }; /** @@ -70,32 +75,32 @@ static const size_t animations_size = DT_INST_PROP_LEN(0, animations); * Pixel configuration. */ static const struct animation_pixel pixels[] = { - DT_INST_FOREACH_PROP_ELEM(0, animations, PHANDLE_TO_PIXEL) + ZMK_DT_INST_FOREACH_PROP_ELEM(0, pixels, PHANDLE_TO_PIXEL) }; /** * Size of the pixels array. */ -const size_t pixels_size = DT_INST_PROP_LEN(0, pixels); +static const size_t pixels_size = DT_INST_PROP_LEN(0, pixels); /** * Buffer for RGB values ready to be sent to the drivers. */ -struct led_rgb px_buffer[DT_INST_PROP_LEN(0, pixels)]; +static struct led_rgb px_buffer[DT_INST_PROP_LEN(0, pixels)]; -void zmk_animation_tick() { - for (size_t i = 0; i < ZMK_ANIMATIONS_LENGTH; ++i) { +static void zmk_animation_tick(struct k_work *work) { + for (size_t i = 0; i < animations_size; ++i) { animation_prep_next_frame(animations[i]); } for (size_t i = 0; i < pixels_size; ++i) { - zmk_color_rgb rgb = { + struct zmk_color_rgb rgb = { .r = 0, .g = 0, .b = 0, }; - animation_get_pixel(pixel.animation, &pixel.position, &rgb); + animation_get_pixel(pixels[i].animation, &pixels[i].position, &rgb); zmk_rgb_to_led_rgb(&rgb, &px_buffer[i]); } @@ -109,12 +114,10 @@ void zmk_animation_tick() { pixels_per_driver[i] ); - pixels_updated += pixels_per_driver; + pixels_updated += (size_t) pixels_per_driver; } } -// Set up timer here - K_WORK_DEFINE(animation_work, zmk_animation_tick); static void zmk_animation_tick_handler(struct k_timer *timer) { @@ -123,44 +126,12 @@ static void zmk_animation_tick_handler(struct k_timer *timer) { K_TIMER_DEFINE(animation_tick, zmk_animation_tick_handler, NULL); -// Init +static int zmk_animation_init(const struct device *dev) { + LOG_INF("ZMK Animation Ready"); -void zmk_animation_init(const struct device *dev) { - // default FPS: 24, 30 or 60? - k_timer_start(&animation_tick, K_NO_WAIT, K_MSEC(1000 / ZMK_ANIMATION_FPS)); + k_timer_start(&animation_tick, K_NO_WAIT, K_MSEC(1000 / CONFIG_ZMK_ANIMATION_FPS)); + + return 0; } -// Actually, all of this might be a little hard to represent inside a config file. -// We need: -// -// - Each animation has its own node -// -// - animations[] = phandle array of animations -// -// - pixel.pos = x,y coordinates of each pixels, could be a byte array -// -// - pixel.animations = Number array, but it's per pixel and it's not fixed length per pixel!! PROBLEM!!! -// - pixel.blending_modes = Could be a number array again. Use some macros. -// -// - unless we say there can only be 32 different animations and use uint32_t as a bitmask? -// - but then blending modes suck and you can't order them -// - -// ALTERNATIVE: -// -// Eventually we don't want to be using the device tree to set these up anyway. -// It should be possible to instantiate animations dynamically and the settings should be stored in flash. -// Maybe it's something to look into now? -// - -// ALTERNATIVE no2: -// -// Look at behaviors. -// It seems that pixels themselves could be 'drivers' ? -// -// That's probably best tbh - -// NOTE WHEN DEFINING PIXELS: -// See if it's maybe possible to re-use default_transform to assign pixels to keys? -// Assuming the first batch is always the keys which is not an easy assumption to make. -// Otherwise need it's own map +SYS_INIT(zmk_animation_init, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY);