diff options
Diffstat (limited to 'src/kern/main.c')
-rw-r--r-- | src/kern/main.c | 236 |
1 files changed, 174 insertions, 62 deletions
diff --git a/src/kern/main.c b/src/kern/main.c index fab2eb9..cdaa2b1 100644 --- a/src/kern/main.c +++ b/src/kern/main.c @@ -1,11 +1,19 @@ +#include <assert.h> + #include "arch.h" #include "arch/arm/cortex-m4/mpu.h" #include "arch/stm32l4xxx/peripherals/clock.h" #include "arch/stm32l4xxx/peripherals/dma.h" +#include "arch/stm32l4xxx/peripherals/exti.h" #include "arch/stm32l4xxx/peripherals/irq.h" #include "arch/stm32l4xxx/peripherals/rcc.h" #include "arch/stm32l4xxx/peripherals/spi.h" +#include "arch/stm32l4xxx/peripherals/syscfg.h" #include "arch/stm32l4xxx/peripherals/system.h" +#include "arch/stm32l4xxx/peripherals/tim.h" +#include "drv/ir/control.h" +#include "drv/ir/ir.h" +#include "drv/ir/lg_remote_codes.h" #include "drv/ws2812B/ws2812b.h" #include "kern/delay.h" #include "kern/dma/dma_manager.h" @@ -19,8 +27,23 @@ #include "kern/priv.h" #include "kern/spi/spi_manager.h" #include "kern/systick/systick_manager.h" +#include "shared/math.h" #include "user/syscall.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() { panic("Hard fault encountered!\n"); @@ -49,100 +72,189 @@ void configure_gpio() } } -static uint8_t* compiled; -static size_t compiled_len; +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; + } -extern uint8_t sintable[256]; + /* Add a little white flair that comes around every once in a while. */ -static uint32_t time; + 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, + }; -static void on_systick(void* nil) + 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) { - ++time; + (*v)++; } -#define min(a, b) (a) < (b) ? (a) : (b) +void decrement_it_u8(uint32_t unused, uint8_t* v) +{ + (*v)--; +} -static uint8_t amp(uint8_t in) +void timetick_up(uint32_t unused, void* nil) { - uint32_t out = in; + state.timetick += 5; +} - for (int i = 0; i < 20; ++i) { - out = (out * in) / 256; +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; +} - return min(out, 255); +static void set_red() +{ + state.n_red += 50; + state.n_red %= 250; } -static uint32_t bytescale(uint32_t n, uint32_t sc) +static void reset_state() { - return n * sc / 255; + 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("Entering main\n"); - gpio_reserved_pin_t sysled = get_sysled(); + klogf("Entering Main\n"); systick_add_callback(on_systick, NULL); - enable_systick(1000); + 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, 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, 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, reset_state, NULL); + add_ir_code_callback(RC_POWER, toggle_power, NULL); + int ec; - ws2812b_t* drv = ws2812b_new(SPI_SELECT_SPI1, &ec); + state.drv = ws2812b_new(SPI_SELECT_SPI1, &ec); - if (ec || !drv) { + if (ec || !state.drv) { panic("Unable to create WS2812b driver :( (%d)\n", ec); } -#define SIZE 256 - rgb_t rgb[SIZE]; - for (int i = 0; i < SIZE; ++i) { - rgb[i].g = 0xff; - rgb[i].r = 0xff; - rgb[i].b = 0xff; - } - - uint32_t red = 0x40; - uint32_t green = 0x40; - uint32_t brightness = 255; + reset_state(); - for (int i = 0; i < 100; ++i) { - ws2812b_write_rgb_sync(drv, 0, 0, 0); + 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(drv); + ws2812b_latch(state.drv); for (;;) { - set_gpio_pin_high(sysled); - ws2812b_latch(drv); - - int i; - for (i = 0; i < SIZE; ++i) { - red = byte_sin(time / 1000 + i * 4); - green = 255 - red; - - brightness = 3 * byte_sin(time / 5000) / 4 + 63; - - /* Add a little white flair that comes around every once in a while. */ - uint32_t white = time / 137 + i * 4; - if ((white / 256) % 8 == 0) { - white = amp(byte_sin(white)); - } else { - white = 0; - } - - ws2812b_write_rgb_sync( - drv, - bytescale(min(red + white, 255), brightness), - bytescale(min(green + white, 255), brightness), - bytescale(white, brightness)); - } - - set_gpio_pin_low(sysled); - - ws2812b_latch(drv); + // while (!do_redraw) + // ; + // do_redraw = 0; + if (!state.sleep) redraw(); } } |