Mercurial > ~darius > hgwebdir.cgi > avr-lib
annotate cons.c @ 11:b46f0c742316
Include io headers, not 100% sure it's necessary but is good practise.
author | Daniel O'Connor <darius@dons.net.au> |
---|---|
date | Sat, 01 Jan 2011 19:44:02 +1030 |
parents | 095216e8453d |
children |
rev | line source |
---|---|
0 | 1 /* |
2 * Console code for AVR board | |
3 * | |
4
095216e8453d
Hide register name abstraction in a separate file.
darius@Inchoate
parents:
3
diff
changeset
|
4 * Copyright (c) 2008-2009 |
0 | 5 * Daniel O'Connor <darius@dons.net.au>. All rights reserved. |
6 * | |
7 * Redistribution and use in source and binary forms, with or without | |
8 * modification, are permitted provided that the following conditions | |
9 * are met: | |
10 * 1. Redistributions of source code must retain the above copyright | |
11 * notice, this list of conditions and the following disclaimer. | |
12 * 2. Redistributions in binary form must reproduce the above copyright | |
13 * notice, this list of conditions and the following disclaimer in the | |
14 * documentation and/or other materials provided with the distribution. | |
15 * | |
16 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND | |
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
19 * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE | |
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
26 * SUCH DAMAGE. | |
27 */ | |
28 | |
29 #include <ctype.h> | |
30 #include <stdio.h> | |
31 #include <stdint.h> | |
32 #include <stdlib.h> | |
11
b46f0c742316
Include io headers, not 100% sure it's necessary but is good practise.
Daniel O'Connor <darius@dons.net.au>
parents:
4
diff
changeset
|
33 #include <avr/io.h> |
0 | 34 #include <avr/interrupt.h> |
35 #include <avr/pgmspace.h> | |
36 #include "cons.h" | |
4
095216e8453d
Hide register name abstraction in a separate file.
darius@Inchoate
parents:
3
diff
changeset
|
37 #include "cons-reg.h" |
0 | 38 |
39 #define UART_BAUD_SELECT(baudRate,xtalCpu) ((xtalCpu)/((baudRate)*16l)-1) | |
40 | |
41 /* Receive buffer storage */ | |
42 consbuf_t cmd; | |
43 | |
44 /* | |
45 * Stub to use with fdevopen | |
46 * | |
47 * We ignore f and always succeed | |
48 */ | |
49 static int _putc(char c, FILE *f) { | |
50 cons_putc(c); | |
51 return(0); | |
52 } | |
53 | |
54 /* | |
55 * Stub to use with fdevopen | |
56 * | |
57 * We ignore f and always succeed | |
58 */ | |
59 static int _getc(FILE *f) { | |
60 return(cons_getc()); | |
61 } | |
62 | |
63 void | |
64 cons_init(void) { | |
4
095216e8453d
Hide register name abstraction in a separate file.
darius@Inchoate
parents:
3
diff
changeset
|
65 _SETBAUD(38400); |
0 | 66 |
67 /* Enable receiver and transmitter. Turn on rx interrupts */ | |
4
095216e8453d
Hide register name abstraction in a separate file.
darius@Inchoate
parents:
3
diff
changeset
|
68 _INITREG(); |
095216e8453d
Hide register name abstraction in a separate file.
darius@Inchoate
parents:
3
diff
changeset
|
69 |
0 | 70 fdevopen(_putc, NULL); /* Open stdout */ |
71 fdevopen(NULL, _getc); /* Open stdin */ | |
72 } | |
73 | |
74 int | |
75 cons_putc(char c) { | |
4
095216e8453d
Hide register name abstraction in a separate file.
darius@Inchoate
parents:
3
diff
changeset
|
76 loop_until_bit_is_set(_UCSRA, _UDRE); |
095216e8453d
Hide register name abstraction in a separate file.
darius@Inchoate
parents:
3
diff
changeset
|
77 _UDR = c; |
0 | 78 |
79 return(0); | |
80 } | |
81 | |
82 void | |
83 cons_putsP(const char *addr) { | |
84 char c; | |
85 | |
86 while ((c = pgm_read_byte_near(addr++))) | |
87 cons_putc(c); | |
88 } | |
89 | |
90 void | |
91 cons_puts(const char *addr) { | |
92 while (*addr) | |
93 cons_putc(*addr++); | |
94 } | |
95 | |
96 void | |
97 cons_puts_dec(uint8_t a, uint8_t l) { | |
98 char s[4]; | |
99 | |
100 if (l && a < 10) | |
101 cons_putsP(PSTR("0")); | |
102 cons_puts(utoa(a, s, 10)); | |
103 } | |
104 | |
105 void | |
106 cons_puts_hex(uint8_t a) { | |
107 char s[3]; | |
108 | |
109 if (a < 0x10) | |
110 cons_putc('0'); | |
111 | |
112 cons_puts(utoa(a, s, 16)); | |
113 } | |
114 | |
115 char | |
116 cons_getc(void) { | |
4
095216e8453d
Hide register name abstraction in a separate file.
darius@Inchoate
parents:
3
diff
changeset
|
117 while (!(_UCSRA & _BV(_RXC))) |
0 | 118 ; |
4
095216e8453d
Hide register name abstraction in a separate file.
darius@Inchoate
parents:
3
diff
changeset
|
119 return (_UDR); |
0 | 120 } |
121 | |
122 /* Rx complete */ | |
4
095216e8453d
Hide register name abstraction in a separate file.
darius@Inchoate
parents:
3
diff
changeset
|
123 ISR(_RXVECT) { |
0 | 124 char c; |
125 | |
4
095216e8453d
Hide register name abstraction in a separate file.
darius@Inchoate
parents:
3
diff
changeset
|
126 while (_UCSRA & _BV(_RXC)) { |
095216e8453d
Hide register name abstraction in a separate file.
darius@Inchoate
parents:
3
diff
changeset
|
127 c = _UDR; |
0 | 128 /* 255 means we're waiting for main to process the command, |
3
15d89caaf516
Add support for single UART devices, although untested apart from a compile.
darius@Inchoate
parents:
0
diff
changeset
|
129 * just throw stuff away |
15d89caaf516
Add support for single UART devices, although untested apart from a compile.
darius@Inchoate
parents:
0
diff
changeset
|
130 */ |
15d89caaf516
Add support for single UART devices, although untested apart from a compile.
darius@Inchoate
parents:
0
diff
changeset
|
131 if (cmd.state == 255) |
0 | 132 continue; |
133 | |
134 /* End of line? */ | |
135 if (c == '\n' || c == '\r') { | |
136 cmd.buf[cmd.state] = '\0'; | |
137 printf_P(PSTR("\r\n")); | |
138 cmd.len = cmd.state; | |
139 cmd.state = 255; | |
140 continue; | |
141 } | |
142 | |
143 /* Backspace/delete */ | |
144 if (c == 0x08 || c == 0x7f) { | |
145 if (cmd.state > 0) { | |
146 cmd.state--; | |
147 printf_P(PSTR("\010\040\010")); | |
148 } | |
149 continue; | |
150 } | |
151 | |
152 /* Anything unprintable just ignore it */ | |
153 if (!isprint(c)) | |
154 continue; | |
155 | |
156 cmd.buf[cmd.state] = tolower(c); | |
157 | |
158 /* Echo back to the user */ | |
159 cons_putc(cmd.buf[cmd.state]); | |
160 | |
161 cmd.state++; | |
162 /* Over flow? */ | |
163 if (cmd.state == ((sizeof(cmd.buf) / sizeof(cmd.buf[0])) - 1)) { | |
164 printf_P(PSTR("\r\nLine too long")); | |
165 cmd.state = 0; | |
166 continue; | |
167 } | |
168 } | |
169 } | |
170 | |
171 /* Tx complete */ | |
4
095216e8453d
Hide register name abstraction in a separate file.
darius@Inchoate
parents:
3
diff
changeset
|
172 ISR(_TXVECT) { |
0 | 173 } |
174 |