190 lines
7.8 KiB
C
190 lines
7.8 KiB
C
/*
|
|
* awinic AW20108 / AW20072 / AW20054 / AW20036 LED Matrix Driver
|
|
*/
|
|
|
|
#ifndef AW20X_LED_MATRIX_H
|
|
#define AW20X_LED_MATRIX_H
|
|
|
|
|
|
|
|
#include <stdint.h>
|
|
|
|
#include "i2c.h"
|
|
|
|
|
|
|
|
#define PLATFORM_INIT_DELAY() { uint16_t zz = 1000; while(zz--); }
|
|
// burn cycles for ~200us
|
|
|
|
#define AW20X_MAX_COLS 9
|
|
#define AW20X_MAX_ROWS 12
|
|
|
|
#define AW20X_MAX_LEDON_BITS 6
|
|
|
|
#define AW20X_ADDR_SCL 0x38 // AD pin tied to SCL
|
|
#define AW20X_ADDR_SDA 0x39 // AD pin tied to SDA
|
|
#define AW20X_ADDR_GND 0x3A // AD pin tied to GND
|
|
#define AW20X_ADDR_VDD 0x3B // AD pin tied to VDD
|
|
|
|
#define AW20X_CONF_IMAX_MASK 0xf0 // 7:4
|
|
#define AW20X_CONF_IMAX_OFFSET 4 // 7:4
|
|
#define AW20X_CONF_ADDR_MASK 0x03 // 1:0
|
|
#define AW20X_CONF_ADDR_OFFSET 0 // 1:0
|
|
|
|
#define AW20X_CONF_USE_FADEDIM 0x08 // aw20x.fade now becomes fadedim; updates are done with FADEDIM page
|
|
// this mode uses 2 bytes per LED; dim as byte 0, fade as byte 1
|
|
#define AW20X_CONF_USE_EXPEN 0x04 // sets GCCR.EXPEN=1; fade is now only 6 bits (not yet implemented)
|
|
|
|
#define AW20X_PAGE_MASK 0x07
|
|
|
|
#define AW20X_STATE_PAGE_MASK AW20X_PAGE_MASK
|
|
#define AW20X_STATE_SLEEP_MASK 0x80
|
|
|
|
|
|
#define AW20X_PAGE0_CONFIG 0x00 // function register
|
|
#define AW20X_PAGE1_DIM 0x01 // 5:0 dim; 8 bits per LED
|
|
#define AW20X_PAGE2_FADE 0x02 // 7:0 fade; 8 bits per LED
|
|
#define AW20X_PAGE3_PATTERN 0x03 // 1:0 pattern; 8 bits per LED
|
|
#define AW20X_PAGE4_DIMFADE 0x04 // 13:8 dim, 7:0 fade; 16 bits per LED
|
|
#define AW20X_PAGE5_DFP 0x05 // 15:14 pat, 13:8 dim, 7:0 fade; 16 bits per LED
|
|
|
|
#define AW20X_REG_IDR 0x00 // R 7:0 chip ID {0x18}
|
|
#define AW20X_REG_SLPCR 0x01 // RW 7 sleep {0x80}
|
|
#define AW20X_REG_RSTR 0x02 // W 7:0 SW_RSTN (?)
|
|
#define AW20X_REG_GCCR 0x03 // RW 7:3 IMAX(7:4), ALLON, -, -, EXPEN {0x10}
|
|
#define AW20X_REG_FCD 0x04 // W 0 FCDE (fast clear display enable)
|
|
#define AW20X_REG_CLKSYS 0x05 // RW 1:0 CLK_IO, CLK_SEL
|
|
#define AW20X_REG_FLTCFG1 0x09 // RW 5:0 UVLOPE, OTPE, UVIE, OTIE, UVLOE, OTE
|
|
#define AW20X_REG_FLTCFG2 0x0a // RW 3:2 UVTH
|
|
#define AW20X_REG_ISRFLT 0x0b // RW 5:0 PAT2IS, PAT1IS, PAT0IS, -, -, UVLOIS, OTIS
|
|
#define AW20X_REG_LEDON0 0x31 // W 5:0 ON0:ON5, same pattern through to LEDON17 (0x42)
|
|
#define AW20X_REG_PATCR 0x43 // RW 6:0 PAT2IE, PAT1IE, PAT0IE, -, PAT2EN, PAT1EN, PAT0EN
|
|
#define AW20X_REG_FADEH0 0x44 // RW 7:0 FADEH0
|
|
#define AW20X_REG_FADEH1 0x45
|
|
#define AW20X_REG_FADEH2 0x46
|
|
#define AW20X_REG_FADEL0 0x47
|
|
#define AW20X_REG_FADEL1 0x48
|
|
#define AW20X_REG_FADEL2 0x49 // RW 7:0 FADEL2
|
|
#define AW20X_REG_PAT0T0 0x4a // RW 7:0 T1[4], T2[4]
|
|
#define AW20X_REG_PAT0T1 0x4b // RW 7:0 T3[4], T4[4]
|
|
#define AW20X_REG_PAT0T2 0x4c // RW 7:0 LE[2], LB[2], LT(11:8)[4]
|
|
#define AW20X_REG_PAT0T3 0x4d // RW 7:0 LT(7:0)
|
|
#define AW20X_REG_PAT1T0 0x4e
|
|
#define AW20X_REG_PAT1T1 0x4f
|
|
#define AW20X_REG_PAT1T2 0x50
|
|
#define AW20X_REG_PAT1T3 0x51
|
|
#define AW20X_REG_PAT2T0 0x52
|
|
#define AW20X_REG_PAT2T1 0x53
|
|
#define AW20X_REG_PAT2T2 0x54
|
|
#define AW20X_REG_PAT2T3 0x55
|
|
#define AW20X_REG_PAT0CFG 0x56 // RW 2:0 SWITCH, RAMPE, PATMD
|
|
#define AW20X_REG_PAT1CFG 0x57
|
|
#define AW20X_REG_PAT2CFG 0x58
|
|
#define AW20X_REG_PATGO 0x59 // RW 6:0 PAT2ST, PAT1ST, PAT0ST, -, RUN2, RUN1, RUN0
|
|
#define AW20X_REG_SIZE 0x80 // RW 3:0 SWSEL
|
|
#define AW20X_REG_PAGE 0xf0 // RW 2:0 page select, 0-5; available from all pages
|
|
|
|
#define AW20X_IDR_ID 0x18 // value for all chips in this series
|
|
|
|
#define AW20X_SLPCR_SLEEP 0x01 // sleep mode (default is HIGH / asleep)
|
|
|
|
#define AW20X_RSTR_SW_RSTN 0x01 // write value to soft reset the chip
|
|
|
|
#define AW20X_GCCR_IMAX 0xf0 // global current setting (default 20mA)
|
|
#define AW20X_GCCR_ALLON 0x08 // 0=normal, 1=force all on
|
|
#define AW20X_GCCR_EXPEN 0x01 // 0=fade is linear 8-bit, 1=fade is exponential 6-bit
|
|
|
|
#define AW20X_FCD_FCDE 0x01 // write value to clear display (DS doesn't specify; is this a blanker?)
|
|
|
|
#define AW20X_CLKSYS_CLK_IO 0x02 // 0=no clk output, 1=clk output on (output) CLKIO pin
|
|
#define AW20X_CLKSYS_CLK_SEL 0x01 // 0=internal 4MHz, 1=use clk on (input) CLKIO pin
|
|
|
|
#define AW20X_FLTCFG1_UVLOPE 0x20 // 1=enable UVLO protection; chip sets SLPCR.SLEEP when ISRFLT.UVLOIS=1
|
|
#define AW20X_FLTCFG1_OTPE 0x10 // 1=enable overtemp protection; chip sets SLPCR.SLEEP when ISRFLT.UVLOIS=1
|
|
#define AW20X_FLTCFG1_UVIE 0x08 // 1=UVLO interrupt enable
|
|
#define AW20X_FLTCFG1_OTIE 0x04 // 1=overtemp interrupt enable
|
|
#define AW20X_FLTCFG1_UVLOE 0x02 // 1=enable UVLO detect
|
|
#define AW20X_FLTCFG1_OTE 0x01 // 1=enable overtemp detect
|
|
|
|
#define AW20X_FLTCFG1_UVTH_2V0 (0x00 << 2) // UVLO threshold voltage
|
|
#define AW20X_FLTCFG1_UVTH_2V1 (0x01 << 2) // UVLO threshold voltage
|
|
#define AW20X_FLTCFG1_UVTH_2V2 (0x02 << 2) // UVLO threshold voltage
|
|
#define AW20X_FLTCFG1_UVTH_2V3 (0x03 << 2) // UVLO threshold voltage
|
|
|
|
#define AW20X_ISRFLT_PAT2IS 0x40 // pattern controller 2 interrupt (finished breath loop)
|
|
#define AW20X_ISRFLT_PAT1IS 0x20 // pattern controller 1 interrupt (finished breath loop)
|
|
#define AW20X_ISRFLT_PAT0IS 0x10 // pattern controller 0 interrupt (finished breath loop)
|
|
#define AW20X_ISRFLT_UVLOIS 0x02 // 0=normal, 1=UVLO detected
|
|
#define AW20X_ISRFLT_OTIS 0x01 // 0=normal, 1=overtemp detected
|
|
|
|
// todo: fill in all values from PATCR onward
|
|
|
|
|
|
|
|
#define AW20X_SOFT_RESET AW20X_RSTR_SW_RSTN
|
|
|
|
enum aw20x_imax {
|
|
AW20X_IMAX_10MA = 0x00,
|
|
AW20X_IMAX_20MA = 0x10,
|
|
AW20X_IMAX_30MA = 0x20,
|
|
AW20X_IMAX_40MA = 0x30,
|
|
AW20X_IMAX_60MA = 0x40,
|
|
AW20X_IMAX_80MA = 0x50,
|
|
AW20X_IMAX_120MA = 0x60,
|
|
AW20X_IMAX_160MA = 0x70,
|
|
AW20X_IMAX_3_3MA = 0x80,
|
|
AW20X_IMAX_6_7MA = 0x90,
|
|
AW20X_IMAX_10MA_2 = 0xa0,
|
|
AW20X_IMAX_13_3MA = 0xb0,
|
|
AW20X_IMAX_20MA_2 = 0xc0,
|
|
AW20X_IMAX_26_7MA = 0xd0,
|
|
AW20X_IMAX_40MA_2 = 0xe0,
|
|
AW20X_IMAX_53_3MA = 0xf0
|
|
};
|
|
|
|
enum aw20x_size {
|
|
AW20X_SIZE_1COL = 0,
|
|
AW20X_SIZE_2COL,
|
|
AW20X_SIZE_3COL,
|
|
AW20X_SIZE_4COL,
|
|
AW20X_SIZE_5COL,
|
|
AW20X_SIZE_6COL,
|
|
AW20X_SIZE_7COL,
|
|
AW20X_SIZE_8COL,
|
|
AW20X_SIZE_9COL
|
|
};
|
|
|
|
|
|
|
|
#define AW20X_I2C_busy() (0)
|
|
#define AW20X_I2C_writereg(adr, reg, buf, siz) i2c_write_addr1b(adr, reg, buf, siz);
|
|
|
|
|
|
|
|
typedef struct AW20x {
|
|
uint8_t addr;
|
|
uint8_t config; // settings for the chip
|
|
uint8_t cols; // highest column used, 1-6
|
|
uint8_t rows; // highest row used, 1-12
|
|
uint8_t state; // keeps track of active page, and high bit is set if asleep
|
|
uint8_t pad[3];
|
|
uint8_t *fade; // led buffer location for FADE (required), of size cols+rows
|
|
uint8_t *gain; // led buffer location for GAIN (optional), of size cols+rows
|
|
} AW20x;
|
|
|
|
|
|
|
|
void aw20x_init(struct AW20x *aw, uint8_t addr, uint8_t cols, uint8_t rows, uint8_t imax);
|
|
|
|
void aw20x_sleep(struct AW20x *aw, uint8_t sleep);
|
|
|
|
void aw20x_commit_fade(struct AW20x *aw);
|
|
void aw20x_commit_dim_global(struct AW20x *aw, uint8_t dim);
|
|
|
|
void aw20x_led_enable(struct AW20x *aw, uint8_t first, uint8_t last);
|
|
|
|
|
|
|
|
#endif /* AW02X_LED_MATRIX_H */
|
|
|