Mercurial > ~darius > hgwebdir.cgi > avr
annotate testavr.c @ 18:108a703c39e6
Covert to a later version of avr-libc. Stuff like not using inb/outb,
etc.. Get the mcu/part right, change includes..
author | darius |
---|---|
date | Fri, 25 Nov 2005 21:49:56 +1030 |
parents | a58b41b7d15c |
children | 2b0ed085b95b |
rev | line source |
---|---|
0 | 1 /* |
9
7ed10c59ba06
Supply clock speed via the command line so 1wire-delay.h can use it.
darius
parents:
7
diff
changeset
|
2 * Test various AVR bits and pieces |
7ed10c59ba06
Supply clock speed via the command line so 1wire-delay.h can use it.
darius
parents:
7
diff
changeset
|
3 * |
7ed10c59ba06
Supply clock speed via the command line so 1wire-delay.h can use it.
darius
parents:
7
diff
changeset
|
4 * $Id$ |
7ed10c59ba06
Supply clock speed via the command line so 1wire-delay.h can use it.
darius
parents:
7
diff
changeset
|
5 * |
0 | 6 * Copyright (c) 2004 |
7 * Daniel O'Connor <darius@dons.net.au>. All rights reserved. | |
8 * | |
9 * Redistribution and use in source and binary forms, with or without | |
10 * modification, are permitted provided that the following conditions | |
11 * are met: | |
12 * 1. Redistributions of source code must retain the above copyright | |
13 * notice, this list of conditions and the following disclaimer. | |
14 * 2. Redistributions in binary form must reproduce the above copyright | |
15 * notice, this list of conditions and the following disclaimer in the | |
16 * documentation and/or other materials provided with the distribution. | |
17 * | |
18 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND | |
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
21 * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE | |
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
28 * SUCH DAMAGE. | |
29 */ | |
30 | |
31 #include <avr/io.h> | |
32 #include <avr/interrupt.h> | |
33 #include <avr/pgmspace.h> | |
34 #include <string.h> | |
4 | 35 #include <ctype.h> |
13 | 36 #include <stdlib.h> |
0 | 37 |
38 #include "1wire.h" | |
39 | |
40 #define UART_BAUD_SELECT(baudRate,xtalCpu) ((xtalCpu)/((baudRate)*16l)-1) | |
4 | 41 #define UART_BAUD_RATE 19200 |
0 | 42 |
43 void uart_putsP(const char *addr); | |
44 void uart_puts(const char *addr); | |
45 int uart_putc(char c); | |
4 | 46 int uart_getc(void); |
13 | 47 void uart_puts_dec(uint8_t a, uint8_t l); |
48 void uart_puts_hex(uint8_t a); | |
0 | 49 |
50 int | |
51 main(void) { | |
4 | 52 uint8_t ROM[8]; |
53 char cmdbuf[40]; | |
13 | 54 int8_t i, arg; |
15 | 55 uint8_t crc, buf[9];; |
56 int8_t temp; | |
57 uint16_t tfrac; | |
58 | |
0 | 59 cli(); |
11 | 60 |
17
a58b41b7d15c
Covert to a later version of avr-libc. Stuff like not using inb/outb,
darius
parents:
16
diff
changeset
|
61 DDRC = 0xfc; |
a58b41b7d15c
Covert to a later version of avr-libc. Stuff like not using inb/outb,
darius
parents:
16
diff
changeset
|
62 PORTC = 0x00; |
15 | 63 DDRA = 0xff; |
11 | 64 |
0 | 65 /* Init UART */ |
17
a58b41b7d15c
Covert to a later version of avr-libc. Stuff like not using inb/outb,
darius
parents:
16
diff
changeset
|
66 UBRR = UART_BAUD_SELECT(UART_BAUD_RATE,XTAL_CPU); |
0 | 67 |
68 /* Enable receiver and transmitter. Turn on transmit interrupts */ | |
17
a58b41b7d15c
Covert to a later version of avr-libc. Stuff like not using inb/outb,
darius
parents:
16
diff
changeset
|
69 UCR = _BV(RXEN) | _BV(TXEN); |
0 | 70 |
4 | 71 uart_putsP(PSTR("\n\r\n\r===============\n\r" |
72 "Inited!\n\r\n\r")); | |
73 | |
74 while (1) { | |
75 uart_putsP(PSTR("> ")); | |
76 i = 0; | |
77 while (1) { | |
78 cmdbuf[i] = tolower(uart_getc()); | |
79 if (cmdbuf[i] == '\n' || cmdbuf[i] == '\r') | |
80 break; | |
81 | |
15 | 82 /* Backspace/Delete */ |
83 if (cmdbuf[i] == 0x08) { | |
4 | 84 if (i > 0) { |
85 uart_putsP(PSTR("\010\040\010")); | |
86 i--; | |
87 } | |
88 continue; | |
89 } | |
0 | 90 |
4 | 91 /* Anything unprintable just ignore it */ |
92 if (!isprint(cmdbuf[i])) | |
93 continue; | |
94 | |
95 uart_putc(cmdbuf[i]); | |
96 i++; | |
97 if (i == sizeof(cmdbuf)) { | |
13 | 98 uart_putsP(PSTR("\n\rLine too long")); |
4 | 99 i = 0; |
13 | 100 break; |
4 | 101 } |
102 } | |
103 cmdbuf[i + 1] = '\0'; | |
104 uart_putsP(PSTR("\n\r")); | |
105 if (i == 0) | |
106 continue; | |
0 | 107 |
4 | 108 if (cmdbuf[0] == '?') { |
109 uart_putsP(PSTR("rs Reset and check for presence\n\r" | |
7 | 110 "sr Search the bus for ROMs\n\r" |
4 | 111 "re Read a bit\n\r" |
112 "rb Read a byte\n\r" | |
113 "wr bit Write a bit\n\r" | |
114 "wb byte Write a byte (hex)\n\r" | |
115 "wc cmd [ROMID] Write command\n\r" | |
15 | 116 "te ROMID Read the temperature from a DS1820\n\r" |
117 "le byte Set the LED port\n\r")); | |
11 | 118 |
4 | 119 continue; |
120 } | |
0 | 121 |
4 | 122 if (i < 2) |
123 goto badcmd; | |
124 | |
125 if (cmdbuf[0] == 'r' && cmdbuf[1] == 's') { | |
126 uart_putsP(PSTR("Resetting... ")); | |
127 | |
128 if (OWTouchReset() == 1) | |
16 | 129 uart_putsP(PSTR("No presence pulse found\n\r")); |
4 | 130 else |
16 | 131 uart_putsP(PSTR("Presence pulse found\n\r")); |
4 | 132 } else if (cmdbuf[0] == 'r' && cmdbuf[1] == 'e') { |
0 | 133 if (OWReadBit()) |
134 uart_putsP(PSTR("Read a 1\n\r")); | |
135 else | |
136 uart_putsP(PSTR("Read a 0\n\r")); | |
4 | 137 } else if (cmdbuf[0] == 'r' && cmdbuf[1] == 'b') { |
13 | 138 uart_putsP(PSTR("Read a 0x")); |
139 uart_puts_hex(OWReadByte()); | |
140 uart_putsP(PSTR("\n\r")); | |
4 | 141 } else if (cmdbuf[0] == 'w' && cmdbuf[1] == 'r') { |
13 | 142 arg = strtol(cmdbuf + 3, (char **)NULL, 10); |
4 | 143 OWWriteBit(arg); |
13 | 144 uart_putsP(PSTR("Wrote a ")); |
145 if (arg) | |
146 uart_putsP(PSTR("1\n\r")); | |
147 else | |
148 uart_putsP(PSTR("0\n\r")); | |
4 | 149 } else if (cmdbuf[0] == 'w' && cmdbuf[1] == 'b') { |
13 | 150 arg = (int)strtol(cmdbuf + 3, (char **)NULL, 16); |
151 OWWriteByte(arg); | |
152 } else if (cmdbuf[0] == 'w' && cmdbuf[1] == 'c') { | |
153 i = strlen(cmdbuf); | |
154 if (i < 5) { | |
155 uart_putsP(PSTR("No arguments\n\r")); | |
4 | 156 continue; |
157 } | |
158 | |
13 | 159 arg = (int)strtol(cmdbuf + 3, (char **)NULL, 16); |
160 if (arg == 0) { | |
161 uart_putsP(PSTR("Unparseable command\n\r")); | |
162 continue; | |
163 } | |
0 | 164 |
13 | 165 if (i == 5) { |
4 | 166 OWSendCmd(NULL, arg); |
13 | 167 continue; |
4 | 168 } |
169 | |
13 | 170 if (i < 29) { |
171 uart_putsP(PSTR("Can't parse ROM ID\n\r")); | |
172 continue; | |
173 } | |
174 for (i = 0; i < 8; i++) | |
175 ROM[i] = (int)strtol(cmdbuf + 6 + (3 * i), (char **)NULL, 16); | |
176 | |
177 OWSendCmd(ROM, arg); | |
4 | 178 } else if (cmdbuf[0] == 't' && cmdbuf[1] == 'e') { |
13 | 179 if (strlen(cmdbuf) < 26) { |
4 | 180 uart_putsP(PSTR("Unable to parse ROM ID\n\r")); |
181 continue; | |
182 } | |
13 | 183 |
184 for (i = 0; i < 8; i++) | |
185 ROM[i] = (int)strtol(cmdbuf + 3 * (i + 1), (char **)NULL, 16); | |
186 | |
4 | 187 if (ROM[0] != OW_FAMILY_TEMP) { |
188 uart_putsP(PSTR("ROM specified isn't a temperature sensor\n\r")); | |
189 continue; | |
190 } | |
191 | |
192 OWSendCmd(ROM, OW_CONVERTT_CMD); | |
193 i = 0; | |
194 while (OWReadBit() == 0) { | |
195 i++; | |
196 } | |
197 OWSendCmd(ROM, OW_RD_SCR_CMD); | |
198 crc = 0; | |
199 for (i = 0; i < 9; i++) { | |
200 buf[i] = OWReadByte(); | |
201 if (i < 8) | |
202 OWCRC(buf[i], &crc); | |
203 } | |
204 | |
205 if (crc != buf[8]) { | |
13 | 206 uart_putsP(PSTR("CRC mismatch\n\r")); |
4 | 207 continue; |
208 } | |
209 | |
13 | 210 #if 0 |
211 uart_putsP(PSTR("temperature ")); | |
212 uart_puts_dec(temp >> 4, 0); | |
213 uart_putsP(PSTR(".")); | |
214 uart_puts_dec((temp << 12) / 6553, 0); | |
215 uart_putsP(PSTR("\n\r")); | |
216 #else | |
217 /* 0 Temperature LSB | |
218 * 1 Temperature MSB | |
219 * 2 Th | |
220 * 3 Tl | |
221 * 4 Reserved | |
222 * 5 Reserved | |
223 * 6 Count Remain | |
224 * 7 Count per C | |
225 * 8 CRC | |
226 */ | |
227 #if 0 | |
228 for (i = 0; i < 9; i++) { | |
229 uart_puts_dec(buf[i], 0); | |
230 uart_putsP(PSTR("\n\r")); | |
231 } | |
232 #endif | |
233 temp = buf[0]; | |
234 if (buf[0] & 0x01) | |
235 temp -= 256; | |
236 temp >>= 1; | |
237 | |
238 tfrac = buf[7] - buf[6]; | |
239 tfrac *= (uint16_t)100; | |
240 tfrac /= buf[7]; | |
241 tfrac += 75; | |
242 if (tfrac < 100) { | |
243 temp--; | |
244 } else { | |
245 tfrac -= 100; | |
246 } | |
247 | |
248 if (temp < 0){ | |
249 uart_putc('-'); | |
250 uart_puts_dec(-temp, 0); | |
251 } else | |
252 uart_puts_dec(temp, 0); | |
253 uart_putsP(PSTR(".")); | |
254 uart_puts_dec(tfrac, 1); | |
255 uart_putsP(PSTR("\n\r")); | |
256 | |
257 #endif | |
4 | 258 } else if (cmdbuf[0] == 's' && cmdbuf[1] == 'r') { |
259 memset(ROM, 0, 8); | |
10 | 260 |
261 i = OWFirst(ROM, 1, 0); | |
0 | 262 do { |
10 | 263 switch (i) { |
264 case OW_BADWIRE: | |
16 | 265 uart_putsP(PSTR("Presence pulse, but no module found, bad module/cabling?\n\r")); |
10 | 266 break; |
267 | |
268 case OW_NOPRESENCE: | |
16 | 269 uart_putsP(PSTR("No presence pulse found\n\r")); |
10 | 270 break; |
271 | |
272 case OW_BADCRC: | |
273 uart_putsP(PSTR("Bad CRC\n\r")); | |
274 break; | |
275 | |
276 case OW_NOMODULES: | |
277 case OW_FOUND: | |
278 break; | |
279 | |
280 default: | |
281 uart_putsP(PSTR("Unknown error from 1 wire library\n\r")); | |
282 break; | |
283 } | |
284 | |
285 if (i != OW_FOUND) | |
286 break; | |
13 | 287 |
288 for (i = 0; i < 7; i++) { | |
289 uart_puts_hex(ROM[i]); | |
290 uart_putc(':'); | |
291 } | |
292 uart_puts_hex(ROM[7]); | |
293 uart_putsP(PSTR("\n\r")); | |
10 | 294 |
295 i = OWNext(ROM, 1, 0); | |
296 } while (1); | |
15 | 297 } else if (cmdbuf[0] == 'l' && cmdbuf[1] == 'e') { |
298 crc = (uint8_t)strtol(cmdbuf + 3, (char **)NULL, 16); | |
299 PORTA = crc; | |
300 #if 1 | |
301 uart_putsP(PSTR("LEDs set to 0x")); | |
302 uart_puts_hex(crc); | |
303 uart_putsP(PSTR("\n\r")); | |
304 #endif | |
4 | 305 } else { |
306 badcmd: | |
307 uart_putsP(PSTR("Unknown command, ? for a list\n\r")); | |
0 | 308 } |
309 | |
310 } | |
311 | |
312 return(0); | |
313 } | |
314 | |
315 int | |
316 uart_putc(char c) { | |
317 loop_until_bit_is_set(USR, UDRE); | |
17
a58b41b7d15c
Covert to a later version of avr-libc. Stuff like not using inb/outb,
darius
parents:
16
diff
changeset
|
318 UDR = c; |
0 | 319 |
320 return(0); | |
321 } | |
322 | |
323 void | |
324 uart_putsP(const char *addr) { | |
325 char c; | |
326 | |
17
a58b41b7d15c
Covert to a later version of avr-libc. Stuff like not using inb/outb,
darius
parents:
16
diff
changeset
|
327 while ((c = pgm_read_byte_near(addr++))) |
0 | 328 uart_putc(c); |
329 } | |
330 | |
331 void | |
332 uart_puts(const char *addr) { | |
333 while (*addr) | |
334 uart_putc(*addr++); | |
335 } | |
336 | |
13 | 337 void |
338 uart_puts_dec(uint8_t a, uint8_t l) { | |
339 char s[4]; | |
340 | |
341 if (l && a < 10) | |
342 uart_putsP(PSTR("0")); | |
343 uart_puts(utoa(a, s, 10)); | |
344 } | |
345 | |
346 void | |
347 uart_puts_hex(uint8_t a) { | |
348 char s[3]; | |
349 | |
350 if (a < 0x10) | |
351 uart_putc('0'); | |
352 | |
353 uart_puts(utoa(a, s, 16)); | |
354 } | |
355 | |
4 | 356 int |
0 | 357 uart_getc(void) { |
17
a58b41b7d15c
Covert to a later version of avr-libc. Stuff like not using inb/outb,
darius
parents:
16
diff
changeset
|
358 while (!USR & 0x80) |
0 | 359 ; |
360 | |
17
a58b41b7d15c
Covert to a later version of avr-libc. Stuff like not using inb/outb,
darius
parents:
16
diff
changeset
|
361 return (UDR); |
0 | 362 } |
4 | 363 |