Mercurial > ~darius > hgwebdir.cgi > tempctrl
annotate cons.c @ 68:ac45a96e8034
Check the right value for staleness(!)
author | darius@Inchoate |
---|---|
date | Mon, 19 Jan 2009 22:52:36 +1030 |
parents | 11c453539d31 |
children |
rev | line source |
---|---|
41 | 1 /* |
2 * Console code for AVR board | |
3 * | |
4 * Copyright (c) 2008 | |
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> | |
33 #include <avr/interrupt.h> | |
34 #include <avr/pgmspace.h> | |
35 #include "cons.h" | |
36 | |
37 #define UART_BAUD_SELECT(baudRate,xtalCpu) ((xtalCpu)/((baudRate)*16l)-1) | |
38 | |
39 /* Receive buffer storage */ | |
40 consbuf_t cmd; | |
41 | |
42 /* | |
43 * Stub to use with fdevopen | |
44 * | |
45 * We ignore f and always succeed | |
46 */ | |
47 static int _putc(char c, FILE *f) { | |
48 cons_putc(c); | |
49 return(0); | |
50 } | |
51 | |
52 /* | |
53 * Stub to use with fdevopen | |
54 * | |
55 * We ignore f and always succeed | |
56 */ | |
57 static int _getc(FILE *f) { | |
58 return(cons_getc()); | |
59 } | |
60 | |
61 void | |
62 cons_init(void) { | |
63 UBRRH = UART_BAUD_SELECT(38400, F_CPU) >> 8; | |
64 UBRRL = (uint8_t)UART_BAUD_SELECT(38400, F_CPU); | |
65 | |
66 /* Enable receiver and transmitter. Turn on rx interrupts */ | |
67 UCSRA = 0; | |
68 UCSRB = _BV(RXEN) | _BV(TXEN) | _BV(RXCIE); | |
69 UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0); | |
70 | |
71 fdevopen(_putc, NULL); /* Open stdout */ | |
72 fdevopen(NULL, _getc); /* Open stdin */ | |
73 } | |
74 | |
75 int | |
76 cons_putc(char c) { | |
77 loop_until_bit_is_set(UCSRA, UDRE); | |
78 UDR = c; | |
79 | |
80 return(0); | |
81 } | |
82 | |
83 void | |
84 cons_putsP(const char *addr) { | |
85 char c; | |
86 | |
87 while ((c = pgm_read_byte_near(addr++))) | |
88 cons_putc(c); | |
89 } | |
90 | |
91 void | |
92 cons_puts(const char *addr) { | |
93 while (*addr) | |
94 cons_putc(*addr++); | |
95 } | |
96 | |
97 void | |
98 cons_puts_dec(uint8_t a, uint8_t l) { | |
99 char s[4]; | |
100 | |
101 if (l && a < 10) | |
102 cons_putsP(PSTR("0")); | |
103 cons_puts(utoa(a, s, 10)); | |
104 } | |
105 | |
106 void | |
107 cons_puts_hex(uint8_t a) { | |
108 char s[3]; | |
109 | |
110 if (a < 0x10) | |
111 cons_putc('0'); | |
112 | |
113 cons_puts(utoa(a, s, 16)); | |
114 } | |
115 | |
116 char | |
117 cons_getc(void) { | |
118 while (!(UCSRA & _BV(RXC))) | |
119 ; | |
120 | |
121 return (UDR); | |
122 } | |
123 | |
124 /* Rx complete */ | |
125 ISR(USART_RXC_vect) { | |
126 volatile char pit; | |
127 char c; | |
128 | |
129 while (UCSRA & _BV(RXC)) { | |
130 /* 255 means we're waiting for main to process the command, | |
131 just throw stuff away | |
132 */ | |
133 if (cmd.state == 255) { | |
134 pit = UDR; | |
135 continue; | |
136 } | |
137 c = UDR; | |
138 | |
139 /* End of line? */ | |
140 if (c == '\n' || c == '\r') { | |
64
11c453539d31
Fix off by one bug when terminating input command.
darius@Inchoate
parents:
41
diff
changeset
|
141 cmd.buf[cmd.state] = '\0'; |
41 | 142 cons_putsP(PSTR("\r\n")); |
143 cmd.len = cmd.state; | |
144 cmd.state = 255; | |
145 continue; | |
146 } | |
147 | |
148 /* Backspace/delete */ | |
149 if (c == 0x08 || c == 0x7f) { | |
150 if (cmd.state > 0) { | |
151 cmd.state--; | |
152 cons_putsP(PSTR("\010\040\010")); | |
153 } | |
154 continue; | |
155 } | |
156 | |
157 /* Anything unprintable just ignore it */ | |
158 if (!isprint(c)) | |
159 continue; | |
160 | |
161 cmd.buf[cmd.state] = tolower(c); | |
162 | |
163 /* Echo back to the user */ | |
164 cons_putc(cmd.buf[cmd.state]); | |
165 | |
166 cmd.state++; | |
167 /* Over flow? */ | |
168 if (cmd.state == ((sizeof(cmd.buf) / sizeof(cmd.buf[0])) - 1)) { | |
169 cons_putsP(PSTR("\r\nLine too long")); | |
170 cmd.state = 0; | |
171 continue; | |
172 } | |
173 } | |
174 } | |
175 | |
176 /* Tx complete */ | |
177 ISR(USART_TXC_vect) { | |
178 | |
179 } | |
180 |