Mercurial > ~darius > hgwebdir.cgi > avr
comparison testavr.c @ 4:81e2f85e02ce
Implement a command driven 1 wire bus tool.
author | darius |
---|---|
date | Mon, 12 Jul 2004 15:41:35 +0930 |
parents | ffeab3c04e83 |
children | a940431af6f5 |
comparison
equal
deleted
inserted
replaced
3:ee3c9a16099e | 4:81e2f85e02ce |
---|---|
28 #include <avr/io.h> | 28 #include <avr/io.h> |
29 #include <avr/interrupt.h> | 29 #include <avr/interrupt.h> |
30 #include <avr/signal.h> | 30 #include <avr/signal.h> |
31 #include <avr/pgmspace.h> | 31 #include <avr/pgmspace.h> |
32 #include <string.h> | 32 #include <string.h> |
33 #include <ctype.h> | |
33 | 34 |
34 #include "1wire.h" | 35 #include "1wire.h" |
35 | 36 |
36 #define UART_BAUD_SELECT(baudRate,xtalCpu) ((xtalCpu)/((baudRate)*16l)-1) | 37 #define UART_BAUD_SELECT(baudRate,xtalCpu) ((xtalCpu)/((baudRate)*16l)-1) |
37 #define XTAL_CPU 4000000 /* 4Mhz */ | 38 #define XTAL_CPU 4000000 /* 4Mhz */ |
38 #define UART_BAUD_RATE 9600 /* 9600 baud */ | 39 #define UART_BAUD_RATE 19200 |
39 | 40 |
41 void uart_putsP(const char *addr); | |
42 void uart_puts(const char *addr); | |
43 int uart_putc(char c); | |
44 int uart_getc(void); | |
45 int beginswith_P(const char *s1, const char *s2); | |
46 | |
47 #if 0 | |
48 uint8_t PROGMEM ledvals[] = {0x01, 0x03, 0x07, 0x0e, 0x1c, 0x38, 0x70, 0xe0, 0xc0, 0x80}; | |
40 static uint8_t dir = 0; | 49 static uint8_t dir = 0; |
41 static volatile uint8_t leds = 0; | 50 static volatile uint8_t leds = 0; |
42 static uint8_t ledpos = 0; | 51 static uint8_t ledpos = 0; |
43 | |
44 void uart_putsP(const char *addr); | |
45 void uart_puts(const char *addr); | |
46 int uart_putc(char c); | |
47 uint8_t uart_getc(void); | |
48 | |
49 uint8_t PROGMEM ledvals[] = {0x01, 0x03, 0x07, 0x0e, 0x1c, 0x38, 0x70, 0xe0, 0xc0, 0x80}; | |
50 | 52 |
51 INTERRUPT(SIG_OVERFLOW0) { | 53 INTERRUPT(SIG_OVERFLOW0) { |
52 if (!leds) | 54 if (!leds) |
53 return; | 55 return; |
54 | 56 |
74 doleds: | 76 doleds: |
75 TCNT0 = 0; | 77 TCNT0 = 0; |
76 | 78 |
77 PORTA = pgm_read_byte(&ledvals[ledpos]); | 79 PORTA = pgm_read_byte(&ledvals[ledpos]); |
78 } | 80 } |
81 #endif | |
79 | 82 |
80 void | 83 void |
81 usleep(uint16_t usec) { | 84 usleep(uint16_t usec) { |
82 /* 4Mhz = 250ns per clock cycle */ | 85 /* 4Mhz = 250ns per clock cycle */ |
83 usec /= 2; | 86 usec /= 2; |
90 ::); | 93 ::); |
91 } | 94 } |
92 | 95 |
93 int | 96 int |
94 main(void) { | 97 main(void) { |
95 uint8_t ROM[8], count; | 98 uint8_t ROM[8]; |
96 char foo[40]; | 99 char cmdbuf[40]; |
97 int i; | 100 int i; |
98 | 101 |
99 cli(); | 102 cli(); |
103 #if 0 | |
100 outp(0xff, DDRA); | 104 outp(0xff, DDRA); |
105 | |
106 /* Timer Clock divisor - CK/1024 */ | |
107 outp(BV(CS00) | BV(CS02), TCCR0); | |
108 #endif | |
101 outp(0xfe, DDRC); | 109 outp(0xfe, DDRC); |
102 outp(0x00, PORTC); | 110 outp(0x00, PORTC); |
103 | 111 |
104 /* Init UART */ | 112 /* Init UART */ |
105 outp(UART_BAUD_SELECT(UART_BAUD_RATE,XTAL_CPU), UBRR); | 113 outp(UART_BAUD_SELECT(UART_BAUD_RATE,XTAL_CPU), UBRR); |
106 | 114 |
107 /* Enable receiver and transmitter. Turn on transmit interrupts */ | 115 /* Enable receiver and transmitter. Turn on transmit interrupts */ |
108 outp(BV(RXEN) | BV(TXEN), UCR); | 116 outp(BV(RXEN) | BV(TXEN), UCR); |
109 | 117 |
110 /* Timer Clock divisor - CK/1024 */ | 118 uart_putsP(PSTR("\n\r\n\r===============\n\r" |
111 outp(BV(CS00) | BV(CS02), TCCR0); | 119 "Inited!\n\r\n\r")); |
112 | 120 |
113 uart_putsP(PSTR("\n\r\n\r===============\n\r")); | |
114 uart_putsP(PSTR("Inited!\n\r\n\r")); | |
115 uart_putsP(PSTR("Test message 1\n\r")); | |
116 | |
117 count = 0; | |
118 while (1) { | 121 while (1) { |
119 char cmd; | 122 uart_putsP(PSTR("> ")); |
123 i = 0; | |
124 while (1) { | |
125 cmdbuf[i] = tolower(uart_getc()); | |
126 if (cmdbuf[i] == '\n' || cmdbuf[i] == '\r') | |
127 break; | |
128 | |
129 /* Backspace */ | |
130 if (cmdbuf[i] == 010) { | |
131 if (i > 0) { | |
132 uart_putsP(PSTR("\010\040\010")); | |
133 i--; | |
134 } | |
135 continue; | |
136 } | |
137 | |
138 /* Anything unprintable just ignore it */ | |
139 if (!isprint(cmdbuf[i])) | |
140 continue; | |
141 | |
142 uart_putc(cmdbuf[i]); | |
143 i++; | |
144 if (i == sizeof(cmdbuf)) { | |
145 uart_putsP(PSTR("\n\rLine too long\n\r")); | |
146 i = 0; | |
147 continue; | |
148 } | |
149 } | |
150 cmdbuf[i + 1] = '\0'; | |
151 uart_putsP(PSTR("\n\r")); | |
152 if (i == 0) | |
153 continue; | |
154 | |
155 if (cmdbuf[0] == '?') { | |
156 uart_putsP(PSTR("rs Reset and check for presence\n\r" | |
157 "re Read a bit\n\r" | |
158 "rb Read a byte\n\r" | |
159 "wr bit Write a bit\n\r" | |
160 "wb byte Write a byte (hex)\n\r" | |
161 "wc cmd [ROMID] Write command\n\r" | |
162 "te ROMID Read the temperature from a DS1820\n\r")); | |
163 continue; | |
164 } | |
120 | 165 |
121 cmd = uart_getc(); | 166 if (i < 2) |
122 switch (cmd) { | 167 goto badcmd; |
123 case 'r': | 168 |
124 uart_putsP(PSTR("Resetting... ")); | 169 if (cmdbuf[0] == 'r' && cmdbuf[1] == 's') { |
125 | 170 uart_putsP(PSTR("Resetting... ")); |
126 if (OWTouchReset() == 1) | 171 |
127 uart_putsP(PSTR("No presense\n\r")); | 172 if (OWTouchReset() == 1) |
128 else | 173 uart_putsP(PSTR("No presense\n\r")); |
129 uart_putsP(PSTR("Presense\n\r")); | 174 else |
130 break; | 175 uart_putsP(PSTR("Presense\n\r")); |
131 | 176 } else if (cmdbuf[0] == 'r' && cmdbuf[1] == 'e') { |
132 case 'R': | |
133 if (OWReadBit()) | 177 if (OWReadBit()) |
134 uart_putsP(PSTR("Read a 1\n\r")); | 178 uart_putsP(PSTR("Read a 1\n\r")); |
135 else | 179 else |
136 uart_putsP(PSTR("Read a 0\n\r")); | 180 uart_putsP(PSTR("Read a 0\n\r")); |
137 break; | 181 } else if (cmdbuf[0] == 'r' && cmdbuf[1] == 'b') { |
138 | 182 sprintf_P(cmdbuf, PSTR("Read a 0x%02x\n\r"), OWReadByte()); |
139 case 'w': | 183 uart_puts(cmdbuf); |
140 OWWriteBit(0); | 184 } else if (cmdbuf[0] == 'w' && cmdbuf[1] == 'r') { |
141 uart_putsP(PSTR("Wote a 0\n\r")); | 185 int arg; |
142 break; | 186 |
143 | 187 if (sscanf_P(cmdbuf + 3, PSTR("%d"), &arg) != 1) { |
144 case 'W': | 188 uart_putsP(PSTR("Unable to parse wr command\n\r")); |
145 OWWriteBit(1); | 189 continue; |
146 uart_putsP(PSTR("Wote a 1\n\r")); | 190 } |
147 break; | 191 |
148 | 192 OWWriteBit(arg); |
149 case 'd': | 193 sprintf_P(cmdbuf, PSTR("Wrote a %d\n\r"), arg); |
150 bzero(ROM, 8); | 194 uart_puts(cmdbuf); |
195 } else if (cmdbuf[0] == 'w' && cmdbuf[1] == 'b') { | |
196 int arg; | |
197 | |
198 if (sscanf_P(cmdbuf + 3, PSTR("%2x"), &arg) != 1) { | |
199 uart_putsP(PSTR("Unable to parse wb command\n\r")); | |
200 continue; | |
201 } | |
202 | |
203 OWWriteByte(arg); | |
204 sprintf_P(cmdbuf, PSTR("Wrote a 0x%02x\n\r"), arg); | |
205 uart_puts(cmdbuf); | |
206 } else if (cmdbuf[0] == 'w' && cmdbuf[1] == 'c') { | |
207 int arg; | |
208 | |
209 switch (sscanf_P(cmdbuf + 3, PSTR("%x %x:%x:%x:%x:%x:%x:%x:%x:%x"), &arg, | |
210 &ROM[0], &ROM[1], &ROM[2], &ROM[3], | |
211 &ROM[4], &ROM[5], &ROM[6], &ROM[7])) { | |
212 break; | |
213 | |
214 case 1: | |
215 OWSendCmd(NULL, arg); | |
216 sprintf_P(cmdbuf, PSTR("Sent 0x%02x to all ROMS\n\r"), arg); | |
217 uart_puts(cmdbuf); | |
218 break; | |
219 | |
220 case 9: | |
221 OWSendCmd(ROM, arg); | |
222 sprintf_P(cmdbuf, PSTR("Sent 0x%02x to ROM %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n\r"), | |
223 arg, ROM[0], ROM[1], ROM[2], ROM[3], | |
224 ROM[4], ROM[5], ROM[6], ROM[7]); | |
225 uart_puts(cmdbuf); | |
226 | |
227 break; | |
228 | |
229 case 0: | |
230 default: | |
231 uart_putsP(PSTR("Unable to parse wc command\n\r")); | |
232 break; | |
233 } | |
234 | |
235 OWWriteByte(arg); | |
236 sprintf_P(cmdbuf, PSTR("Wrote a 0x%02x\n\r"), arg); | |
237 uart_puts(cmdbuf); | |
238 } else if (cmdbuf[0] == 't' && cmdbuf[1] == 'e') { | |
239 uint8_t crc; | |
240 uint16_t temp; | |
241 uint8_t buf[9]; | |
242 | |
243 if (sscanf_P(cmdbuf + 3, PSTR("%x:%x:%x:%x:%x:%x:%x:%x:%x"), | |
244 &ROM[0], &ROM[1], &ROM[2], &ROM[3], | |
245 &ROM[4], &ROM[5], &ROM[6], &ROM[7]) != 8) { | |
246 uart_putsP(PSTR("Unable to parse ROM ID\n\r")); | |
247 continue; | |
248 } | |
249 | |
250 if (ROM[0] != OW_FAMILY_TEMP) { | |
251 uart_putsP(PSTR("ROM specified isn't a temperature sensor\n\r")); | |
252 continue; | |
253 } | |
254 | |
255 OWSendCmd(ROM, OW_CONVERTT_CMD); | |
256 #if OW_DEBUG | |
257 uart_putsP(PSTR("Command sent, waiting\n\r")); | |
258 #endif | |
259 i = 0; | |
260 while (OWReadBit() == 0) { | |
261 i++; | |
262 } | |
263 #if OW_DEBUG | |
264 sprintf_P(cmdbuf, PSTR("Temp comversion took %d cycles\n\r"), i); | |
265 uart_puts(cmdbuf); | |
266 #endif | |
267 OWSendCmd(ROM, OW_RD_SCR_CMD); | |
268 crc = 0; | |
269 for (i = 0; i < 9; i++) { | |
270 buf[i] = OWReadByte(); | |
271 if (i < 8) | |
272 OWCRC(buf[i], &crc); | |
273 } | |
274 | |
275 temp = buf[0]; | |
276 temp |= (uint16_t)buf[1] << 8; | |
277 temp <<= 3; | |
278 | |
279 if (crc != buf[8]) { | |
280 sprintf_P(cmdbuf, PSTR("CRC mismatch got %d vs calcd %d\n\r"), buf[8], crc); | |
281 uart_puts(cmdbuf); | |
282 continue; | |
283 } | |
284 | |
285 sprintf_P(cmdbuf, PSTR("temperature %d.%01d\n\r"), | |
286 temp >> 4, (temp << 12) / 6553); | |
287 uart_puts(cmdbuf); | |
288 } else if (cmdbuf[0] == 's' && cmdbuf[1] == 'r') { | |
289 memset(ROM, 0, 8); | |
151 if (OWTouchReset()) { | 290 if (OWTouchReset()) { |
152 uart_putsP(PSTR("No devices on bus\n\r")); | 291 uart_putsP(PSTR("No devices on bus\n\r")); |
153 break; | 292 break; |
154 } | 293 } |
155 if (OWFirst(ROM, 1, 0) == 0) { | 294 if (OWFirst(ROM, 1, 0) == 0) { |
156 uart_putsP(PSTR("No module found\n\r")); | 295 uart_putsP(PSTR("No module found\n\r")); |
157 break; | 296 break; |
158 } | 297 } |
159 do { | 298 do { |
160 uart_putsP(PSTR("Found a module ")); | 299 sprintf_P(cmdbuf, PSTR("%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n\r"), |
161 sprintf_P(foo, PSTR("%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x"), | |
162 ROM[0], | 300 ROM[0], |
163 ROM[1], | 301 ROM[1], |
164 ROM[2], | 302 ROM[2], |
165 ROM[3], | 303 ROM[3], |
166 ROM[4], | 304 ROM[4], |
167 ROM[5], | 305 ROM[5], |
168 ROM[6], | 306 ROM[6], |
169 ROM[7]); | 307 ROM[7]); |
170 uart_puts(foo); | 308 uart_puts(cmdbuf); |
171 if (ROM[0] == OW_FAMILY_TEMP) { | |
172 uint8_t tempbuf[9]; | |
173 uint8_t crc; | |
174 uint16_t temp; | |
175 | |
176 uart_putsP(PSTR(" is a temp sensor\n\r")); | |
177 OWSendCmd(ROM, OW_CONVERTT_CMD); | |
178 #if OW_DEBUG | |
179 uart_putsP(PSTR("Command sent, waiting\n\r")); | |
180 #endif | |
181 i = 0; | |
182 while (OWReadBit() == 0) { | |
183 i++; | |
184 } | |
185 #if OW_DEBUG | |
186 sprintf_P(foo, PSTR("Temp comversion took %d cycles\n\r"), i); | |
187 uart_puts(foo); | |
188 #endif | |
189 OWSendCmd(ROM, OW_RD_SCR_CMD); | |
190 crc = 0; | |
191 for (i = 0; i < 9; i++) { | |
192 tempbuf[i] = OWReadByte(); | |
193 if (i < 8) | |
194 OWCRC(tempbuf[i], &crc); | |
195 } | |
196 | |
197 temp = tempbuf[0]; | |
198 temp |= (uint16_t)tempbuf[1] << 8; | |
199 temp <<= 3; | |
200 | |
201 if (crc != tempbuf[9]) { | |
202 sprintf_P(foo, PSTR("CRC mismatch got %d vs calcd %d\n\r"), tempbuf[9], crc); | |
203 uart_puts(foo); | |
204 } | |
205 | |
206 sprintf_P(foo, PSTR("temperature %d.%01d\n\r"), | |
207 temp >> 4, (temp << 12) / 6553); | |
208 uart_puts(foo); | |
209 } | |
210 | |
211 if (ROM[0] == OW_FAMILY_ROM) { | |
212 uart_putsP(PSTR(" is a ROM\n\r")); | |
213 } | |
214 } while (OWNext(ROM, 1, 0)); | 309 } while (OWNext(ROM, 1, 0)); |
215 break; | 310 #if 0 |
216 | 311 |
217 case 'l': | 312 } else if (cmdbuf[0] == 'l' && cmdbuf[1] == 'e' && cmdbuf[2] == 'd') { |
218 if (leds == 0) { | 313 if (leds == 0) { |
219 leds = 1; | 314 leds = 1; |
220 ledpos = 0; | 315 ledpos = 0; |
221 outp(0, TCNT0); | 316 outp(0, TCNT0); |
222 sbi(TIMSK, TOIE0); | 317 sbi(TIMSK, TOIE0); |
228 PORTA = 0x00; | 323 PORTA = 0x00; |
229 cbi(TIMSK, TOIE0); | 324 cbi(TIMSK, TOIE0); |
230 cli(); | 325 cli(); |
231 uart_putsP(PSTR("Stopping\n\r")); | 326 uart_putsP(PSTR("Stopping\n\r")); |
232 } | 327 } |
233 | 328 #endif |
234 break; | 329 } else { |
235 | 330 badcmd: |
236 default: | 331 uart_putsP(PSTR("Unknown command, ? for a list\n\r")); |
237 uart_putsP(PSTR("Unknown command\n\r")); | |
238 break; | |
239 } | 332 } |
240 | 333 |
241 } | 334 } |
242 | 335 |
243 return(0); | 336 return(0); |
263 uart_puts(const char *addr) { | 356 uart_puts(const char *addr) { |
264 while (*addr) | 357 while (*addr) |
265 uart_putc(*addr++); | 358 uart_putc(*addr++); |
266 } | 359 } |
267 | 360 |
268 uint8_t | 361 int |
269 uart_getc(void) { | 362 uart_getc(void) { |
270 while (!(inp(USR) & 0x80)) | 363 while (!(inp(USR) & 0x80)) |
271 ; | 364 ; |
272 | 365 |
273 return (inp(UDR)); | 366 return (inp(UDR)); |
274 } | 367 } |
368 |