changeset 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 845934a4e7fe
children a52bc6b9e305
files 1wire.h Makefile testavr.c
diffstat 3 files changed, 361 insertions(+), 233 deletions(-) [+]
line wrap: on
line diff
--- a/1wire.h	Mon Dec 12 23:32:59 2005 +1030
+++ b/1wire.h	Mon Dec 12 23:37:16 2005 +1030
@@ -40,11 +40,11 @@
 void		OWCRC(uint8_t x, uint8_t *crc);
 void		OWSendCmd(uint8_t *ROM, uint8_t cmd);
 
-#define OWIREOUTPORT		PORTC
-#define OWIREOUTPIN		0
+#define OWIREOUTPORT		PORTD
+#define OWIREOUTPIN		2
 
-#define OWIREINPORT		PINC
-#define OWIREDDR		DDRC
+#define OWIREINPORT		PIND
+#define OWIREDDR		DDRD
 #define OWIREINPIN		OWIREOUTPIN
 
 /* Return codes for OWFirst()/OWNext() */
--- a/Makefile	Mon Dec 12 23:32:59 2005 +1030
+++ b/Makefile	Mon Dec 12 23:37:16 2005 +1030
@@ -3,10 +3,11 @@
 #
 
 PROG=	testavr
-SRCS=	1wire.c testavr.c
+SRCS=	1wire.c testavr.c usb.c
 
-MCU=	at90s8515
-CFLAGS+=-Os -g -Wall -fno-inline-functions -fno-inline 
-CFLAGS+=-DXTAL_CPU=4000000
-
+MCU=	atmega32
+PART=	m32
+CFLAGS+=-O2 -g -Wall -Wunreachable-code
+CFLAGS+=-DF_CPU=16000000
+#CFLAGS+= -mcall-prologues -frename-registers -fstrict-aliasing -fnew-ra
 .include "Makefile.avr"
--- a/testavr.c	Mon Dec 12 23:32:59 2005 +1030
+++ b/testavr.c	Mon Dec 12 23:37:16 2005 +1030
@@ -34,233 +34,319 @@
 #include <string.h>
 #include <ctype.h>
 #include <stdlib.h>
+#include <util/delay.h>
 
 #include "1wire.h"
+#include "usb.h"
 
 #define UART_BAUD_SELECT(baudRate,xtalCpu) ((xtalCpu)/((baudRate)*16l)-1)
-#define UART_BAUD_RATE      19200
+#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);
-int		uart_getc(void);
 void		uart_puts_dec(uint8_t a, uint8_t l);
 void		uart_puts_hex(uint8_t a);
-
-int
-main(void) {
-    uint8_t	ROM[8];
-    char	cmdbuf[40];
-    int8_t	i, arg;
-    uint8_t	crc, buf[9];;
-    int8_t	temp;
-    uint16_t	tfrac;
-
-    cli();
+char		uart_getc(void);
 
-    DDRC = 0xfc;
-    PORTC = 0x00;
-    DDRA = 0xff;
-
-    /* Init UART */
-    UBRR = UART_BAUD_SELECT(UART_BAUD_RATE,XTAL_CPU);
-
-    /* Enable receiver and transmitter. Turn on transmit interrupts */
-    UCR = _BV(RXEN) | _BV(TXEN);
-
-    uart_putsP(PSTR("\n\r\n\r===============\n\r"
-		    "Inited!\n\r\n\r"));
+/* Receive buffer storage */
+volatile struct {
+    char	buf[40];
+    uint8_t	state;
+    uint8_t	len;
+} cmd = {
+    .state = 255,
+    .len = 0
+};
 
-    while (1) {
-	uart_putsP(PSTR("> "));
-	i = 0;
-	while (1) {
-	    cmdbuf[i] = tolower(uart_getc());
-	    if (cmdbuf[i] == '\n' || cmdbuf[i] == '\r')
-		break;
-	    
-	    /* Backspace/Delete */
-	    if (cmdbuf[i] == 0x08) {
-		if (i > 0) {
-		    uart_putsP(PSTR("\010\040\010"));
-		    i--;
-		}
-		continue;
+/* 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("\n\r"));
+	    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"));
 	    }
-
-	    /* Anything unprintable just ignore it */
-	    if (!isprint(cmdbuf[i]))
-		continue;
-	    
-	    uart_putc(cmdbuf[i]);
-	    i++;
-	    if (i == sizeof(cmdbuf)) {
-		uart_putsP(PSTR("\n\rLine too long"));
-		i = 0;
-		break;
-	    }
-	}
-	cmdbuf[i + 1] = '\0';
-	uart_putsP(PSTR("\n\r"));
-	if (i == 0)
-	    continue;
-
-	if (cmdbuf[0] == '?') {
-	    uart_putsP(PSTR("rs               Reset and check for presence\n\r"
-			    "sr               Search the bus for ROMs\n\r"
-			    "re               Read a bit\n\r"
-			    "rb               Read a byte\n\r"
-			    "wr bit           Write a bit\n\r"
-			    "wb byte          Write a byte (hex)\n\r"
-			    "wc cmd [ROMID]   Write command\n\r"
-			    "te ROMID         Read the temperature from a DS1820\n\r"
-			    "le byte	      Set the LED port\n\r"));
-	    
 	    continue;
 	}
 	
-	if (i < 2)
-	    goto badcmd;
+	/* 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("\n\rLine too long"));
+	    cmd.state = 0;
+	    continue;
+	}
+    }
+}
+
+/* Tx complete */
+ISR(USART_TXC_vect) {
 	
-	if (cmdbuf[0] == 'r' && cmdbuf[1] == 's') {
-	    uart_putsP(PSTR("Resetting... "));
-	    
-	    if (OWTouchReset() == 1)
-		uart_putsP(PSTR("No presence pulse found\n\r"));
-	    else
-		uart_putsP(PSTR("Presence pulse found\n\r"));
-	} else if (cmdbuf[0] == 'r' && cmdbuf[1] == 'e') {
-	    if (OWReadBit())
-		uart_putsP(PSTR("Read a 1\n\r"));
-	    else
-		uart_putsP(PSTR("Read a 0\n\r"));
-	} else if (cmdbuf[0] == 'r' && cmdbuf[1] == 'b') {
-	    uart_putsP(PSTR("Read a 0x"));
-	    uart_puts_hex(OWReadByte());
-	    uart_putsP(PSTR("\n\r"));
-	} else if (cmdbuf[0] == 'w' && cmdbuf[1] == 'r') {
-	    arg = strtol(cmdbuf + 3, (char **)NULL, 10);
-	    OWWriteBit(arg);
-	    uart_putsP(PSTR("Wrote a "));
-	    if (arg)
-		uart_putsP(PSTR("1\n\r"));
-	    else
-		uart_putsP(PSTR("0\n\r"));
-	} else if (cmdbuf[0] == 'w' && cmdbuf[1] == 'b') {
-	    arg = (int)strtol(cmdbuf + 3, (char **)NULL, 16); 
-	    OWWriteByte(arg);
-	} else if (cmdbuf[0] == 'w' && cmdbuf[1] == 'c') {
-	    i = strlen(cmdbuf);
-	    if (i < 5) {
-		uart_putsP(PSTR("No arguments\n\r"));
-		continue;
-	    }
-	    
-	    arg = (int)strtol(cmdbuf + 3, (char **)NULL, 16);
-	    if (arg == 0) {
-		uart_putsP(PSTR("Unparseable command\n\r"));
-		continue;
-	    }
+}
+    
+int
+main(void) {
+    /* Disable interrupts while we frob stuff */
+    cli();
+
+    /* Disable JTAG (yes twice) */
+    MCUCSR |= _BV(JTD);
+    MCUCSR |= _BV(JTD);
+    
+    /* USB data bus (7:0) */
+    DDRA = 0x00;
+    PORTA = 0x00;
+    
+    /* USB control (3:0) */
+    DDRB = 0x0e;
+    PORTB = 0x00;
+    
+    /* GPIO (0:7) */
+    DDRC = 0xff;
+    PORTC = 0x00;
+
+    /* GPIO (2:7) */
+    DDRD = 0xfc;
+    PORTD = 0x00;
+
+    /* 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("\n\r\n\r===============\n\r"
+		    "Inited!\n\r\n\r"));
+
+    /* Ready to go! */
+    sei();
+
+    usb_init();
+    _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;
+	}
+	
+	if (!(PINB & _BV(PB0)))
+	    usb_intr();
+    }
+}
+
+void
+process_cmd(void) {
+    uint8_t	ROM[8];
+    int8_t	i, arg;
+    uint8_t	crc, buf[9];
+    int8_t	temp;
+    uint16_t	tfrac;
 
-	    if (i == 5) {
-		OWSendCmd(NULL, arg);
-		continue;
-	    }
+    /* User just pressed enter */
+    if (cmd.len == 0)
+	return;
+	     
+    if (cmd.buf[0] == '?') {
+        uart_putsP(PSTR("rs               Reset and check for presence\n\r"
+                        "sr               Search the bus for ROMs\n\r"
+                        "re               Read a bit\n\r"
+                        "rb               Read a byte\n\r"
+                        "wr  bit          Write a bit\n\r"
+                        "wb  byte         Write a byte (hex)\n\r"
+                        "wc  cmd [ROMID]  Write command\n\r"
+                        "te  ROMID        Read the temperature from a DS1820\n\r"
+                        "in  port         Read from a port\n\r"
+                        "out port val     Write to a port\n\r"
+                        "ddr port [val]   Read/write DDR for a port\n\r"));
+	    
+	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 (i < 29) {
-		uart_putsP(PSTR("Can't parse ROM ID\n\r"));
-		continue;
-	    }
-	    for (i = 0; i < 8; i++)
-		ROM[i] = (int)strtol(cmdbuf + 6 + (3 * i), (char **)NULL, 16);
-
-	    OWSendCmd(ROM, arg);
-	} else if (cmdbuf[0] == 't' && cmdbuf[1] == 'e') {
-	    if (strlen(cmdbuf) < 26) {
-		uart_putsP(PSTR("Unable to parse ROM ID\n\r"));
-		continue;
-	    }
-
-	    for (i = 0; i < 8; i++)
-		ROM[i] = (int)strtol(cmdbuf + 3 * (i + 1), (char **)NULL, 16);
+	if (OWTouchReset() == 1)
+	    uart_putsP(PSTR("No presence pulse found\n\r"));
+	else
+	    uart_putsP(PSTR("Presence pulse found\n\r"));
+    } else if (cmd.buf[0] == 'r' && cmd.buf[1] == 'e') {
+	if (OWReadBit())
+	    uart_putsP(PSTR("Read a 1\n\r"));
+	else
+	    uart_putsP(PSTR("Read a 0\n\r"));
+    } else if (cmd.buf[0] == 'r' && cmd.buf[1] == 'b') {
+	uart_putsP(PSTR("Read a 0x"));
+	uart_puts_hex(OWReadByte());
+	uart_putsP(PSTR("\n\r"));
+    } 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\n\r"));
+	else
+	    uart_putsP(PSTR("0\n\r"));
+    } 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] == 'w' && cmd.buf[1] == 'c') {
+	if (cmd.len < 5) {
+	    uart_putsP(PSTR("No arguments\n\r"));
+	    return;
+	}
+	    
+	arg = (int)strtol((char *)cmd.buf + 3, (char **)NULL, 16);
+	if (arg == 0) {
+	    uart_putsP(PSTR("Unparseable command\n\r"));
+	    return;
+	}
 
-	    if (ROM[0] != OW_FAMILY_TEMP) {
-		uart_putsP(PSTR("ROM specified isn't a temperature sensor\n\r"));
-		continue;
-	    }
+	if (i == 5) {
+	    OWSendCmd(NULL, arg);
+	    return;
+	}
 	    
-	    OWSendCmd(ROM, OW_CONVERTT_CMD);
-	    i = 0;
-	    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 (i < 29) {
+	    uart_putsP(PSTR("Can't parse ROM ID\n\r"));
+	    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\n\r"));
+	    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\n\r"));
+	    return;
+	}
 	    
-	    if (crc != buf[8]) {
-		uart_putsP(PSTR("CRC mismatch\n\r"));
-		continue;
-	    }
+	OWSendCmd(ROM, OW_CONVERTT_CMD);
+	i = 0;
+	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\n\r"));
+	    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("\n\r"));
+	uart_putsP(PSTR("temperature "));
+	uart_puts_dec(temp >> 4, 0);
+	uart_putsP(PSTR("."));
+	uart_puts_dec((temp << 12) / 6553, 0);
+	uart_putsP(PSTR("\n\r"));
 #else
-	    /* 0	Temperature LSB
-	     * 1	Temperature MSB
-	     * 2	Th
-	     * 3	Tl
-	     * 4	Reserved
-	     * 5	Reserved
-	     * 6	Count Remain
-	     * 7	Count per C
-	     * 8	CRC
-	     */
+	/* 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("\n\r"));
-	    }
+	for (i = 0; i < 9; i++) {
+	    uart_puts_dec(buf[i], 0);
+	    uart_putsP(PSTR("\n\r"));
+	}
 #endif
-	    temp = buf[0];
-	    if (buf[0] & 0x01)
-		temp -= 256;
-	    temp >>= 1;
+	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;
-	    }
+	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("\n\r"));
+	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("\n\r"));
 	    
 #endif
-	} else if (cmdbuf[0] == 's' && cmdbuf[1] == 'r') {
-	    memset(ROM, 0, 8);
+    } else if (cmd.buf[0] == 's' && cmd.buf[1] == 'r') {
+	memset(ROM, 0, 8);
 
-	    i = OWFirst(ROM, 1, 0);
-	    do {
-		switch (i) {
+	i = OWFirst(ROM, 1, 0);
+	do {
+	    switch (i) {
 		case OW_BADWIRE:
 		    uart_putsP(PSTR("Presence pulse, but no module found, bad module/cabling?\n\r"));
 		    break;
@@ -280,41 +366,82 @@
 		default:
 		    uart_putsP(PSTR("Unknown error from 1 wire library\n\r"));
 		    break;
-		}
+	    }
 		
-		if (i != OW_FOUND)
-		    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("\n\r"));
+	    for (i = 0; i < 7; i++) {
+		uart_puts_hex(ROM[i]);
+		uart_putc(':');
+	    }
+	    uart_puts_hex(ROM[7]);
+	    uart_putsP(PSTR("\n\r"));
 
-		i = OWNext(ROM, 1, 0);
-	    } while (1);
-	} else if (cmdbuf[0] == 'l' && cmdbuf[1] == 'e') {
-	    crc = (uint8_t)strtol(cmdbuf + 3, (char **)NULL, 16);
-	    PORTA = crc;
-#if 1
-	    uart_putsP(PSTR("LEDs set to 0x"));
-	    uart_puts_hex(crc);
-	    uart_putsP(PSTR("\n\r"));
-#endif
-	} else {
-	  badcmd:
-	    uart_putsP(PSTR("Unknown command, ? for a list\n\r"));
+	    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\n\r"));
+		return;
 	}
-
+	uart_putsP(PSTR("0x"));
+	uart_puts_hex(crc);
+	uart_putsP(PSTR("\n\r"));
+    } 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\n\r"));
+		return;
+	}
+	uart_putsP(PSTR("0x"));
+	uart_puts_hex(crc);
+	uart_putsP(PSTR("\n\r")); 
+    } else if (cmd.buf[0] == 'u' && cmd.buf[1] == 's') {
+	usb_gendata();
+    } else {
+      badcmd:
+	uart_putsP(PSTR("Unknown command, ? for a list\n\r"));
     }
+}
     
-    return(0);
-}
-
 int
 uart_putc(char c) {
-    loop_until_bit_is_set(USR, UDRE);
+    loop_until_bit_is_set(UCSRA, UDRE);
     UDR = c;
 
     return(0);
@@ -353,9 +480,9 @@
     uart_puts(utoa(a, s, 16));
 }
 
-int
+char
 uart_getc(void) {
-    while (!USR & 0x80)
+    while (!(UCSRA & _BV(RXC)))
 	;
     
     return (UDR);