/** * attiny.c: interface to attiny88's features * 2014 true * * ---- * * attiny88's I2C address is 0x73 - see led_eyes.h for define **/ #include // for settings #include "attiny.h" #include "../interface/i2c.h" #include "../interface/gpio.h" #include "../device/lightsensor.h" // led mode static uint8_t led_eyes_mode; // led brightness static uint8_t led_level[2][4]; // led programs #include "../led/led_eyes_prog.h" static void (*led_program)(); static void (*led_program_list[])() = { led_prog_candle_flicker, led_prog_candle_flicker_favcolor, led_prog_randflasher, led_prog_mic_spl, led_prog_fader }; const char led_eyes_prog_name[LED_EYES_PROG_COUNT][16] = { {"CandleFlicker"}, {"Candle+FavColor"}, {"RandFlasher"}, {"MicSPL"}, {"CFader"} }; /* functions */ void attiny_write(uint16_t cmd, void *data, uint8_t bytes) { uint8_t cmdlen; uint8_t *d; cmdlen = (cmd > 0xff) ? 2 : 1; d = ((uint8_t *)data); if (bytes) { I2C_WriteTransfer(ATTINY_I2C_ADDR, d, bytes, cmd, cmdlen); } } uint32_t attiny_read(uint16_t cmd, uint8_t bytes) { uint8_t cmdlen; uint8_t fb[4] = {0, 0, 0, 0}; cmdlen = (cmd > 0xff) ? 2 : 1; if (bytes && bytes <= 4) { I2C_ReadTransfer(ATTINY_I2C_ADDR, fb, bytes, cmd, cmdlen); } return fb[0] | fb[1] << 8 | fb[2] << 16 | fb[3] << 24; } uint8_t attiny_read_temp() { return (uint8_t)attiny_read(ATTINY_CMD_READ_TEMP, 1); } uint8_t attiny_read_light_level(uint8_t led_idx) { return (uint8_t)attiny_read(ATTINY_CMD_READ_LIGHT + (led_idx & 0x03), 1); } void attiny_write_light_sensitivity(uint8_t led, uint8_t sensitivity) { uint8_t buf[2]; buf[0] = led; buf[1] = sensitivity; attiny_write(ATTINY_CMD_LIGHTSENSOR_SENS, buf, 2); } void attiny_sleep() { I2C_WriteTransfer(ATTINY_I2C_ADDR, 0, 0, ATTINY_CMD_SLEEP, 1); } /* rgbled-related functions */ void led_eyes_tx() { uint8_t buf[12]; uint16_t scaler; uint8_t i, j; // build up the packet i = j = 0; while (i < 12) { buf[i++] = ATTINY_CMD_LED_LEVEL + j; scaler = (settings.led_autoadjust & 0x80) ? lightsensor_get_scalerval(LIGHTSENS_SCALED_EYES) : 256; buf[i++] = ((led_level[j >> 2][j % 4]) * scaler) >> 8; if (i == 6) { j = 4; } else { j++; } } // and send it I2C_WriteTransfer(ATTINY_I2C_ADDR, buf, 12, 0, 0); } void led_eyes_set_level(uint8_t idx, uint8_t level) { led_level[idx >> 2][idx & 0x03] = level; } void led_eyes_set_mode(uint8_t mode) { led_eyes_mode = mode; } void led_eyes_set_program(uint8_t program_idx, uint8_t init, uint16_t wait, uint16_t level, uint32_t offset, uint32_t settings) { // we need to be in program mode led_eyes_set_mode(LED_EYES_MODE_PROGRAM); // update the program pointer led_program = led_program_list[program_idx]; // set initial program variables led_prog_set_wait = wait; led_prog_set_level = level; led_prog_set_offset = offset; led_prog_set_option = settings; // is this a new set? if so, initialize program parameters if (init) { uint8_t i; led_prog_wait = 0; for (i = 0; i < 4; i++) { led_prog_state[i] = 0; led_prog_work[i] = 0; } } } void led_eyes_mode_update() { uint8_t i; switch (led_eyes_mode) { case LED_EYES_MODE_PROGRAM: { // if we have a valid program loaded, run it if (led_program != NULL) { led_program(); } break; } case LED_EYES_MODE_OFF: { led_program = NULL; for (i = 0; i < 4; i++) { led_level[0][i] = 0; led_level[1][i] = 0; } break; } } }