From a038463097e1c047f21f4c270da08559c75842a9 Mon Sep 17 00:00:00 2001 From: bsx Date: Fri, 16 Dec 2011 22:09:09 +0100 Subject: [PATCH] added rgb-flame code --- firmware/applications/final/flame_rgb.c | 177 ++++++++++++++++++++++++ 1 file changed, 177 insertions(+) create mode 100644 firmware/applications/final/flame_rgb.c diff --git a/firmware/applications/final/flame_rgb.c b/firmware/applications/final/flame_rgb.c new file mode 100644 index 0000000..100495a --- /dev/null +++ b/firmware/applications/final/flame_rgb.c @@ -0,0 +1,177 @@ +/* + + flame m0dul with RGB (rev c) - https://github.com/schneider42/flame + LED driver is a PCA9633 +*/ + +#include "basic/basic.h" +#include "core/i2c/i2c.h" +#include "basic/config.h" +#include "basic/xxtea.h" + +#define FLAME_I2C_WRITE 0xC6 +#define FLAME_I2C_READ 0xC7 + +#define FLAME_I2C_CR_MODE1 0x00 +#define FLAME_I2C_CR_MODE2 0x01 +#define FLAME_I2C_CR_PWM0 0x02 +#define FLAME_I2C_CR_PWM1 0x03 +#define FLAME_I2C_CR_PWM2 0x04 +#define FLAME_I2C_CR_PWM3 0x05 +#define FLAME_I2C_CR_GRPPWM 0x06 +#define FLAME_I2C_CR_GRPFREQ 0x07 +#define FLAME_I2C_CR_LEDOUT 0x08 + +#define FLAME_I2C_LED0_OFF 0x00 +#define FLAME_I2C_LED0_FULL 0x01 +#define FLAME_I2C_LED0_INDY 0x02 +#define FLAME_I2C_LED0_GRP 0x03 +#define FLAME_I2C_LED1_OFF 0x00 +#define FLAME_I2C_LED1_FULL 0x04 +#define FLAME_I2C_LED1_INDY 0x08 +#define FLAME_I2C_LED1_GRP 0x0c +#define FLAME_I2C_LED2_OFF 0x00 +#define FLAME_I2C_LED2_FULL 0x10 +#define FLAME_I2C_LED2_INDY 0x20 +#define FLAME_I2C_LED2_GRP 0x30 +#define FLAME_I2C_LED3_OFF 0x00 +#define FLAME_I2C_LED3_FULL 0x40 +#define FLAME_I2C_LED3_INDY 0x80 +#define FLAME_I2C_LED3_GRP 0xC0 + +#define FLAME_OFF 0x00 +#define FLAME_UP 0x01 +#define FLAME_UP_WAIT 0x02 +#define FLAME_DOWN 0x03 +#define FLAME_DOWN_WAIT 0x04 + +/**************************************************************************/ + +#define flameBrightnessMax GLOBAL(flamemax) +#define flameBrightnessMin GLOBAL(flamemin) +#define flameSpeedUp GLOBAL(flamespeed) +#define flameSpeedDown GLOBAL(flamespeed) +#define flameWaitUp GLOBAL(flamemaxw) +#define flameWaitDown GLOBAL(flameminw) + +#define nick GLOBAL(nickname) + +uint32_t flameRGBSetI2C(uint8_t cr, uint8_t value) { + I2CMasterBuffer[0] = FLAME_I2C_WRITE; + I2CMasterBuffer[1] = cr; + I2CMasterBuffer[2] = value; + I2CWriteLength = 3; + I2CReadLength = 0; + return i2cEngine(); +} + +uint8_t flameRGBEnabled = 0; +uint8_t flameRGBMode = FLAME_OFF; +uint8_t flameRGBI2Cpwm = 0; +uint8_t flameRGBTicks = 0; + +void setFlameRGBPWM() { + flameRGBSetI2C(FLAME_I2C_CR_GRPPWM, flameRGBI2Cpwm); // set pwm +} + +void setFlameRGBColor() { + // generate a hash from the nickname + uint32_t hash[4]; + uint32_t const key[4] = {0xcfd97ebc, 0x21117b45, 0x7193727, 0xa336f4d6}; + xxtea_cbcmac(hash, (uint32_t *)nick, 4, key); + // set color, LED0 = red, LED1 = unused, LED2 = blue, LED3 = green + flameRGBSetI2C(FLAME_I2C_CR_PWM0, hash[0] % 255); + flameRGBSetI2C(FLAME_I2C_CR_PWM1, hash[1] % 255); + flameRGBSetI2C(FLAME_I2C_CR_PWM2, hash[2] % 255); + flameRGBSetI2C(FLAME_I2C_CR_PWM3, hash[3] % 255); +} + +void tick_flame_rgb(void) { // every 10ms + static char night=0; + + if (!flameRGBEnabled) { + return; + } + + if (night != isNight()) { + night = isNight(); + if (!night) { + flameRGBMode = FLAME_OFF; + flameRGBI2Cpwm = 0; + push_queue(&setFlameRGBPWM); + }; + }; + + flameRGBTicks++; + + if (flameRGBI2Cpwm > flameBrightnessMax) { + flameRGBI2Cpwm = flameBrightnessMax; + } + if (flameRGBI2Cpwm < flameBrightnessMin) { + flameRGBI2Cpwm = flameBrightnessMin; + } + + if (flameRGBMode == FLAME_OFF) { + if (isNight()) { + flameRGBTicks = 0; + flameRGBMode = FLAME_UP; + } + } + + if (flameRGBMode == FLAME_UP) { + if (0xFF - flameRGBI2Cpwm >= flameSpeedUp ) { + flameRGBI2Cpwm += flameSpeedUp; + } else { + flameRGBI2Cpwm = 0xFF; + } + push_queue(&setFlameRGBPWM); + if (flameRGBI2Cpwm >= flameBrightnessMax) { + flameRGBMode = FLAME_UP_WAIT; + flameRGBTicks = 0; + } + } + + if (flameRGBMode == FLAME_UP_WAIT) { + if (flameRGBTicks >= flameWaitUp) { + flameRGBMode = FLAME_DOWN; + } + } + + if (flameRGBMode == FLAME_DOWN) { + if (flameSpeedDown <= flameRGBI2Cpwm) { + flameRGBI2Cpwm -= flameSpeedDown; + } else { + flameRGBI2Cpwm = 0x00; + } + push_queue(&setFlameRGBPWM); + if (flameRGBI2Cpwm <= flameBrightnessMin) { + flameRGBMode = FLAME_DOWN_WAIT; + flameRGBTicks = 0; + } + } + + if (flameRGBMode == FLAME_DOWN_WAIT) { + if (flameRGBTicks >= flameWaitDown) { + flameRGBMode = FLAME_OFF; + } + } +} + +void init_flame_rgb(void) { + i2cInit(I2CMASTER); // Init I2C + + flameRGBEnabled = (flameRGBSetI2C(FLAME_I2C_CR_MODE1, 0x00) == I2CSTATE_ACK); // probe i2c and enable flame if present + + if (!flameRGBEnabled) + return; + + // enable individual PWN and group PWN for LED0, LED3 and LED2 and disable LED1 + flameRGBSetI2C(FLAME_I2C_CR_LEDOUT, FLAME_I2C_LED0_GRP | FLAME_I2C_LED1_OFF | FLAME_I2C_LED2_GRP | FLAME_I2C_LED3_GRP); + + flameRGBSetI2C(FLAME_I2C_CR_GRPPWM, 0x00); // overall dimming + + push_queue(&setFlameRGBColor); + + enableConfig(CFG_TYPE_FLAME,1); +} +