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