aboutsummaryrefslogtreecommitdiff
path: root/protocol/serial_soft.c
diff options
context:
space:
mode:
authortmk <nobody@nowhere>2013-02-25 08:40:15 +0900
committertmk <nobody@nowhere>2013-02-25 14:14:46 +0900
commit308abf598d4cc19be3c5b137bbd13d18510a083a (patch)
tree8cc5d21272b79d4011734ee074479c2bb99e7fc8 /protocol/serial_soft.c
parentea1ede83c36272ccaeb5e4d80efc3885edbb9209 (diff)
downloadqmk_firmware-308abf598d4cc19be3c5b137bbd13d18510a083a.tar.gz
qmk_firmware-308abf598d4cc19be3c5b137bbd13d18510a083a.zip
Fix software serial configure
Diffstat (limited to 'protocol/serial_soft.c')
-rw-r--r--protocol/serial_soft.c98
1 files changed, 53 insertions, 45 deletions
diff --git a/protocol/serial_soft.c b/protocol/serial_soft.c
index c906c6647..e8870bcd7 100644
--- a/protocol/serial_soft.c
+++ b/protocol/serial_soft.c
@@ -43,12 +43,32 @@ POSSIBILITY OF SUCH DAMAGE.
43 43
44/* 44/*
45 * Stupid Inefficient Busy-wait Software Serial 45 * Stupid Inefficient Busy-wait Software Serial
46 * is still useful for negative logic signal like Sun protocol not supported by hardware USART. 46 * which is still useful for negative logic signal like Sun protocol
47 * if it is not supported by hardware UART.
48 *
49 * TODO: delay is not accurate enough. Instruction cycle should be counted and inline assemby is needed.
47 */ 50 */
48 51
49#define WAIT_US (1000000L/SERIAL_BAUD) 52#define WAIT_US (1000000L/SERIAL_SOFT_BAUD)
53
54#ifdef SERIAL_SOFT_LOGIC_NEGATIVE
55 #define SERIAL_SOFT_RXD_IN() !(SERIAL_SOFT_RXD_READ())
56 #define SERIAL_SOFT_TXD_ON() SERIAL_SOFT_TXD_LO()
57 #define SERIAL_SOFT_TXD_OFF() SERIAL_SOFT_TXD_HI()
58#else
59 #define SERIAL_SOFT_RXD_IN() !!(SERIAL_SOFT_RXD_READ())
60 #define SERIAL_SOFT_TXD_ON() SERIAL_SOFT_TXD_HI()
61 #define SERIAL_SOFT_TXD_OFF() SERIAL_SOFT_TXD_LO()
62#endif
63
64#ifdef SERIAL_SOFT_PARITY_EVEN
65 #define SERIAL_SOFT_PARITY_VAL 0
66#elif defined(SERIAL_SOFT_PARITY_ODD)
67 #define SERIAL_SOFT_PARITY_VAL 1
68#endif
50 69
51/* debug for signal timing, see debug pin with oscilloscope */ 70/* debug for signal timing, see debug pin with oscilloscope */
71#define SERIAL_SOFT_DEBUG
52#ifdef SERIAL_SOFT_DEBUG 72#ifdef SERIAL_SOFT_DEBUG
53 #define SERIAL_SOFT_DEBUG_INIT() (DDRD |= 1<<7) 73 #define SERIAL_SOFT_DEBUG_INIT() (DDRD |= 1<<7)
54 #define SERIAL_SOFT_DEBUG_TGL() (PORTD ^= 1<<7) 74 #define SERIAL_SOFT_DEBUG_TGL() (PORTD ^= 1<<7)
@@ -62,8 +82,8 @@ void serial_init(void)
62{ 82{
63 SERIAL_SOFT_DEBUG_INIT(); 83 SERIAL_SOFT_DEBUG_INIT();
64 84
65 SERIAL_RXD_INIT(); 85 SERIAL_SOFT_RXD_INIT();
66 SERIAL_TXD_INIT(); 86 SERIAL_SOFT_TXD_INIT();
67} 87}
68 88
69/* RX ring buffer */ 89/* RX ring buffer */
@@ -101,109 +121,97 @@ void serial_send(uint8_t data)
101{ 121{
102 /* signal state: IDLE: ON, START: OFF, STOP: ON, DATA0: OFF, DATA1: ON */ 122 /* signal state: IDLE: ON, START: OFF, STOP: ON, DATA0: OFF, DATA1: ON */
103 123
104#ifdef SERIAL_BIT_ORDER_MSB 124#ifdef SERIAL_SOFT_BIT_ORDER_MSB
105 uint8_t mask = 0x80; 125 uint8_t mask = 0x80;
106#else 126#else
107 uint8_t mask = 0x01; 127 uint8_t mask = 0x01;
108#endif 128#endif
109 129
110#ifdef SERIAL_PARITY_ODD
111 uint8_t parity = 1;
112#elif defined(SERIAL_PARITY_EVEN)
113 uint8_t parity = 0; 130 uint8_t parity = 0;
114#endif
115 131
116 /* start bit */ 132 /* start bit */
117 SERIAL_TXD_OFF(); 133 SERIAL_SOFT_TXD_OFF();
118 _delay_us(WAIT_US-2); 134 _delay_us(WAIT_US);
119 135
120 while (mask) { 136 while (mask) {
121 if (data&mask) { 137 if (data&mask) {
122 SERIAL_TXD_ON(); 138 SERIAL_SOFT_TXD_ON();
123#if defined(SERIAL_PARITY_EVEN) || defined(SERIAL_PARITY_ODD)
124 parity ^= 1; 139 parity ^= 1;
125#endif
126 } else { 140 } else {
127 SERIAL_TXD_OFF(); 141 SERIAL_SOFT_TXD_OFF();
128 } 142 }
129 _delay_us(WAIT_US-2); 143 _delay_us(WAIT_US);
130 144
131#ifdef SERIAL_BIT_ORDER_MSB 145#ifdef SERIAL_SOFT_BIT_ORDER_MSB
132 mask >>= 1; 146 mask >>= 1;
133#else 147#else
134 mask <<= 1; 148 mask <<= 1;
135#endif 149#endif
136 } 150 }
137 151
138#if defined(SERIAL_PARITY_EVEN) || defined(SERIAL_PARITY_ODD) 152#if defined(SERIAL_SOFT_PARITY_EVEN) || defined(SERIAL_SOFT_PARITY_ODD)
139 /* to center of parity bit */ 153 /* to center of parity bit */
140 if (parity) { 154 if (parity != SERIAL_SOFT_PARITY_VAL) {
141 SERIAL_TXD_ON(); 155 SERIAL_SOFT_TXD_ON();
142 } else { 156 } else {
143 SERIAL_TXD_OFF(); 157 SERIAL_SOFT_TXD_OFF();
144 } 158 }
145 _delay_us(WAIT_US-2); 159 _delay_us(WAIT_US);
146#endif 160#endif
147 161
148 /* stop bit */ 162 /* stop bit */
149 SERIAL_TXD_ON(); 163 SERIAL_SOFT_TXD_ON();
150 _delay_us(WAIT_US-2); 164 _delay_us(WAIT_US);
151} 165}
152 166
153/* detect edge of start bit */ 167/* detect edge of start bit */
154ISR(SERIAL_RXD_VECT) 168ISR(SERIAL_SOFT_RXD_VECT)
155{ 169{
156 SERIAL_SOFT_DEBUG_TGL() 170 SERIAL_SOFT_DEBUG_TGL();
157 SERIAL_RXD_INT_ENTER() 171 SERIAL_SOFT_RXD_INT_ENTER()
158 172
159 uint8_t data = 0; 173 uint8_t data = 0;
160 174
161#ifdef SERIAL_BIT_ORDER_MSB 175#ifdef SERIAL_SOFT_BIT_ORDER_MSB
162 uint8_t mask = 0x80; 176 uint8_t mask = 0x80;
163#else 177#else
164 uint8_t mask = 0x01; 178 uint8_t mask = 0x01;
165#endif 179#endif
166 180
167#ifdef SERIAL_PARITY_ODD
168 uint8_t parity = 0; 181 uint8_t parity = 0;
169#elif defined(SERIAL_PARITY_EVEN)
170 uint8_t parity = 1;
171#endif
172 182
173 /* to center of start bit */ 183 /* to center of start bit */
174 _delay_us(WAIT_US/2); 184 _delay_us(WAIT_US/2);
175 SERIAL_SOFT_DEBUG_TGL() 185 SERIAL_SOFT_DEBUG_TGL();
176 do { 186 do {
177 /* to center of next bit */ 187 /* to center of next bit */
178 _delay_us(WAIT_US); 188 _delay_us(WAIT_US);
179 189
180 SERIAL_SOFT_DEBUG_TGL() 190 SERIAL_SOFT_DEBUG_TGL();
181 if (SERIAL_RXD_READ()) { 191 if (SERIAL_SOFT_RXD_IN()) {
182 data |= mask; 192 data |= mask;
183#if defined(SERIAL_PARITY_EVEN) || defined(SERIAL_PARITY_ODD)
184 parity ^= 1; 193 parity ^= 1;
185#endif
186 } 194 }
187#ifdef SERIAL_BIT_ORDER_MSB 195#ifdef SERIAL_SOFT_BIT_ORDER_MSB
188 mask >>= 1; 196 mask >>= 1;
189#else 197#else
190 mask <<= 1; 198 mask <<= 1;
191#endif 199#endif
192 } while (mask); 200 } while (mask);
193 201
194#if defined(SERIAL_PARITY_EVEN) || defined(SERIAL_PARITY_ODD) 202#if defined(SERIAL_SOFT_PARITY_EVEN) || defined(SERIAL_SOFT_PARITY_ODD)
195 /* to center of parity bit */ 203 /* to center of parity bit */
196 _delay_us(WAIT_US); 204 _delay_us(WAIT_US);
197 if (SERIAL_RXD_READ()) { parity ^= 1; } 205 if (SERIAL_SOFT_RXD_IN()) { parity ^= 1; }
198 SERIAL_SOFT_DEBUG_TGL() 206 SERIAL_SOFT_DEBUG_TGL();
199#endif 207#endif
200 208
201 /* to center of stop bit */ 209 /* to center of stop bit */
202 _delay_us(WAIT_US); 210 _delay_us(WAIT_US);
203 211
204 uint8_t next = (rbuf_head + 1) % RBUF_SIZE; 212 uint8_t next = (rbuf_head + 1) % RBUF_SIZE;
205#if defined(SERIAL_PARITY_EVEN) || defined(SERIAL_PARITY_ODD) 213#if defined(SERIAL_SOFT_PARITY_EVEN) || defined(SERIAL_SOFT_PARITY_ODD)
206 if (parity && next != rbuf_tail) { 214 if ((parity == SERIAL_SOFT_PARITY_VAL) && next != rbuf_tail) {
207#else 215#else
208 if (next != rbuf_tail) { 216 if (next != rbuf_tail) {
209#endif 217#endif
@@ -211,6 +219,6 @@ ISR(SERIAL_RXD_VECT)
211 rbuf_head = next; 219 rbuf_head = next;
212 } 220 }
213 221
214 SERIAL_RXD_INT_EXIT(); 222 SERIAL_SOFT_RXD_INT_EXIT();
215 SERIAL_SOFT_DEBUG_TGL() 223 SERIAL_SOFT_DEBUG_TGL();
216} 224}