From de81911ef4c15a9518acf32f61ad2d7d0e2f156f Mon Sep 17 00:00:00 2001 From: Josh Rahm Date: Sat, 5 Dec 2020 01:53:33 -0700 Subject: Got a very basic external interrupt to work. --- src/kern/main.c | 86 +++++++++++++++++++++------------------------------------ 1 file changed, 31 insertions(+), 55 deletions(-) (limited to 'src/kern/main.c') diff --git a/src/kern/main.c b/src/kern/main.c index fab2eb9..2b97197 100644 --- a/src/kern/main.c +++ b/src/kern/main.c @@ -2,9 +2,11 @@ #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 "drv/ws2812B/ws2812b.h" #include "kern/delay.h" @@ -82,68 +84,42 @@ static uint32_t bytescale(uint32_t n, uint32_t sc) /* Main function. This gets executed from the interrupt vector defined above. */ int main() { - klogf("Entering main\n"); - gpio_reserved_pin_t sysled = get_sysled(); + regset(RCC.apb2en_r, rcc_syscfgen, 1); - systick_add_callback(on_systick, NULL); - enable_systick(1000); - configure_gpio(); + klogf("Entering main\n"); int ec; - ws2812b_t* drv = ws2812b_new(SPI_SELECT_SPI1, &ec); - - if (ec || !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; - } + gpio_reserved_pin_t sysled = get_sysled(); - uint32_t red = 0x40; - uint32_t green = 0x40; - uint32_t brightness = 255; + gpio_pin_opts_t opts = DEFAULT_GPIO_OPTS_INPUT; + opts.pull_dir = GPIO_PULL_DIR_NONE; + gpio_reserved_pin_t pb6 = reserve_gpio_pin(GPIO_PIN_PB6, &opts, &ec); - for (int i = 0; i < 100; ++i) { - ws2812b_write_rgb_sync(drv, 0, 0, 0); + if (ec) { + panic("Unable to reserve GPIO pin ec=%d\n", ec); } - ws2812b_latch(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 (1) { + // if (get_gpio_pin_input_state(pb6)) { + // set_gpio_pin_high(sysled); + // } else { + // set_gpio_pin_low(sysled); + // } + // // klogf("GPIO is set? %d\n", get_gpio_pin_input_state(pb6)); + // } + + regset(SYSCFG.extic_r2, syscfg_exti6, 1 /* Port B. */); + regset(EXTI.im_r1, exti_im_n(6), 1); /* Enable the EXTI interrupt. */ + regset(EXTI.fts_r1, exti_ft_n(6), 1); /* Enable for falling edge. */ + regset(EXTI.rts_r1, exti_rt_n(6), 1); /* Enable for rising edge. */ + enable_interrupt(IRQ_EXTI9_5); + enable_interrupt(IRQ_EXTI0_IRQ); + enable_interrupt(IRQ_EXTI1_IRQ); + enable_interrupt(IRQ_EXTI2_IRQ); + enable_interrupt(IRQ_EXTI3_IRQ); + enable_interrupt(IRQ_EXTI4_IRQ); + + for(;;); } #endif -- cgit From a5923b21e48fcfe660c1e7d586fe0c6a5b79e421 Mon Sep 17 00:00:00 2001 From: Josh Rahm Date: Wed, 9 Dec 2020 20:29:31 -0700 Subject: Got a basic timer to work. --- src/kern/main.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) (limited to 'src/kern/main.c') diff --git a/src/kern/main.c b/src/kern/main.c index 2b97197..082d450 100644 --- a/src/kern/main.c +++ b/src/kern/main.c @@ -2,6 +2,7 @@ #include "arch/arm/cortex-m4/mpu.h" #include "arch/stm32l4xxx/peripherals/clock.h" #include "arch/stm32l4xxx/peripherals/dma.h" +#include "arch/stm32l4xxx/peripherals/tim.h" #include "arch/stm32l4xxx/peripherals/exti.h" #include "arch/stm32l4xxx/peripherals/irq.h" #include "arch/stm32l4xxx/peripherals/rcc.h" @@ -23,6 +24,15 @@ #include "kern/systick/systick_manager.h" #include "user/syscall.h" +void on_exti9_5() +{ + klogf("Exit Interrupt!\n"); + klogf("Pending Reg_again: %p\n", EXTI.p_r1); + klogf("Write: %p\n", (1 << 6)); + EXTI.p_r1 |= 1 << 6; + klogf("Pending Reg_again: %p\n", EXTI.p_r1); +} + void on_hard_fault() { panic("Hard fault encountered!\n"); @@ -81,6 +91,15 @@ static uint32_t bytescale(uint32_t n, uint32_t sc) return n * sc / 255; } +void on_tim2() +{ + if (regget(TIM2.s_r, tim_uif)) { + regset(TIM2.s_r, tim_uif, 0); + } + + klogf("Tim2 Update\n"); +} + /* Main function. This gets executed from the interrupt vector defined above. */ int main() { @@ -88,6 +107,21 @@ int main() klogf("Entering main\n"); + klogf("Enable ir\n"); + enable_interrupt(IRQ_TIM2); + klogf("Enable clock\n"); + regset(RCC.apb1en1_r, rcc_tim2en, 1); + klogf("psc\n"); + TIM2.psc = 39999; /* Counts every half millisecond. */ + klogf("ar_r\n"); + TIM2.ar_r = 1000; + klogf("die_r\n"); + regset(TIM2.die_r, tim_uie, 1); + klogf("eg_r\n"); + regset(TIM2.eg_r, tim_ug, 1); + klogf("c_r1\n"); + regset(TIM2.c_r1, tim_cen, 1); + int ec; gpio_reserved_pin_t sysled = get_sysled(); -- cgit From 5f1763ec87503527583cb1a7c6deb73604db0dfc Mon Sep 17 00:00:00 2001 From: Josh Rahm Date: Wed, 9 Dec 2020 23:15:14 -0700 Subject: Can read from the A/C remote control! --- src/kern/main.c | 145 +++++++++++--------------------------------------------- 1 file changed, 27 insertions(+), 118 deletions(-) (limited to 'src/kern/main.c') diff --git a/src/kern/main.c b/src/kern/main.c index 082d450..208f5d9 100644 --- a/src/kern/main.c +++ b/src/kern/main.c @@ -2,13 +2,16 @@ #include "arch/arm/cortex-m4/mpu.h" #include "arch/stm32l4xxx/peripherals/clock.h" #include "arch/stm32l4xxx/peripherals/dma.h" -#include "arch/stm32l4xxx/peripherals/tim.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" @@ -23,15 +26,7 @@ #include "kern/spi/spi_manager.h" #include "kern/systick/systick_manager.h" #include "user/syscall.h" - -void on_exti9_5() -{ - klogf("Exit Interrupt!\n"); - klogf("Pending Reg_again: %p\n", EXTI.p_r1); - klogf("Write: %p\n", (1 << 6)); - EXTI.p_r1 |= 1 << 6; - klogf("Pending Reg_again: %p\n", EXTI.p_r1); -} +#include void on_hard_fault() { @@ -40,120 +35,34 @@ void on_hard_fault() #ifdef ARCH_STM32L4 -void configure_gpio() +void printit(uint32_t code, const char* str) { - 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); - } -} - -static uint8_t* compiled; -static size_t compiled_len; - -extern uint8_t sintable[256]; - -static uint32_t time; - -static void on_systick(void* nil) -{ - ++time; -} - -#define min(a, b) (a) < (b) ? (a) : (b) - -static uint8_t amp(uint8_t in) -{ - uint32_t out = in; - - for (int i = 0; i < 20; ++i) { - out = (out * in) / 256; - } - - return min(out, 255); -} - -static uint32_t bytescale(uint32_t n, uint32_t sc) -{ - return n * sc / 255; -} - -void on_tim2() -{ - if (regget(TIM2.s_r, tim_uif)) { - regset(TIM2.s_r, tim_uif, 0); - } - - klogf("Tim2 Update\n"); + (void)code; + klogf("%s\n", str); } /* Main function. This gets executed from the interrupt vector defined above. */ int main() { - regset(RCC.apb2en_r, rcc_syscfgen, 1); - - klogf("Entering main\n"); - - klogf("Enable ir\n"); - enable_interrupt(IRQ_TIM2); - klogf("Enable clock\n"); - regset(RCC.apb1en1_r, rcc_tim2en, 1); - klogf("psc\n"); - TIM2.psc = 39999; /* Counts every half millisecond. */ - klogf("ar_r\n"); - TIM2.ar_r = 1000; - klogf("die_r\n"); - regset(TIM2.die_r, tim_uie, 1); - klogf("eg_r\n"); - regset(TIM2.eg_r, tim_ug, 1); - klogf("c_r1\n"); - regset(TIM2.c_r1, tim_cen, 1); - - int ec; - gpio_reserved_pin_t sysled = get_sysled(); - - gpio_pin_opts_t opts = DEFAULT_GPIO_OPTS_INPUT; - opts.pull_dir = GPIO_PULL_DIR_NONE; - gpio_reserved_pin_t pb6 = reserve_gpio_pin(GPIO_PIN_PB6, &opts, &ec); - - if (ec) { - panic("Unable to reserve GPIO pin ec=%d\n", ec); - } - - // while (1) { - // if (get_gpio_pin_input_state(pb6)) { - // set_gpio_pin_high(sysled); - // } else { - // set_gpio_pin_low(sysled); - // } - // // klogf("GPIO is set? %d\n", get_gpio_pin_input_state(pb6)); - // } - - regset(SYSCFG.extic_r2, syscfg_exti6, 1 /* Port B. */); - regset(EXTI.im_r1, exti_im_n(6), 1); /* Enable the EXTI interrupt. */ - regset(EXTI.fts_r1, exti_ft_n(6), 1); /* Enable for falling edge. */ - regset(EXTI.rts_r1, exti_rt_n(6), 1); /* Enable for rising edge. */ - enable_interrupt(IRQ_EXTI9_5); - enable_interrupt(IRQ_EXTI0_IRQ); - enable_interrupt(IRQ_EXTI1_IRQ); - enable_interrupt(IRQ_EXTI2_IRQ); - enable_interrupt(IRQ_EXTI3_IRQ); - enable_interrupt(IRQ_EXTI4_IRQ); - - for(;;); + klogf("Ir begin listening\n"); + 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_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_UNITS, printit, "RC_UNITS"); + add_ir_code_callback(RC_TIMER, printit, "RC_TIMER"); + add_ir_code_callback(RC_POWER, printit, "RC_POWER"); + + for (;;) + ; } #endif -- cgit From 90eb3a0b79bfef67c70dc545b49c48928eea05f4 Mon Sep 17 00:00:00 2001 From: Josh Rahm Date: Mon, 27 Sep 2021 22:56:46 -0600 Subject: Completed ws2812b 2020 Christmas Lights. --- src/kern/main.c | 219 ++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 206 insertions(+), 13 deletions(-) (limited to 'src/kern/main.c') 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 + #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 + +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 -- cgit