diff options
author | Josh Rahm <joshuarahm@gmail.com> | 2021-09-27 22:56:46 -0600 |
---|---|---|
committer | Josh Rahm <joshuarahm@gmail.com> | 2021-09-27 22:56:46 -0600 |
commit | 90eb3a0b79bfef67c70dc545b49c48928eea05f4 (patch) | |
tree | 66718a17063ce4fa5c32c4a8ac094d09f7fab6de /src | |
parent | 5f1763ec87503527583cb1a7c6deb73604db0dfc (diff) | |
download | stm32l4-90eb3a0b79bfef67c70dc545b49c48928eea05f4.tar.gz stm32l4-90eb3a0b79bfef67c70dc545b49c48928eea05f4.tar.bz2 stm32l4-90eb3a0b79bfef67c70dc545b49c48928eea05f4.zip |
Completed ws2812b 2020 Christmas Lights.ir_leds
Diffstat (limited to 'src')
-rw-r--r-- | src/drv/ws2812B/ws2812b.c | 26 | ||||
-rw-r--r-- | src/kern/main.c | 219 | ||||
-rw-r--r-- | src/shared/math.c | 38 |
3 files changed, 244 insertions, 39 deletions
diff --git a/src/drv/ws2812B/ws2812b.c b/src/drv/ws2812B/ws2812b.c index 3cf3570..aeb3784 100644 --- a/src/drv/ws2812B/ws2812b.c +++ b/src/drv/ws2812B/ws2812b.c @@ -4,32 +4,6 @@ #include "kern/mem.h" #include "kern/panic.h" -uint8_t sintable[256] = { - 128, 131, 134, 137, 140, 143, 146, 149, 152, 155, 158, 162, 165, 167, 170, - 173, 176, 179, 182, 185, 188, 190, 193, 196, 198, 201, 203, 206, 208, 211, - 213, 215, 218, 220, 222, 224, 226, 228, 230, 232, 234, 235, 237, 238, 240, - 241, 243, 244, 245, 246, 248, 249, 250, 250, 251, 252, 253, 253, 254, 254, - 254, 255, 255, 255, 255, 255, 255, 255, 254, 254, 254, 253, 253, 252, 251, - 250, 250, 249, 248, 246, 245, 244, 243, 241, 240, 238, 237, 235, 234, 232, - 230, 228, 226, 224, 222, 220, 218, 215, 213, 211, 208, 206, 203, 201, 198, - 196, 193, 190, 188, 185, 182, 179, 176, 173, 170, 167, 165, 162, 158, 155, - 152, 149, 146, 143, 140, 137, 134, 131, 128, 124, 121, 118, 115, 112, 109, - 106, 103, 100, 97, 93, 90, 88, 85, 82, 79, 76, 73, 70, 67, 65, - 62, 59, 57, 54, 52, 49, 47, 44, 42, 40, 37, 35, 33, 31, 29, - 27, 25, 23, 21, 20, 18, 17, 15, 14, 12, 11, 10, 9, 7, 6, - 5, 5, 4, 3, 2, 2, 1, 1, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 2, 2, 3, 4, 5, 5, 6, 7, 9, 10, 11, - 12, 14, 15, 17, 18, 20, 21, 23, 25, 27, 29, 31, 33, 35, 37, - 40, 42, 44, 47, 49, 52, 54, 57, 59, 62, 65, 67, 70, 73, 76, - 79, 82, 85, 88, 90, 93, 97, 100, 103, 106, 109, 112, 115, 118, 121, - 124, -}; - -uint8_t byte_sin(uint8_t n) -{ - return sintable[n]; -} - ws2812b_t* ws2812b_new(spi_select_t spi_select, int* ec) { spi_opts_t spi_opts = DEFAULT_SPI_OPTS; diff --git a/src/kern/main.c b/src/kern/main.c index 208f5d9..cdaa2b1 100644 --- a/src/kern/main.c +++ b/src/kern/main.c @@ -1,3 +1,5 @@ +#include <assert.h> + #include "arch.h" #include "arch/arm/cortex-m4/mpu.h" #include "arch/stm32l4xxx/peripherals/clock.h" @@ -25,8 +27,22 @@ #include "kern/priv.h" #include "kern/spi/spi_manager.h" #include "kern/systick/systick_manager.h" +#include "shared/math.h" #include "user/syscall.h" -#include <assert.h> + +volatile struct { + uint32_t time; + signed int timetick; + ws2812b_t* drv; + uint8_t brightness; + uint8_t n_leds; + uint8_t off; + uint8_t n_snow; + uint8_t n_red; + bool sleep; + bool power; + bool cool; +} state; void on_hard_fault() { @@ -35,34 +51,211 @@ void on_hard_fault() #ifdef ARCH_STM32L4 +void configure_gpio() +{ + int ec = 0; + + gpio_enable_alternate_function( + GPIO_ALTERNATE_FUNCTION_SPI1_MOSI, GPIO_PIN_PA7, &ec); + if (ec) { + panic("Unable to set pin PA7 (ec=%d)\n", ec); + } + gpio_enable_alternate_function( + GPIO_ALTERNATE_FUNCTION_SPI1_NSS, GPIO_PIN_PA4, &ec); + if (ec) { + panic("Unable to set pin PA4 (ec=%d)\n", ec); + } + gpio_enable_alternate_function( + GPIO_ALTERNATE_FUNCTION_SPI1_SCK, GPIO_PIN_PA5, &ec); + if (ec) { + panic("Unable to set pin PA5 (ec=%d)\n", ec); + } +} + void printit(uint32_t code, const char* str) { (void)code; klogf("%s\n", str); } +volatile bool do_redraw; +static void on_systick() +{ + if (!state.sleep) state.time += state.timetick; +} + +void redraw() +{ + uint32_t red = 0, green = 0, blue = 0; + + for (int i = 0; i < state.n_leds; ++i) { + if (!state.power) { + ws2812b_write_rgb_sync(state.drv, 0, 0, 0); + continue; + } + + red = byte_scale(byte_sin(state.time / 1000 + i * 4), 255 - state.n_red) + + state.n_red; + green = 255 - red; + + if (state.cool) { + uint32_t tmp = green; + green = blue; + blue = tmp; + } + + /* Add a little white flair that comes around every once in a while. */ + + uint32_t whitesum = 0; + if (state.n_snow) { + uint32_t white[] = { + /* Parallax "snow" */ + state.time / 179 + i * 8, + state.time / 193 + i * 12, + state.time / 211 + i * 16, + (state.time) / 233 + i * 8, + // (state.time + 128) / 233 + i * 8, + }; + + for (int i = 0; i < sizeof(white) / sizeof(uint32_t); ++i) { + if ((white[i] / 256) % state.n_snow == 0) { + white[i] = amp(byte_sin(white[i]), 20); + } else { + white[i] = 0; + } + whitesum += white[i]; + } + } + + ws2812b_write_rgb_sync( + state.drv, + byte_scale(min(red + whitesum, 255), state.brightness), + byte_scale(min(green + whitesum, 255), state.brightness), + byte_scale(min(blue + whitesum, 255), state.brightness)); + } + + ws2812b_latch(state.drv); + + delay(100000); +} + +void increment_it_u8(uint32_t unused, uint8_t* v) +{ + (*v)++; +} + +void decrement_it_u8(uint32_t unused, uint8_t* v) +{ + (*v)--; +} + +void timetick_up(uint32_t unused, void* nil) +{ + state.timetick += 5; +} + +void timetick_down(uint32_t unused, void* nil) +{ + state.timetick -= 5; +} + +void toggle_brightness(uint32_t unused, void* nil) +{ + klogf("Toggle %d\n", state.brightness); + if (state.brightness == 255) { + state.brightness = 32; + } else { + state.brightness = 255; + } +} + +static void toggle_sleep(uint32_t unused, void* nil) +{ + state.sleep = !state.sleep; +} + +static void toggle_power(uint32_t unused, void* nil) +{ + state.power = !state.power; +} + +static void toggle_cool(uint32_t unused, void* nil) +{ + state.cool = !state.cool; +} + +static void set_snow() +{ + state.n_snow = (state.n_snow + 1) % 10; +} + +static void set_red() +{ + state.n_red += 50; + state.n_red %= 250; +} + +static void reset_state() +{ + ws2812b_t* tmp = state.drv; + memset((void*) &state, 0, sizeof(state)); + state.drv = tmp; + state.brightness = 255; + state.n_leds = 250; + state.off = 8; + state.timetick = 10; + state.power = 1; + state.n_snow = 2; +} + /* Main function. This gets executed from the interrupt vector defined above. */ int main() { - klogf("Ir begin listening\n"); + klogf("Entering Main\n"); + + systick_add_callback(on_systick, NULL); + enable_systick(10000); + configure_gpio(); + ir_begin_listen(); enable_ir_control(); add_ir_code_callback(RC_HIGH, printit, "RC_HIGH"); - add_ir_code_callback(RC_TEMP_UP, printit, "RC_TEMP_UP"); - add_ir_code_callback(RC_DRY, printit, "RC_DRY"); + add_ir_code_callback(RC_TEMP_UP, timetick_up, NULL); + add_ir_code_callback(RC_DRY, set_red, NULL); add_ir_code_callback(RC_LOW, printit, "RC_LOW"); - add_ir_code_callback(RC_TEMP_DOWN, printit, "RC_TEMP_DOWN"); - add_ir_code_callback(RC_COOL, printit, "RC_COOL"); - add_ir_code_callback(RC_CONTINUOUS, printit, "RC_CONTINUOUS"); - add_ir_code_callback(RC_FAN, printit, "RC_FAN"); - add_ir_code_callback(RC_SLEEP, printit, "RC_SLEEP"); + add_ir_code_callback(RC_TEMP_DOWN, timetick_down, NULL); + add_ir_code_callback(RC_COOL, toggle_cool, NULL); + add_ir_code_callback(RC_CONTINUOUS, set_snow, "RC_CONTINUOUS"); + add_ir_code_callback(RC_FAN, toggle_brightness, NULL); + add_ir_code_callback(RC_SLEEP, toggle_sleep, NULL); add_ir_code_callback(RC_UNITS, printit, "RC_UNITS"); - add_ir_code_callback(RC_TIMER, printit, "RC_TIMER"); - add_ir_code_callback(RC_POWER, printit, "RC_POWER"); + add_ir_code_callback(RC_TIMER, reset_state, NULL); + add_ir_code_callback(RC_POWER, toggle_power, NULL); + + int ec; + state.drv = ws2812b_new(SPI_SELECT_SPI1, &ec); + + if (ec || !state.drv) { + panic("Unable to create WS2812b driver :( (%d)\n", ec); + } + + reset_state(); + + for (int i = 0; i < state.n_leds; ++i) { + /* Clear the LED strip. */ + disable_all_interrupts(); + ws2812b_write_rgb_sync(state.drv, 0, 0, 0); + enable_all_interrupts(); + } + ws2812b_latch(state.drv); - for (;;) - ; + for (;;) { + // while (!do_redraw) + // ; + // do_redraw = 0; + if (!state.sleep) redraw(); + } } #endif diff --git a/src/shared/math.c b/src/shared/math.c new file mode 100644 index 0000000..900cced --- /dev/null +++ b/src/shared/math.c @@ -0,0 +1,38 @@ +#include "shared/math.h" + +uint8_t sintable[256] = { + 128, 131, 134, 137, 140, 143, 146, 149, 152, 155, 158, 162, 165, 167, 170, + 173, 176, 179, 182, 185, 188, 190, 193, 196, 198, 201, 203, 206, 208, 211, + 213, 215, 218, 220, 222, 224, 226, 228, 230, 232, 234, 235, 237, 238, 240, + 241, 243, 244, 245, 246, 248, 249, 250, 250, 251, 252, 253, 253, 254, 254, + 254, 255, 255, 255, 255, 255, 255, 255, 254, 254, 254, 253, 253, 252, 251, + 250, 250, 249, 248, 246, 245, 244, 243, 241, 240, 238, 237, 235, 234, 232, + 230, 228, 226, 224, 222, 220, 218, 215, 213, 211, 208, 206, 203, 201, 198, + 196, 193, 190, 188, 185, 182, 179, 176, 173, 170, 167, 165, 162, 158, 155, + 152, 149, 146, 143, 140, 137, 134, 131, 128, 124, 121, 118, 115, 112, 109, + 106, 103, 100, 97, 93, 90, 88, 85, 82, 79, 76, 73, 70, 67, 65, + 62, 59, 57, 54, 52, 49, 47, 44, 42, 40, 37, 35, 33, 31, 29, + 27, 25, 23, 21, 20, 18, 17, 15, 14, 12, 11, 10, 9, 7, 6, + 5, 5, 4, 3, 2, 2, 1, 1, 1, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 2, 2, 3, 4, 5, 5, 6, 7, 9, 10, 11, + 12, 14, 15, 17, 18, 20, 21, 23, 25, 27, 29, 31, 33, 35, 37, + 40, 42, 44, 47, 49, 52, 54, 57, 59, 62, 65, 67, 70, 73, 76, + 79, 82, 85, 88, 90, 93, 97, 100, 103, 106, 109, 112, 115, 118, 121, + 124, +}; + +uint8_t byte_sin(uint8_t n) +{ + return sintable[n]; +} + +uint8_t amp(uint8_t in, uint8_t n) +{ + uint32_t out = in; + + for (int i = 0; i < n; ++i) { + out = (out * in) / 256; + } + + return min(out, 255); +} |