3 This file is part of R²C²
4 Copyright © 2010 Mikkosoft Productions, Mikko Rasa
5 Distributed under the GPL
7 Firmware for wireless S88 transmitter module
25 Inputs are pulled high by internal pull-up resistors. Connect to GND to
28 The module can be configured by sending a string of form ":Shhh." over the
29 serial port, where hhh is a hex number. Lower two bits indicate the number of
30 inputs (00=4, 01=8, 10=12, 11=16) and upper ten bits indicate offset of lowest
31 input in multiples of 4 bits. At the moment there are no provisions for
32 having 16 physical inputs.
34 Example: ":S016." would configure the module to have 12 inputs at offset 20.
38 #include <avr/interrupt.h>
43 #define BIT(n) (1<<(n))
45 void receive(uint8_t);
46 void send_state(void);
47 uint8_t hexdigit(uint8_t);
48 uint8_t decode_hex(uint8_t);
51 uint8_t rx_fill = 0xFF;
52 volatile uint8_t nibbles = 2;
53 volatile uint8_t offset = 0;
54 volatile uint16_t state = 0;
55 volatile uint8_t time_since_send = 0;
59 if(eeprom_read(0)==0xA5)
61 offset = eeprom_read(1)<<8;
62 offset |= eeprom_read(2);
63 nibbles = eeprom_read(3);
66 DDRD = 0x02; // 00000010
67 PORTD = 0xFC; // 11111100
68 DDRB = 0x00; // 00000000
69 PORTB = 0x3F; // 00111111
72 timer_start_hz(1, 100, 1);
80 uint16_t valid = 0xFFF;
86 pins |= ~((PIND>>2) | ((PINB&0x3F)<<6));
91 valid &= ~(pins^input);
95 input |= state&~valid;
96 input &= (1<<(nibbles*4))-1;
98 if(input!=state && time_since_send>5)
108 void receive(uint8_t c)
117 if(rx_buf[0]=='S' && rx_fill==4)
119 offset = (decode_hex(rx_buf[1])<<8) | (decode_hex(rx_buf[2])<<4) | decode_hex(rx_buf[3]);
120 nibbles = (offset&3)+1;
123 eeprom_write(0, 0xA5);
124 eeprom_write(1, offset>>8);
125 eeprom_write(2, offset);
126 eeprom_write(3, nibbles);
132 if(rx_fill<sizeof(rx_buf))
133 rx_buf[rx_fill++] = c;
139 SERIAL_SET_CALLBACK(receive)
141 void send_state(void)
146 serial_write(hexdigit(offset>>8));
147 serial_write(hexdigit(offset>>4));
148 serial_write(hexdigit(offset|(nibbles-1)));
150 serial_write(hexdigit(state>>(i*4)));
159 if(time_since_send>200)
163 TIMER_SET_CALLBACK(1, timer)
165 uint8_t hexdigit(uint8_t n)
174 uint8_t decode_hex(uint8_t c)
178 else if(c>='A' && c<='F')