diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/btsel.c | 38 | ||||
-rw-r--r-- | src/main.c | 142 |
2 files changed, 115 insertions, 65 deletions
diff --git a/src/btsel.c b/src/btsel.c new file mode 100644 index 0000000..873b20a --- /dev/null +++ b/src/btsel.c @@ -0,0 +1,38 @@ +#include "btsel.h" + +#include "ch573/gpio.h" +#include "isr_vector.h" + +#define GPIO ch573_gpio__gpio +#define GPIO_I CH573_GPIO__GPIO_T_INTF +#define GPIO_PORT CH573_GPIO__GPIO_PORT_T_INTF +#define GPIO_PORT_A ch573_gpio__gpio_port_a +#define GPIO_PORT_B ch573_gpio__gpio_port_b + +extern bootsel_cb_t BOOTSEL_LISTENERS_START; +extern bootsel_cb_t BOOTSEL_LISTENERS_END; + +#define BOOTSEL_PIN 7 + +void enable_bootsel_button(void) +{ + GPIO_PORT.dir.set(GPIO_PORT_B, DIR_IN, BOOTSEL_PIN); + GPIO_PORT.pu.set(GPIO_PORT_B, ENABLED, BOOTSEL_PIN); + // GPIO_PORT.pd_drv.set(GPIO_PORT_B, PD_DRV_OPEN_DRAIN, BOOTSEL_PIN); + GPIO_PORT.out.set(GPIO_PORT_B, OFF, BOOTSEL_PIN); + GPIO_PORT.clr.set(GPIO_PORT_B, 1 << BOOTSEL_PIN); + + GPIO_I.pb_interrupt_mode.set(GPIO, 1 << BOOTSEL_PIN); + GPIO_I.pb_interrupt_flag.set(GPIO, 1 << BOOTSEL_PIN); + GPIO_I.pb_interrupt_enable.set(GPIO, 1 << BOOTSEL_PIN); +} + +IRQ(gpio_b) +{ + bootsel_cb_t* cur = &BOOTSEL_LISTENERS_START; + while (cur != &BOOTSEL_LISTENERS_END) { + (*cur)(); + ++cur; + } + GPIO_I.pb_interrupt_flag.set(GPIO, 1 << BOOTSEL_PIN); +} @@ -2,13 +2,16 @@ #include <stdint.h> #include <stdio.h> +#include "btsel.h" #include "byte_math.h" #include "ch573/gpio.h" #include "ch573/pfic.h" #include "ch573/pwr.h" #include "ch573/uart.h" #include "clock.h" +#include "isr_vector.h" #include "panic.h" +#include "pattern.h" #include "spi.h" #include "string.h" #include "sysled.h" @@ -16,12 +19,28 @@ #include "systick.h" #include "ws2812b.h" +#ifndef LED_BYTE_ORDER +#define LED_BYTE_ORDER GRB +#endif + +#define PASTER(x, y) x##y +#define CONCAT(x, y) PASTER(x, y) +#define LED_BYTE_ORDER_ENUM CONCAT(BYTE_ORDER_, LED_BYTE_ORDER) + +#define STRINGIFY(x) #x +#define TOSTRING(x) STRINGIFY(x) +#ifndef DEFAULT_PATTERN +#define DEFAULT_PATTERN CandyCane +#endif + #define PFIC_I CH573_PFIC__PFIC_T_INTF #define PFIC ch573_pfic__pfic #define GPIO_PORT_A ch573_gpio__gpio_port_a #define GPIO_PORT_B ch573_gpio__gpio_port_b #define GPIO_PORT CH573_GPIO__GPIO_PORT_T_INTF +#define GPIO_I CH573_GPIO__GPIO_T_INTF +#define GPIO ch573_gpio__gpio #define UART1 ch573_uart__uart1 #define UART CH573_UART__UART_T_INTF @@ -29,8 +48,6 @@ #define PWR1 ch573_pwr__pwr_mgmt #define PWR CH573_PWR__PWR_MGMT_T_INTF -#define AS_BYTE(n) ((n) * 256) - #define min(a, b) (a) < (b) ? (a) : (b) uint8_t amp(uint8_t in, uint8_t n) @@ -44,21 +61,6 @@ uint8_t amp(uint8_t in, uint8_t n) return min(out, 255); } -uint32_t collatz(uint32_t n) -{ - uint32_t c = 0; - - while (n > 1) { - if (n % 2 == 0) { - n /= 2; - } else { - n = n * 3 + 1; - } - c++; - } - - return c; -} static void set_system_clock_60Mhz(void) { @@ -71,58 +73,40 @@ static void set_system_clock_60Mhz(void) } } -#define N_LEDS 150 -#define N_DMA_XFER 2 +#define N_LEDS 255 +#define N_DMA_XFER 3 extern int uart1_FILE_get(FILE* f); -static inline uint8_t byte_scale(uint8_t v, uint8_t scale) -{ - uint16_t acc = v; - return (acc * scale) >> 8; -} - -uint8_t clip(int x) -{ - if (x > 240) { - return 240; - } - - if (x < 0) { - return 0; - } - - return (uint8_t)x; -} - #define TIME_STEP 1 -rgb_t get_rgb(uint32_t time, size_t x) -{ - int r = 0, g = 0, b = 0; - - uint8_t time8 = time & 0xff; - int w = calc_w(time8 * TIME_STEP + x * 4); +static volatile uint32_t time = 0; +static volatile int spin_lock = 0; - r = 0xff; - g = byte_scale(byte_sin(time8 * TIME_STEP + x * 2), 0x90); - b = byte_scale(byte_sin(time8 * TIME_STEP + x * 2), 0x20); +static size_t current_pattern_idx = 0; - rgb_t color; - color.color = 0; - color.r = clip(r + w); - color.g = clip(byte_scale(g, AS_BYTE(0.75)) + w); - color.b = clip(byte_scale(b, AS_BYTE(0.75)) + w); - return color; +static size_t debounce = 0; +On_SysTick() +{ + if (debounce > 0) { + debounce --; + } + time++; + spin_lock = 0; } +On_BootSelPress() +{ + if (debounce > 0) return; + debounce = 10; -static volatile uint32_t time = 0; -static volatile int spin_lock = 0; - -On_SysTick() { - time ++; - spin_lock = 0; + size_t tmp = current_pattern_idx; + tmp ++; + if (tmp >= n_patterns) { + tmp = 0; + } + current_pattern_idx = tmp; + printf("Switch to '%s'\n", patterns[current_pattern_idx].name); } /* @@ -135,6 +119,10 @@ int main(void) PFIC_I.vector_table_control.set(PFIC, 1); PFIC->interrupt_priority_threshold = 0x10; PFIC->interrupt_enable |= IRQ_SysTick; + PFIC->interrupt_priority_threshold = 0x10; + PFIC->interrupt_enable |= IRQ_GpioA; + PFIC->interrupt_priority_threshold = 0x10; + PFIC->interrupt_enable |= IRQ_GpioB; set_system_clock_60Mhz(); set_systick(250000); @@ -142,30 +130,54 @@ int main(void) enable_sysled(); enable_spi(); + for (current_pattern_idx = 0; current_pattern_idx < n_patterns; + ++current_pattern_idx) { + if (strcmp( + patterns[current_pattern_idx].name, "" TOSTRING(DEFAULT_PATTERN)) == + 0) { + break; + } + } + + if (current_pattern_idx == n_patterns) { + printf( + "Could not find a pattern with the name '%s'.\n", + TOSTRING(DEFAULT_PATTERN)); + panic(0xaa); + } + + printf("\nRunning Pattern '%s'\n", patterns[current_pattern_idx].name); + + enable_bootsel_button(); + size_t n = sizeof(buf); struct ws2812b_buf ws_buf; make_wsb2812b(&ws_buf, buf, n); - ws_buf.byte_order = BYTE_ORDER_GRB; + ws_buf.byte_order = LED_BYTE_ORDER_ENUM; rgb_t color; - GPIO_PORT.dir.set(GPIO_PORT_B, DIR_OUT, 7); + GPIO_PORT.dir.set(GPIO_PORT_A, DIR_OUT, 10); + + // GPIO->pb_interrupt_mode |= (1 << 7) | (1 << 8); while (1) { + pattern_t* current_pattern = &patterns[current_pattern_idx]; ws_buf.cur = 0; for (int i = 0; i < N_LEDS; ++i) { - rgb_t rgb = get_rgb(time, i); + rgb_t rgb = current_pattern->get_rgb(time, i); write_rgb(&ws_buf, rgb); } while (spin_lock) { - set_sysled(1); // Setting the sysled helps me to measure down time. + // set_sysled(1); // Setting the sysled helps me to measure down time. + GPIO_PORT.out.set(GPIO_PORT_A, ON, 10); } - set_sysled(0); + GPIO_PORT.out.set(GPIO_PORT_A, OFF, 10); spin_lock = 1; - for (int j = 0; j < N_DMA_XFER; ++ j) { + for (int j = 0; j < N_DMA_XFER; ++j) { wait_for_dma(); start_dma(&ws_buf); } |