#include #include #include #include #include #include "writepin.h" #include "decoder.h" static constexpr uint8_t T0_A = PB0; static constexpr uint8_t T0_B = PB1; static constexpr uint8_t T1_A = PB3; static constexpr uint8_t T1_B = PB4; static volatile bool turnout0Flag = false; static volatile bool turnout1Flag = false; uint16_t oldData = 0; constexpr bool debug = false; void handler(uint16_t data, void *user_data) { (void)user_data; if constexpr(debug) { writePin(&PORTB, T0_A, false); _delay_ms(1); for(uint8_t i = 0; i < 10; ++i) { writePin(&PORTB, T0_A, true); _delay_us(25); if(data & (1 << (9-i))) _delay_us(75); writePin(&PORTB, T0_A, false); _delay_us(25); if(!(data & (1 << (9-i)))) _delay_us(75); } } if(data == oldData) { if(((bool)(data & (1 << 9))) != ((bool)(data & (1 << 8))) || ((bool)(data & (1 << 7))) != ((bool)(data & (1 << 6))) || ((bool)(data & (1 << 5))) != ((bool)(data & (1 << 4)))) return; bool set = data & (1 << 9); if(data & (1 << 7)) turnout0Flag = set; if(data & (1 << 5)) turnout1Flag = set; } else { oldData = data; } } static void setTurnout0(bool in) { writePin(&PORTB, T0_A, in); writePin(&PORTB, T0_B, !in); _delay_ms(150); writePin(&PORTB, T0_A, false); writePin(&PORTB, T0_B, false); } static void setTurnout1(bool in) { writePin(&PORTB, T1_A, in); writePin(&PORTB, T1_B, !in); _delay_ms(150); writePin(&PORTB, T1_A, false); writePin(&PORTB, T1_B, false); } Decoder decoder(&PINB, PB2, &TCNT1, &handler, nullptr, 0x01); ISR(TIMER1_OVF_vect) { decoder.overflowInterrupt(); } ISR(INT0_vect) { if constexpr(debug) { writePin(&PORTB, T1_A, !readPin(&PORTB, T1_A)); } decoder.interrupt(); } int main() { DDRB = (1 << PB0) | (1 << PB1) | (1 << PB3) | (1 << PB4); bool turnout0 = turnout0Flag; bool turnout1 = turnout1Flag; _delay_ms(100); setTurnout0(turnout0); setTurnout1(turnout1); MCUCR = (1 << ISC00); //enable rising and falling irq on INT0 GIMSK = (1 << INT0); //unmask INT0 TIMSK = (1 << TOIE1); //enable timer 1 overflow irq TCCR1 = (1 << CS12) | (1 << CS10); //enable timer 1 with /16 timer sei(); while(true) { if(turnout0 != turnout0Flag) { turnout0 = turnout0Flag; setTurnout0(turnout0); } if(turnout1 != turnout1Flag) { turnout1 = turnout1Flag; setTurnout1(turnout1); } } }