aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/drv/ws2812B/ws2812b.c71
-rw-r--r--src/kern/main.c278
2 files changed, 152 insertions, 197 deletions
diff --git a/src/drv/ws2812B/ws2812b.c b/src/drv/ws2812B/ws2812b.c
index e1e9309..2a1ccfb 100644
--- a/src/drv/ws2812B/ws2812b.c
+++ b/src/drv/ws2812B/ws2812b.c
@@ -1,13 +1,38 @@
#include "drv/ws2812B/ws2812b.h"
+#include "arch/stm32l4xxx/peripherals/spi.h"
+#include "kern/dma/dma_manager.h"
#include "kern/mem.h"
#include "kern/panic.h"
-#include "kern/dma/dma_manager.h"
-#include "arch/stm32l4xxx/peripherals/spi.h"
+
+uint8_t sintable[256] = {
+ 128, 148, 156, 162, 168, 172, 177, 181, 184, 187, 191, 194, 196, 199, 202,
+ 204, 207, 209, 211, 213, 215, 217, 219, 221, 223, 224, 226, 228, 229, 231,
+ 232, 233, 235, 236, 237, 239, 240, 241, 242, 243, 244, 245, 246, 246, 247,
+ 248, 249, 249, 250, 251, 251, 252, 252, 253, 253, 253, 254, 254, 254, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 254, 254, 253, 253,
+ 253, 252, 252, 251, 251, 250, 249, 249, 248, 247, 246, 246, 245, 244, 243,
+ 242, 241, 240, 239, 237, 236, 235, 233, 232, 231, 229, 228, 226, 224, 223,
+ 221, 219, 217, 215, 213, 211, 209, 207, 204, 202, 199, 196, 194, 191, 187,
+ 184, 181, 177, 172, 168, 162, 156, 148, 128, 108, 100, 94, 88, 84, 79,
+ 75, 72, 69, 65, 62, 60, 57, 54, 52, 49, 47, 45, 43, 41, 39,
+ 37, 35, 33, 32, 30, 28, 27, 25, 24, 23, 21, 20, 19, 17, 16,
+ 15, 14, 13, 12, 11, 10, 10, 9, 8, 7, 7, 6, 5, 5, 4,
+ 4, 3, 3, 3, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6, 7,
+ 7, 8, 9, 10, 10, 11, 12, 13, 14, 15, 16, 17, 19, 20, 21,
+ 23, 24, 25, 27, 28, 30, 32, 33, 35, 37, 39, 41, 43, 45, 47,
+ 49, 52, 54, 57, 60, 62, 65, 69, 72, 75, 79, 84, 88, 94, 100,
+ 108};
+
+uint8_t byte_sin(uint8_t n)
+{
+ return sintable[n];
+}
uint8_t* ws2812b_compile_rgb(rgb_t* out_, size_t arr_len)
{
- uint8_t* out = (uint8_t*) out_;
+ uint8_t* out = (uint8_t*)out_;
uint8_t* spi_out = kalloc(arr_len * 9);
if (!spi_out) {
@@ -20,35 +45,17 @@ uint8_t* ws2812b_compile_rgb(rgb_t* out_, size_t arr_len)
for (i = 0, j = 0; i < arr_len * 3; ++i, j += 3) {
// stuff
uint8_t c = out[i];
- spi_out[j] = 0
- | (1 << 7)
- | ((c & (1 << 7)) << 6)
- | (0 << 5)
- | (1 << 4)
- | ((c & (1 << 6)) << 3)
- | (0 << 2)
- | (1 << 1)
- | ((c & (1 << 5)) << 0);
-
- spi_out[j + 1] = 0
- | (0 << 7)
- | (1 << 6)
- | ((c & (1 << 4)) << 5)
- | (0 << 4)
- | (1 << 3)
- | ((c & (1 << 3)) << 2)
- | (0 << 1)
- | (1 << 0);
-
- spi_out[j + 2] = 0
- | ((c & (1 << 2)) << 7)
- | (0 << 6)
- | (1 << 5)
- | ((c & (1 << 1)) << 4)
- | (0 << 3)
- | (1 << 2)
- | ((c & (1 << 0)) << 1)
- | (0 << 0);
+ spi_out[j] = 0 | (1 << 7) | ((c & (1 << 7)) << 6) | (0 << 5) | (1 << 4) |
+ ((c & (1 << 6)) << 3) | (0 << 2) | (1 << 1) |
+ ((c & (1 << 5)) << 0);
+
+ spi_out[j + 1] = 0 | (0 << 7) | (1 << 6) | ((c & (1 << 4)) << 5) |
+ (0 << 4) | (1 << 3) | ((c & (1 << 3)) << 2) | (0 << 1) |
+ (1 << 0);
+
+ spi_out[j + 2] = 0 | ((c & (1 << 2)) << 7) | (0 << 6) | (1 << 5) |
+ ((c & (1 << 1)) << 4) | (0 << 3) | (1 << 2) |
+ ((c & (1 << 0)) << 1) | (0 << 0);
}
return spi_out;
diff --git a/src/kern/main.c b/src/kern/main.c
index 3dcadf6..5af5fa7 100644
--- a/src/kern/main.c
+++ b/src/kern/main.c
@@ -2,203 +2,52 @@
#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/rcc.h"
#include "arch/stm32l4xxx/peripherals/spi.h"
#include "arch/stm32l4xxx/peripherals/system.h"
-#include "kern/gpio/gpio_manager.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/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()
+void configure_spi1()
{
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);
+ 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) {
- klogf("Unable to set pin PA4 (ec=%d)\n", 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) {
- klogf("Unable to set pin PA5 (ec=%d)\n", ec);
+ panic("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);
@@ -210,7 +59,7 @@ int main()
regset(reg, spi_frf, 0);
regset(reg, spi_nssp, 0);
regset(reg, spi_ssoe, 0);
- regset(reg, spi_txdmaen, 1);
+ regset(reg, spi_txdmaen, 0);
regset(reg, spi_rxdmaen, 0);
SPI1.c_r2 = reg;
@@ -229,13 +78,112 @@ int main()
regset(reg, spi_cpol, 0);
regset(reg, spi_cpha, 0);
SPI1.c_r1 = reg;
+}
+
+static uint8_t* compiled;
+static size_t compiled_len;
- klogf("Initiate xfer\n");
- dma_mem2p_initiate_transfer(dma_chan, dataptr, size * 9);
- klogf("Post\n");
+extern uint8_t sintable[256];
- // for (;;);
+static void spi_write(uint8_t byte)
+{
+ while (!regget(SPI1.s_r, spi_txe))
+ ;
+ SPI1.d_r = byte;
+ asm volatile("nop");
}
+static void write_rgb(uint8_t red, uint8_t green, uint8_t blue)
+{
+#undef BIT
+#define BIT(b, n) (!!((b) & (1 << (n))))
+ spi_write(
+ (1 << 7) | (BIT(green, 7) << 6) | (0 << 5) | (0 << 4) | (1 << 3) |
+ (BIT(green, 6) << 2) | (0 << 1) | (0 << 0));
+ spi_write(
+ (1 << 7) | (BIT(green, 5) << 6) | (0 << 5) | (0 << 4) | (1 << 3) |
+ (BIT(green, 4) << 2) | (0 << 1) | (0 << 0));
+ spi_write(
+ (1 << 7) | (BIT(green, 3) << 6) | (0 << 5) | (0 << 4) | (1 << 3) |
+ (BIT(green, 2) << 2) | (0 << 1) | (0 << 0));
+ spi_write(
+ (1 << 7) | (BIT(green, 1) << 6) | (0 << 5) | (0 << 4) | (1 << 3) |
+ (BIT(green, 0) << 2) | (0 << 1) | (0 << 0));
+
+ spi_write(
+ (1 << 7) | (BIT(red, 7) << 6) | (0 << 5) | (0 << 4) | (1 << 3) |
+ (BIT(red, 6) << 2) | (0 << 1) | (0 << 0));
+ spi_write(
+ (1 << 7) | (BIT(red, 5) << 6) | (0 << 5) | (0 << 4) | (1 << 3) |
+ (BIT(red, 4) << 2) | (0 << 1) | (0 << 0));
+ spi_write(
+ (1 << 7) | (BIT(red, 3) << 6) | (0 << 5) | (0 << 4) | (1 << 3) |
+ (BIT(red, 2) << 2) | (0 << 1) | (0 << 0));
+ spi_write(
+ (1 << 7) | (BIT(red, 1) << 6) | (0 << 5) | (0 << 4) | (1 << 3) |
+ (BIT(red, 0) << 2) | (0 << 1) | (0 << 0));
+
+ spi_write(
+ (1 << 7) | (BIT(blue, 7) << 6) | (0 << 5) | (0 << 4) | (1 << 3) |
+ (BIT(blue, 6) << 2) | (0 << 1) | (0 << 0));
+ spi_write(
+ (1 << 7) | (BIT(blue, 5) << 6) | (0 << 5) | (0 << 4) | (1 << 3) |
+ (BIT(blue, 4) << 2) | (0 << 1) | (0 << 0));
+ spi_write(
+ (1 << 7) | (BIT(blue, 3) << 6) | (0 << 5) | (0 << 4) | (1 << 3) |
+ (BIT(blue, 2) << 2) | (0 << 1) | (0 << 0));
+ spi_write(
+ (1 << 7) | (BIT(blue, 1) << 6) | (0 << 5) | (0 << 4) | (1 << 3) |
+ (BIT(blue, 0) << 2) | (0 << 1) | (0 << 0));
+}
+
+void latch()
+{
+ for (int i = 0; i < 20; ++i) {
+ spi_write(0);
+ }
+}
+
+/* Main function. This gets executed from the interrupt vector defined above. */
+int main()
+{
+ gpio_reserved_pin_t sysled = get_sysled();
+ klogf("Start\n");
+ klogf("sintable: %p\n", sintable);
+ klogf("sintable[5]: %d\n", sintable[5]);
+
+#define SIZE 16
+ rgb_t rgb[SIZE];
+ for (int i = 0; i < SIZE; ++i) {
+ rgb[i].g = 0x18;
+ rgb[i].r = 0x80;
+ rgb[i].b = 0x18;
+ }
+
+ uint8_t red = 0x30;
+ uint8_t green = 0x30;
+ uint8_t blue = 0x00;
+
+ // compiled = ws2812b_compile_rgb(rgb, SIZE);
+ // compiled_len = SIZE * 9;
+
+ configure_spi1();
+
+ set_gpio_pin_high(sysled);
+ for (int i = 0; i < 100; ++ i) {
+ write_rgb(0, 0, 0);
+ }
+
+ latch();
+
+ for (int i = 0; i < 256; ++i) {
+ write_rgb(red, byte_sin((i * 16) & 0xff) / 2, blue);
+ }
+ set_gpio_pin_low(sysled);
+
+ for (;;) {
+ spi_write(0);
+ }
+}
#endif