#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/rcc.h" #include "arch/stm32l4xxx/peripherals/irq.h" #include "arch/stm32l4xxx/peripherals/spi.h" #include "arch/stm32l4xxx/peripherals/system.h" #include "kern/gpio/gpio_manager.h" #include "kern/dma/dma_manager.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/delay.h" #include "kern/priv.h" #include "kern/gpio/sysled.h" #include "arch/stm32l4xxx/peripherals/clock.h" #include "user/syscall.h" #include "drv/ws2812B/ws2812b.h" gpio_reserved_pin_t sysl; int syslon; int n; uint16_t my_short; extern uint16_t dma_inuse; void on_spi1() { SPI1.d_r = ~my_short; if (n++ == 10000) { if (syslon) { set_gpio_pin_low(sysl); } else { set_gpio_pin_high(sysl); } syslon = !syslon; n = 0; } } inline void spi_write_byte(uint8_t byte) { // volatile uint32_t read; //delay(5); //while (regget(SPI1.s_r, spi_rxne)) { // read = SPI1.d_r; //} //delay(5); //delay(5); while (regget(SPI1.s_r, spi_ftlvl) > SPI_FIFO_STATUS_HALF); SPI1.d_r = (byte << 8) | byte; } void on_hard_fault() { panic("Hard fault encountered!\n"); } void on_systick() /* Overrides weak-symbol on_systick. */ { // klogf("systick\n"); if (my_short == 0) my_short = 0xffff; my_short >>=1; } void configure_mpu() { configure_flash_region((void*)0x08000000, REGION_SIZE_256Kb, NOT_PRIVILEGED); configure_ram_region((void*)SRAM1_BASE, REGION_SIZE_64Kb, NOT_PRIVILEGED); configure_ram_region((void*)SRAM2_BASE, REGION_SIZE_16Kb, NOT_PRIVILEGED); configure_peripheral_region((void*)0x40000000, REGION_SIZE_512Mb, PRIVILEGED); mpu_set_enabled(1); } static void dma_callback(void* arg) { klogf("Dma callback\n"); dma_channel_t* chan = arg; release_dma_channel(*chan); dma_channel_interrupt_enable(*chan, 0); regset(SPI1.c_r1, spi_spe, 0); DMA2.ifc_r |= 0xffffffff; DMA1.ifc_r |= 0xffffffff; regset(DMA2.channel_config[3].cc_r, dma_cc_en, 0); } #ifdef ARCH_STM32L4 /* Main function. This gets executed from the interrupt vector defined above. */ int main() { int ec = 0; size_t size = 20; rgb_t arr[] = { {0x00, 0x00, 0xff}, {0x00, 0xff, 0x00}, {0xff, 0x00, 0x00}, {0xff, 0x80, 0x80}, {0x80, 0xff, 0x80}, {0x80, 0x80, 0xff}, {0xff, 0xff, 0xff}, {0xff, 0xff, 0xff}, {0xff, 0xff, 0xff}, {0xff, 0xff, 0xff}, {0xff, 0xff, 0xff}, {0xff, 0xff, 0xff}, {0xff, 0xff, 0xff}, {0xff, 0xff, 0xff}, {0xff, 0xff, 0xff}, {0xff, 0xff, 0xff}, {0xff, 0xff, 0xff}, {0xff, 0xff, 0xff}, {0xff, 0xff, 0xff}, {0xff, 0xff, 0xff}, {0xff, 0xff, 0xff}, {0xff, 0xff, 0xff}, {0xff, 0xff, 0xff}, {0xff, 0xff, 0xff}, {0xff, 0xff, 0xff}, {0xff, 0xff, 0xff}, {0xff, 0xff, 0xff}, {0xff, 0xff, 0xff}, {0xff, 0xff, 0xff}, {0xff, 0xff, 0xff}, }; uint8_t* dataptr = ws2812b_compile_rgb(arr, size); klogf("Heap start: %p\n", &HEAP_START); klogf("Heap end: %p\n", &HEAP_STOP); klogf("Dataptr start: %p\n", dataptr); klogf("Dataptr end: %p\n", (dataptr + size)); dma_opts_t opts = DEFAULT_DMA_OPTS; opts.transfer_complete_interrupt_enable = 1; opts.circular_mode = 0; dma_mem2p_channel_t dma_chan = select_dma_channel_mem2p(DMA2_PERIPH_SPI1_TX, &opts, &ec); dma_chan_set_callback(dma_chan.c_, dma_callback, &dma_chan); if (ec) { panic("Unable to allocate dma channel: %d\n", ec); } my_short = 0xff; klogf("This is weird.\n"); // configure_mpu(); sysl = get_sysled(); // gpio_enable_alternate_function( // GPIO_ALTERNATE_FUNCTION_SPI1_MISO, GPIO_PIN_PA6, &ec); // if (ec) { // klogf("Unable to set pin PA6 (ec=%d)\n", ec); // } gpio_enable_alternate_function( GPIO_ALTERNATE_FUNCTION_SPI1_MOSI, GPIO_PIN_PA7, &ec); if (ec) { klogf("Unable to set pin PA7 (ec=%d)\n", ec); } gpio_enable_alternate_function( GPIO_ALTERNATE_FUNCTION_SPI1_NSS, GPIO_PIN_PA4, &ec); if (ec) { klogf("Unable to set pin PA4 (ec=%d)\n", ec); } gpio_enable_alternate_function( GPIO_ALTERNATE_FUNCTION_SPI1_SCK, GPIO_PIN_PA5, &ec); if (ec) { klogf("Unable to set pin PA5 (ec=%d)\n", ec); } /* Set the countdown to start from 10,000,0000. */ SCB.strv_r = 1000000; /* Enable interrupts. */ regset(SCB.stcs_r, scb_tickint, 1); /* Start the systick. */ regset(SCB.stcs_r, scb_enable, 1); regset(RCC.apb2en_r, rcc_spi1en, 1); enable_interrupt(IRQ_SPI1); uint32_t reg = 0; regset(reg, spi_ldma_tx, 0); regset(reg, spi_ldma_rx, 0); regset(reg, spi_frxth, 0); regset(reg, spi_ds, SPI_DATA_SIZE_8_BITS); regset(reg, spi_txeie, 0); regset(reg, spi_rxneie, 0); regset(reg, spi_errie, 0); regset(reg, spi_frf, 0); regset(reg, spi_nssp, 0); regset(reg, spi_ssoe, 0); regset(reg, spi_txdmaen, 1); regset(reg, spi_rxdmaen, 0); SPI1.c_r2 = reg; reg = 0; regset(reg, spi_bidimode, 0); regset(reg, spi_crcen, 0); regset(reg, spi_crcnext, 0); regset(reg, spi_crcl, 0); regset(reg, spi_rxonly, 0); regset(reg, spi_ssm, 1); regset(reg, spi_ssi, 1); regset(reg, spi_lsbfirst, 0); regset(reg, spi_spe, 1); regset(reg, spi_br, SPI_BAUD_FPCLK_DIV_32); regset(reg, spi_mstr, 1); regset(reg, spi_cpol, 0); regset(reg, spi_cpha, 0); SPI1.c_r1 = reg; klogf("Initiate xfer\n"); dma_mem2p_initiate_transfer(dma_chan, dataptr, size * 9); klogf("Post\n"); // for (;;); } #endif