3 This file is part of the MSP Märklin suite
4 Copyright © 2010 Mikkosoft Productions, Mikko Rasa
5 Distributed under the GPL
7 Firmware for wireless S88 transmitter module
21 Inputs are pulled high by internal pull-up resistors. Connect to GND to
26 #include <avr/interrupt.h>
31 #define BIT(n) (1<<(n))
33 void receive(uint8_t);
34 void send_state(void);
35 uint8_t hexdigit(uint8_t);
36 uint8_t decode_hex(uint8_t);
39 uint8_t rx_fill = 0xFF;
40 volatile uint8_t nibbles = 2;
41 volatile uint8_t offset = 0;
42 volatile uint16_t state = 0;
46 if(eeprom_read(0)==0xA5)
48 offset = eeprom_read(1)<<8;
49 offset |= eeprom_read(2);
50 nibbles = eeprom_read(3);
53 DDRD = 0x02; // 00000010
54 PORTD = 0xFC; // 11111100
55 DDRB = 0x20; // 00000000
56 PORTB = 0x3F; // 00111111
59 serial_set_callback(receive);
61 timer_set_callback(send_state);
69 uint16_t valid = 0xFFF;
75 pins = ~((PIND>>2) | ((PINB&0x3F)<<6));
78 valid &= ~(pins^input);
82 input |= state&~valid;
83 input &= (1<<(nibbles*4))-1;
95 void receive(uint8_t c)
104 if(rx_buf[0]=='S' && rx_fill==4)
106 offset = (decode_hex(rx_buf[1])<<8) | (decode_hex(rx_buf[2])<<4) | decode_hex(rx_buf[3]);
107 nibbles = (offset&3)+1;
110 eeprom_write(0, 0xA5);
111 eeprom_write(1, offset>>8);
112 eeprom_write(2, offset);
113 eeprom_write(3, nibbles);
119 if(rx_fill<sizeof(rx_buf))
120 rx_buf[rx_fill++] = c;
126 void send_state(void)
130 serial_write(hexdigit(offset>>8));
131 serial_write(hexdigit(offset>>4));
132 serial_write(hexdigit(offset|(nibbles-1)));
134 serial_write(hexdigit(state>>(i*4)));
138 uint8_t hexdigit(uint8_t n)
147 uint8_t decode_hex(uint8_t c)
151 else if(c>='A' && c<='F')