예제 #1
0
void rgblight_sethsv_eeprom_helper(uint16_t hue, uint8_t sat, uint8_t val, bool write_to_eeprom) {
  if (rgblight_config.enable) {
    if (rgblight_config.mode == RGBLIGHT_MODE_STATIC_LIGHT) {
      // same static color
      LED_TYPE tmp_led;
      sethsv(hue, sat, val, &tmp_led);
      rgblight_setrgb(tmp_led.r, tmp_led.g, tmp_led.b);
    } else {
      // all LEDs in same color
      if ( 1 == 0 ) { //dummy
      }
#ifdef RGBLIGHT_EFFECT_BREATHING
      else if (rgblight_config.mode >= RGBLIGHT_MODE_BREATHING &&
          rgblight_config.mode <= RGBLIGHT_MODE_BREATHING_end) {
        // breathing mode, ignore the change of val, use in memory value instead
        val = rgblight_config.val;
      }
#endif
#ifdef RGBLIGHT_EFFECT_RAINBOW_MOOD
      else if (rgblight_config.mode >= RGBLIGHT_MODE_RAINBOW_MOOD &&
                  rgblight_config.mode <= RGBLIGHT_MODE_RAINBOW_MOOD_end) {
        // rainbow mood, ignore the change of hue
        hue = rgblight_config.hue;
      }
#endif
#ifdef RGBLIGHT_EFFECT_RAINBOW_SWIRL
      else if (rgblight_config.mode >= RGBLIGHT_MODE_RAINBOW_SWIRL &&
               rgblight_config.mode <= RGBLIGHT_MODE_RAINBOW_SWIRL_end) {
        // rainbow swirl, ignore the change of hue
        hue = rgblight_config.hue;
      }
#endif
#ifdef RGBLIGHT_EFFECT_STATIC_GRADIENT
      else if (rgblight_config.mode >= RGBLIGHT_MODE_STATIC_GRADIENT &&
               rgblight_config.mode <= RGBLIGHT_MODE_STATIC_GRADIENT_end) {
        // static gradient
        uint16_t _hue;
        int8_t direction = ((rgblight_config.mode - RGBLIGHT_MODE_STATIC_GRADIENT) % 2) ? -1 : 1;
        uint16_t range = pgm_read_word(&RGBLED_GRADIENT_RANGES[(rgblight_config.mode - RGBLIGHT_MODE_STATIC_GRADIENT) / 2]);
        for (uint8_t i = 0; i < RGBLED_NUM; i++) {
          _hue = (range / RGBLED_NUM * i * direction + hue + 360) % 360;
          dprintf("rgblight rainbow set hsv: %u,%u,%d,%u\n", i, _hue, direction, range);
          sethsv(_hue, sat, val, (LED_TYPE *)&led[i]);
        }
        rgblight_set();
      }
#endif
    }
    rgblight_config.hue = hue;
    rgblight_config.sat = sat;
    rgblight_config.val = val;
    if (write_to_eeprom) {
      eeconfig_update_rgblight(rgblight_config.raw);
      xprintf("rgblight set hsv [EEPROM]: %u,%u,%u\n", rgblight_config.hue, rgblight_config.sat, rgblight_config.val);
    } else {
      xprintf("rgblight set hsv [NOEEPROM]: %u,%u,%u\n", rgblight_config.hue, rgblight_config.sat, rgblight_config.val);
    }
  }
}
예제 #2
0
void rgblight_effect_alternating(animation_status_t *anim) {

  for(int i = 0; i<RGBLED_NUM; i++){
      if(i<RGBLED_NUM/2 && anim->pos){
          sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, (LED_TYPE *)&led[i]);
      }else if (i>=RGBLED_NUM/2 && !anim->pos){
          sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, (LED_TYPE *)&led[i]);
      }else{
          sethsv(rgblight_config.hue, rgblight_config.sat, 0, (LED_TYPE *)&led[i]);
      }
  }
  rgblight_set();
  anim->pos = (anim->pos + 1) % 2;
}
예제 #3
0
void rgblight_effect_rgbtest(void) {
  static uint8_t pos = 0;
  static uint16_t last_timer = 0;
  static uint8_t maxval = 0;
  uint8_t g; uint8_t r; uint8_t b;

  if (timer_elapsed(last_timer) < pgm_read_word(&RGBLED_RGBTEST_INTERVALS[0])) {
    return;
  }

  if( maxval == 0 ) {
      LED_TYPE tmp_led;
      sethsv(0, 255, RGBLIGHT_LIMIT_VAL, &tmp_led);
      maxval = tmp_led.r;
  }
  last_timer = timer_read();
  g = r = b = 0;
  switch( pos ) {
    case 0: r = maxval; break;
    case 1: g = maxval; break;
    case 2: b = maxval; break;
  }
  rgblight_setrgb(r, g, b);
  pos = (pos + 1) % 3;
}
예제 #4
0
void rgblight_sethsv(uint16_t hue, uint8_t sat, uint8_t val) {
  if (rgblight_config.enable) {
    if (rgblight_config.mode == 1) {
      // same static color
      rgblight_sethsv_noeeprom(hue, sat, val);
    } else {
      // all LEDs in same color
      if (rgblight_config.mode >= 2 && rgblight_config.mode <= 5) {
        // breathing mode, ignore the change of val, use in memory value instead
        val = rgblight_config.val;
      } else if (rgblight_config.mode >= 6 && rgblight_config.mode <= 14) {
        // rainbow mood and rainbow swirl, ignore the change of hue
        hue = rgblight_config.hue;
      } else if (rgblight_config.mode >= 25 && rgblight_config.mode <= 34) {
        // static gradient
        uint16_t _hue;
        int8_t direction = ((rgblight_config.mode - 25) % 2) ? -1 : 1;
        uint16_t range = pgm_read_word(&RGBLED_GRADIENT_RANGES[(rgblight_config.mode - 25) / 2]);
        for (uint8_t i = 0; i < RGBLED_NUM; i++) {
          _hue = (range / RGBLED_NUM * i * direction + hue + 360) % 360;
          dprintf("rgblight rainbow set hsv: %u,%u,%d,%u\n", i, _hue, direction, range);
          sethsv(_hue, sat, val, (LED_TYPE *)&led[i]);
        }
        rgblight_set();
      }
    }
    rgblight_config.hue = hue;
    rgblight_config.sat = sat;
    rgblight_config.val = val;
    eeconfig_update_rgblight(rgblight_config.raw);
    xprintf("rgblight set hsv [EEPROM]: %u,%u,%u\n", rgblight_config.hue, rgblight_config.sat, rgblight_config.val);
  }
}
예제 #5
0
void rgblight_sethsv_range(uint16_t hue, uint8_t sat, uint8_t val, uint8_t start, uint8_t end) {
  if (!rgblight_config.enable) { return; }

  LED_TYPE tmp_led;
  sethsv(hue, sat, val, &tmp_led);
  rgblight_setrgb_range(tmp_led.r, tmp_led.g, tmp_led.b, start, end);
}
예제 #6
0
void scan_rgblight_fadeout(void) { // Don't effing change this function .... rgblight_sethsv is supppppper intensive
    bool litup = false;
    for (uint8_t light_index = 0 ; light_index < RGBLED_NUM ; ++light_index ) {
        if (lights[light_index].enabled && timer_elapsed(lights[light_index].timer) > 10) {
        rgblight_fadeout *light = &lights[light_index];
        litup = true;

        if (light->life) {
            light->life -= 1;
            if (biton32(layer_state) == 0) {
                sethsv(light->hue + rand() % 0xF, 255, light->life, (LED_TYPE *)&led[light_index]);
            }
            light->timer = timer_read();
        }
        else {
            if (light->enabled && biton32(layer_state) == 0) {
                rgblight_sethsv_default_helper(light_index);
            }
            litup = light->enabled = false;
        }
        }
    }
    if (litup && biton32(layer_state) == 0) {
        rgblight_set();
    }
}
예제 #7
0
void rgblight_sethsv_at(uint16_t hue, uint8_t sat, uint8_t val, uint8_t index) {
  if (!rgblight_config.enable) { return; }

  LED_TYPE tmp_led;
  sethsv(hue, sat, val, &tmp_led);
  rgblight_setrgb_at(tmp_led.r, tmp_led.g, tmp_led.b, index);
}
예제 #8
0
void rgblight_effect_rainbow_swirl(uint8_t interval) {
  static uint16_t current_hue = 0;
  static uint16_t last_timer = 0;
  uint16_t hue;
  uint8_t i;
  if (timer_elapsed(last_timer) < pgm_read_byte(&RGBLED_RAINBOW_SWIRL_INTERVALS[interval / 2])) {
    return;
  }
  last_timer = timer_read();
  for (i = 0; i < RGBLED_NUM; i++) {
    hue = (360 / RGBLED_NUM * i + current_hue) % 360;
    sethsv(hue, rgblight_config.sat, rgblight_config.val, (LED_TYPE *)&led[i]);
  }
  rgblight_set();

  if (interval % 2) {
    current_hue = (current_hue + 1) % 360;
  } else {
    if (current_hue - 1 < 0) {
      current_hue = 359;
    } else {
      current_hue = current_hue - 1;
    }
  }
}
예제 #9
0
void rgblight_sethsv_noeeprom_old(uint16_t hue, uint8_t sat, uint8_t val) {
  if (rgblight_config.enable) {
    LED_TYPE tmp_led;
    sethsv(hue, sat, val, &tmp_led);
    // dprintf("rgblight set hue [MEMORY]: %u,%u,%u\n", inmem_config.hue, inmem_config.sat, inmem_config.val);
    rgblight_setrgb(tmp_led.r, tmp_led.g, tmp_led.b);
  }
}
예제 #10
0
void rgblight_effect_snake(animation_status_t *anim) {
  static uint8_t pos = 0;
  uint8_t i, j;
  int8_t k;
  int8_t increment = 1;

  if (anim->delta % 2) {
    increment = -1;
  }

#if defined(RGBLIGHT_SPLIT) && !defined(RGBLIGHT_SPLIT_NO_ANIMATION_SYNC)
  if (anim->pos == 0) { // restart signal
    if (increment == 1) {
      pos = RGBLED_NUM - 1;
    } else {
      pos = 0;
    }
    anim->pos = 1;
  }
#endif

  for (i = 0; i < RGBLED_NUM; i++) {
    led[i].r = 0;
    led[i].g = 0;
    led[i].b = 0;
    for (j = 0; j < RGBLIGHT_EFFECT_SNAKE_LENGTH; j++) {
      k = pos + j * increment;
      if (k < 0) {
        k = k + RGBLED_NUM;
      }
      if (i == k) {
        sethsv(rgblight_config.hue, rgblight_config.sat,
               (uint8_t)(rgblight_config.val*(RGBLIGHT_EFFECT_SNAKE_LENGTH-j)/RGBLIGHT_EFFECT_SNAKE_LENGTH),
               (LED_TYPE *)&led[i]);
      }
    }
  }
  rgblight_set();
  if (increment == 1) {
    if (pos - 1 < 0) {
      pos = RGBLED_NUM - 1;
#if defined(RGBLIGHT_SPLIT) && !defined(RGBLIGHT_SPLIT_NO_ANIMATION_SYNC)
      anim->pos = 0;
#endif
    } else {
      pos -= 1;
#if defined(RGBLIGHT_SPLIT) && !defined(RGBLIGHT_SPLIT_NO_ANIMATION_SYNC)
      anim->pos = 1;
#endif
    }
  } else {
    pos = (pos + 1) % RGBLED_NUM;
#if defined(RGBLIGHT_SPLIT) && !defined(RGBLIGHT_SPLIT_NO_ANIMATION_SYNC)
    anim->pos = pos;
#endif
  }
}
예제 #11
0
void rgblight_effect_alternating(void){
  static uint16_t last_timer = 0;
  static uint16_t pos = 0;
  if (timer_elapsed(last_timer) < 500) {
    return;
  }
  last_timer = timer_read();

  for(int i = 0; i<RGBLED_NUM; i++){
      if(i<RGBLED_NUM/2 && pos){
          sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, (LED_TYPE *)&led[i]);
      }else if (i>=RGBLED_NUM/2 && !pos){
          sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, (LED_TYPE *)&led[i]);
      }else{
          sethsv(rgblight_config.hue, rgblight_config.sat, 0, (LED_TYPE *)&led[i]);
      }
  }
  rgblight_set();
  pos = (pos + 1) % 2;
}
예제 #12
0
void rgblight_effect_christmas(animation_status_t *anim) {
  uint16_t hue;
  uint8_t i;

  anim->current_offset = (anim->current_offset + 1) % 2;
  for (i = 0; i < RGBLED_NUM; i++) {
    hue = 0 + ((i/RGBLIGHT_EFFECT_CHRISTMAS_STEP + anim->current_offset) % 2) * 120;
    sethsv(hue, rgblight_config.sat, rgblight_config.val, (LED_TYPE *)&led[i]);
  }
  rgblight_set();
}
예제 #13
0
void rgblight_set(void) {
  if (!rgblight_config.enable) {
    for (uint8_t i = 0; i < RGBLED_NUM; i++) {
      if (i == RGBLIGHT_FLED1 && i == RGBLIGHT_FLED2)
          continue;
      
      led[i].r = 0;
      led[i].g = 0;
      led[i].b = 0;
    }
  }
  
  switch (fled_mode) {
      case FLED_OFF:
      setrgb(0, 0, 0, &led[RGBLIGHT_FLED1]);
      setrgb(0, 0, 0, &led[RGBLIGHT_FLED2]);
      break;
      
      case FLED_INDI:
      copyrgb(&fleds[0], &led[RGBLIGHT_FLED1]);
      copyrgb(&fleds[1], &led[RGBLIGHT_FLED2]);
      break;
      
      case FLED_RGB:
      if (fled_hs[0].hue == 0 && fled_hs[0].hue == 0 && (rgblight_config.mode >= 15 && rgblight_config.mode <= 23))
          setrgb(0, 0, 0, &led[RGBLIGHT_FLED1]);
      else
        sethsv(fled_hs[0].hue, fled_hs[0].sat, fled_val, &led[RGBLIGHT_FLED1]);
      
      if (fled_hs[1].hue == 0 && fled_hs[1].hue == 0 && (rgblight_config.mode >= 15 && rgblight_config.mode <= 23))
          setrgb(0, 0, 0, &led[RGBLIGHT_FLED2]);
      else
          sethsv(fled_hs[1].hue, fled_hs[1].sat, fled_val, &led[RGBLIGHT_FLED2]);
      break;
      
      default:
      break;
  }

   ws2812_setleds(led, RGBLED_NUM);
}
예제 #14
0
void rgblight_effect_knight(uint8_t interval) {
  static int8_t pos = 0;
  static uint16_t last_timer = 0;
  uint8_t i, j, cur;
  int8_t k;
  LED_TYPE preled[RGBLED_NUM];
  static int8_t increment = -1;
  if (timer_elapsed(last_timer) < pgm_read_byte(&RGBLED_KNIGHT_INTERVALS[interval])) {
    return;
  }
  last_timer = timer_read();
  for (i = 0; i < RGBLED_NUM; i++) {
    preled[i].r = 0;
    preled[i].g = 0;
    preled[i].b = 0;
    for (j = 0; j < RGBLIGHT_EFFECT_KNIGHT_LENGTH; j++) {
      k = pos + j * increment;
      if (k < 0) {
        k = 0;
      }
      if (k >= RGBLED_NUM) {
        k = RGBLED_NUM - 1;
      }
      if (i == k) {
        sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, (LED_TYPE *)&preled[i]);
      }
    }
  }
  if (RGBLIGHT_EFFECT_KNIGHT_OFFSET) {
    for (i = 0; i < RGBLED_NUM; i++) {
      cur = (i + RGBLIGHT_EFFECT_KNIGHT_OFFSET) % RGBLED_NUM;
      led[i].r = preled[cur].r;
      led[i].g = preled[cur].g;
      led[i].b = preled[cur].b;
    }
  }
  rgblight_set();
  if (increment == 1) {
    if (pos - 1 < 0 - RGBLIGHT_EFFECT_KNIGHT_LENGTH) {
      pos = 0 - RGBLIGHT_EFFECT_KNIGHT_LENGTH;
      increment = -1;
    } else {
      pos -= 1;
    }
  } else {
    if (pos + 1 > RGBLED_NUM + RGBLIGHT_EFFECT_KNIGHT_LENGTH) {
      pos = RGBLED_NUM + RGBLIGHT_EFFECT_KNIGHT_LENGTH - 1;
      increment = 1;
    } else {
      pos += 1;
    }
  }
}
예제 #15
0
void rgblight_effect_knight(animation_status_t *anim) {

  static int8_t low_bound = 0;
  static int8_t high_bound = RGBLIGHT_EFFECT_KNIGHT_LENGTH - 1;
  static int8_t increment = 1;
  uint8_t i, cur;

#if defined(RGBLIGHT_SPLIT) && !defined(RGBLIGHT_SPLIT_NO_ANIMATION_SYNC)
  if (anim->pos == 0) { // restart signal
      anim->pos = 1;
      low_bound = 0;
      high_bound = RGBLIGHT_EFFECT_KNIGHT_LENGTH - 1;
      increment = 1;
  }
#endif
  // Set all the LEDs to 0
  for (i = 0; i < RGBLED_NUM; i++) {
    led[i].r = 0;
    led[i].g = 0;
    led[i].b = 0;
  }
  // Determine which LEDs should be lit up
  for (i = 0; i < RGBLIGHT_EFFECT_KNIGHT_LED_NUM; i++) {
    cur = (i + RGBLIGHT_EFFECT_KNIGHT_OFFSET) % RGBLED_NUM;

    if (i >= low_bound && i <= high_bound) {
      sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, (LED_TYPE *)&led[cur]);
    } else {
      led[cur].r = 0;
      led[cur].g = 0;
      led[cur].b = 0;
    }
  }
  rgblight_set();

  // Move from low_bound to high_bound changing the direction we increment each
  // time a boundary is hit.
  low_bound += increment;
  high_bound += increment;

  if (high_bound <= 0 || low_bound >= RGBLIGHT_EFFECT_KNIGHT_LED_NUM - 1) {
    increment = -increment;
#if defined(RGBLIGHT_SPLIT) && !defined(RGBLIGHT_SPLIT_NO_ANIMATION_SYNC)
    if (increment == 1) {
        anim->pos = 0;
    }
#endif
  }
}
예제 #16
0
void rgblight_effect_christmas(void) {
  static uint16_t current_offset = 0;
  static uint16_t last_timer = 0;
  uint16_t hue;
  uint8_t i;
  if (timer_elapsed(last_timer) < RGBLIGHT_EFFECT_CHRISTMAS_INTERVAL) {
    return;
  }
  last_timer = timer_read();
  current_offset = (current_offset + 1) % 2;
  for (i = 0; i < RGBLED_NUM; i++) {
    hue = 0 + ((i/RGBLIGHT_EFFECT_CHRISTMAS_STEP + current_offset) % 2) * 120;
    sethsv(hue, rgblight_config.sat, rgblight_config.val, (LED_TYPE *)&led[i]);
  }
  rgblight_set();
}
예제 #17
0
void rgblight_effect_christmas(void) {
  static uint16_t current_offset = 0;
  static uint16_t last_timer = 0;
  uint16_t hue;
  uint8_t i;
  if (timer_elapsed(last_timer) < 1000) {
    return;
  }
  last_timer = timer_read();
  current_offset = (current_offset + 1) % 2;
  for (i = 0; i < RGBLED_NUM; i++) {
    hue = 0 + ((RGBLED_NUM * (i + current_offset)) % 2) * 80;
    sethsv(hue, rgblight_config.sat, rgblight_config.val, (LED_TYPE *)&led[i]);
  }
  rgblight_set();
}
예제 #18
0
void rgblight_effect_knight(uint8_t interval) {
  static uint16_t last_timer = 0;
  if (timer_elapsed(last_timer) < pgm_read_byte(&RGBLED_KNIGHT_INTERVALS[interval])) {
    return;
  }
  last_timer = timer_read();

  static int8_t low_bound = 0;
  static int8_t high_bound = RGBLIGHT_EFFECT_KNIGHT_LENGTH - 1;
  static int8_t increment = 1;
  uint8_t i, cur;

  // Set all the LEDs to 0
  for (i = 0; i < RGBLED_NUM; i++) {
    led[i].r = 0;
    led[i].g = 0;
    led[i].b = 0;
  }
  // Determine which LEDs should be lit up
  for (i = 0; i < RGBLIGHT_EFFECT_KNIGHT_LED_NUM; i++) {
    cur = (i + RGBLIGHT_EFFECT_KNIGHT_OFFSET) % RGBLED_NUM;

    if (i >= low_bound && i <= high_bound) {
      sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, (LED_TYPE *)&led[cur]);
    } else {
      if (i == RGBLIGHT_FLED1 || i == RGBLIGHT_FLED2) {
          fled_hs[0].hue = fled_hs[1].hue = 0;
          fled_hs[0].sat = fled_hs[1].sat = 0;
      }
        
      led[cur].r = 0;
      led[cur].g = 0;
      led[cur].b = 0;
    }
  }
  rgblight_set();

  // Move from low_bound to high_bound changing the direction we increment each
  // time a boundary is hit.
  low_bound += increment;
  high_bound += increment;

  if (high_bound <= 0 || low_bound >= RGBLIGHT_EFFECT_KNIGHT_LED_NUM - 1) {
    increment = -increment;
  }
}
예제 #19
0
void rgblight_effect_rgbtest(animation_status_t *anim) {
  static uint8_t maxval = 0;
  uint8_t g; uint8_t r; uint8_t b;

  if( maxval == 0 ) {
      LED_TYPE tmp_led;
      sethsv(0, 255, RGBLIGHT_LIMIT_VAL, &tmp_led);
      maxval = tmp_led.r;
  }
  g = r = b = 0;
  switch( anim->pos ) {
    case 0: r = maxval; break;
    case 1: g = maxval; break;
    case 2: b = maxval; break;
  }
  rgblight_setrgb(r, g, b);
  anim->pos = (anim->pos + 1) % 3;
}
예제 #20
0
void rgblight_effect_snake(uint8_t interval) {
  static uint8_t pos = 0;
  static uint16_t last_timer = 0;
  uint8_t i, j;
  int8_t k;
  int8_t increment = 1;
  if (interval % 2) {
    increment = -1;
  }
  if (timer_elapsed(last_timer) < pgm_read_byte(&RGBLED_SNAKE_INTERVALS[interval / 2])) {
    return;
  }
  last_timer = timer_read();
  
  fled_hs[0].hue = fled_hs[1].hue = 0;
  fled_hs[0].sat = fled_hs[1].sat = 0;
  
  for (i = 0; i < RGBLED_NUM; i++) {
    led[i].r = 0;
    led[i].g = 0;
    led[i].b = 0;

    for (j = 0; j < RGBLIGHT_EFFECT_SNAKE_LENGTH; j++) {
      k = pos + j * increment;
      if (k < 0) {
        k = k + RGBLED_NUM;
      }
      if (i == k) {
        sethsv(rgblight_config.hue, rgblight_config.sat, (uint8_t)(rgblight_config.val*(RGBLIGHT_EFFECT_SNAKE_LENGTH-j)/RGBLIGHT_EFFECT_SNAKE_LENGTH), (LED_TYPE *)&led[i]);
      }
    }
  }
  rgblight_set();
  if (increment == 1) {
    if (pos - 1 < 0) {
      pos = RGBLED_NUM - 1;
    } else {
      pos -= 1;
    }
  } else {
    pos = (pos + 1) % RGBLED_NUM;
  }
}
예제 #21
0
void rgblight_effect_rainbow_swirl(animation_status_t *anim) {
  uint16_t hue;
  uint8_t i;

  for (i = 0; i < RGBLED_NUM; i++) {
    hue = (RGBLIGHT_RAINBOW_SWIRL_RANGE / RGBLED_NUM * i + anim->current_hue) % 360;
    sethsv(hue, rgblight_config.sat, rgblight_config.val, (LED_TYPE *)&led[i]);
  }
  rgblight_set();

  if (anim->delta % 2) {
    anim->current_hue = (anim->current_hue + 1) % 360;
  } else {
    if (anim->current_hue - 1 < 0) {
      anim->current_hue = 359;
    } else {
      anim->current_hue = anim->current_hue - 1;
    }
  }
}
예제 #22
0
int main (void)
{
    IRMP_DATA irmp_data;

    // Setup everything
    irmp_init();
    timer_init();
    pwm_init();

    // enable interrupts
    sei();

    // Main Loop
    for(;;)
    {
        if (!irmp_get_data(&irmp_data)) continue;

        //Repeating Commands
        if (!(irmp_data.flags&&IRMP_FLAG_REPETITION))
        {
            switch (irmp_data.command)
            {
            case 0x0B: //flash
                led.steps=0;
                if (led.mode == FLASH)
                {
                    led.mode=FIXED;
                    led.hsv.val=255;
                    led.steps=1;
                }
                else
                {
                    led.mode = FLASH;
                    led.speed = 100;
                    led.steps=1;
                }
                break;

            case 0x0F: //strobe
                led.steps=0;
                if (led.mode == STROBE)
                {
                    led.mode=FIXED;
                    led.hsv.val=255;
                }
                else
                {
                    led.mode = STROBE;
                    led.speed = 20;
                    led.hsv.sat=255;
                    led.hsv.val=255;
                }
                break;

            case 0x13: //fade
                led.steps=0;
                if (led.mode == FADE)
                {
                    led.mode=FIXED;
                    led.hsv.val=255;
                    led.speed=10;
                    led.steps=1;
                }
                else
                {
                    led.mode = FADE;
                    led.speed = 10;
                    led.hsv.sat=255;
                    led.hsv.val=255;
                    led.steps=1;
                }
                break;

            case 0x17: //smooth
                led.steps=0;
                if (led.mode == FLASH)
                {
                    led.mode=FIXED;
                    led.hsv.sat=255;
                    led.hsv.val=255;
                }
                else
                {
                    led.mode = FLASH;
                    led.speed = 0xFF;
                }
                break;
            }
        }

        //Non-Repeating Commands
        switch (irmp_data.command)
        {
            //Lightness
        case 0x00: //lighter
            if (led.hsv.val <= 245) led.hsv.val+=10;
            break;

        case 0x01: //darker
            if (led.hsv.val > 20) led.hsv.val-=10;
            break;

            //Power On/Off Maybe use idle modes?!
        case 0x02: //off
            led.hsv.val=0;
            break;

        case 0x03: //on
            led.hsv.val=255;
            break;

            //Predefined Colors
        case 0x04: //R
            led.mode=FIXED;
            sethsv(0,255,255);
            break;

        case 0x05: //G
            led.mode=FIXED;
            sethsv(85,255,255);
            break;

        case 0x06: //B
            led.mode=FIXED;
            sethsv(170,255,255);
            break;

        case 0x07: //W
            led.mode=FIXED;
            sethsv(0,0,255);
            break;

        case 0x08:
            led.mode=FIXED;
            sethsv(42,255,255);
            break;

        case 0x09:
            led.mode=FIXED;
            sethsv(127,255,255);
            break;

        case 0x0A:
            led.mode=FIXED;
            sethsv(212,255,255);
            break;

        case 0x0C: // Speed+
            if (led.speed > 1) --led.speed;
            break;

        case 0x0D:
            led.hsv.hue+=2;
            break;

        case 0x0E:
            if (led.hsv.sat<250) led.hsv.sat+=5;
            break;

        case 0x10: // Speed-
            if (led.speed < 255) ++led.speed;
            break;

        case 0x11: //hue-
            led.hsv.hue-=2;
            break;

        case 0x12:
            if (led.hsv.sat>5) led.hsv.sat-=5;
            break;

        case 0x14:
            break;

        case 0x15:
            break;

        case 0x16:
            break;

        }
    }
}