diff options
Diffstat (limited to 'include')
| -rw-r--r-- | include/btsel.h | 19 | ||||
| -rw-r--r-- | include/byte_math.h | 21 | ||||
| -rw-r--r-- | include/gpio.h | 90 | ||||
| -rw-r--r-- | include/pattern.h | 31 | ||||
| -rw-r--r-- | include/risc-v.h | 45 | ||||
| -rw-r--r-- | include/sysled.h | 10 | ||||
| -rw-r--r-- | include/systick.h | 9 | ||||
| -rw-r--r-- | include/task.h | 9 | ||||
| -rw-r--r-- | include/voltdisc.h | 19 | ||||
| -rw-r--r-- | include/ws2812b.h | 12 |
10 files changed, 258 insertions, 7 deletions
diff --git a/include/btsel.h b/include/btsel.h new file mode 100644 index 0000000..9d2c676 --- /dev/null +++ b/include/btsel.h @@ -0,0 +1,19 @@ +#pragma once + +// Header file for detecting bootsel button presses. + +#define PASTER(x, y) x##y +#define CONCAT(x, y) PASTER(x, y) + +typedef void (*bootsel_cb_t)(void); +#define On_BootSelPress() \ + static void __local_on_bootsel__(void); \ + __attribute__(( \ + __section__(".bootsel_callbacks"))) static volatile bootsel_cb_t \ + __bootsel__position = __local_on_bootsel__; \ + static void __local_on_bootsel__() + +#undef PASTER +#undef CONCAT + +void enable_bootsel_button(void); diff --git a/include/byte_math.h b/include/byte_math.h index 79f93b8..9be4b67 100644 --- a/include/byte_math.h +++ b/include/byte_math.h @@ -13,3 +13,24 @@ static inline uint8_t byte_sin(uint8_t n) } uint8_t calc_w(uint8_t n); + +static inline uint8_t byte_scale(uint8_t v, uint8_t scale) +{ + uint16_t acc = v; + return (acc * scale) >> 8; +} + +static inline uint8_t clip(int x) +{ + if (x > 240) { + return 240; + } + + if (x < 0) { + return 0; + } + + return (uint8_t)x; +} + +#define AS_BYTE(n) ((n) * 256) diff --git a/include/gpio.h b/include/gpio.h new file mode 100644 index 0000000..99b6e5f --- /dev/null +++ b/include/gpio.h @@ -0,0 +1,90 @@ +#pragma once + +#include "ch573/gpio.h" + +#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 IS_PORT_B 0x80 + +typedef enum { + PIN_PA4 = 4, + PIN_PA5 = 5, + + PIN_PA8 = 8, + PIN_PA9 = 9, + PIN_PA10 = 10, + PIN_PA11 = 11, + PIN_PA12 = 12, + PIN_PA13 = 13, + PIN_PA14 = 14, + PIN_PA15 = 15, + + PIN_PB0 = IS_PORT_B | 0, + PIN_PB4 = IS_PORT_B | 4, + PIN_PB6 = IS_PORT_B | 6, + PIN_PB7 = IS_PORT_B | 7, + + PIN_PB10 = IS_PORT_B | 10, + PIN_PB11 = IS_PORT_B | 11, + PIN_PB12 = IS_PORT_B | 12, + PIN_PB13 = IS_PORT_B | 13, + PIN_PB14 = IS_PORT_B | 14, + PIN_PB15 = IS_PORT_B | 15, + + PIN_PB22 = IS_PORT_B | 8, + PIN_PB23 = IS_PORT_B | 9, +} gpio_pin_t; + +typedef enum { + PIN_CFG_INPUT_FLOATING, + PIN_CFG_INPUT_PULL_UP, + PIN_CFG_INPUT_PULL_DOWN, + PIN_CFG_OUTPUT_5mA, + PIN_CFG_OUTPUT_20mA, +} gpio_config_t; + +typedef enum { + AF_SPI = 8, + AF_UART1 = 5, + AF_UART0 = 4, + AF_TMR2 = 2, + AF_TMR1 = 1, + AF_TMR0 = 0, +} alternate_function_t; + +typedef enum { + INT_MODE_FALLING_EDGE, + INT_MODE_RISING_EDGE, + INT_MODE_LEVEL_HIGH, + INT_MODE_LEVEL_LOW +} interrupt_mode_t; + +typedef void (*gpio_callback_t)(gpio_pin_t pin); + +#define On_Gpio(arg) \ + static void __local_on_gpio__(gpio_pin_t pin); \ + __attribute__((__section__( \ + ".gpio_callbacks"))) static volatile gpio_callback_t __gpio__position = \ + __local_on_gpio__; \ + static void __local_on_gpio__(arg) + +void gpio_init(); + +/** Configure the given gpio pin for .*/ +void gpio_configure_pin(gpio_pin_t pin, gpio_config_t); + +/** Read the input value of the gpio. */ +int gpio_read(gpio_pin_t pin); + +/** Sets the gpio pin. */ +void gpio_set(gpio_pin_t pin, int high); + +/** Set or unset the peripheral to the alternate set of pins. */ +void gpio_enable_alternate_function(alternate_function_t af, int enable); + +/** Enables the interrupt for a with the provided interrupt mode. */ +void gpio_enable_interrupt(gpio_pin_t pin, interrupt_mode_t int_mode); diff --git a/include/pattern.h b/include/pattern.h new file mode 100644 index 0000000..f56e1ec --- /dev/null +++ b/include/pattern.h @@ -0,0 +1,31 @@ +#pragma once + +#include <stdint.h> + +#include "ws2812b.h" + +#define DEFINE_PATTERN \ + __attribute__((__section__( \ + ".patterns"))) volatile static pattern_t __FILE__ = + +typedef struct { + /* Name of the pattern. */ + const char* name; + + /* Return the rgb for the pixel at the given offset 'x' and time 't' */ + rgb_t (*get_rgb)(uint32_t t, size_t x); + + /* Resets the pattern to the beginning. */ + void (*reset)(void); +} pattern_t; + +extern pattern_t PATTERNS_START; +extern pattern_t PATTERNS_END; + +#define patterns (&PATTERNS_START) +#define n_patterns (&PATTERNS_END - &PATTERNS_START) + +rgb_t twinkle(uint32_t t, size_t x); + +rgb_t more_twinkle(uint32_t t, size_t x); + diff --git a/include/risc-v.h b/include/risc-v.h new file mode 100644 index 0000000..946ca7c --- /dev/null +++ b/include/risc-v.h @@ -0,0 +1,45 @@ +#pragma once + +#include <stdint.h> + +/* Macros and functions for generic RISC-V cores. */ + +/* Wait for interrupt macro. */ +static inline void wfi() +{ + asm volatile("wfi"); +} + +/* The mode for the mtvec. */ +typedef enum { + MODE_DIRECT = 0, + MODE_VECTORED = 1, +} mtvec_mode_t; + +/* Macro to read the value from a RISC-V CSR. */ +#define csrr(csr) \ + ({ \ + uint32_t _tmp_csr; \ + asm volatile("csrr %0, " csr : "=r"(_tmp_csr)); \ + _tmp_csr; \ + }) + +/* Macro to write a value to a RISC-V CSR. */ +#define csrw(csr, v) \ + { \ + asm volatile("csrw " csr ", %0" : : "r"(v)); \ + } + +/* Sets the mtvec to point to the given vector_table with the given mode. */ +static inline void set_mtvec(void* vector_table, mtvec_mode_t mode) +{ + uint32_t mtvec = (uint32_t)vector_table; + mtvec |= !!mode; + csrw("mtvec", mtvec); +} + +#define MCAUSE csrr("mcause") +#define MEPC csrr("mepc") +#define MTVAL csrr("mtval") + +#define __nop() asm volatile ("nop") diff --git a/include/sysled.h b/include/sysled.h index b9556f1..fea8f54 100644 --- a/include/sysled.h +++ b/include/sysled.h @@ -6,14 +6,12 @@ static inline void enable_sysled() { - CH573_GPIO__GPIO_PORT_T_INTF.dir.set(ch573_gpio__gpio_port_a, DIR_OUT, 8); - CH573_GPIO__GPIO_PORT_T_INTF.pd_drv.set(ch573_gpio__gpio_port_a, 0, 8); + CH573_GPIO__GPIO_PORT_T_INTF.dir.set(ch573_gpio__gpio_port_a, DIR_OUT, 11); + CH573_GPIO__GPIO_PORT_T_INTF.pd_drv.set(ch573_gpio__gpio_port_a, 1, 11); } -// If "on" then turn on the sysled (which counter-intuitively means turning off -// the GPIO). static inline void set_sysled(int on) { -// CH573_GPIO__GPIO_PORT_T_INTF.out.set( -// ch573_gpio__gpio_port_a, on ? OFF : ON, 8); + CH573_GPIO__GPIO_PORT_T_INTF.out.set( + ch573_gpio__gpio_port_a, on ? ON : OFF, 11); } diff --git a/include/systick.h b/include/systick.h index 285b9b8..09c69ec 100644 --- a/include/systick.h +++ b/include/systick.h @@ -10,9 +10,16 @@ uint64_t get_systick(); int systick_interrupt(); + +#define PASTER(x, y) x##y +#define CONCAT(x, y) PASTER(x, y) + #define On_SysTick() \ static void __local_on_systick__(void); \ __attribute__(( \ __section__(".systick_callbacks"))) static volatile systick_cb_t \ - __FILE__##__LINE__ = __local_on_systick__; \ + __systick__position = __local_on_systick__; \ static void __local_on_systick__() + +#undef PASTER +#undef CONCAT diff --git a/include/task.h b/include/task.h new file mode 100644 index 0000000..63fe543 --- /dev/null +++ b/include/task.h @@ -0,0 +1,9 @@ +#pragma once + +#include <stdint.h> + +typedef struct { + uint32_t x[32]; + + uint32_t pc; +} task_t; diff --git a/include/voltdisc.h b/include/voltdisc.h new file mode 100644 index 0000000..562b352 --- /dev/null +++ b/include/voltdisc.h @@ -0,0 +1,19 @@ +#pragma once + +// Volatge discovery. Determines what the voltage of the christmas lights is. +// +// This is done by using channel 0 of the ADC (which is on pin PA4). There is a +// voltage divider from the main power source to pin PA4 which uses a 4.7MOhm +// resistor and a 470KOhm resistor to divide the voltage by 10, which may then +// be turned into a reading on the ADC. +// +// This helps to determine if the lights being driven are WS2812b's or WS2811 as +// the latter are run on 12v and use RGB instead of GRB byte order. + + +#include <stdint.h> + +typedef uint32_t millivolts_t; + +// Returns the estimated input voltage in millivolts. +millivolts_t get_input_voltage(); diff --git a/include/ws2812b.h b/include/ws2812b.h index 2061379..6f8aff0 100644 --- a/include/ws2812b.h +++ b/include/ws2812b.h @@ -45,11 +45,23 @@ typedef struct { uint8_t r; uint8_t g; uint8_t b; + + /* Color alpha. 0 is perfectly opaque, 255 is perfectly transparent). */ + uint8_t a; }; uint32_t color; }; } rgb_t; +typedef struct { + uint8_t mat[4][4]; +} rgb_mat_t; + +/** Returns the new RGB as if rgb1 was overlayed on top of rgb2. */ +rgb_t blend(rgb_t rgb1, rgb_t rgb2); + +rgb_t mat_mul(rgb_t rgb, const rgb_mat_t* mat); + int write_rgb(struct ws2812b_buf* out, rgb_t color); void start_dma(struct ws2812b_buf* buf); |