X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=firmware%2Fs88w-r.c;fp=firmware%2Fs88w-r.c;h=dac0cfcaf85948eeebd70f2eaebae030d9fe3ac6;hb=af6a469f761ceec44e94bea5fe8e5345fd368966;hp=0000000000000000000000000000000000000000;hpb=fd3352aba49e455947bdcbfccc8a37e165564ba3;p=model-railway-devices.git diff --git a/firmware/s88w-r.c b/firmware/s88w-r.c new file mode 100644 index 0000000..dac0cfc --- /dev/null +++ b/firmware/s88w-r.c @@ -0,0 +1,120 @@ +/* $Id$ + +This file is part of the MSP Märklin suite +Copyright © 2010 Mikkosoft Productions, Mikko Rasa +Distributed under the GPL + +Firmware for wireless S88 receiver module + +S88 pinout: +1 - DATA +2 - GND +3 - CLOCK +4 - LOAD +5 - RESET +6 - POWER + +ATMega pinout: +D0 - serial RX +D1 - serial TX +D2 - S88 DATA +D3 - S88 CLOCK +D4 - S88 LOAD +D5 - S88 RESET +*/ + +#include +#include + +#define DATA_OUT PORTD2 +#define CLOCK PIND3 +#define LOAD PIND4 +#define RESET PIND5 + +#define BIT(n) (1<<(n)) + +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; + +int main() +{ + uint8_t clock_high = 0; + uint8_t bits = 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); + + sei(); + + while(1) + { + uint8_t d_pins; + + d_pins = PIND; + + if(d_pins&BIT(CLOCK)) + { + if(!clock_high) + { + if(d_pins&BIT(LOAD)) + bits = latch; + else + bits >>= 1; + + if(bits&1) + PORTD |= BIT(DATA_OUT); + else + PORTD &= ~BIT(DATA_OUT); + + clock_high = 1; + } + } + else if(clock_high) + clock_high = 0; + + if(d_pins&BIT(RESET)) + latch = input; + } +} + +ISR(USART_RX_vect) +{ + uint8_t c = UDR0; + if(rx_fill==0) + { + if(c==':') + rx_buf[rx_fill++] = c; + } + else + { + rx_buf[rx_fill++] = c; + if(rx_buf[0]==':' && rx_fill==3) + { + input = (decode_hex(rx_buf[1])<<4) | decode_hex(rx_buf[2]); + latch |= input; + rx_fill = 0; + } + } +} + +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; +}