annotate cons.c @ 64:11c453539d31

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