X-Git-Url: http://git.tdb.fi/?p=model-railway-devices.git;a=blobdiff_plain;f=firmware%2Fs88w-t.c;h=e394d603032fe07b14047f554abc633afb451c7a;hp=e88a1f509eb6fc24aec4c4a8e05e83bce6a4fd7e;hb=d8a31ed675778c08ca781beb62863c62d6f0bd94;hpb=af6a469f761ceec44e94bea5fe8e5345fd368966 diff --git a/firmware/s88w-t.c b/firmware/s88w-t.c index e88a1f5..e394d60 100644 --- a/firmware/s88w-t.c +++ b/firmware/s88w-t.c @@ -24,48 +24,55 @@ activate. #include #include +#include "eeprom.h" +#include "serial.h" +#include "timer.h" #define BIT(n) (1<<(n)) +void receive(uint8_t); void send_state(void); -void write_serial(uint8_t); uint8_t hexdigit(uint8_t); +uint8_t decode_hex(uint8_t); -volatile uint8_t state = 0; +uint8_t rx_buf[4]; +uint8_t rx_fill = 0xFF; +volatile uint8_t nibbles = 2; +volatile uint8_t offset = 0; +volatile uint16_t state = 0; int main() { + if(eeprom_read(0)==0xA5) + { + offset = eeprom_read(1)<<8; + offset |= eeprom_read(2); + nibbles = eeprom_read(3); + } + DDRD = 0x02; // 00000010 PORTD = 0xFC; // 11111100 - DDRB = 0x20; // 00100000 + DDRB = 0x20; // 00000000 PORTB = 0x3F; // 00111111 - // 9600 baud, 8N1 - UBRR0H = 0; - UBRR0L = 103; - UCSR0C = BIT(UCSZ00) | BIT(UCSZ01); - UCSR0B = BIT(RXEN0) | BIT(TXEN0); - - // 0.5 Hz (CK/1024, TOP=31250) - TCCR1A = 0; - TCCR1B = BIT(WGM12) | BIT(CS12) | BIT(CS10); - OCR1AH = 122; - OCR1AL = 18; - TIMSK1 = BIT(OCIE1A); + serial_init(9600); + serial_set_callback(receive); + timer_init(1, 2); + timer_set_callback(send_state); sei(); while(1) { uint8_t i; - uint8_t input = 0; - uint8_t valid = 0xFF; + uint16_t input = 0; + uint16_t valid = 0xFFF; for(i=0; i<100; ++i) { - uint8_t pins; + uint16_t pins; - pins = ~((PIND>>2) | (PINB<<6)); + pins = ~((PIND>>2) | ((PINB&0x3F)<<6)); if(i==0) input = pins; valid &= ~(pins^input); @@ -73,6 +80,7 @@ int main() input &= valid; input |= state&~valid; + input &= (1<<(nibbles*4))-1; if(input!=state) { @@ -84,28 +92,64 @@ int main() return 0; } -ISR(TIMER1_COMPA_vect) +void receive(uint8_t c) { - send_state(); + if(rx_fill==0xFF) + { + if(c==':') + rx_fill = 0; + } + else if(c=='.') + { + if(rx_buf[0]=='S' && rx_fill==4) + { + offset = (decode_hex(rx_buf[1])<<8) | (decode_hex(rx_buf[2])<<4) | decode_hex(rx_buf[3]); + nibbles = (offset&3)+1; + offset &= 0xFFC; + + eeprom_write(0, 0xA5); + eeprom_write(1, offset>>8); + eeprom_write(2, offset); + eeprom_write(3, nibbles); + } + rx_fill = 0xFF; + } + else + { + if(rx_fill>4)); - write_serial(hexdigit(state&0xF)); -} - -void write_serial(uint8_t c) -{ - while(!(UCSR0A&(1<>8)); + serial_write(hexdigit(offset>>4)); + serial_write(hexdigit(offset|(nibbles-1))); + for(i=nibbles; i--;) + serial_write(hexdigit(state>>(i*4))); + serial_write('.'); } uint8_t hexdigit(uint8_t n) { + n &= 0xF; if(n<10) return '0'+n; else return 'A'+(n-0xA); } + +uint8_t decode_hex(uint8_t c) +{ + if(c>='0' && c<='9') + return c-'0'; + else if(c>='A' && c<='F') + return 0xA+(c-'A'); + else + return 0; +}