Mercurial > ~darius > hgwebdir.cgi > avr-lib
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 |