comparison testavr.c @ 24:2b0ed085b95b

- Change to 38400 baud. - Change to ATMega32 - Use interrupt driven serial comms (for rx anyway) - Reformat.
author darius
date Mon, 12 Dec 2005 23:37:16 +1030
parents 108a703c39e6
children 48056516b3eb
comparison
equal deleted inserted replaced
23:845934a4e7fe 24:2b0ed085b95b
32 #include <avr/interrupt.h> 32 #include <avr/interrupt.h>
33 #include <avr/pgmspace.h> 33 #include <avr/pgmspace.h>
34 #include <string.h> 34 #include <string.h>
35 #include <ctype.h> 35 #include <ctype.h>
36 #include <stdlib.h> 36 #include <stdlib.h>
37 #include <util/delay.h>
37 38
38 #include "1wire.h" 39 #include "1wire.h"
40 #include "usb.h"
39 41
40 #define UART_BAUD_SELECT(baudRate,xtalCpu) ((xtalCpu)/((baudRate)*16l)-1) 42 #define UART_BAUD_SELECT(baudRate,xtalCpu) ((xtalCpu)/((baudRate)*16l)-1)
41 #define UART_BAUD_RATE 19200 43 #define UART_BAUD_RATE 38400
44
45 void process_cmd(void);
42 46
43 void uart_putsP(const char *addr); 47 void uart_putsP(const char *addr);
44 void uart_puts(const char *addr); 48 void uart_puts(const char *addr);
45 int uart_putc(char c); 49 int uart_putc(char c);
46 int uart_getc(void);
47 void uart_puts_dec(uint8_t a, uint8_t l); 50 void uart_puts_dec(uint8_t a, uint8_t l);
48 void uart_puts_hex(uint8_t a); 51 void uart_puts_hex(uint8_t a);
49 52 char uart_getc(void);
53
54 /* Receive buffer storage */
55 volatile struct {
56 char buf[40];
57 uint8_t state;
58 uint8_t len;
59 } cmd = {
60 .state = 255,
61 .len = 0
62 };
63
64 /* Rx complete */
65 ISR(USART_RXC_vect) {
66 volatile char pit;
67 char c;
68
69 while (UCSRA & _BV(RXC)) {
70 /* 255 means we're waiting for main to process the command,
71 just throw stuff away
72 */
73 if (cmd.state == 255) {
74 pit = UDR;
75 continue;
76 }
77 c = UDR;
78
79 /* End of line? */
80 if (c == '\n' || c == '\r') {
81 cmd.buf[cmd.state + 1] = '\0';
82 uart_putsP(PSTR("\n\r"));
83 cmd.len = cmd.state;
84 cmd.state = 255;
85 continue;
86 }
87
88 /* Backspace/delete */
89 if (c == 0x08 || c == 0x7f) {
90 if (cmd.state > 0) {
91 cmd.state--;
92 uart_putsP(PSTR("\010\040\010"));
93 }
94 continue;
95 }
96
97 /* Anything unprintable just ignore it */
98 if (!isprint(c))
99 continue;
100
101 cmd.buf[cmd.state] = tolower(c);
102
103 /* Echo back to the user */
104 uart_putc(cmd.buf[cmd.state]);
105
106 cmd.state++;
107 /* Over flow? */
108 if (cmd.state == ((sizeof(cmd.buf) / sizeof(cmd.buf[0])) - 1)) {
109 uart_putsP(PSTR("\n\rLine too long"));
110 cmd.state = 0;
111 continue;
112 }
113 }
114 }
115
116 /* Tx complete */
117 ISR(USART_TXC_vect) {
118
119 }
120
50 int 121 int
51 main(void) { 122 main(void) {
123 /* Disable interrupts while we frob stuff */
124 cli();
125
126 /* Disable JTAG (yes twice) */
127 MCUCSR |= _BV(JTD);
128 MCUCSR |= _BV(JTD);
129
130 /* USB data bus (7:0) */
131 DDRA = 0x00;
132 PORTA = 0x00;
133
134 /* USB control (3:0) */
135 DDRB = 0x0e;
136 PORTB = 0x00;
137
138 /* GPIO (0:7) */
139 DDRC = 0xff;
140 PORTC = 0x00;
141
142 /* GPIO (2:7) */
143 DDRD = 0xfc;
144 PORTD = 0x00;
145
146 /* Init UART */
147 UBRRH = UART_BAUD_SELECT(UART_BAUD_RATE, F_CPU) >> 8;
148 UBRRL = (uint8_t)UART_BAUD_SELECT(UART_BAUD_RATE, F_CPU);
149
150 /* Enable receiver and transmitter. Turn on transmit interrupts */
151 UCSRA = 0;
152 UCSRB = _BV(RXEN) | _BV(TXEN) | _BV(RXCIE);
153 UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0);
154 uart_putsP(PSTR("\n\r\n\r===============\n\r"
155 "Inited!\n\r\n\r"));
156
157 /* Ready to go! */
158 sei();
159
160 usb_init();
161 _delay_us(1000);
162
163 uart_putsP(PSTR("> "));
164 cmd.state = 0;
165
166 /* Wait for user input or an "interrupt" */
167 while (1) {
168 if (cmd.state == 255) {
169 process_cmd();
170 uart_putsP(PSTR("> "));
171 /* Allow new characters to be processed */
172 cmd.state = 0;
173 }
174
175 if (!(PINB & _BV(PB0)))
176 usb_intr();
177 }
178 }
179
180 void
181 process_cmd(void) {
52 uint8_t ROM[8]; 182 uint8_t ROM[8];
53 char cmdbuf[40];
54 int8_t i, arg; 183 int8_t i, arg;
55 uint8_t crc, buf[9];; 184 uint8_t crc, buf[9];
56 int8_t temp; 185 int8_t temp;
57 uint16_t tfrac; 186 uint16_t tfrac;
58 187
59 cli(); 188 /* User just pressed enter */
60 189 if (cmd.len == 0)
61 DDRC = 0xfc; 190 return;
62 PORTC = 0x00; 191
63 DDRA = 0xff; 192 if (cmd.buf[0] == '?') {
64 193 uart_putsP(PSTR("rs Reset and check for presence\n\r"
65 /* Init UART */ 194 "sr Search the bus for ROMs\n\r"
66 UBRR = UART_BAUD_SELECT(UART_BAUD_RATE,XTAL_CPU); 195 "re Read a bit\n\r"
67 196 "rb Read a byte\n\r"
68 /* Enable receiver and transmitter. Turn on transmit interrupts */ 197 "wr bit Write a bit\n\r"
69 UCR = _BV(RXEN) | _BV(TXEN); 198 "wb byte Write a byte (hex)\n\r"
70 199 "wc cmd [ROMID] Write command\n\r"
71 uart_putsP(PSTR("\n\r\n\r===============\n\r" 200 "te ROMID Read the temperature from a DS1820\n\r"
72 "Inited!\n\r\n\r")); 201 "in port Read from a port\n\r"
73 202 "out port val Write to a port\n\r"
74 while (1) { 203 "ddr port [val] Read/write DDR for a port\n\r"));
75 uart_putsP(PSTR("> ")); 204
205 return;
206 }
207
208 i = strlen((char *)cmd.buf);
209 if (cmd.len < 2)
210 goto badcmd;
211
212 if (cmd.buf[0] == 'r' && cmd.buf[1] == 's') {
213 uart_putsP(PSTR("Resetting... "));
214
215 if (OWTouchReset() == 1)
216 uart_putsP(PSTR("No presence pulse found\n\r"));
217 else
218 uart_putsP(PSTR("Presence pulse found\n\r"));
219 } else if (cmd.buf[0] == 'r' && cmd.buf[1] == 'e') {
220 if (OWReadBit())
221 uart_putsP(PSTR("Read a 1\n\r"));
222 else
223 uart_putsP(PSTR("Read a 0\n\r"));
224 } else if (cmd.buf[0] == 'r' && cmd.buf[1] == 'b') {
225 uart_putsP(PSTR("Read a 0x"));
226 uart_puts_hex(OWReadByte());
227 uart_putsP(PSTR("\n\r"));
228 } else if (cmd.buf[0] == 'w' && cmd.buf[1] == 'r') {
229 arg = strtol((char *)cmd.buf + 3, (char **)NULL, 10);
230 OWWriteBit(arg);
231 uart_putsP(PSTR("Wrote a "));
232 if (arg)
233 uart_putsP(PSTR("1\n\r"));
234 else
235 uart_putsP(PSTR("0\n\r"));
236 } else if (cmd.buf[0] == 'w' && cmd.buf[1] == 'b') {
237 arg = (int)strtol((char *)cmd.buf + 3, (char **)NULL, 16);
238 OWWriteByte(arg);
239 } else if (cmd.buf[0] == 'w' && cmd.buf[1] == 'c') {
240 if (cmd.len < 5) {
241 uart_putsP(PSTR("No arguments\n\r"));
242 return;
243 }
244
245 arg = (int)strtol((char *)cmd.buf + 3, (char **)NULL, 16);
246 if (arg == 0) {
247 uart_putsP(PSTR("Unparseable command\n\r"));
248 return;
249 }
250
251 if (i == 5) {
252 OWSendCmd(NULL, arg);
253 return;
254 }
255
256 if (i < 29) {
257 uart_putsP(PSTR("Can't parse ROM ID\n\r"));
258 return;
259 }
260 for (i = 0; i < 8; i++)
261 ROM[i] = (int)strtol((char *)cmd.buf + 6 + (3 * i), (char **)NULL, 16);
262
263 OWSendCmd(ROM, arg);
264 } else if (cmd.buf[0] == 't' && cmd.buf[1] == 'e') {
265 if (cmd.len < 26) {
266 uart_putsP(PSTR("Unable to parse ROM ID\n\r"));
267 return;
268 }
269
270 for (i = 0; i < 8; i++)
271 ROM[i] = (int)strtol((char *)cmd.buf + 3 * (i + 1), (char **)NULL, 16);
272
273 if (ROM[0] != OW_FAMILY_TEMP) {
274 uart_putsP(PSTR("ROM specified isn't a temperature sensor\n\r"));
275 return;
276 }
277
278 OWSendCmd(ROM, OW_CONVERTT_CMD);
76 i = 0; 279 i = 0;
77 while (1) { 280 while (OWReadBit() == 0) {
78 cmdbuf[i] = tolower(uart_getc());
79 if (cmdbuf[i] == '\n' || cmdbuf[i] == '\r')
80 break;
81
82 /* Backspace/Delete */
83 if (cmdbuf[i] == 0x08) {
84 if (i > 0) {
85 uart_putsP(PSTR("\010\040\010"));
86 i--;
87 }
88 continue;
89 }
90
91 /* Anything unprintable just ignore it */
92 if (!isprint(cmdbuf[i]))
93 continue;
94
95 uart_putc(cmdbuf[i]);
96 i++; 281 i++;
97 if (i == sizeof(cmdbuf)) { 282 }
98 uart_putsP(PSTR("\n\rLine too long")); 283 OWSendCmd(ROM, OW_RD_SCR_CMD);
99 i = 0; 284 crc = 0;
100 break; 285 for (i = 0; i < 9; i++) {
101 } 286 buf[i] = OWReadByte();
102 } 287 if (i < 8)
103 cmdbuf[i + 1] = '\0'; 288 OWCRC(buf[i], &crc);
289 }
290
291 if (crc != buf[8]) {
292 uart_putsP(PSTR("CRC mismatch\n\r"));
293 return;
294 }
295
296 #if 0
297 uart_putsP(PSTR("temperature "));
298 uart_puts_dec(temp >> 4, 0);
299 uart_putsP(PSTR("."));
300 uart_puts_dec((temp << 12) / 6553, 0);
104 uart_putsP(PSTR("\n\r")); 301 uart_putsP(PSTR("\n\r"));
105 if (i == 0) 302 #else
106 continue; 303 /* 0 Temperature LSB
107 304 * 1 Temperature MSB
108 if (cmdbuf[0] == '?') { 305 * 2 Th
109 uart_putsP(PSTR("rs Reset and check for presence\n\r" 306 * 3 Tl
110 "sr Search the bus for ROMs\n\r" 307 * 4 Reserved
111 "re Read a bit\n\r" 308 * 5 Reserved
112 "rb Read a byte\n\r" 309 * 6 Count Remain
113 "wr bit Write a bit\n\r" 310 * 7 Count per C
114 "wb byte Write a byte (hex)\n\r" 311 * 8 CRC
115 "wc cmd [ROMID] Write command\n\r" 312 */
116 "te ROMID Read the temperature from a DS1820\n\r" 313 #if 0
117 "le byte Set the LED port\n\r")); 314 for (i = 0; i < 9; i++) {
118 315 uart_puts_dec(buf[i], 0);
119 continue;
120 }
121
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)
129 uart_putsP(PSTR("No presence pulse found\n\r"));
130 else
131 uart_putsP(PSTR("Presence pulse found\n\r"));
132 } else if (cmdbuf[0] == 'r' && cmdbuf[1] == 'e') {
133 if (OWReadBit())
134 uart_putsP(PSTR("Read a 1\n\r"));
135 else
136 uart_putsP(PSTR("Read a 0\n\r"));
137 } else if (cmdbuf[0] == 'r' && cmdbuf[1] == 'b') {
138 uart_putsP(PSTR("Read a 0x"));
139 uart_puts_hex(OWReadByte());
140 uart_putsP(PSTR("\n\r")); 316 uart_putsP(PSTR("\n\r"));
141 } else if (cmdbuf[0] == 'w' && cmdbuf[1] == 'r') { 317 }
142 arg = strtol(cmdbuf + 3, (char **)NULL, 10);
143 OWWriteBit(arg);
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"));
149 } else if (cmdbuf[0] == 'w' && cmdbuf[1] == 'b') {
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"));
156 continue;
157 }
158
159 arg = (int)strtol(cmdbuf + 3, (char **)NULL, 16);
160 if (arg == 0) {
161 uart_putsP(PSTR("Unparseable command\n\r"));
162 continue;
163 }
164
165 if (i == 5) {
166 OWSendCmd(NULL, arg);
167 continue;
168 }
169
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);
178 } else if (cmdbuf[0] == 't' && cmdbuf[1] == 'e') {
179 if (strlen(cmdbuf) < 26) {
180 uart_putsP(PSTR("Unable to parse ROM ID\n\r"));
181 continue;
182 }
183
184 for (i = 0; i < 8; i++)
185 ROM[i] = (int)strtol(cmdbuf + 3 * (i + 1), (char **)NULL, 16);
186
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]) {
206 uart_putsP(PSTR("CRC mismatch\n\r"));
207 continue;
208 }
209
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 318 #endif
233 temp = buf[0]; 319 temp = buf[0];
234 if (buf[0] & 0x01) 320 if (buf[1] & 0x80)
235 temp -= 256; 321 temp -= 256;
236 temp >>= 1; 322 temp >>= 1;
237 323
238 tfrac = buf[7] - buf[6]; 324 tfrac = buf[7] - buf[6];
239 tfrac *= (uint16_t)100; 325 tfrac *= (uint16_t)100;
240 tfrac /= buf[7]; 326 tfrac /= buf[7];
241 tfrac += 75; 327 tfrac += 75;
242 if (tfrac < 100) { 328 if (tfrac < 100) {
243 temp--; 329 temp--;
244 } else { 330 } else {
245 tfrac -= 100; 331 tfrac -= 100;
246 } 332 }
247 333
248 if (temp < 0){ 334 if (temp < 0){
249 uart_putc('-'); 335 uart_putc('-');
250 uart_puts_dec(-temp, 0); 336 uart_puts_dec(-temp, 0);
251 } else 337 } else
252 uart_puts_dec(temp, 0); 338 uart_puts_dec(temp, 0);
253 uart_putsP(PSTR(".")); 339 uart_putsP(PSTR("."));
254 uart_puts_dec(tfrac, 1); 340 uart_puts_dec(tfrac, 1);
255 uart_putsP(PSTR("\n\r")); 341 uart_putsP(PSTR("\n\r"));
256 342
257 #endif 343 #endif
258 } else if (cmdbuf[0] == 's' && cmdbuf[1] == 'r') { 344 } else if (cmd.buf[0] == 's' && cmd.buf[1] == 'r') {
259 memset(ROM, 0, 8); 345 memset(ROM, 0, 8);
260 346
261 i = OWFirst(ROM, 1, 0); 347 i = OWFirst(ROM, 1, 0);
262 do { 348 do {
263 switch (i) { 349 switch (i) {
264 case OW_BADWIRE: 350 case OW_BADWIRE:
265 uart_putsP(PSTR("Presence pulse, but no module found, bad module/cabling?\n\r")); 351 uart_putsP(PSTR("Presence pulse, but no module found, bad module/cabling?\n\r"));
266 break; 352 break;
267 353
268 case OW_NOPRESENCE: 354 case OW_NOPRESENCE:
278 break; 364 break;
279 365
280 default: 366 default:
281 uart_putsP(PSTR("Unknown error from 1 wire library\n\r")); 367 uart_putsP(PSTR("Unknown error from 1 wire library\n\r"));
282 break; 368 break;
283 } 369 }
284 370
285 if (i != OW_FOUND) 371 if (i != OW_FOUND)
286 break; 372 break;
287 373
288 for (i = 0; i < 7; i++) { 374 for (i = 0; i < 7; i++) {
289 uart_puts_hex(ROM[i]); 375 uart_puts_hex(ROM[i]);
290 uart_putc(':'); 376 uart_putc(':');
291 } 377 }
292 uart_puts_hex(ROM[7]); 378 uart_puts_hex(ROM[7]);
293 uart_putsP(PSTR("\n\r"));
294
295 i = OWNext(ROM, 1, 0);
296 } while (1);
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")); 379 uart_putsP(PSTR("\n\r"));
304 #endif 380
305 } else { 381 i = OWNext(ROM, 1, 0);
306 badcmd: 382 } while (1);
307 uart_putsP(PSTR("Unknown command, ? for a list\n\r")); 383 } else if (cmd.buf[0] == 'i' && cmd.buf[1] == 'n') {
308 } 384 switch (tolower(cmd.buf[3])) {
309 385 case 'a':
386 crc = PINA;
387 break;
388
389 case 'b':
390 crc = PINB;
391 break;
392
393 case 'c':
394 crc = PINC;
395 break;
396
397 case 'd':
398 crc = PIND;
399 break;
400
401 default:
402 uart_putsP(PSTR("Unknown port\n\r"));
403 return;
404 }
405 uart_putsP(PSTR("0x"));
406 uart_puts_hex(crc);
407 uart_putsP(PSTR("\n\r"));
408 } else if (cmd.buf[0] == 'o' && cmd.buf[1] == 'u') {
409 crc = strtol((char *)cmd.buf + 8, (char **)NULL, 16);
410 switch (tolower(cmd.buf[4])) {
411 case 'a':
412 PORTA = crc;
413 break;
414
415 case 'b':
416 PORTB = crc;
417 break;
418
419 case 'c':
420 PORTC = crc;
421 break;
422
423 case 'd':
424 PORTD = crc;
425 break;
426
427 default:
428 uart_putsP(PSTR("Unknown port\n\r"));
429 return;
430 }
431 uart_putsP(PSTR("0x"));
432 uart_puts_hex(crc);
433 uart_putsP(PSTR("\n\r"));
434 } else if (cmd.buf[0] == 'u' && cmd.buf[1] == 's') {
435 usb_gendata();
436 } else {
437 badcmd:
438 uart_putsP(PSTR("Unknown command, ? for a list\n\r"));
310 } 439 }
311 440 }
312 return(0); 441
313 }
314
315 int 442 int
316 uart_putc(char c) { 443 uart_putc(char c) {
317 loop_until_bit_is_set(USR, UDRE); 444 loop_until_bit_is_set(UCSRA, UDRE);
318 UDR = c; 445 UDR = c;
319 446
320 return(0); 447 return(0);
321 } 448 }
322 449
351 uart_putc('0'); 478 uart_putc('0');
352 479
353 uart_puts(utoa(a, s, 16)); 480 uart_puts(utoa(a, s, 16));
354 } 481 }
355 482
356 int 483 char
357 uart_getc(void) { 484 uart_getc(void) {
358 while (!USR & 0x80) 485 while (!(UCSRA & _BV(RXC)))
359 ; 486 ;
360 487
361 return (UDR); 488 return (UDR);
362 } 489 }
363 490