Mercurial > ~darius > hgwebdir.cgi > tempctrl
annotate testavr.c @ 12:4b141cc7cbd4
- Reduce type widths where possible.
- Add URL for Dallas OWPD kit.
- Hide more stuff behind OW_DEBUG.
author | darius |
---|---|
date | Wed, 01 Sep 2004 17:45:24 +0930 |
parents | ccc39c9f320b |
children | 2c03ec600dbc |
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 <stdio.h> | |
32 #include <avr/io.h> | |
33 #include <avr/interrupt.h> | |
34 #include <avr/signal.h> | |
35 #include <avr/pgmspace.h> | |
36 #include <string.h> | |
4 | 37 #include <ctype.h> |
0 | 38 |
39 #include "1wire.h" | |
40 | |
41 #define UART_BAUD_SELECT(baudRate,xtalCpu) ((xtalCpu)/((baudRate)*16l)-1) | |
4 | 42 #define UART_BAUD_RATE 19200 |
0 | 43 |
44 void uart_putsP(const char *addr); | |
45 void uart_puts(const char *addr); | |
46 int uart_putc(char c); | |
4 | 47 int uart_getc(void); |
48 int beginswith_P(const char *s1, const char *s2); | |
0 | 49 |
50 uint8_t PROGMEM ledvals[] = {0x01, 0x03, 0x07, 0x0e, 0x1c, 0x38, 0x70, 0xe0, 0xc0, 0x80}; | |
4 | 51 static uint8_t dir = 0; |
52 static volatile uint8_t leds = 0; | |
53 static uint8_t ledpos = 0; | |
0 | 54 |
55 INTERRUPT(SIG_OVERFLOW0) { | |
56 if (!leds) | |
57 return; | |
58 | |
59 /* Going up */ | |
60 if (dir == 0) { | |
61 if (ledpos == 9) { | |
62 dir = 1; | |
63 TCNT0 = 0; | |
64 goto doleds; | |
65 } | |
66 | |
67 ledpos++; | |
68 } else { | |
69 if (ledpos == 0) { | |
70 dir = 0; | |
71 TCNT0 = 0; | |
72 goto doleds; | |
73 } | |
74 | |
75 ledpos--; | |
76 } | |
77 | |
78 doleds: | |
79 TCNT0 = 0; | |
80 | |
81 PORTA = pgm_read_byte(&ledvals[ledpos]); | |
82 } | |
83 | |
84 void | |
85 usleep(uint16_t usec) { | |
86 /* 4Mhz = 250ns per clock cycle */ | |
87 usec /= 2; | |
88 if (usec < 1) | |
89 return; | |
90 | |
91 while (usec--) | |
92 asm volatile ( | |
93 "" | |
94 ::); | |
95 } | |
96 | |
97 int | |
98 main(void) { | |
4 | 99 uint8_t ROM[8]; |
100 char cmdbuf[40]; | |
0 | 101 int i; |
102 | |
103 cli(); | |
104 outp(0xff, DDRA); | |
4 | 105 |
106 /* Timer Clock divisor - CK/1024 */ | |
107 outp(BV(CS00) | BV(CS02), TCCR0); | |
11 | 108 |
109 outp(0xfc, DDRC); | |
0 | 110 outp(0x00, PORTC); |
11 | 111 |
0 | 112 /* Init UART */ |
113 outp(UART_BAUD_SELECT(UART_BAUD_RATE,XTAL_CPU), UBRR); | |
114 | |
115 /* Enable receiver and transmitter. Turn on transmit interrupts */ | |
116 outp(BV(RXEN) | BV(TXEN), UCR); | |
117 | |
11 | 118 #if 0 |
119 int was; | |
120 uint32_t count; | |
121 | |
122 was = inp(PINC) & 0x02; | |
123 | |
124 count = 0; | |
125 while (1) { | |
126 if (was) { | |
127 if (!(inp(PINC) & 0x02)) { | |
128 sprintf_P(cmdbuf, PSTR("high -> low, i = %d\n\r"), count); | |
129 uart_puts(cmdbuf); | |
130 count = 0; | |
131 was = 0x00; | |
132 } | |
133 } else { | |
134 if ((inp(PINC) & 0x02)) { | |
135 sprintf_P(cmdbuf, PSTR("low -> high, i = %d\n\r"), count); | |
136 uart_puts(cmdbuf); | |
137 count = 0; | |
138 was = 0x02; | |
139 } | |
140 } | |
141 | |
142 count++; | |
143 } | |
144 #endif | |
145 | |
4 | 146 uart_putsP(PSTR("\n\r\n\r===============\n\r" |
147 "Inited!\n\r\n\r")); | |
148 | |
149 while (1) { | |
150 uart_putsP(PSTR("> ")); | |
151 i = 0; | |
152 while (1) { | |
153 cmdbuf[i] = tolower(uart_getc()); | |
154 if (cmdbuf[i] == '\n' || cmdbuf[i] == '\r') | |
155 break; | |
156 | |
157 /* Backspace */ | |
158 if (cmdbuf[i] == 010) { | |
159 if (i > 0) { | |
160 uart_putsP(PSTR("\010\040\010")); | |
161 i--; | |
162 } | |
163 continue; | |
164 } | |
0 | 165 |
4 | 166 /* Anything unprintable just ignore it */ |
167 if (!isprint(cmdbuf[i])) | |
168 continue; | |
169 | |
170 uart_putc(cmdbuf[i]); | |
171 i++; | |
172 if (i == sizeof(cmdbuf)) { | |
173 uart_putsP(PSTR("\n\rLine too long\n\r")); | |
174 i = 0; | |
175 continue; | |
176 } | |
177 } | |
178 cmdbuf[i + 1] = '\0'; | |
179 uart_putsP(PSTR("\n\r")); | |
180 if (i == 0) | |
181 continue; | |
0 | 182 |
4 | 183 if (cmdbuf[0] == '?') { |
184 uart_putsP(PSTR("rs Reset and check for presence\n\r" | |
7 | 185 "sr Search the bus for ROMs\n\r" |
4 | 186 "re Read a bit\n\r" |
187 "rb Read a byte\n\r" | |
188 "wr bit Write a bit\n\r" | |
189 "wb byte Write a byte (hex)\n\r" | |
190 "wc cmd [ROMID] Write command\n\r" | |
11 | 191 "te ROMID Read the temperature from a DS1820\n\r" |
192 "le Turn pretty LED cycling on\n\r")); | |
193 | |
4 | 194 continue; |
195 } | |
0 | 196 |
4 | 197 if (i < 2) |
198 goto badcmd; | |
199 | |
200 if (cmdbuf[0] == 'r' && cmdbuf[1] == 's') { | |
201 uart_putsP(PSTR("Resetting... ")); | |
202 | |
203 if (OWTouchReset() == 1) | |
10 | 204 uart_putsP(PSTR("No presense pulse found\n\r")); |
4 | 205 else |
10 | 206 uart_putsP(PSTR("Presense pulse found\n\r")); |
4 | 207 } else if (cmdbuf[0] == 'r' && cmdbuf[1] == 'e') { |
0 | 208 if (OWReadBit()) |
209 uart_putsP(PSTR("Read a 1\n\r")); | |
210 else | |
211 uart_putsP(PSTR("Read a 0\n\r")); | |
4 | 212 } else if (cmdbuf[0] == 'r' && cmdbuf[1] == 'b') { |
213 sprintf_P(cmdbuf, PSTR("Read a 0x%02x\n\r"), OWReadByte()); | |
214 uart_puts(cmdbuf); | |
215 } else if (cmdbuf[0] == 'w' && cmdbuf[1] == 'r') { | |
216 int arg; | |
217 | |
218 if (sscanf_P(cmdbuf + 3, PSTR("%d"), &arg) != 1) { | |
219 uart_putsP(PSTR("Unable to parse wr command\n\r")); | |
220 continue; | |
221 } | |
222 | |
223 OWWriteBit(arg); | |
224 sprintf_P(cmdbuf, PSTR("Wrote a %d\n\r"), arg); | |
225 uart_puts(cmdbuf); | |
226 } else if (cmdbuf[0] == 'w' && cmdbuf[1] == 'b') { | |
227 int arg; | |
228 | |
229 if (sscanf_P(cmdbuf + 3, PSTR("%2x"), &arg) != 1) { | |
230 uart_putsP(PSTR("Unable to parse wb command\n\r")); | |
231 continue; | |
232 } | |
233 | |
234 OWWriteByte(arg); | |
235 sprintf_P(cmdbuf, PSTR("Wrote a 0x%02x\n\r"), arg); | |
236 uart_puts(cmdbuf); | |
237 } else if (cmdbuf[0] == 'w' && cmdbuf[1] == 'c') { | |
238 int arg; | |
0 | 239 |
4 | 240 switch (sscanf_P(cmdbuf + 3, PSTR("%x %x:%x:%x:%x:%x:%x:%x:%x:%x"), &arg, |
241 &ROM[0], &ROM[1], &ROM[2], &ROM[3], | |
242 &ROM[4], &ROM[5], &ROM[6], &ROM[7])) { | |
243 break; | |
244 | |
245 case 1: | |
246 OWSendCmd(NULL, arg); | |
247 sprintf_P(cmdbuf, PSTR("Sent 0x%02x to all ROMS\n\r"), arg); | |
248 uart_puts(cmdbuf); | |
249 break; | |
250 | |
251 case 9: | |
252 OWSendCmd(ROM, arg); | |
253 sprintf_P(cmdbuf, PSTR("Sent 0x%02x to ROM %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n\r"), | |
254 arg, ROM[0], ROM[1], ROM[2], ROM[3], | |
255 ROM[4], ROM[5], ROM[6], ROM[7]); | |
256 uart_puts(cmdbuf); | |
257 | |
258 break; | |
259 | |
260 case 0: | |
261 default: | |
262 uart_putsP(PSTR("Unable to parse wc command\n\r")); | |
263 break; | |
264 } | |
265 | |
266 OWWriteByte(arg); | |
267 sprintf_P(cmdbuf, PSTR("Wrote a 0x%02x\n\r"), arg); | |
268 uart_puts(cmdbuf); | |
269 } else if (cmdbuf[0] == 't' && cmdbuf[1] == 'e') { | |
270 uint8_t crc; | |
271 uint16_t temp; | |
272 uint8_t buf[9]; | |
273 | |
274 if (sscanf_P(cmdbuf + 3, PSTR("%x:%x:%x:%x:%x:%x:%x:%x:%x"), | |
275 &ROM[0], &ROM[1], &ROM[2], &ROM[3], | |
276 &ROM[4], &ROM[5], &ROM[6], &ROM[7]) != 8) { | |
277 uart_putsP(PSTR("Unable to parse ROM ID\n\r")); | |
278 continue; | |
279 } | |
280 | |
281 if (ROM[0] != OW_FAMILY_TEMP) { | |
282 uart_putsP(PSTR("ROM specified isn't a temperature sensor\n\r")); | |
283 continue; | |
284 } | |
285 | |
286 OWSendCmd(ROM, OW_CONVERTT_CMD); | |
287 #if OW_DEBUG | |
288 uart_putsP(PSTR("Command sent, waiting\n\r")); | |
289 #endif | |
290 i = 0; | |
291 while (OWReadBit() == 0) { | |
292 i++; | |
293 } | |
294 #if OW_DEBUG | |
295 sprintf_P(cmdbuf, PSTR("Temp comversion took %d cycles\n\r"), i); | |
296 uart_puts(cmdbuf); | |
297 #endif | |
298 OWSendCmd(ROM, OW_RD_SCR_CMD); | |
299 crc = 0; | |
300 for (i = 0; i < 9; i++) { | |
301 buf[i] = OWReadByte(); | |
302 if (i < 8) | |
303 OWCRC(buf[i], &crc); | |
304 } | |
305 | |
306 temp = buf[0]; | |
307 temp |= (uint16_t)buf[1] << 8; | |
308 temp <<= 3; | |
309 | |
310 if (crc != buf[8]) { | |
311 sprintf_P(cmdbuf, PSTR("CRC mismatch got %d vs calcd %d\n\r"), buf[8], crc); | |
312 uart_puts(cmdbuf); | |
313 continue; | |
314 } | |
315 | |
316 sprintf_P(cmdbuf, PSTR("temperature %d.%01d\n\r"), | |
317 temp >> 4, (temp << 12) / 6553); | |
318 uart_puts(cmdbuf); | |
319 } else if (cmdbuf[0] == 's' && cmdbuf[1] == 'r') { | |
320 memset(ROM, 0, 8); | |
10 | 321 |
322 i = OWFirst(ROM, 1, 0); | |
0 | 323 do { |
10 | 324 switch (i) { |
325 case OW_BADWIRE: | |
326 uart_putsP(PSTR("Presense pulse, but no module found, bad module/cabling?\n\r")); | |
327 break; | |
328 | |
329 case OW_NOPRESENCE: | |
330 uart_putsP(PSTR("No presense pulse found\n\r")); | |
331 break; | |
332 | |
333 case OW_BADCRC: | |
334 uart_putsP(PSTR("Bad CRC\n\r")); | |
335 break; | |
336 | |
337 case OW_NOMODULES: | |
338 case OW_FOUND: | |
339 break; | |
340 | |
341 default: | |
342 uart_putsP(PSTR("Unknown error from 1 wire library\n\r")); | |
343 break; | |
344 } | |
345 | |
346 if (i != OW_FOUND) | |
347 break; | |
348 | |
4 | 349 sprintf_P(cmdbuf, PSTR("%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n\r"), |
0 | 350 ROM[0], |
351 ROM[1], | |
352 ROM[2], | |
353 ROM[3], | |
354 ROM[4], | |
355 ROM[5], | |
356 ROM[6], | |
357 ROM[7]); | |
4 | 358 uart_puts(cmdbuf); |
10 | 359 |
360 i = OWNext(ROM, 1, 0); | |
361 } while (1); | |
11 | 362 } else if (cmdbuf[0] == 'l' && cmdbuf[1] == 'e') { |
0 | 363 if (leds == 0) { |
364 leds = 1; | |
365 ledpos = 0; | |
366 outp(0, TCNT0); | |
367 sbi(TIMSK, TOIE0); | |
368 sei(); | |
369 uart_putsP(PSTR("Starting\n\r")); | |
370 } else { | |
371 leds = 0; | |
372 ledpos = 0; | |
373 PORTA = 0x00; | |
374 cbi(TIMSK, TOIE0); | |
375 cli(); | |
376 uart_putsP(PSTR("Stopping\n\r")); | |
377 } | |
4 | 378 } else { |
379 badcmd: | |
380 uart_putsP(PSTR("Unknown command, ? for a list\n\r")); | |
0 | 381 } |
382 | |
383 } | |
384 | |
385 return(0); | |
386 } | |
387 | |
388 int | |
389 uart_putc(char c) { | |
390 loop_until_bit_is_set(USR, UDRE); | |
391 outp(c, UDR); | |
392 | |
393 return(0); | |
394 } | |
395 | |
396 void | |
397 uart_putsP(const char *addr) { | |
398 char c; | |
399 | |
400 while ((c = PRG_RDB((unsigned short)addr++))) | |
401 uart_putc(c); | |
402 } | |
403 | |
404 void | |
405 uart_puts(const char *addr) { | |
406 while (*addr) | |
407 uart_putc(*addr++); | |
408 } | |
409 | |
4 | 410 int |
0 | 411 uart_getc(void) { |
412 while (!(inp(USR) & 0x80)) | |
413 ; | |
414 | |
415 return (inp(UDR)); | |
416 } | |
4 | 417 |