123 lines
3.0 KiB
C
123 lines
3.0 KiB
C
#ifndef LED_H
|
|
#define LED_H
|
|
|
|
#include "ch.h"
|
|
#include "hal.h"
|
|
#include <stdint.h>
|
|
|
|
#define PWM_TIM_FREQ STM32_PCLK
|
|
#define PWM_FREQ 800000
|
|
#define PWM_PERIOD (PWM_TIM_FREQ/PWM_FREQ)
|
|
|
|
#define ACT_PWM_TIM_FREQ STM32_PCLK
|
|
#define ACT_PWM_FREQ 1
|
|
#define ACT_PWM_PERIOD (ACT_PWM_TIM_FREQ/ACT_PWM_FREQ)
|
|
|
|
#define SIG_LOW (((PWM_PERIOD * 1) / 4) - 1)
|
|
#define SIG_HIGH (((PWM_PERIOD * 3) / 4) - 1)
|
|
#define SIG_RESET (PWM_PERIOD - 1)
|
|
|
|
#define LEDS_PER_IRQ (30)
|
|
#define BYTES_PER_LED 3
|
|
#define BITS_PER_LED (8*BYTES_PER_LED)
|
|
#define DMA_BUF_HALF (LEDS_PER_IRQ * BITS_PER_LED)
|
|
#define DMA_BUF_LEN (2 * DMA_BUF_HALF)
|
|
#define RESET_PERIOD_US (25)
|
|
#define LED_UNIT_US ((BITS_PER_LED * 1000000) / PWM_FREQ) // one "led" is BITS_PER_LED bits / PWM_FREQ seconds long
|
|
#define RESET_UNITS ((((RESET_PERIOD_US*10) / (LED_UNIT_US)) / 10))
|
|
#define RESET_PRE 2
|
|
|
|
#define LED_EVENT(x) ((eventflags_t)(1 << x))
|
|
#define LED_EVENT_DONE LED_EVENT(0)
|
|
#define LED_EVENT_BUFRDY LED_EVENT(1)
|
|
|
|
#define NUM_DRIVERS 5
|
|
#define LEDS_PER_DRIVER 14
|
|
|
|
#define DRIVER_FB_SIZE (LEDS_PER_DRIVER*NUM_DRIVERS)
|
|
|
|
typedef struct {
|
|
uint8_t g;
|
|
uint8_t r;
|
|
uint8_t b;
|
|
} led_t;
|
|
|
|
typedef enum {
|
|
C_OFF = 0,
|
|
C_DARK_GREEN = 1,
|
|
C_DARK_RED = 2,
|
|
C_DARK_BLUE = 3,
|
|
C_DARK_PURPLE = 4,
|
|
C_DARK_CYAN = 5,
|
|
C_DARK_WHITE = 6,
|
|
C_GREEN = 7,
|
|
C_RED = 8,
|
|
C_BLUE = 9,
|
|
C_WHITE = 10,
|
|
C_GRAY = 11,
|
|
C_PALETTE_SIZE = 12,
|
|
} palette_colour_t;
|
|
|
|
typedef struct led_ctx led_ctx_t;
|
|
|
|
typedef void (*led_done_callback_t)(led_ctx_t * driver);
|
|
|
|
typedef struct {
|
|
uint8_t bit_sigs[BITS_PER_LED];
|
|
} ws2812_signal_t;
|
|
|
|
// Instance of LED driver
|
|
typedef struct led_ctx {
|
|
// 1 if the leds are currently updating, 0 if the driver is idle
|
|
volatile int upd_lck;
|
|
// dma storage
|
|
uint8_t dma_buf[DMA_BUF_LEN];
|
|
uint8_t * dma_buf_ptr;
|
|
// number of leds(reset and real) that have been transmitted
|
|
uint32_t tx_cnt;
|
|
// number of real and reset leds that have been commited to the buffer
|
|
uint32_t buf_cnt;
|
|
// number of leds(reset and real) to be transmitted
|
|
uint32_t tx_led_cnt;
|
|
const stm32_dma_stream_t * dma_stream;
|
|
PWMDriver * pwm_driver;
|
|
uint8_t tim_channel;
|
|
uint8_t done;
|
|
event_source_t event_source;
|
|
stm32_gpio_t * port;
|
|
uint8_t pin;
|
|
uint8_t * framebuffer;
|
|
uint8_t num;
|
|
thread_t * draw_thread;
|
|
} led_ctx_t;
|
|
|
|
typedef struct led_cfg {
|
|
uint32_t dma_stream_id;
|
|
PWMDriver * pwm_driver;
|
|
uint8_t tim_channel;
|
|
stm32_gpio_t * port;
|
|
uint8_t pin;
|
|
uint8_t af;
|
|
uint8_t num;
|
|
} led_cfg_t;
|
|
|
|
typedef struct dma_ctx {
|
|
uint8_t id;
|
|
volatile bool done;
|
|
const stm32_dma_stream_t * stream;
|
|
} dma_ctx_t;
|
|
|
|
extern led_ctx_t led_drivers[NUM_DRIVERS];
|
|
extern uint8_t framebuffer[NUM_DRIVERS*LEDS_PER_DRIVER];
|
|
extern led_t palette[C_PALETTE_SIZE];
|
|
extern event_listener_t event_listeners[NUM_DRIVERS];
|
|
|
|
int start_led_transfer(led_ctx_t * driver);
|
|
int setup_led_transfer(led_ctx_t * driver);
|
|
|
|
void led_init(thread_t * draw_thread);
|
|
void led_draw(event_listener_t* event_listeners);
|
|
void fill_dmabuf(led_ctx_t * driver);
|
|
|
|
#endif // LED_H
|