#define F_CPU 16000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
void FCG_initclk(void) {
CLKPR = (1<<CLKPCE);
CLKPR = 0x00;
}
void FCG_initbp(void) {
DDRC |= (1 << PC5);
}
void FCG_initt0(void) {
sei();
TCNT0=0;
OCR0A=160;
TIMSK0= (1 << OCIE0A);
TCCR0A= (1 << WGM01);
TCCR0B= (1 << CS00) | (1 << CS02);
}
volatile unsigned char FCG_systime;
unsigned char FCG_systime_recent;
unsigned char FCG_systime_delta(void) {
unsigned char now= FCG_systime;
unsigned char dt= now-FCG_systime_recent;
FCG_systime_recent+= dt;
return dt;
}
volatile unsigned char FCG_beepcnt=0;
void FCG_beep(unsigned char dur) {
FCG_beepcnt=dur;
}
ISR(TIMER0_COMPA_vect){
FCG_systime++;
if(FCG_beepcnt!=0) {
if(! ( PORTC & (1 << PC5) )) {
PORTC |= (1 << PC5);
} else {
PORTC &= ~(1 << PC5);
FCG_beepcnt--;
}
}
}
static int FCG_exec_event=-1;
static int FCG_sched_event=0;
static int FCG_status=0;
static int FCG_parallel_state_0=0;
static int FCG_parallel_state_1=0;
static int FCG_parallel_state_2=0;
static int FCG_line_level_0;
unsigned char FCG_pending_events[] = { 0x00, 0x00 };
unsigned char FCG_enabled_events[2];
unsigned char FCG_executable_events[2];
static int FCG_timer_Tick_cnt= 25;
static char FCG_timer_Tick_run= 0;
unsigned char FCG_aux_locenabled[2];
static int FCG_aux_parsetrans;
static int FCG_aux_parseevent;
static unsigned char FCG_aux_wordret;
static int FCG_aux_edge;
static int FCG_aux_wordaddr;
static int FCG_aux_bitaddr;
static unsigned char FCG_aux_bitmask;
const int FCG_generator_vector_0[] PROGMEM =
{ 3, 3, 0, 4, 6, 0, 5, 9, 0, 6, 12, 0, 7, 15, 0, 8, 18, 0, 9, 0, 0 };
const int FCG_generator_vector_1[] PROGMEM =
{ 3, 13, 4, 13, 5, 13, 7, 13, 8, 13, 9, 13, 0, 2, 0, 0 };
const int FCG_generator_vector_2[] PROGMEM =
{ 7, 0, 1, 5, 0, 3, 5, 7, 0, 1, 5, 0 };
void FCG_cyclic(void) {
if( FCG_exec_event == -1 ) {
FCG_line_level_0 = ( PINB & ( 1 << PB4 ) );
if( ! ( FCG_line_level_0 ) ) {
FCG_pending_events[0] |= 0x01;
};
};
if( FCG_exec_event != -1 ) {
FCG_aux_edge = ( PINB & ( 1 << PB4 ) );
if( FCG_aux_edge != FCG_line_level_0 ) {
if( FCG_line_level_0 ) {
FCG_pending_events[0] |= 0x01;
FCG_sched_event = 0;
};
FCG_line_level_0 = FCG_aux_edge;
};
};
if( FCG_timer_Tick_run && (FCG_timer_Tick_cnt <= 0) ) {
FCG_timer_Tick_run = 0;
FCG_pending_events[0] |= 0x02;
FCG_sched_event = 0;
};
if( FCG_exec_event != 0 ) {
FCG_enabled_events[0] = 0xff;
FCG_enabled_events[1] = 0x01;
FCG_aux_locenabled[0] = 0x03;
FCG_aux_locenabled[1] = 0x00;
FCG_aux_parsetrans = FCG_parallel_state_0;
while(1) {
FCG_aux_parseevent = pgm_read_word( &( FCG_generator_vector_0[FCG_aux_parsetrans] ) );
if( FCG_aux_parseevent == 0 ) break;
FCG_aux_bitaddr = FCG_aux_parseevent;
FCG_aux_bitaddr--;
FCG_aux_wordaddr = FCG_aux_bitaddr / 8;
FCG_aux_bitaddr = FCG_aux_bitaddr % 8;
FCG_aux_bitmask = (0x01 << FCG_aux_bitaddr);
FCG_aux_locenabled[FCG_aux_wordaddr] |= FCG_aux_bitmask;
FCG_aux_parsetrans += 2;
};
FCG_enabled_events[0] &= FCG_aux_locenabled[0];
FCG_enabled_events[1] &= FCG_aux_locenabled[1];
FCG_aux_locenabled[0] = 0x21;
FCG_aux_locenabled[1] = 0x00;
FCG_aux_parsetrans = FCG_parallel_state_1;
while(1) {
FCG_aux_parseevent = pgm_read_word( &( FCG_generator_vector_1[FCG_aux_parsetrans] ) );
if( FCG_aux_parseevent == 0 ) break;
FCG_aux_bitaddr = FCG_aux_parseevent;
FCG_aux_bitaddr--;
FCG_aux_wordaddr = FCG_aux_bitaddr / 8;
FCG_aux_bitaddr = FCG_aux_bitaddr % 8;
FCG_aux_bitmask = (0x01 << FCG_aux_bitaddr);
FCG_aux_locenabled[FCG_aux_wordaddr] |= FCG_aux_bitmask;
FCG_aux_parsetrans += 2;
};
FCG_enabled_events[0] &= FCG_aux_locenabled[0];
FCG_enabled_events[1] &= FCG_aux_locenabled[1];
FCG_aux_locenabled[0] = 0xba;
FCG_aux_locenabled[1] = 0x01;
FCG_aux_parsetrans = FCG_parallel_state_2;
while(1) {
FCG_aux_parseevent = pgm_read_word( &( FCG_generator_vector_2[FCG_aux_parsetrans] ) );
if( FCG_aux_parseevent == 0 ) break;
FCG_aux_bitaddr = FCG_aux_parseevent;
FCG_aux_bitaddr--;
FCG_aux_wordaddr = FCG_aux_bitaddr / 8;
FCG_aux_bitaddr = FCG_aux_bitaddr % 8;
FCG_aux_bitmask = (0x01 << FCG_aux_bitaddr);
FCG_aux_locenabled[FCG_aux_wordaddr] |= FCG_aux_bitmask;
FCG_aux_parsetrans += 2;
};
FCG_enabled_events[0] &= FCG_aux_locenabled[0];
FCG_enabled_events[1] &= FCG_aux_locenabled[1];
FCG_exec_event = 0;
FCG_sched_event = 0;
};
if( FCG_sched_event == 0 ) {
FCG_executable_events[0] = FCG_pending_events[0] | 0xfc;
FCG_executable_events[1] = FCG_pending_events[1] | 0x01;
FCG_executable_events[0] &= FCG_enabled_events[0];
FCG_executable_events[1] &= FCG_enabled_events[1];
FCG_sched_event = 0;
if( FCG_executable_events[0] != 0x00 ) {
if( ( FCG_executable_events[0] & 0x0f ) != 0 ) {
if( ( FCG_executable_events[0] & 0x03 ) != 0 ) {
if( ( FCG_executable_events[0] & 0x01 ) != 0 ) {
FCG_sched_event = 1;
} else {
FCG_sched_event = 2;
};
} else {
if( ( FCG_executable_events[0] & 0x04 ) != 0 ) {
FCG_sched_event = 3;
} else {
FCG_sched_event = 4;
};
};
} else {
if( ( FCG_executable_events[0] & 0x30 ) != 0 ) {
if( ( FCG_executable_events[0] & 0x10 ) != 0 ) {
FCG_sched_event = 5;
} else {
FCG_sched_event = 6;
};
} else {
if( ( FCG_executable_events[0] & 0x40 ) != 0 ) {
FCG_sched_event = 7;
} else {
FCG_sched_event = 8;
};
};
};
};
if( FCG_sched_event == 0 ) {
if( FCG_executable_events[1] != 0x00 ) {
FCG_sched_event = 9;
};
};
if( FCG_sched_event > 0 ) {
FCG_aux_bitaddr = FCG_sched_event;
FCG_aux_bitaddr--;
FCG_aux_wordaddr = FCG_aux_bitaddr / 8;
FCG_aux_bitaddr = FCG_aux_bitaddr % 8;
FCG_aux_bitmask = (0x01 << FCG_aux_bitaddr);
FCG_pending_events[FCG_aux_wordaddr] &= ~(FCG_aux_bitmask);
};
if( FCG_sched_event == 0 ) {
FCG_aux_wordret = FCG_pending_events[0];
FCG_pending_events[1] &= 0x01;
FCG_aux_wordret |= FCG_pending_events[1];
if( FCG_aux_wordret != 0x00 ) {
FCG_status = 2;
};
};
if( FCG_sched_event == 0 ) {
FCG_pending_events[0] = 0x00;
FCG_pending_events[1] = 0x00;
};
};
if( FCG_sched_event != 0 ) {
FCG_exec_event = FCG_sched_event;
FCG_sched_event = 0;
FCG_aux_parsetrans = FCG_parallel_state_0;
while(1) {
FCG_aux_parseevent = pgm_read_word( &( FCG_generator_vector_0[FCG_aux_parsetrans] ) );
if( FCG_aux_parseevent == FCG_exec_event ) break;
if( FCG_aux_parseevent == 0 ) break;
FCG_aux_parsetrans += 2;
};
if( FCG_aux_parseevent > 0 ) {
FCG_aux_parsetrans++;
FCG_parallel_state_0 = pgm_read_word( &( FCG_generator_vector_0[FCG_aux_parsetrans] ) );
};
FCG_aux_parsetrans = FCG_parallel_state_1;
while(1) {
FCG_aux_parseevent = pgm_read_word( &( FCG_generator_vector_1[FCG_aux_parsetrans] ) );
if( FCG_aux_parseevent == FCG_exec_event ) break;
if( FCG_aux_parseevent == 0 ) break;
FCG_aux_parsetrans += 2;
};
if( FCG_aux_parseevent > 0 ) {
FCG_aux_parsetrans++;
FCG_parallel_state_1 = pgm_read_word( &( FCG_generator_vector_1[FCG_aux_parsetrans] ) );
};
FCG_aux_parsetrans = FCG_parallel_state_2;
while(1) {
FCG_aux_parseevent = pgm_read_word( &( FCG_generator_vector_2[FCG_aux_parsetrans] ) );
if( FCG_aux_parseevent == FCG_exec_event ) break;
if( FCG_aux_parseevent == 0 ) break;
FCG_aux_parsetrans += 2;
};
if( FCG_aux_parseevent > 0 ) {
FCG_aux_parsetrans++;
FCG_parallel_state_2 = pgm_read_word( &( FCG_generator_vector_2[FCG_aux_parsetrans] ) );
};
};
if( FCG_exec_event > 0 ) {
switch(FCG_exec_event) {
case 3:
FCG_timer_Tick_cnt = 25;
FCG_timer_Tick_run = 1;
break;
case 4:
FCG_timer_Tick_cnt = 25;
FCG_timer_Tick_run = 1;
break;
case 5:
FCG_timer_Tick_cnt = 25;
FCG_timer_Tick_run = 1;
break;
case 7:
FCG_timer_Tick_cnt = 25;
FCG_timer_Tick_run = 1;
break;
case 8:
FCG_timer_Tick_cnt = 25;
FCG_timer_Tick_run = 1;
break;
case 9:
FCG_timer_Tick_cnt = 25;
FCG_timer_Tick_run = 1;
break;
default:
break;
};
};
if( FCG_exec_event > 2 ) {
switch(FCG_exec_event) {
case 3:
PORTC |= ( 1 << PC0 );
break;
case 4:
PORTC |= ( 1 << PC1 );
break;
case 5:
PORTC |= ( 1 << PC2 );
break;
case 6:
FCG_beep(100);;
break;
case 7:
PORTC &= ~( 1 << PC0 );
break;
case 8:
PORTC &= ~( 1 << PC1 );
break;
case 9:
PORTC &= ~( 1 << PC2 );
break;
default:
break;
};
};
};
void FCG_timerdec(int dec) {
if( FCG_timer_Tick_run ) FCG_timer_Tick_cnt -= dec;
};
void FCG_initpio(void) {
DDRC |= ( 1 << PC0 ) | ( 1 << PC1 ) | ( 1 << PC2 );
PORTB |= ( 1 << PB4 );
};
int main(void){
FCG_initclk();
FCG_initpio();
FCG_initt0();
FCG_initbp();
while(1) {
FCG_cyclic();
FCG_timerdec(FCG_systime_delta());
}
return 0;
}