Mercurial > ~darius > hgwebdir.cgi > avr
view testavr.c @ 39:599d013ce3f2
Use parallel programmer.
author | darius |
---|---|
date | Fri, 23 Nov 2007 12:02:22 +1030 |
parents | 0a148f362097 |
children | 5898fba6593c |
line wrap: on
line source
/* * Test various AVR bits and pieces * * $Id$ * * Copyright (c) 2004 * Daniel O'Connor <darius@dons.net.au>. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include <avr/io.h> #include <avr/interrupt.h> #include <avr/pgmspace.h> #include <string.h> #include <ctype.h> #include <stdlib.h> #include <util/delay.h> #include "1wire.h" #ifdef WITHUSB #include "usb.h" #endif #define UART_BAUD_SELECT(baudRate,xtalCpu) ((xtalCpu)/((baudRate)*16l)-1) #define UART_BAUD_RATE 38400 void process_cmd(void); void uart_putsP(const char *addr); void uart_puts(const char *addr); int uart_putc(char c); void uart_puts_dec(uint8_t a, uint8_t l); void uart_puts_hex(uint8_t a); char uart_getc(void); /* Receive buffer storage */ volatile struct { char buf[40]; uint8_t state; uint8_t len; } cmd = { .state = 255, .len = 0 }; /* Rx complete */ ISR(USART_RXC_vect) { volatile char pit; char c; while (UCSRA & _BV(RXC)) { /* 255 means we're waiting for main to process the command, just throw stuff away */ if (cmd.state == 255) { pit = UDR; continue; } c = UDR; /* End of line? */ if (c == '\n' || c == '\r') { cmd.buf[cmd.state + 1] = '\0'; uart_putsP(PSTR("\r\n")); cmd.len = cmd.state; cmd.state = 255; continue; } /* Backspace/delete */ if (c == 0x08 || c == 0x7f) { if (cmd.state > 0) { cmd.state--; uart_putsP(PSTR("\010\040\010")); } continue; } /* Anything unprintable just ignore it */ if (!isprint(c)) continue; cmd.buf[cmd.state] = tolower(c); /* Echo back to the user */ uart_putc(cmd.buf[cmd.state]); cmd.state++; /* Over flow? */ if (cmd.state == ((sizeof(cmd.buf) / sizeof(cmd.buf[0])) - 1)) { uart_putsP(PSTR("\r\nLine too long")); cmd.state = 0; continue; } } } /* Tx complete */ ISR(USART_TXC_vect) { } int main(void) { /* Disable interrupts while we frob stuff */ cli(); #if 1 /* Disable JTAG (yes twice) */ MCUCSR |= _BV(JTD); MCUCSR |= _BV(JTD); #endif #ifdef WITHUSB /* USB data bus (7:0) */ DDRA = 0x00; PORTA = 0x00; /* USB control (4:0) */ DDRB = 0x0d; PORTB = 0x00; #else DDRA = 0xff; PORTA = 0x00; #endif /* GPIO (0:7) */ DDRC = 0xff; PORTC = 0x00; /* USART (0:1), IDBus (2:5), 485 (6:6), GPIO (7:7) */ DDRD = 0xf7; PORTD = 0xf7; /* Set up the one wire stuff */ OWInit(); /* Init UART */ UBRRH = UART_BAUD_SELECT(UART_BAUD_RATE, F_CPU) >> 8; UBRRL = (uint8_t)UART_BAUD_SELECT(UART_BAUD_RATE, F_CPU); /* Enable receiver and transmitter. Turn on transmit interrupts */ UCSRA = 0; UCSRB = _BV(RXEN) | _BV(TXEN) | _BV(RXCIE); UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0); uart_putsP(PSTR("\r\n\r\n===============\r\n" "Inited!\r\n\r\n")); /* Ready to go! */ sei(); #if 0 DDRA = 0xff; DDRC = 0xff; while (1) { uart_putsP(PSTR("1\r\n")); PORTA = 0xff; uart_putsP(PSTR("2\r\n")); PORTC = 0x00; uart_putsP(PSTR("3\r\n")); _delay_us(1); uart_putsP(PSTR("4\r\n")); PORTA = 0x80; uart_putsP(PSTR("5\r\n")); PORTC = 0xff; uart_putsP(PSTR("6\r\n")); } #endif #ifdef WITHUSB uart_putsP(PSTR("Calling usb_init\r\n")); usb_init(); #endif uart_putsP(PSTR("done\r\n")); _delay_us(1000); uart_putsP(PSTR("> ")); cmd.state = 0; /* Wait for user input or an "interrupt" */ while (1) { if (cmd.state == 255) { process_cmd(); uart_putsP(PSTR("> ")); /* Allow new characters to be processed */ cmd.state = 0; } #ifdef WITHUSB if (!(PDICTL & _BV(PDIINT))) usb_intr(); #endif } } void process_cmd(void) { uint8_t ROM[8]; int8_t i, arg; uint8_t crc, buf[9]; int8_t temp; uint16_t tfrac; /* User just pressed enter */ if (cmd.len == 0) return; if (cmd.buf[0] == '?') { uart_putsP(PSTR("rs Reset and check for presence\r\n" "sr Search the bus for ROMs\r\n" "re Read a bit\r\n" "rb Read a byte\r\n" "wr bit Write a bit\r\n" "wb byte Write a byte (hex)\r\n" "wc cmd [ROMID] Write command\r\n" "te ROMID Read the temperature from a DS1820\r\n" "in port Read from a port\r\n" "out port val Write to a port\r\n" "ddr port [val] Read/write DDR for a port\r\n")); return; } i = strlen((char *)cmd.buf); if (cmd.len < 2) goto badcmd; if (cmd.buf[0] == 'r' && cmd.buf[1] == 's') { uart_putsP(PSTR("Resetting... ")); if (OWTouchReset() == 1) uart_putsP(PSTR("No presence pulse found\r\n")); else uart_putsP(PSTR("Presence pulse found\r\n")); } else if (cmd.buf[0] == 'r' && cmd.buf[1] == 'e') { if (OWReadBit()) uart_putsP(PSTR("Read a 1\r\n")); else uart_putsP(PSTR("Read a 0\r\n")); } else if (cmd.buf[0] == 'r' && cmd.buf[1] == 'b') { uart_putsP(PSTR("Read a 0x")); uart_puts_hex(OWReadByte()); uart_putsP(PSTR("\r\n")); } else if (cmd.buf[0] == 'w' && cmd.buf[1] == 'r') { arg = strtol((char *)cmd.buf + 3, (char **)NULL, 10); OWWriteBit(arg); uart_putsP(PSTR("Wrote a ")); if (arg) uart_putsP(PSTR("1\r\n")); else uart_putsP(PSTR("0\r\n")); } else if (cmd.buf[0] == 'w' && cmd.buf[1] == 'b') { arg = (int)strtol((char *)cmd.buf + 3, (char **)NULL, 16); OWWriteByte(arg); } else if (cmd.buf[0] == 'r' && cmd.buf[1] == 't') { if (cmd.len < 26) { uart_putsP(PSTR("Unable to parse ROM ID\r\n")); return; } if (OWTouchReset() != 0) { uart_putsP(PSTR("No presence\r\n")); return; } for (i = 0; i < 8; i++) ROM[i] = (int)strtol((char *)cmd.buf + 3 * (i + 1), (char **)NULL, 16); if (ROM[0] != OW_FAMILY_ROM) { uart_putsP(PSTR("ROM specified isn't a DS2502\r\n")); return; } if (OWTouchReset() != 0) { uart_putsP(PSTR("No presence\r\n")); return; } crc = 0; OWCRC(OW_READ_STATUS, &crc); OWSendCmd(ROM, OW_READ_STATUS); OWWriteByte(0x00); OWCRC(0x00, &crc); OWWriteByte(0x00); OWCRC(0x00, &crc); if (crc != OWReadByte()) { uart_putsP(PSTR("CRC mismatch on command & address\r\n")); return; } crc = 0; for (i = 0; i < 8; i++) { temp = OWReadByte(); uart_puts_hex(temp); OWCRC(temp, &crc); uart_putsP(PSTR(" ")); } uart_putsP(PSTR("\r\n")); if (crc != OWReadByte()) { uart_putsP(PSTR("CRC mismatch on data\r\n")); return; } } else if (cmd.buf[0] == 'w' && cmd.buf[1] == 'e') { if (cmd.len < 26) { uart_putsP(PSTR("Unable to parse ROM ID\r\n")); return; } for (i = 0; i < 8; i++) ROM[i] = (int)strtol((char *)cmd.buf + 3 * (i + 1), (char **)NULL, 16); if (ROM[0] != OW_FAMILY_ROM) { uart_putsP(PSTR("ROM specified isn't a ROM\r\n")); return; } buf[0] = (int)strtol((char *)cmd.buf + 27, (char **)NULL, 16); /* Address */ buf[1] = (int)strtol((char *)cmd.buf + 30, (char **)NULL, 16); /* Data .. */ buf[2] = (int)strtol((char *)cmd.buf + 33, (char **)NULL, 16); if (OWTouchReset() != 0) { uart_putsP(PSTR("No presence\r\n")); return; } i = OWProgROM(ROM, buf[0], 2, &buf[1], 0, 0); uart_putsP(PSTR("OWProgROM returned ")); uart_puts_dec(i, 0); uart_putsP(PSTR("\r\n")); } else if (cmd.buf[0] == 'r' && cmd.buf[1] == 'r') { if (cmd.len < 26) { uart_putsP(PSTR("Unable to parse ROM ID\r\n")); return; } for (i = 0; i < 8; i++) ROM[i] = (int)strtol((char *)cmd.buf + 3 * (i + 1), (char **)NULL, 16); if (ROM[0] != OW_FAMILY_ROM) { uart_putsP(PSTR("ROM specified isn't a ROM\r\n")); return; } crc = 0; OWSendCmd(ROM, OW_READ_MEMORY); OWCRC(OW_READ_MEMORY, &crc); OWWriteByte(0x00); OWCRC(0x00, &crc); OWWriteByte(0x00); OWCRC(0x00, &crc); if (crc != OWReadByte()) { uart_putsP(PSTR("CRC mismatch on command & address\r\n")); return; } crc = 0; for (buf[0] = 0; buf[0] < 128; buf[0]++) { buf[1] = OWReadByte(); if (buf[0] > 0) { if (buf[0] % 16 != 0) uart_putsP(PSTR(" ")); else uart_putsP(PSTR("\r\n")); } uart_puts_hex(buf[1]); OWCRC(buf[1], &crc); } uart_putsP(PSTR("\r\n")); if (crc != OWReadByte()) { uart_putsP(PSTR("CRC mismatch on data\r\n")); return; } } else if (cmd.buf[0] == 'w' && cmd.buf[1] == 'c') { if (cmd.len < 5) { uart_putsP(PSTR("No arguments\r\n")); return; } arg = (int)strtol((char *)cmd.buf + 3, (char **)NULL, 16); if (arg == 0) { uart_putsP(PSTR("Unparseable command\r\n")); return; } if (i == 5) { OWSendCmd(NULL, arg); return; } if (i < 29) { uart_putsP(PSTR("Can't parse ROM ID\r\n")); return; } for (i = 0; i < 8; i++) ROM[i] = (int)strtol((char *)cmd.buf + 6 + (3 * i), (char **)NULL, 16); OWSendCmd(ROM, arg); } else if (cmd.buf[0] == 't' && cmd.buf[1] == 'e') { if (cmd.len < 26) { uart_putsP(PSTR("Unable to parse ROM ID\r\n")); return; } for (i = 0; i < 8; i++) ROM[i] = (int)strtol((char *)cmd.buf + 3 * (i + 1), (char **)NULL, 16); if (ROM[0] != OW_FAMILY_TEMP) { uart_putsP(PSTR("ROM specified isn't a temperature sensor\r\n")); return; } OWSendCmd(ROM, OW_CONVERTT_CMD); i = 0; /* Wait for the conversion */ while (OWReadBit() == 0) { i++; } OWSendCmd(ROM, OW_RD_SCR_CMD); crc = 0; for (i = 0; i < 9; i++) { buf[i] = OWReadByte(); if (i < 8) OWCRC(buf[i], &crc); } if (crc != buf[8]) { uart_putsP(PSTR("CRC mismatch\r\n")); return; } #if 0 uart_putsP(PSTR("temperature ")); uart_puts_dec(temp >> 4, 0); uart_putsP(PSTR(".")); uart_puts_dec((temp << 12) / 6553, 0); uart_putsP(PSTR("\r\n")); #else /* 0 Temperature LSB * 1 Temperature MSB * 2 Th * 3 Tl * 4 Reserved * 5 Reserved * 6 Count Remain * 7 Count per C * 8 CRC */ #if 0 for (i = 0; i < 9; i++) { uart_puts_dec(buf[i], 0); uart_putsP(PSTR("\r\n")); } #endif temp = buf[0]; if (buf[1] & 0x80) temp -= 256; temp >>= 1; tfrac = buf[7] - buf[6]; tfrac *= (uint16_t)100; tfrac /= buf[7]; tfrac += 75; if (tfrac < 100) { temp--; } else { tfrac -= 100; } if (temp < 0){ uart_putc('-'); uart_puts_dec(-temp, 0); } else uart_puts_dec(temp, 0); uart_putsP(PSTR(".")); uart_puts_dec(tfrac, 1); uart_putsP(PSTR("\r\n")); #endif } else if (cmd.buf[0] == 's' && cmd.buf[1] == 'r') { memset(ROM, 0, 8); i = OWFirst(ROM, 1, 0); do { switch (i) { case OW_BADWIRE: uart_putsP(PSTR("Presence pulse, but no module found, bad module/cabling?\r\n")); break; case OW_NOPRESENCE: uart_putsP(PSTR("No presence pulse found\r\n")); break; case OW_BADCRC: uart_putsP(PSTR("Bad CRC\r\n")); break; case OW_NOMODULES: case OW_FOUND: break; default: uart_putsP(PSTR("Unknown error from 1 wire library\r\n")); break; } if (i != OW_FOUND) break; for (i = 0; i < 7; i++) { uart_puts_hex(ROM[i]); uart_putc(':'); } uart_puts_hex(ROM[7]); uart_putsP(PSTR("\r\n")); i = OWNext(ROM, 1, 0); } while (1); } else if (cmd.buf[0] == 'i' && cmd.buf[1] == 'n') { switch (tolower(cmd.buf[3])) { case 'a': crc = PINA; break; case 'b': crc = PINB; break; case 'c': crc = PINC; break; case 'd': crc = PIND; break; default: uart_putsP(PSTR("Unknown port\r\n")); return; } uart_putsP(PSTR("0x")); uart_puts_hex(crc); uart_putsP(PSTR("\r\n")); } else if (cmd.buf[0] == 'o' && cmd.buf[1] == 'u') { crc = strtol((char *)cmd.buf + 8, (char **)NULL, 16); switch (tolower(cmd.buf[4])) { case 'a': PORTA = crc; break; case 'b': PORTB = crc; break; case 'c': PORTC = crc; break; case 'd': PORTD = crc; break; default: uart_putsP(PSTR("Unknown port\r\n")); return; } uart_putsP(PSTR("0x")); uart_puts_hex(crc); uart_putsP(PSTR("\r\n")); } else if (cmd.buf[0] == 'd' && cmd.buf[1] == 'd') { crc = strtol((char *)cmd.buf + 8, (char **)NULL, 16); switch (tolower(cmd.buf[4])) { case 'a': DDRA = crc; break; case 'b': DDRB = crc; break; case 'c': DDRC = crc; break; case 'd': DDRD = crc; break; default: uart_putsP(PSTR("Unknown port\r\n")); return; } uart_putsP(PSTR("0x")); uart_puts_hex(crc); uart_putsP(PSTR("\r\n")); #ifdef WITHUSB } else if (cmd.buf[0] == 'u' && cmd.buf[1] == 's') { usb_gendata(); #endif } else { badcmd: uart_putsP(PSTR("Unknown command, ? for a list\r\n")); } } int uart_putc(char c) { loop_until_bit_is_set(UCSRA, UDRE); UDR = c; return(0); } void uart_putsP(const char *addr) { char c; while ((c = pgm_read_byte_near(addr++))) uart_putc(c); } void uart_puts(const char *addr) { while (*addr) uart_putc(*addr++); } void uart_puts_dec(uint8_t a, uint8_t l) { char s[4]; if (l && a < 10) uart_putsP(PSTR("0")); uart_puts(utoa(a, s, 10)); } void uart_puts_hex(uint8_t a) { char s[3]; if (a < 0x10) uart_putc('0'); uart_puts(utoa(a, s, 16)); } char uart_getc(void) { while (!(UCSRA & _BV(RXC))) ; return (UDR); }