Initial commit for stepper controller
[radiotelescope.git] / stepper_controller / arduino / stepper / serial_io.c
1 //
2 // Product: Serial library for QPnano and Arduino
3 // Version: 0.1
4 // Date:    25 November 2010
5 //
6 //                      +-----------------------+
7 //                      |   d e c i s i o n s   |
8 //                      +-----------------------+
9 //                      | a n d   d e s i g n s |
10 //                      +-----------------------+
11 //
12 // Copyright (C) 2010 Decisions and Designs Pty Ltd. All rights reserved.
13 //
14 // This software may be distributed and modified under the terms of the GNU
15 // General Public License version 2 (GPL) as published by the Free Software
16 // Foundation and appearing in the file GPL.TXT included in the packaging of
17 // this file. Please note that GPL Section 2[b] requires that all works based
18 // on this software must also be made publicly available under the terms of
19 // the GPL ("Copyleft").
20 //
21 // Contact information:
22 // Decisions and Designs Web site: http://www.decisions-and-designs.com.au
23 // e-mail:                         [email protected]
24 //
25
26 // Serial hardware IO driver.
27
28 #include "signals.h"
29 #include "serial_io.h"
30
31 #ifdef abs
32 #undef abs
33 #endif
34 #define abs(x) ((x)>0?(x):-(x))
35 #ifndef cbi
36 #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
37 #endif
38 #ifndef sbi
39 #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
40 #endif
41
42 QActive *serial_rx;
43 QActive *serial_tx;
44 #if defined(__AVR_ATmega1280__)
45 QActive *serial1_rx;
46 QActive *serial1_tx;
47 QActive *serial2_rx;
48 QActive *serial2_tx;
49 QActive *serial3_rx;
50 QActive *serial3_tx;
51 #endif /* __AVR_ATmega1280__ */
52
53 /* Adapted baud rate initialization code from function:
54  *           void HardwareSerial::begin(long baud) 
55  * in file: HardwareSerial.cpp - Hardware serial library for Wiring
56  *          Copyright (c) 2006 Nicholas Zambetti.  All right reserved.
57  *          Modified 23 November 2006 by David A. Mellis 
58  */
59 uint16_t baudSetting(uint32_t baud, uint8_t *use_u2x)
60 {
61     // Calculate optimum baud clock rate and source
62     // U2X mode is needed for baud rates higher than (CPU Hz / 16)
63     if (baud > F_CPU / 16) {
64         *use_u2x = 1;
65     } else {
66         // figure out if U2X mode would allow for a better connection
67         // calculate the percent difference between the baud-rate specified and
68         // the real baud rate for both U2X and non-U2X mode (0-255 error percent)
69         uint8_t nonu2x_baud_error = abs((int)(255-((F_CPU/(16*(((F_CPU/8/baud-1)/2)+1))*255)/baud)));
70         uint8_t u2x_baud_error = abs((int)(255-((F_CPU/(8*(((F_CPU/4/baud-1)/2)+1))*255)/baud)));
71
72         // prefer non-U2X mode because it handles clock skew better
73         *use_u2x = (nonu2x_baud_error > u2x_baud_error);
74     }
75
76     if (*use_u2x) {
77         return (F_CPU / 4 / baud - 1) / 2;
78     } else {
79         return (F_CPU / 8 / baud - 1) / 2;
80     }
81 }   
82
83 /* Initialise hardware and attach the receiver and/or transmitter to a HSM.
84    If rx or tx are NULL then an assignment will not be made for that part.
85    This allows two different HSMs to use the tx and rx part but the baud
86    rate will be set by the last caller */
87 void initSerial(uint32_t baud, QActive *rx, QActive *tx)
88 {
89     uint16_t baud_count;
90     uint8_t use_u2x;
91
92     if (!rx && !tx) return;
93     /* Set the baud rate */    
94     baud_count = baudSetting(baud, &use_u2x);
95     #if defined(__AVR_ATmega8__)
96     if (use_u2x) {
97         UCSRA  = 1 << U2X;
98     } else {
99         UCSRA  = 0;
100     }
101     UBRRH  = baud_count >> 8;
102     UBRRL  = baud_count;
103     #else
104     if (use_u2x) {
105         UCSR0A  = 1 << U2X0;
106     } else {
107         UCSR0A  = 0;
108     }
109     UBRR0H = baud_count >> 8;
110     UBRR0L = baud_count;
111     #endif
112     if (rx) {
113         #if defined(__AVR_ATmega8__)
114         cbi(UCSRA, FE);
115         cbi(UCSRA, DOR);
116         cbi(UCSRA, UPE);
117         sbi(UCSRB, RXEN);
118         sbi(UCSRB, RXCIE);
119         #else
120         cbi(UCSR0A, FE0);
121         cbi(UCSR0A, DOR0);
122         cbi(UCSR0A, UPE0);
123         sbi(UCSR0B, RXEN0);
124         sbi(UCSR0B, RXCIE0);
125         #endif
126         serial_rx = rx;
127     }
128     if (tx) {
129         #if defined(__AVR_ATmega8__)
130         sbi(UCSRB, TXEN);
131         #else
132         sbi(UCSR0B, TXEN0);
133         #endif
134         serial_tx = tx;
135     }
136 }
137
138 #if defined(__AVR_ATmega1280__)
139 void initSerial1(uint32_t baud, QActive *rx, QActive *tx)
140 {
141     uint16_t baud_count;
142     uint8_t use_u2x;
143
144     if (!rx && !tx) return;
145     /* Set the baud rate */    
146     baud_count = baudSetting(baud, &use_u2x);
147     if (use_u2x) {
148         UCSR1A  = 1 << U2X1;
149     } else {
150         UCSR1A  = 0;
151     }
152     UBRR1H = baud_count >> 8;
153     UBRR1L = baud_count;
154     if (rx) {
155         cbi(UCSR1A, FE1);
156         cbi(UCSR1A, DOR1);
157         cbi(UCSR1A, UPE1);
158         sbi(UCSR1B, RXEN1);
159         sbi(UCSR1B, RXCIE1);
160         serial1_rx = rx;
161     }
162     if (tx) {
163         sbi(UCSR1B, TXEN1);
164         serial1_tx = tx;
165     }
166 }
167
168 void initSerial2(uint32_t baud, QActive *rx, QActive *tx)
169 {
170     uint16_t baud_count;
171     uint8_t use_u2x;
172
173     if (!rx && !tx) return;
174     /* Set the baud rate */    
175     baud_count = baudSetting(baud, &use_u2x);
176     if (use_u2x) {
177         UCSR2A  = 1 << U2X2;
178     } else {
179         UCSR2A  = 0;
180     }
181     UBRR2H = baud_count >> 8;
182     UBRR2L = baud_count;
183     if (rx) {
184         cbi(UCSR2A, FE2);
185         cbi(UCSR2A, DOR2);
186         cbi(UCSR2A, UPE2);
187         sbi(UCSR2B, RXEN2);
188         sbi(UCSR2B, RXCIE2);
189         serial2_rx = rx;
190     }
191     if (tx) {
192         sbi(UCSR2B, TXEN2); 
193         serial2_tx = tx;
194     }
195 }
196
197 void initSerial3(uint32_t baud, QActive *rx, QActive *tx)
198 {
199     uint16_t baud_count;
200     uint8_t use_u2x;
201
202     if (!rx && !tx) return;
203     /* Set the baud rate */    
204     baud_count = baudSetting(baud, &use_u2x);
205     if (use_u2x) {
206         UCSR3A  = 1 << U2X3;
207     } else {
208         UCSR3A  = 0;
209     }
210     UBRR3H = baud_count >> 8;
211     UBRR3L = baud_count;
212     if (rx) {
213         cbi(UCSR3A, FE3);
214         cbi(UCSR3A, DOR3);
215         cbi(UCSR3A, UPE3);
216         sbi(UCSR3B, RXEN3);
217         sbi(UCSR3B, RXCIE3);
218         serial3_rx = rx;
219     }
220     if (tx) {
221         sbi(UCSR3B, TXEN3);
222         serial3_tx = tx;
223     }
224 }
225 #endif /* __AVR_ATmega1280__ */
226
227 uint8_t serialTransmit(uint8_t ch)
228 {\r
229         volatile uint8_t z = 0;\r
230
231     #if defined(__AVR_ATmega8__)
232     if (!(UCSRA & (1 << UDRE)))     // tx register is not empty yet
233         return SERIAL_TRANSMIT_BUSY;
234     UDR = ch;                       // load the char (clears tx empty flag)
235     sbi(UCSRB, UDRIE);              // enable tx empty interrupt
236     #else
237     if (!(UCSR0A & (1 << UDRE0))) {  // as above
238                 z = 1;\r
239         return SERIAL_TRANSMIT_BUSY;
240         }\r
241     UDR0 = ch;
242     sbi(UCSR0B, UDRIE0);
243     #endif
244     return SERIAL_SUCCESS;
245 }
246
247 #if defined(__AVR_ATmega1280__)
248 uint8_t serial1Transmit(uint8_t ch)
249 {
250     if (!(UCSR1A & (1 << UDRE1))) {  // as above
251         return SERIAL_TRANSMIT_BUSY;\r
252         }
253     UDR1 = ch;
254     sbi(UCSR1B, UDRIE1);
255     return SERIAL_SUCCESS;
256 }
257
258 uint8_t serial2Transmit(uint8_t ch)
259 {
260     if (!(UCSR2A & (1 << UDRE2))) {  // as above
261         return SERIAL_TRANSMIT_BUSY;\r
262         }
263     UDR2 = ch;
264     sbi(UCSR2B, UDRIE2);
265     return SERIAL_SUCCESS;
266 }
267
268 uint8_t serial3Transmit(uint8_t ch)
269 {
270     if (!(UCSR3A & (1 << UDRE3)))   // as above
271         return SERIAL_TRANSMIT_BUSY;
272     UDR3 = ch;
273     sbi(UCSR3B, UDRIE3);
274     return SERIAL_SUCCESS;
275 }
276 #endif /* __AVR_ATmega1280__ */
277
278 void serialTransmitComplete(void)
279 {
280     #if defined(__AVR_ATmega8__)
281     sbi(UCSRB, TXCIE);              // enable tx complete interrupt
282     #else
283     sbi(UCSR0B, TXCIE0);            // enable tx complete interrupt
284     #endif
285 }
286
287 #if defined(__AVR_ATmega1280__)
288 void serial1TransmitComplete(void)
289 {
290     sbi(UCSR1B, TXCIE1);            // enable tx complete interrupt
291 }
292
293 void serial2TransmitComplete(void)
294 {
295     sbi(UCSR2B, TXCIE2);            // enable tx complete interrupt
296 }
297
298 void serial3TransmitComplete(void)
299 {
300     sbi(UCSR3B, TXCIE3);            // enable tx complete interrupt
301 }
302 #endif /* __AVR_ATmega1280__ */
303
304 #if defined(__AVR_ATmega8__)
305 // Serial character received
306 ISR(SIG_UART_RECV)
307 {
308     SerialParam pa;
309     pa.msg.port   = USART;
310     pa.msg.status = 0;
311
312     // spurious interrupt (no handler) need to discard the character(!)
313     if (!serial_rx) {
314         pa.msg.ch = UDR0;
315         return;
316     }  
317     // sense and signal receiver overrun, parity, or frame error
318     if (UCSRA & (1 << DOR)) {
319         pa.msg.status |= 1 << SERIAL_STATUS_OVERRUN;
320     }
321     if (UCSRA & (1 << FE)) {
322         pa.msg.status |= 1 << SERIAL_STATUS_FRAME;
323     
324     if (UCSRA & (1 << UPE)) {
325         pa.msg.status |= 1 << SERIAL_STATUS_PARITY; 
326     }
327     // fetch char into message (also clears any error flags)
328     pa.msg.ch = UDR;
329     if (pa.msg.status) {
330         QActive_postISR(serial_rx, SERIAL_RX_ERROR_SIG, pa.param);
331     } else {
332         QActive_postISR(serial_rx, SERIAL_RX_DATA_SIG, pa.param);
333     }
334     return;
335 }
336
337 // Transmitter data register empty
338 ISR(SIG_UART_DATA)
339 {
340     // one shot interrupt, re-armed by serialTransmit()
341     cbi(UCSRB, UDRIE);
342     // sanity check handler is defined
343     if (serial_tx) {
344         QActive_postISR(serial_tx, SERIAL_TX_EMPTY_SIG, (QParam)0);
345         }
346         return;
347 }
348
349 // Transmission complete
350 ISR(SIG_UART_TRANS)
351 {
352     // one shot interrupt, re-armed by serialTransmitComplete()
353     cbi(UCSRB, TXC);
354     // sanity check handler is defined
355     if (serial_tx) {
356         QActive_postISR(serial_tx, SERIAL_TX_COMPLETE_SIG, (QParam)0);
357     }
358         return;
359 }
360 #endif
361
362 #if defined(__AVR_ATmega1280__) || !defined(__AVR_ATmega8__)
363
364 // Serial character received
365 #if defined(__AVR_ATmega1280__)
366 ISR(USART0_RX_vect)
367 #else // ATmega328
368 ISR(USART_RX_vect)
369 #endif
370 {
371     SerialParam pa;
372     pa.msg.port   = USART; 
373     pa.msg.status = 0;
374
375     // spurious interrupt (no handler) need to discard the character(!)
376     if (!serial_rx) {
377         pa.msg.ch = UDR0;
378         return;
379     }  
380     // sense and signal receiver overrun, parity, or frame error
381     if (UCSR0A & (1 << DOR0)) {
382         pa.msg.status |= 1 << SERIAL_STATUS_OVERRUN;
383     }
384     if (UCSR0A & (1 << FE0)) {
385         pa.msg.status |= 1 << SERIAL_STATUS_FRAME;
386     }
387     if (UCSR0A & (1 << UPE0)) {
388         pa.msg.status |= 1 << SERIAL_STATUS_PARITY; 
389     }
390     // fetch char into message (also clears any error flags)
391     pa.msg.ch = UDR0;
392     if (pa.msg.status) {
393         QActive_postISR(serial_rx, SERIAL_RX_ERROR_SIG, pa.param);
394     } else {
395         QActive_postISR(serial_rx, SERIAL_RX_DATA_SIG, pa.param);
396     }
397     return;
398 }
399
400 // Transmitter data register empty
401 #if defined(__AVR_ATmega1280__)
402 ISR(USART0_UDRE_vect)
403 #else // ATmega328
404 ISR(USART_UDRE_vect)
405 #endif
406 {
407     // one shot interrupt, re-armed by serialTransmit()
408     cbi(UCSR0B, UDRIE0);
409     // sanity check handler is defined
410     if (serial_tx) {
411         QActive_postISR(serial_tx, SERIAL_TX_EMPTY_SIG, (QParam)0);
412     }
413         return;
414 }
415
416 #if defined(__AVR_ATmega1280__)
417 ISR(USART0_TX_vect)
418 #else // ATmega328
419 ISR(USART_TX_vect)
420 #endif
421 {
422     // one shot interrupt, re-armed by serialTransmitComplete()
423     cbi(UCSR0B, TXC0);
424     // sanity check handler is defined
425     if (serial_tx) {
426         QActive_postISR(serial_tx, SERIAL_TX_COMPLETE_SIG, (QParam)0);
427     }
428         return;
429 }
430 #endif // defined(__AVR_ATmega1280__) | !defined(__AVR_ATmega8__)    
431
432 #if defined(__AVR_ATmega1280__)
433 ISR(USART1_RX_vect)
434 {
435     SerialParam pa;
436     pa.msg.port   = USART1; 
437     pa.msg.status = 0;
438
439     // spurious interrupt (no handler) need to discard the character(!)
440     if (!serial1_rx) {
441         pa.msg.ch = UDR0;
442         return;
443     }  
444     // sense and signal receiver overrun, parity, or frame error
445     if (UCSR1A & (1 << DOR1)) {
446         pa.msg.status |= 1 << SERIAL_STATUS_OVERRUN;
447     }
448     if (UCSR1A & (1 << FE1)) {
449         pa.msg.status |= 1 << SERIAL_STATUS_FRAME;
450     }
451     if (UCSR1A & (1 << UPE1)) {
452         pa.msg.status |= 1 << SERIAL_STATUS_PARITY; 
453     }
454     // fetch char into message (also clears any error flags)
455     pa.msg.ch = UDR1;
456     if (pa.msg.status) {
457         QActive_postISR(serial1_rx, SERIAL1_RX_ERROR_SIG, pa.param);
458     } else {
459         QActive_postISR(serial1_rx, SERIAL1_RX_DATA_SIG, pa.param);
460     }
461     return;
462 }
463
464 ISR(USART1_UDRE_vect)
465 {
466     // one shot interrupt, re-armed by serialTransmit()
467     cbi(UCSR1B, UDRIE1);
468     // sanity check handler is defined
469     if (serial1_tx) {
470         QActive_postISR(serial1_tx, SERIAL1_TX_EMPTY_SIG, (QParam)0);
471     }
472         return;
473 }
474
475 ISR(USART1_TX_vect)
476 {
477     // one shot interrupt, re-armed by serialTransmitComplete()
478     cbi(UCSR1B, TXC1);
479     // sanity check handler is defined
480     if (serial1_tx) {
481         QActive_postISR(serial1_tx, SERIAL1_TX_COMPLETE_SIG, (QParam)0);
482     }
483         return;
484 }
485
486 ISR(USART2_RX_vect)
487 {
488     SerialParam pa;
489     pa.msg.port   = USART2; 
490     pa.msg.status = 0;
491
492     // spurious interrupt (no handler) need to discard the character(!)
493     if (!serial2_rx) {
494         pa.msg.ch = UDR2;
495         return;
496     }  
497     // sense and signal receiver overrun, parity, or frame error
498     if (UCSR2A & (1 << DOR2)) {
499         pa.msg.status |= 1 << SERIAL_STATUS_OVERRUN;
500     }
501     if (UCSR2A & (1 << FE2)) {
502         pa.msg.status |= 1 << SERIAL_STATUS_FRAME;
503     }
504     if (UCSR2A & (1 << UPE2)) {
505         pa.msg.status |= 1 << SERIAL_STATUS_PARITY; 
506     }
507     // fetch char into message (also clears any error flags)
508     pa.msg.ch = UDR2;
509     if (pa.msg.status) {
510         QActive_postISR(serial2_rx, SERIAL2_RX_ERROR_SIG, pa.param);
511     } else {
512         QActive_postISR(serial2_rx, SERIAL2_RX_DATA_SIG, pa.param);
513     }
514     return;
515 }
516
517 ISR(USART2_UDRE_vect)
518 {
519     // one shot interrupt, re-armed by serialTransmit()
520     cbi(UCSR2B, UDRIE2);
521     // sanity check handler is defined
522     if (serial2_tx) {
523         QActive_postISR(serial2_tx, SERIAL2_TX_EMPTY_SIG, (QParam)0);
524     }
525         return;
526 }
527
528 ISR(USART2_TX_vect)
529 {
530     // one shot interrupt, re-armed by serialTransmitComplete()
531     cbi(UCSR2B, TXC2);
532     // sanity check handler is defined
533     if (serial2_tx) { 
534             QActive_postISR(serial2_tx, SERIAL2_TX_COMPLETE_SIG, (QParam)0);
535     }
536         return;
537 }
538
539 ISR(USART3_RX_vect)
540 {
541     SerialParam pa;
542     pa.msg.port   = USART3; 
543     pa.msg.status = 0;
544
545     // spurious interrupt (no handler) need to discard the character(!)
546     if (!serial3_rx) {
547         pa.msg.ch = UDR3;
548         return;
549     }  
550     // sense and signal receiver overrun, parity, or frame error
551     if (UCSR3A & (1 << DOR3)) {
552         pa.msg.status |= 1 << SERIAL_STATUS_OVERRUN;
553     }
554     if (UCSR3A & (1 << FE3)) {
555         pa.msg.status |= 1 << SERIAL_STATUS_FRAME;
556     }
557     if (UCSR3A & (1 << UPE3)) {
558         pa.msg.status |= 1 << SERIAL_STATUS_PARITY; 
559     }
560     // fetch char into message (also clears any error flags)
561     pa.msg.ch = UDR3;
562     if (pa.msg.status) {
563         QActive_postISR(serial3_rx, SERIAL3_RX_ERROR_SIG, pa.param);
564     } else {
565         QActive_postISR(serial3_rx, SERIAL3_RX_DATA_SIG, pa.param);
566     }
567     return;
568 }
569
570 ISR(USART3_UDRE_vect)
571 {
572     // one shot interrupt, re-armed by serialTransmit()
573     cbi(UCSR3B, UDRIE3);
574     // sanity check handler is defined
575     if (serial3_tx) {
576         QActive_postISR(serial3_tx, SERIAL3_TX_EMPTY_SIG, (QParam)0);
577         }
578     return;
579 }
580
581 ISR(USART3_TX_vect)
582 {
583     // one shot interrupt, re-armed by serialTransmitComplete()
584     cbi(UCSR3B, TXC3);
585     // sanity check handler is defined
586     if (serial3_tx) {
587         QActive_postISR(serial3_tx, SERIAL3_TX_COMPLETE_SIG, (QParam)0);
588         }
589     return;
590 }
591 #endif // defined(__AVR_ATmega1280__)
592

UCC git Repository :: git.ucc.asn.au