]> git.tdb.fi Git - model-railway-devices.git/blob - firmware/s88w-r.c
dac0cfcaf85948eeebd70f2eaebae030d9fe3ac6
[model-railway-devices.git] / firmware / s88w-r.c
1 /* $Id$
2
3 This file is part of the MSP Märklin suite
4 Copyright © 2010  Mikkosoft Productions, Mikko Rasa
5 Distributed under the GPL
6
7 Firmware for wireless S88 receiver module
8
9 S88 pinout:
10 1 - DATA
11 2 - GND
12 3 - CLOCK
13 4 - LOAD
14 5 - RESET
15 6 - POWER
16
17 ATMega pinout:
18 D0 - serial RX
19 D1 - serial TX
20 D2 - S88 DATA
21 D3 - S88 CLOCK
22 D4 - S88 LOAD
23 D5 - S88 RESET
24 */
25
26 #include <avr/io.h>
27 #include <avr/interrupt.h>
28
29 #define DATA_OUT PORTD2
30 #define CLOCK    PIND3
31 #define LOAD     PIND4
32 #define RESET    PIND5
33
34 #define BIT(n)   (1<<(n))
35
36 uint8_t decode_hex(uint8_t);
37
38 volatile uint8_t rx_buf[3];
39 volatile uint8_t rx_fill = 0;
40 volatile uint8_t input = 0;
41 volatile uint8_t latch = 0;
42
43 int main()
44 {
45         uint8_t clock_high = 0;
46         uint8_t bits = 0;
47
48         DDRD = 0x06;  // 00000110
49         PIND = 0xC0;  // 11000000
50         DDRB = 0x20;  // 00100000
51         PINB = 0x1F;  // 00011111
52
53         // 9600 baud, 8N1
54         UBRR0H = 0;
55         UBRR0L = 103;
56         UCSR0C = BIT(UCSZ00) | BIT(UCSZ01);
57         UCSR0B = BIT(RXEN0) | BIT(TXEN0) | BIT(RXCIE0);
58
59         sei();
60
61         while(1)
62         {
63                 uint8_t d_pins;
64
65                 d_pins = PIND;
66
67                 if(d_pins&BIT(CLOCK))
68                 {
69                         if(!clock_high)
70                         {
71                                 if(d_pins&BIT(LOAD))
72                                         bits = latch;
73                                 else
74                                         bits >>= 1;
75
76                                 if(bits&1)
77                                         PORTD |= BIT(DATA_OUT);
78                                 else
79                                         PORTD &= ~BIT(DATA_OUT);
80
81                                 clock_high = 1;
82                         }
83                 }
84                 else if(clock_high)
85                         clock_high = 0;
86
87                 if(d_pins&BIT(RESET))
88                         latch = input;
89         }
90 }
91
92 ISR(USART_RX_vect)
93 {
94         uint8_t c = UDR0;
95         if(rx_fill==0)
96         {
97                 if(c==':')
98                         rx_buf[rx_fill++] = c;
99         }
100         else
101         {
102                 rx_buf[rx_fill++] = c;
103                 if(rx_buf[0]==':' && rx_fill==3)
104                 {
105                         input = (decode_hex(rx_buf[1])<<4) | decode_hex(rx_buf[2]);
106                         latch |= input;
107                         rx_fill = 0;
108                 }
109         }
110 }
111
112 uint8_t decode_hex(uint8_t c)
113 {
114         if(c>='0' && c<='9')
115                 return c-'0';
116         else if(c>='A' && c<='F')
117                 return 0xA+(c-'A');
118         else
119                 return 0;
120 }