From af6a469f761ceec44e94bea5fe8e5345fd368966 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Fri, 30 Apr 2010 20:47:18 +0000 Subject: [PATCH] Add wireless s88 firmware and schematic --- firmware/s88w-r.c | 120 +++ firmware/s88w-t.c | 111 ++ firmware/s88w-t.svg | 2362 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 2593 insertions(+) create mode 100644 firmware/s88w-r.c create mode 100644 firmware/s88w-t.c create mode 100644 firmware/s88w-t.svg 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; +} diff --git a/firmware/s88w-t.c b/firmware/s88w-t.c new file mode 100644 index 0000000..e88a1f5 --- /dev/null +++ b/firmware/s88w-t.c @@ -0,0 +1,111 @@ +/* $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 transmitter module + +ATMega pinout: +D0 - serial RX +D1 - serial TX +D2 - input 1 +D3 - input 2 +D4 - input 3 +D5 - input 4 +D6 - input 5 +D7 - input 6 +B0 - input 7 +B1 - input 8 + +Inputs are pulled high by internal pull-up resistors. Connect to GND to +activate. +*/ + +#include +#include + +#define BIT(n) (1<<(n)) + +void send_state(void); +void write_serial(uint8_t); +uint8_t hexdigit(uint8_t); + +volatile uint8_t state = 0; + +int main() +{ + DDRD = 0x02; // 00000010 + PORTD = 0xFC; // 11111100 + DDRB = 0x20; // 00100000 + PORTB = 0x3F; // 00111111 + + // 9600 baud, 8N1 + UBRR0H = 0; + UBRR0L = 103; + UCSR0C = BIT(UCSZ00) | BIT(UCSZ01); + UCSR0B = BIT(RXEN0) | BIT(TXEN0); + + // 0.5 Hz (CK/1024, TOP=31250) + TCCR1A = 0; + TCCR1B = BIT(WGM12) | BIT(CS12) | BIT(CS10); + OCR1AH = 122; + OCR1AL = 18; + TIMSK1 = BIT(OCIE1A); + + sei(); + + while(1) + { + uint8_t i; + uint8_t input = 0; + uint8_t valid = 0xFF; + + for(i=0; i<100; ++i) + { + uint8_t pins; + + pins = ~((PIND>>2) | (PINB<<6)); + if(i==0) + input = pins; + valid &= ~(pins^input); + } + + input &= valid; + input |= state&~valid; + + if(input!=state) + { + state = input; + send_state(); + } + } + + return 0; +} + +ISR(TIMER1_COMPA_vect) +{ + send_state(); +} + +void send_state(void) +{ + write_serial(':'); + write_serial(hexdigit(state>>4)); + write_serial(hexdigit(state&0xF)); +} + +void write_serial(uint8_t c) +{ + while(!(UCSR0A&(1< + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + J1 + + + + + + + + + + + + + 3.3kΩ + + + + + + + + + + + + + + + + + + + + + + + + + + LM2574 + VIN + GND + OFF + + + + + + VOUT + FB + 5 + 4 + 1 + 7 + + + SIG GND + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + FR206 + LTV847 + + Arduino Mini + + XBee + IO2 (PD2) + IO3 (PD3) + IO4 (PD4) + IO5 (PD5) + IO6 (PD6) + IO7 (PD7) + IO8 (PB0) + IO9 (PB1) + TX (PD0) + RX (PD1) + + + + + + + + + Vcc + GND + Vcc + DOUT + DIN + GND + AD5 + + EZ1085 + + 1 + 7 + 5 + 6 + 8 + 9 + 10 + 11 + 12 + 2 + 21 + 23 + + 1 + 2 + 7 + 5 + 6 + 8 + 9 + 10 + 11 + 12 + 3 + 4 + 13 + 14 + 15 + 16 + 1 + 2 + 7 + 5 + 6 + 8 + 9 + 10 + 11 + 12 + 3 + 4 + 13 + 14 + 15 + 16 + + 680µH + + + + + + + + + + + + 22µF + + + + + + + + 220µF + + + + + + + + + + + + 1.8kΩ + VIN + VOUT + GND + + 1.8kΩ + + 3.3kΩ + + + + + + + + 3 + 2 + 15 + 1 + 10 + + + + 100Ω + + + + + + + + + 1kΩ + + + + + + + + + + 3 + 2 + 1 + 2 + 3 + 1N5819 + + -- 2.43.0