comparison cons.c @ 0:3879f487b661

Initial commit of routines I copy and paste. Need work to make them more portable (esp cons)
author darius@Inchoate
date Wed, 11 Mar 2009 16:42:27 +1030
parents
children 15d89caaf516
comparison
equal deleted inserted replaced
-1:000000000000 0:3879f487b661
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 UBRR0 = UART_BAUD_SELECT(38400, F_CPU);
64
65 /* Enable receiver and transmitter. Turn on rx interrupts */
66 UCSR0A = 0;
67 UCSR0B = _BV(RXEN0) | _BV(TXEN0) | _BV(RXCIE0);
68 UCSR0C = _BV(UCSZ01) | _BV(UCSZ00);
69
70 fdevopen(_putc, NULL); /* Open stdout */
71 fdevopen(NULL, _getc); /* Open stdin */
72 }
73
74 int
75 cons_putc(char c) {
76 loop_until_bit_is_set(UCSR0A, UDRE0);
77 UDR0 = c;
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) {
117 while (!(UCSR0A & _BV(RXC0)))
118 ;
119
120 return (UDR0);
121 }
122
123 /* Rx complete */
124 ISR(USART0_RX_vect) {
125 volatile char pit;
126 char c;
127
128 while (UCSR0A & _BV(RXC0)) {
129 /* 255 means we're waiting for main to process the command,
130 just throw stuff away
131 */
132 if (cmd.state == 255) {
133 pit = UDR0;
134 continue;
135 }
136 c = UDR0;
137
138 /* End of line? */
139 if (c == '\n' || c == '\r') {
140 cmd.buf[cmd.state] = '\0';
141 printf_P(PSTR("\r\n"));
142 cmd.len = cmd.state;
143 cmd.state = 255;
144 continue;
145 }
146
147 /* Backspace/delete */
148 if (c == 0x08 || c == 0x7f) {
149 if (cmd.state > 0) {
150 cmd.state--;
151 printf_P(PSTR("\010\040\010"));
152 }
153 continue;
154 }
155
156 /* Anything unprintable just ignore it */
157 if (!isprint(c))
158 continue;
159
160 cmd.buf[cmd.state] = tolower(c);
161
162 /* Echo back to the user */
163 cons_putc(cmd.buf[cmd.state]);
164
165 cmd.state++;
166 /* Over flow? */
167 if (cmd.state == ((sizeof(cmd.buf) / sizeof(cmd.buf[0])) - 1)) {
168 printf_P(PSTR("\r\nLine too long"));
169 cmd.state = 0;
170 continue;
171 }
172 }
173 }
174
175 /* Tx complete */
176 ISR(USART0_TX_vect) {
177
178 }
179