aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/btsel.h19
-rw-r--r--include/byte_math.h21
-rw-r--r--include/gpio.h90
-rw-r--r--include/pattern.h31
-rw-r--r--include/risc-v.h45
-rw-r--r--include/sysled.h10
-rw-r--r--include/systick.h9
-rw-r--r--include/task.h9
-rw-r--r--include/voltdisc.h19
-rw-r--r--include/ws2812b.h12
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);