#include #include #include #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" #include "system.h" #include "systick.h" #include "ws2812b.h" #include "gpio.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 #define PWR1 ch573_pwr__pwr_mgmt #define PWR CH573_PWR__PWR_MGMT_T_INTF #define min(a, b) (a) < (b) ? (a) : (b) uint8_t amp(uint8_t in, uint8_t n) { uint32_t out = in; for (int i = 0; i < n; ++i) { out = (out * in) / 256; } return min(out, 255); } static void set_system_clock_60Mhz(void) { clock_cfg_t clk_cfg = {0}; clk_cfg.sel = CLOCK_SELECTION_PLL; clk_cfg.pll_clock_divisor = 8; if (set_system_clock(&clk_cfg)) { printf("Failed to set system clock.\n"); panic(0xff); } } #define N_LEDS 255 #define N_DMA_XFER 4 extern int uart1_FILE_get(FILE* f); #define TIME_STEP 1 static volatile uint32_t time = 0; static volatile int spin_lock = 0; static size_t current_pattern_idx = 0; static size_t debounce = 0; On_SysTick() { if (debounce > 0) { debounce--; } time++; spin_lock = 0; } On_Gpio(gpio_pin_t pin) { if (pin == PIN_PB7) { if (debounce > 0) return; debounce = 10; 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); } } /* * Main routine. This is called on_reset once everything else has been set up. */ int main(void) { char buf[N_LEDS * TOTAL_BYTES_PER_LED]; PFIC_I.vector_table_control.set(PFIC, 1); set_system_clock_60Mhz(); set_systick(250000); 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); configure_gpio(PIN_PB7, PIN_CFG_INPUT_PULL_UP); enable_gpio_interrupt(PIN_PB7, INT_MODE_FALLING_EDGE); // enable_bootsel_button(); size_t n = sizeof(buf); struct ws2812b_buf ws_buf; make_wsb2812b(&ws_buf, buf, n); ws_buf.byte_order = LED_BYTE_ORDER_ENUM; rgb_t color; 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 = 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. GPIO_PORT.out.set(GPIO_PORT_A, ON, 10); } GPIO_PORT.out.set(GPIO_PORT_A, OFF, 10); spin_lock = 1; for (int j = 0; j < N_DMA_XFER; ++j) { wait_for_dma(); start_dma(&ws_buf); } } return 0; }