]> git.tdb.fi Git - model-railway-devices.git/blob - firmware/s88w-t.c
e88a1f509eb6fc24aec4c4a8e05e83bce6a4fd7e
[model-railway-devices.git] / firmware / s88w-t.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 transmitter module
8
9 ATMega pinout:
10 D0 - serial RX
11 D1 - serial TX
12 D2 - input 1
13 D3 - input 2
14 D4 - input 3
15 D5 - input 4
16 D6 - input 5
17 D7 - input 6
18 B0 - input 7
19 B1 - input 8
20
21 Inputs are pulled high by internal pull-up resistors.  Connect to GND to
22 activate.
23 */
24
25 #include <avr/io.h>
26 #include <avr/interrupt.h>
27
28 #define BIT(n) (1<<(n))
29
30 void send_state(void);
31 void write_serial(uint8_t);
32 uint8_t hexdigit(uint8_t);
33
34 volatile uint8_t state = 0;
35
36 int main()
37 {
38         DDRD = 0x02;   // 00000010
39         PORTD = 0xFC;  // 11111100
40         DDRB = 0x20;   // 00100000
41         PORTB = 0x3F;  // 00111111
42
43         // 9600 baud, 8N1
44         UBRR0H = 0;
45         UBRR0L = 103;
46         UCSR0C = BIT(UCSZ00) | BIT(UCSZ01);
47         UCSR0B = BIT(RXEN0) | BIT(TXEN0);
48
49         // 0.5 Hz (CK/1024, TOP=31250)
50         TCCR1A = 0;
51         TCCR1B = BIT(WGM12) | BIT(CS12) | BIT(CS10);
52         OCR1AH = 122;
53         OCR1AL = 18;
54         TIMSK1 = BIT(OCIE1A);
55
56         sei();
57
58         while(1)
59         {
60                 uint8_t i;
61                 uint8_t input = 0;
62                 uint8_t valid = 0xFF;
63
64                 for(i=0; i<100; ++i)
65                 {
66                         uint8_t pins;
67
68                         pins = ~((PIND>>2) | (PINB<<6));
69                         if(i==0)
70                                 input = pins;
71                         valid &= ~(pins^input);
72                 }
73
74                 input &= valid;
75                 input |= state&~valid;
76
77                 if(input!=state)
78                 {
79                         state = input;
80                         send_state();
81                 }
82         }
83
84         return 0;
85 }
86
87 ISR(TIMER1_COMPA_vect)
88 {
89         send_state();
90 }
91
92 void send_state(void)
93 {
94         write_serial(':');
95         write_serial(hexdigit(state>>4));
96         write_serial(hexdigit(state&0xF));
97 }
98
99 void write_serial(uint8_t c)
100 {
101         while(!(UCSR0A&(1<<UDRE0))) ;
102         UDR0 = c;
103 }
104
105 uint8_t hexdigit(uint8_t n)
106 {
107         if(n<10)
108                 return '0'+n;
109         else
110                 return 'A'+(n-0xA);
111 }