// MAIN_pinwatch.c /* Copyright (C) 2016 H.Poetzl ** ** This program is free software: you can redistribute it and/or ** modify it under the terms of the GNU General Public License ** as published by the Free Software Foundation, either version ** 2 of the License, or (at your option) any later version. ** */ #define F_CPU 16000000 #include #include #include #include uint64_t cycle = 0; uint8_t col = ~0; static uint8_t gpin[7] = { 0 }; static uint8_t gddr[7] = { 0 }; static uint8_t gport[7] = { 0 }; static uint8_t gmask[7] = { ~0, ~0x40, ~0, ~0, ~0x40, ~0, ~0 }; static uint8_t mask[7]; static uint8_t tcnt[7][8] = {{ 0 }}; static inline void uart0_tx(char chr) { while (!(UCSR0A & (1< '9') chr += 'A' - '9' - 1; uart0_tx(chr); } static inline void uart0_tx_byte(uint8_t val) { uart0_tx_hex(val >> 4); uart0_tx_hex(val & 0xF); } static inline void uart0_tx_uint16(uint16_t val) { uart0_tx_byte(val >> 8); uart0_tx_byte(val & 0xFF); } static inline void uart0_tx_uint32(uint32_t val) { uart0_tx_uint16(val >> 16); uart0_tx_uint16(val & 0xFFFF); } static inline void uart0_tx_uint64(uint64_t val) { uart0_tx_uint32(val >> 32L); uart0_tx_uint32(val & 0xFFFFFFFFL); } static inline void uart0_tx_newline(void) { if (col) { uart0_tx('\r'); uart0_tx('\n'); col = 0; } } static inline void check(uint8_t idx, uint8_t pin, uint8_t ddr, uint8_t port) { uint8_t xor = pin ^ gpin[idx]; uint8_t msk = mask[idx]; if (xor & msk) { for (uint8_t bit=0; bit<8; bit++) { if (((xor & msk) >> bit) & 1) { if (tcnt[idx][bit] < 15) { uart0_tx('A' + idx); uart0_tx_hex(bit); if ((pin >> bit) & 1) uart0_tx('+'); else uart0_tx('-'); tcnt[idx][bit]++; } else if (tcnt[idx][bit] != 0xFF) { uart0_tx('A' + idx); uart0_tx_hex(bit); uart0_tx('!'); mask[idx] &= ~(1 << bit); tcnt[idx][bit] = 0xFF; } } } gpin[idx] = pin; } if ((msk ^ mask[idx]) || ((ddr ^ gddr[idx]) & gmask[idx]) || (port ^ gport[idx]) & gmask[idx]) { uart0_tx_newline(); uart0_tx('A' + idx); uart0_tx(':'); uart0_tx(' '); uart0_tx_byte(pin); uart0_tx('/'); uart0_tx_byte(ddr); uart0_tx('/'); uart0_tx_byte(port); uart0_tx('|'); uart0_tx_byte(mask[idx]); uart0_tx(' '); uart0_tx('#'); uart0_tx_uint64(cycle); uart0_tx_newline(); gddr[idx] = ddr; gport[idx] = port; } } ISR (BADISR_vect) { uart0_tx('$'); asm("jmp 0"); } void bad_pc(void) { uart0_tx('%'); asm("jmp 0"); } int main(void) { uint8_t res; res = MCUSR; MCUSR = 0; cli(); UBRR0H = 0; UBRR0L = 13; // 115200 @ 12MHz UBRR0L = 39; // 38400 @ 12MHz UBRR0L = 52; // 38400 @ 16MHz UCSR0A = (1<> 16) & 0xFF; if (this ^ prev) { if (this & 0xF) { uart0_tx('.'); } else { uart0_tx_newline(); uart0_tx('#'); uart0_tx_uint64(cycle); uart0_tx_newline(); } switch (this >> 4) { case 0: PORTB = ~0x00; PORTE = ~0x00; break; case 1: PORTB = ~0x40; PORTE = ~0x00; break; case 2: PORTB = ~0x00; PORTE = ~0x40; break; case 3: PORTB = ~0x40; PORTE = ~0x40; break; } prev = this; } } uart0_tx('*'); while (1); }