88 lines
1.9 KiB
C
88 lines
1.9 KiB
C
/*
|
|
* WC-Licht.
|
|
*/
|
|
|
|
#include <avr/io.h>
|
|
#include <avr/interrupt.h>
|
|
#include <avr/sleep.h>
|
|
#include "wc-licht.h"
|
|
#include "animations.h"
|
|
|
|
|
|
uint8_t fb[SIZE_X*2]; // Framebuffer.
|
|
uint8_t screen[SIZE_X*2]; // Screen buffer.
|
|
|
|
/*
|
|
* Woot, main!
|
|
*/
|
|
int main (void) {
|
|
/*
|
|
* Init display output ports.
|
|
*/
|
|
// Horizontal pins sink current.
|
|
HORIZ_PORT = 0x00;
|
|
HORIZ_DDR = 0x00;
|
|
// Vertical pins deliver current.
|
|
VERT_PORT = 0x00;
|
|
VERT_DDR = 0xff;
|
|
|
|
/*
|
|
* Init timer for display refresh interrupts.
|
|
*/
|
|
TCCR2 |= 1 << WGM21; // CTC mode.
|
|
TCCR2 |= (1 << CS21) | (1 << CS20); // Prescaling: CLK/32.
|
|
OCR2 = 32; // Set output compare register.
|
|
TIMSK |= 1 << OCIE2; // Enable interrupt.
|
|
|
|
/*
|
|
* Init timer for animation delays.
|
|
*/
|
|
TCCR1B |= 1 << WGM12; // CTC Mode.
|
|
TCCR1B |= (1 << CS12) | (1 << CS10); // clk/1024.
|
|
//TIMSK |= 1 << OCIE1A; // Enable interrupt.
|
|
|
|
ACSR |= 1 << ACD; // Disable analog comparator.
|
|
|
|
sleep_enable();
|
|
sei(); // Starts display.
|
|
|
|
// Play intro.
|
|
play_animation(&intro);
|
|
DELAY = INTERLUDE_DELAY;
|
|
|
|
/*
|
|
* Main loop.
|
|
*/
|
|
while (1) {
|
|
if (TIFR & (1 << OCF1A)) {
|
|
// Time for a new animation.
|
|
TIFR |= 1 << OCF1A;
|
|
|
|
play_animation(&interlude);
|
|
DELAY = INTERLUDE_DELAY;
|
|
}
|
|
|
|
sleep_cpu();
|
|
};
|
|
}
|
|
|
|
|
|
void play_animation (const Animation* anim) {
|
|
DELAY = ANIMATION_DELAY;
|
|
TCNT1 = 0x0000; // Re-start delay timer.
|
|
TIFR |= 1 << OCF1A; // Unset delay passed flag.
|
|
|
|
for (uint8_t i = 0; i < anim->length; i++) {
|
|
copy_layer(anim->frames[i], screen);
|
|
|
|
while (!(TIFR & (1 << OCF1A))) {
|
|
// Delay.
|
|
sleep_cpu();
|
|
};
|
|
|
|
TCNT1 = 0x0000; // Re-start delay timer.
|
|
TIFR |= 1 << OCF1A; // Unset delay passed flag.
|
|
}
|
|
}
|
|
|
|
|