/* $Id$ This file is part of R²C² Copyright © 2010 Mikkosoft Productions, Mikko Rasa Distributed under the GPL */ #include #include #define BIT(n) (1<<(n)) #define NOP() __asm__("nop"); uint8_t digits[11] = { 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, 0x40 }; uint16_t read_input(void); uint16_t read_input_filtered(void); void write_serial(uint8_t); void write_7seg(uint8_t); uint8_t speed = 0; uint16_t funcs = 0; volatile uint8_t ticks = 0; volatile uint8_t rx_buf[3]; volatile uint8_t rx_fill = 0; ISR(TIMER1_COMPA_vect) { if(ticks<255) ++ticks; } ISR(USART_RX_vect) { uint8_t c = UDR0; if(rx_fill==0) { if(c=='A' || c=='S') rx_buf[rx_fill++] = c; } else { rx_buf[rx_fill++] = c; if(rx_buf[0]=='A' && rx_fill==3) { uint8_t n = (rx_buf[1]-'0')*10+(rx_buf[2]-'0'); write_7seg(n/10); write_7seg(n%10); rx_fill = 0; } else if(rx_buf[0]=='S' && rx_fill==3) { speed = (rx_buf[1]-'0')*10+(rx_buf[2]-'0'); rx_fill = 0; } } } int main() { uint16_t state = 0; DDRD = 0x02; // 00000010 PORTD = 0xFC; // 11111100 DDRB = 0x3F; // 00111111 PORTB = 0x0F; // 00001111 write_7seg(10); write_7seg(10); // 9600 baud, 8N1 UBRR0H = 0; UBRR0L = 103; UCSR0C = BIT(UCSZ00) | BIT(UCSZ01); UCSR0B = BIT(RXEN0) | BIT(TXEN0) | BIT(RXCIE0); TCCR1A = 0; TCCR1B = BIT(WGM12) | BIT(CS12); OCR1AH = 24; OCR1AL = 106; TIMSK1 = BIT(OCIE1A); sei(); while(1) { uint16_t toggled; uint8_t i; uint16_t input; input = read_input_filtered(); input ^= 0xFFFC; toggled = state^input; state = input; if((toggled&3)==2 && (state&1)) { uint8_t action = 0; if(state&2) { if(speed<14) { ++speed; action = 1; } } else { if(speed>0) { --speed; action = 1; } else if(ticks>10) action = 2; } if(action==1) { write_serial('S'); write_serial('0'+speed/10); write_serial('0'+speed%10); } else if(action==2) write_serial('R'); ticks = 0; } for(i=0; i<14; ++i) { uint16_t bit = 4<>2; input |= pins&3; input |= (pins&0x3C)<<(row*4); } return input; } uint16_t read_input_filtered(void) { uint16_t valid = 0xFFFF; uint16_t prev; uint16_t input; uint8_t i; prev = read_input(); for(i=0; i<20; ++i) { input = read_input(); valid &= ~(input^prev); prev = input; } return input&valid; } void write_serial(uint8_t c) { while(!(UCSR0A&(1<