X-Git-Url: http://git.tdb.fi/?p=model-railway-devices.git;a=blobdiff_plain;f=firmware%2Fs88w-r.c;h=f64445d81c5a33f12b8f82ef1cae2ea21c7fba5d;hp=dac0cfcaf85948eeebd70f2eaebae030d9fe3ac6;hb=d8a31ed675778c08ca781beb62863c62d6f0bd94;hpb=af6a469f761ceec44e94bea5fe8e5345fd368966 diff --git a/firmware/s88w-r.c b/firmware/s88w-r.c index dac0cfc..f64445d 100644 --- a/firmware/s88w-r.c +++ b/firmware/s88w-r.c @@ -25,6 +25,8 @@ D5 - S88 RESET #include #include +#include "lcd.h" +#include "serial.h" #define DATA_OUT PORTD2 #define CLOCK PIND3 @@ -33,28 +35,33 @@ D5 - S88 RESET #define BIT(n) (1<<(n)) +void receive(uint8_t); +uint8_t hexdigit(uint8_t); uint8_t decode_hex(uint8_t); -volatile uint8_t rx_buf[3]; -volatile uint8_t rx_fill = 0; -volatile uint8_t input = 0; -volatile uint8_t latch = 0; +volatile uint8_t rx_buf[7]; +volatile uint8_t rx_fill = 0xFF; +volatile uint8_t input[128] = { 0 }; +volatile uint8_t latch[128] = { 0 }; +uint8_t log_pos = 0; int main() { uint8_t clock_high = 0; uint8_t bits = 0; + uint8_t n_bits = 8; + uint8_t offset = 0; DDRD = 0x06; // 00000110 PIND = 0xC0; // 11000000 DDRB = 0x20; // 00100000 PINB = 0x1F; // 00011111 - // 9600 baud, 8N1 - UBRR0H = 0; - UBRR0L = 103; - UCSR0C = BIT(UCSZ00) | BIT(UCSZ01); - UCSR0B = BIT(RXEN0) | BIT(TXEN0) | BIT(RXCIE0); + serial_init(9600); + serial_set_callback(receive); + lcd_init(); + lcd_on(); + lcd_clear(); sei(); @@ -69,9 +76,21 @@ int main() if(!clock_high) { if(d_pins&BIT(LOAD)) - bits = latch; + { + offset = 0; + bits = latch[0]; + n_bits = 8; + } else + { bits >>= 1; + if(!--n_bits) + { + ++offset; + bits = latch[offset]; + n_bits = 8; + } + } if(bits&1) PORTD |= BIT(DATA_OUT); @@ -85,28 +104,77 @@ int main() clock_high = 0; if(d_pins&BIT(RESET)) - latch = input; + { + uint8_t i; + for(i=0; i<128; ++i) + latch[i] = input[i]; + } } } -ISR(USART_RX_vect) +void receive(uint8_t c) { - uint8_t c = UDR0; - if(rx_fill==0) + if(rx_fill==0xFF) { if(c==':') - rx_buf[rx_fill++] = c; + rx_fill = 0; } - else + else if(c=='.') { - rx_buf[rx_fill++] = c; - if(rx_buf[0]==':' && rx_fill==3) + if(rx_fill>=4) { - input = (decode_hex(rx_buf[1])<<4) | decode_hex(rx_buf[2]); - latch |= input; - rx_fill = 0; + uint16_t offset; + uint8_t nibbles; + uint8_t i; + + offset = (decode_hex(rx_buf[0])<<8) | (decode_hex(rx_buf[1])<<4) | decode_hex(rx_buf[2]); + nibbles = (offset&3); + offset >>= 2; + if(rx_fill>3+nibbles) + { + for(i=0; i<=nibbles; ++i) + { + uint16_t j = offset+nibbles-i; + uint8_t shift = 4*(j&1); + uint8_t bits = decode_hex(rx_buf[3+i]); + input[j/2] = (input[j/2]&~(0xF<>4)); + lcd_write(hexdigit(input[i])); + } } + rx_fill = 0xFF; + } + else + { + if(rx_fill=60) + log_pos = 0; + lcd_gotoxy(log_pos%20, 1+log_pos/20); + lcd_write(255); +} + +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)