#ifndef RGB_LED_H_
#define RGB_LED_H_

// Prerequisites - I2C driver
#include "i2c.h"

#define RGB_LED_I2C_ADDR		(0x8Au) // For use with UNSHIFTED address type, 0b1000.101W, where W is the read/write bit

#define RGB_RESET_REG			(0x00u) // Reset and chip ID
#define RGB_GCR1_REG			(0x01u) // Global control 1, some interrupts and chip enable
#define RGB_ISR_REG				(0x02u) // Chip status register
#define RGB_PATST_REG			(0x03u) // Pattern status
#define RGB_GCR2_REG			(0x04u) // Max current register
#define RGB_LCTR_REG			(0x30u) // PWM freq and LED enables
#define RGB_LCFG0_REG			(0x31u) // Mode control for LED0
#define RGB_LCFG1_REG			(0x32u) // Mode control for LED1
#define RGB_LCFG2_REG			(0x33u) // Mode control for LED2
#define RGB_PWM0_REG			(0x34u) // PWM for LED0
#define RGB_PWM1_REG			(0x35u) // PWM for LED1
#define RGB_PWM2_REG			(0x36u) // PWM for LED2
#define RGB_LED0T0_REG			(0x37u) // Timing (rise and on) for LED0
#define RGB_LED0T1_REG			(0x38u) // Timing (fall and off) for LED0
#define RGB_LED0T2_REG			(0x39u) // Timing (delay and # of repeats) for LED0
#define RGB_LED1T0_REG			(0x3Au) // Timing (rise and on) for LED1
#define RGB_LED1T1_REG			(0x3Bu) // Timing (fall and off) for LED1
#define RGB_LED1T2_REG			(0x3Cu) // Timing (delay and # of repeats) for LED1
#define RGB_LED2T0_REG			(0x3Du) // Timing (rise and on) for LED2
#define RGB_LED2T1_REG			(0x3Eu) // Timing (fall and off) for LED2
#define RGB_LED2T2_REG			(0x3Fu) // Timing (delay and # of repeats) for LED2

#define RGB_RESET_CODE			(0x55u) // Reset code, setting reset reg with this value resets the chip
#define RGB_GCR1_CHIPEN			(0x01u)
#define RGB_GCR1_CHRGDIS		(0x02u)
#define RGB_GCR2_IMAX_15MA		(0x00u)
#define RGB_GCR2_IMAX_30MA		(0x01u)
#define RGB_GCR2_IMAX_5MA		(0x10u)
#define RGB_GCR2_IMAX_10MA		(0x11u)
#define RGB_LCTR_PWM_SEL		(0x20u) // 0=250Hz, 1=125Hz
#define RGB_LCTR_EXP_RAMP		(0x08u) // 0=exponential ramp, 1=linear ramp
#define RGB_LCTR_LED0_EN		(0x01u) // 1=enable LED0 driver, 0=LED0 output disabled
#define RGB_LCTR_LED1_EN		(0x02u) // 1=enable LED1 driver, 0=LED1 output disabled
#define RGB_LCTR_LED2_EN		(0x04u) // 1=enable LED2 driver, 0=LED2 output disabled
#define RGB_LCFG0_SYNC			(0x80u) // 0=independent control, 1=sync (all outputs controlled by LED0)
#define RGB_LCFGX_FO			(0x40u) // 0=disable PWM fade-out, 1=enable PWM fade-out (timed by T3)
#define RGB_LCFGX_FI			(0x20u) // 0=disable PWM fade-in, 1=enable PWM fade-in (timed by T1)
#define RGB_LCFGX_MD			(0x10u) // 0=manual mode, 1=pattern mode
#define RGB_LCFGX_CUR_MAX		(0x0Fu) // Setting for current output = Imax (output = Imax * CUR / 15)
#define RGB_LEDXT0_T1MASK		(0xF0u) // Top 4 bits are T1, Rise time
#define RGB_LEDXT0_T2MASK		(0x0Fu) // Bottom 4 bits are T2, On time
#define RGB_LEDXT1_T3MASK		(0xF0u) // Top 4 bits are T3, Fall time
#define RGB_LEDXT1_T4MASK		(0x0Fu) // Bottom 4 bits are T4, Off time
#define RGB_LEDXT2_T0MASK		(0xF0u) // Top 4 bits are T0, delay before pattern startup
#define RGB_LEDXT2_RPTMASK		(0x0Fu) // Bottom 4 bits are Repeat, where 0 = infinite, otherwise pattern runs Repeat times

// All timing nibbles (T0 through T4) use the same settings:
#define RGB_TIMING_0_04S		(0x00u) // 0000 = 0.04s
#define RGB_TIMING_0_13S		(0x01u) // 0001 = 0.13s
#define RGB_TIMING_0_26S		(0x02u) // 0010 = 0.26s
#define RGB_TIMING_0_38S		(0x03u) // 0011 = 0.38s
#define RGB_TIMING_0_51S		(0x04u) // 0100 = 0.51s
#define RGB_TIMING_0_77S		(0x05u) // 0101 = 0.77s
#define RGB_TIMING_1_04S		(0x06u) // 0110 = 1.04s
#define RGB_TIMING_1_6S			(0x07u) // 0111 = 1.6s
#define RGB_TIMING_2_1S			(0x08u) // 1000 = 2.1s
#define RGB_TIMING_2_6S			(0x09u) // 1001 = 2.6s
#define RGB_TIMING_3_1S			(0x0Au) // 1010 = 3.1s
#define RGB_TIMING_4_2S			(0x0Bu) // 1011 = 4.2s
#define RGB_TIMING_5_2S			(0x0Cu) // 1100 = 5.2s
#define RGB_TIMING_6_2S			(0x0Du) // 1101 = 6.2s
#define RGB_TIMING_7_3S			(0x0Eu) // 1110 = 7.3s
#define RGB_TIMING_8_3S			(0x0Fu) // 1111 = 8.3s
		

typedef struct{
	uint8_t r;
	uint8_t g;
	uint8_t b;
} RGB_Color_t;

void rgb_led_init(I2C_Handle* hi2c);
void rgb_led_set_color(I2C_Handle* hi2c, const RGB_Color_t* color);
void rgb_led_set_dimming(I2C_Handle* hi2c, uint8_t dimval);

#endif /* RGB_LED_H_ */
