#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/irq.h" #include "arch/stm32l4xxx/peripherals/rcc.h" #include "arch/stm32l4xxx/peripherals/spi.h" #include "arch/stm32l4xxx/peripherals/system.h" #include "drv/ws2812B/ws2812b.h" #include "kern/delay.h" #include "kern/dma/dma_manager.h" #include "kern/gpio/gpio_manager.h" #include "kern/gpio/sysled.h" #include "kern/init.h" #include "kern/log.h" #include "kern/mem.h" #include "kern/mpu/mpu_manager.h" #include "kern/panic.h" #include "kern/priv.h" #include "kern/spi/spi_manager.h" #include "kern/systick/systick_manager.h" #include "user/syscall.h" void on_hard_fault() { panic("Hard fault encountered!\n"); } #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); } } 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; } /* Main function. This gets executed from the interrupt vector defined above. */ int main() { klogf("Entering main\n"); gpio_reserved_pin_t sysled = get_sysled(); systick_add_callback(on_systick, NULL); enable_systick(1000); configure_gpio(); 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; } uint32_t red = 0x40; uint32_t green = 0x40; uint32_t brightness = 255; for (int i = 0; i < 100; ++i) { ws2812b_write_rgb_sync(drv, 0, 0, 0); } 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); } } #endif