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 receiver module
27 #include <avr/interrupt.h>
31 #define DATA_OUT PORTD2
36 #define BIT(n) (1<<(n))
38 void receive(uint8_t);
39 uint8_t hexdigit(uint8_t);
40 uint8_t decode_hex(uint8_t);
42 volatile uint8_t rx_buf[7];
43 volatile uint8_t rx_fill = 0xFF;
44 volatile uint8_t input[128] = { 0 };
45 volatile uint8_t latch[128] = { 0 };
50 uint8_t clock_high = 0;
55 DDRD = 0x06; // 00000110
56 PIND = 0xC0; // 11000000
57 DDRB = 0x20; // 00100000
58 PINB = 0x1F; // 00011111
61 serial_set_callback(receive);
96 PORTD |= BIT(DATA_OUT);
98 PORTD &= ~BIT(DATA_OUT);
106 if(d_pins&BIT(RESET))
115 void receive(uint8_t c)
130 offset = (decode_hex(rx_buf[0])<<8) | (decode_hex(rx_buf[1])<<4) | decode_hex(rx_buf[2]);
131 nibbles = (offset&3);
133 if(rx_fill>3+nibbles)
135 for(i=0; i<=nibbles; ++i)
137 uint16_t j = offset+nibbles-i;
138 uint8_t shift = 4*(j&1);
139 uint8_t bits = decode_hex(rx_buf[3+i]);
140 input[j/2] = (input[j/2]&~(0xF<<shift)) | (bits<<shift);
141 latch[j/2] = input[j/2];
148 lcd_write(hexdigit(input[i]>>4));
149 lcd_write(hexdigit(input[i]));
156 if(rx_fill<sizeof(rx_buf))
157 rx_buf[rx_fill++] = c;
162 lcd_gotoxy(log_pos%20, 1+log_pos/20);
167 lcd_gotoxy(log_pos%20, 1+log_pos/20);
171 uint8_t hexdigit(uint8_t n)
180 uint8_t decode_hex(uint8_t c)
184 else if(c>='A' && c<='F')