void init_current_effect(void) { // Disable flipping until first frame is drawn allow_flipping(false); /* Restore front and back buffer pointers to point to * different locations */ gs_restore_bufs(); // Set up rng srand_from_clock(); // Run initializer init_t init = (init_t)pgm_get(effect->init, word); if (init != NULL) init(); gs_buf_swap(); /* If NO_FLIP, we "broke" flipping if required by pointing * both buffers to the same location */ if (pgm_get(effect->flip_buffers, byte) == NO_FLIP) { gs_buf_back = gs_buf_front; } // Restart tick counter and FPS limiter reset_time(); next_draw_at = 0; }
int main() { cli(); wdt_disable(); // To make sure nothing weird happens init_tlc5940(); init_spi(); init_ps(); init_blank_timer(); init_effect_timer(); init_playlist(); initUSART(); sei(); hcsr04_start_continuous_meas(); adc_start(); serial_boot_report(); // Select correct startup mode pick_startup_mode(); while(1) { /* Serial processing is implementation specific and defined in * serial_common.c */ process_serial(); switch (mode) { case MODE_SLEEP: // Fall through to MODE_IDLE case MODE_IDLE: // No operation sleep_if_no_traffic(); break; case MODE_PLAYLIST: ticks = centisecs(); if (ticks > effect_length) { next_effect(); init_current_effect(); } // no need to break! // fall to MODE_EFFECT on purpose case MODE_EFFECT: // If a buffer is not yet flipped, wait interrupts if (flags.may_flip) { sleep_if_no_traffic(); break; } // Update clock ticks = centisecs(); /* Go back to serial handler if drawing time * is reached. By doing this we avoid serial * port slowdown when FPS is low */ if (ticks < next_draw_at ) { sleep_if_no_traffic(); break; } /* Restart effect if maximum ticks is * reached. This may result a glitch but is * better than the effect to stop. */ if (ticks == ~0) { init_current_effect(); ticks = 0; } // Update sensor values sensors.distance1 = hcsr04_get_distance_in_cm(); sensors.distance2 = hcsr04_get_distance_in_cm(); //TODO: use separate sensor sensors.ambient_light = adc_get(0) >> 2; sensors.sound_pressure_level = adc_get(1) >> 2; // Do the actual drawing draw_t draw = (draw_t)pgm_get(effect->draw,word); if (draw != NULL) { draw(); allow_flipping(true); } // Update time when next drawing is allowed next_draw_at = ticks + pgm_get(effect->minimum_ticks,byte); break; } } return 0; }
int main() { cli(); wdt_disable(); // To make sure nothing weird happens init_tlc5940(); init_spi(); init_ps(); init_blank_timer(); init_effect_timer(); init_playlist(); initUSART(); sei(); hcsr04_start_continuous_meas(); adc_start(); serial_elo_init(); // Select correct startup mode pick_startup_mode(); while(1) { if(serial_available()) { uint8_t cmd = serial_read(); #if defined AVR_ZCL serial_zcl_process(cmd); #elif defined AVR_ELO serial_elo_process(cmd); #elif defined SIMU // Do nothing #else #error Unsupported serial communication type #endif } switch (mode) { case MODE_SLEEP: // Fall through to MODE_IDLE case MODE_IDLE: // No operation sleep_mode(); break; case MODE_PLAYLIST: ticks = centisecs(); if (ticks > effect_length) { next_effect(); init_current_effect(); } // no need to break! // fall to MODE_EFFECT on purpose case MODE_EFFECT: // If a buffer is not yet flipped if (flags.may_flip) break; // Update clock and sensor values ticks = centisecs(); sensors.distance1 = hcsr04_get_distance_in_cm(); sensors.distance2 = hcsr04_get_distance_in_cm(); //TODO: use separate sensor sensors.ambient_light = adc_get(0) >> 2; sensors.sound_pressure_level = adc_get(1) >> 2; // Do the actual drawing draw_t draw = (draw_t)pgm_get(effect->draw,word); if (draw != NULL) { draw(); allow_flipping(true); } // Slow down drawing if FPS is going to be too high uint16_t target_ticks = ticks + pgm_get(effect->minimum_ticks,byte); while (centisecs() < target_ticks ) { sleep_mode(); } break; } } return 0; }