comparison cons.c @ 41:5898fba6593c

Add temperature control. - Split out console stuff to cons.[ch]. Set up stdio so we can use printf etc. - Use \r\n as the line terminator consistently. - Add OWGetTemp to get temperatures from a device. - Load/save settings in EEPROM, defaults loaded from flash. Nearly feature complete except you can't edit ROM IDs without a programming tool :) (To be fixed) Needs more testing.
author darius@inchoate.localdomain
date Sun, 06 Jul 2008 22:19:53 +0930
parents
children 11c453539d31
comparison
equal deleted inserted replaced
40:1061fdbdc44f 41:5898fba6593c
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') {
141 cmd.buf[cmd.state + 1] = '\0';
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