+/* Available colors, 6 bits per color (no values above 0x3f) */
+const unsigned char colors[COLOR_COUNT][LED_COUNT] = {
+ { 0x2c, 0x20, 0x00, 0x18 }, /* candle */
+ { 0x28, 0x00, 0x00, 0x00 }, /* red */
+ { 0x30, 0x20, 0x00, 0x00 }, /* orange */
+ { 0x2c, 0x2c, 0x00, 0x00 }, /* yellow */
+ { 0x20, 0x2c, 0x00, 0x00 }, /* yellow-green */
+ { 0x00, 0x30, 0x00, 0x00 }, /* green */
+ { 0x00, 0x30, 0x18, 0x00 }, /* green-cyan */
+ { 0x00, 0x30, 0x28, 0x00 }, /* cyan */
+ { 0x00, 0x18, 0x30, 0x00 }, /* cyan-blue */
+ { 0x00, 0x00, 0x30, 0x00 }, /* blue */
+ { 0x1c, 0x00, 0x30, 0x00 }, /* magenta */
+ { 0x3f, 0x3f, 0x3f, 0x3f }, /* white */
+};
+
+unsigned char mode = MODE_SOLID;
+unsigned char color = COLOR_CANDLE;
+signed char bright = BRIGHT_INIT;
+bit bright_up;
+led_t red;
+led_t grn;
+led_t blu;
+led_t wht;
+bit on;
+int fade_steps;
+signed char pbHeldCount;
+signed char cbright;
+
+void cfg_write()
+{
+ unsigned char addr = CFG_ADDR;
+ unsigned char m, c;
+ signed char b;
+
+ m = eeprom_read(addr++);
+ c = eeprom_read(addr++);
+ b = eeprom_read(addr);
+ if (mode != m || color != c || bright != b) {
+ addr = CFG_ADDR;
+ eeprom_write(addr++, mode);
+ eeprom_write(addr++, color);
+ eeprom_write(addr, bright);
+ }
+}
+
+void cfg_read()
+{
+ unsigned char addr = CFG_ADDR;
+ unsigned char tmp;
+
+ tmp = eeprom_read(addr++);
+ if (tmp < MODE_COUNT)
+ mode = tmp;
+
+ tmp = eeprom_read(addr++);
+ if (tmp < COLOR_COUNT)
+ color = tmp;
+
+ tmp = eeprom_read(addr);
+ if ((signed char)tmp >= BRIGHT_BOTTOM && (signed char)tmp <= BRIGHT_TOP)
+ bright = tmp;
+}
+
+/* Combine LED color value and brightness level to generate an RGB value.
+ * bright will be BRIGHT_MIN...BRIGHT_MAX
+ *
+ * @param value 0...1023 (6 bit color, left shifted 4 bits, for 10 bits)
+ * @param b brightness value BRIGHT_MIN...BRIGHT_MAX
+ * @return An RGB drive value, 0...255
+ */
+unsigned char led_get(int value, signed char b)