diff testavr.c @ 51:cb184206344d

Rejig command parsing and assume the compiler isn't dumb (eg it can reuse stack variables).
author darius@Inchoate
date Wed, 29 Oct 2008 16:09:55 +1030
parents 13a68734348b
children 3217e93b28a3
line wrap: on
line diff
--- a/testavr.c	Wed Oct 29 16:06:42 2008 +1030
+++ b/testavr.c	Wed Oct 29 16:09:55 2008 +1030
@@ -170,62 +170,63 @@
     if (cmd.len == 0)
 	return;
 	     
-    if (cmd.buf[0] == '?') {
+    if (!strcasecmp_P((char *)cmd.buf, PSTR("?")) ||
+	!strcasecmp_P((char *)cmd.buf, PSTR("help"))) {
         printf_P(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"
-		      "tc ...		Temperature control related (tc help for more)\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"
+		      "ou port val      Write to a port (val in hex)\r\n"
+		      "dd port [val]    Read/write DDR for a port (val in hex)\r\n"
+		      "rt ROMID	        Read DS2502 status page\r\n"
+		      "we ROMID adr val Write data into a DS2502 PROM (adr & val in hex)\r\n"
+		      "rr ROMID         Read DS2502 PROM\r\n"
+		      "zz		Reset MCU\r\n"
+#ifdef WITHUSB
+		      "us               Generate USB data\r\n"
+#endif
+		      "tc ...           Temperature control related (tc help for more)\r\n"));
 	
 	return;
-    }
-	
-    i = strlen((char *)cmd.buf);
-    if (cmd.len < 2)
-	goto badcmd;
-	
-    if (cmd.buf[0] == 'r' && cmd.buf[1] == 's') {
+    } else if (!strncasecmp_P((char *)cmd.buf, PSTR("zz"), 2)) {
+	cli();
+	wdt_enable(WDTO_15MS);
+	for (;;)
+	    ;
+    } else if (!strncasecmp_P((char *)cmd.buf, PSTR("rs"), 2)) {
 	printf_P(PSTR("Resetting... "));
 	    
 	if (OWTouchReset() == 1)
 	    printf_P(PSTR("No presence pulse found\r\n"));
 	else
 	    printf_P(PSTR("Presence pulse found\r\n"));
-    } else if (cmd.buf[0] == 'r' && cmd.buf[1] == 'e') {
+    } else if (!strncasecmp_P((char *)cmd.buf, PSTR("re"), 2)) {
 	if (OWReadBit())
 	    printf_P(PSTR("Read a 1\r\n"));
 	else
 	    printf_P(PSTR("Read a 0\r\n"));
-    } else if (cmd.buf[0] == 'r' && cmd.buf[1] == 'b') {
+    } else if (!strncasecmp_P((char *)cmd.buf, PSTR("rb"), 2)) {
 	printf_P(PSTR("Read a 0x%02x\r\n"), OWReadByte());
-    } else if (cmd.buf[0] == 'w' && cmd.buf[1] == 'r') {
+    } else if (!strncasecmp_P((char *)cmd.buf, PSTR("wr"), 2)) {
 	arg = strtol((char *)cmd.buf + 3, (char **)NULL, 10);
 	OWWriteBit(arg);
 	printf_P(PSTR("Wrote a %c\r\n"), arg ? '1' : '0');
-    } else if (cmd.buf[0] == 'w' && cmd.buf[1] == 'b') {
+    } else if (!strncasecmp_P((char *)cmd.buf, PSTR("wb"), 2)) {
 	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) {
+    } else if (!strncasecmp_P((char *)cmd.buf, PSTR("rt"), 2)) {
+	if (sscanf_P((char *)cmd.buf, PSTR("rt %hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx"), 
+		     &ROM[0], &ROM[1], &ROM[2], &ROM[3],
+		     &ROM[4], &ROM[5], &ROM[6], &ROM[7]) != 8) {
 	    printf_P(PSTR("Unable to parse ROM ID\r\n"));
 	    return;
 	}
-
-	if (OWTouchReset() != 0) {
-	    printf_P(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) {
 	    printf_P(PSTR("ROM specified isn't a DS2502\r\n"));
 	    return;
@@ -263,40 +264,36 @@
 	    printf_P(PSTR("CRC mismatch on data\r\n"));
 	    return;
 	}
-    } else if (cmd.buf[0] == 'w' && cmd.buf[1] == 'e') {
-	if (cmd.len < 26) {
+    } else if (!strncasecmp_P((char *)cmd.buf, PSTR("we"), 2)) {
+	uint8_t	adr, data;
+	
+	if (sscanf_P((char *)cmd.buf, PSTR("we %hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx %hhx %hhx"),
+		     &ROM[0], &ROM[1], &ROM[2], &ROM[3],
+		     &ROM[4], &ROM[5], &ROM[6], &ROM[7],
+		     &adr, &data) != 10) {
 	    printf_P(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) {
-	    printf_P(PSTR("ROM specified isn't a ROM\r\n"));
+	    printf_P(PSTR("ID 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) {
 	    printf_P(PSTR("No presence\r\n"));
 	    return;
 	}
 
-	i = OWProgROM(ROM, buf[0], 2, &buf[1], 0, 0);
-	printf_P(PSTR("OWProgROM returned %d\r\n"), i);
-    } else if (cmd.buf[0] == 'r' && cmd.buf[1] == 'r') {
-	if (cmd.len < 26) {
+	printf_P(PSTR("OWProgROM returned %S\r\n"), OWProgROM_Status[OWProgROM(ROM, buf[0], 2, &buf[1], 0, 0)]);
+    } else if (!strncasecmp_P((char *)cmd.buf, PSTR("rr"), 2)) {
+	if (sscanf_P((char *)cmd.buf, PSTR("rr %hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx"),
+		     &ROM[0], &ROM[1], &ROM[2], &ROM[3],
+		     &ROM[4], &ROM[5], &ROM[6], &ROM[7]) != 8) {
 	    printf_P(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) {
 	    printf_P(PSTR("ROM specified isn't a ROM\r\n"));
 	    return;
@@ -336,96 +333,50 @@
 	    return;
 	}
 	
-    } else if (cmd.buf[0] == 'w' && cmd.buf[1] == 'c') {
-	if (cmd.len < 5) {
-	    printf_P(PSTR("No arguments\r\n"));
+    } else if (!strncasecmp_P((char *)cmd.buf, PSTR("wc"), 2)) {
+	uint8_t c;
+	
+	i = sscanf_P((char *)cmd.buf, PSTR("wc %hhx %hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx"),
+		     &ROM[0], &ROM[1], &ROM[2], &ROM[3],
+		     &ROM[4], &ROM[5], &ROM[6], &ROM[7],
+		     &c);
+	
+	if (i != 1 && i != 9) {
+	    printf_P(PSTR("Incorrect usage\r\n"));
 	    return;
 	}
 	    
-	arg = (int)strtol((char *)cmd.buf + 3, (char **)NULL, 16);
-	if (arg == 0) {
-	    printf_P(PSTR("Unparseable command\r\n"));
-	    return;
-	}
-
-	if (i == 5) {
-	    OWSendCmd(NULL, arg);
+	if (i == 1) {
+	    OWSendCmd(i == 1 ? NULL : ROM, c);
 	    return;
 	}
-	    
-	if (i < 29) {
-	    printf_P(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) {
+    } else if (!strncasecmp_P((char *)cmd.buf, PSTR("te"), 2)) {
+	if (sscanf_P((char *)cmd.buf, PSTR("te %hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx"), 
+		     &ROM[0], &ROM[1], &ROM[2], &ROM[3],
+		     &ROM[4], &ROM[5], &ROM[6], &ROM[7]) != 8) {
 	    printf_P(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);
+	t = OWGetTemp(ROM);
+	switch (t) {
+	    case OW_TEMP_WRONG_FAM:
+		printf_P(PSTR("ROM specified isn't a temperature sensor\r\n"));
+		break;
 
-	if (ROM[0] != OW_FAMILY_TEMP) {
-	    printf_P(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 = 1;
-
+	    case OW_TEMP_CRC_ERR:
+		printf_P(PSTR("CRC mismatch\r\n"));
+		break;
 
-	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]) {
-	    printf_P(PSTR("CRC mismatch\r\n"));
-	    return;
+	    case OW_TEMP_NO_ROM:
+		printf_P(PSTR("No ROM found\r\n"));
+		break;
+
+	    default:
+		printf_P(PSTR("%d.%02d\r\n"), GETWHOLE(t), GETFRAC(t));
+		break;
 	}
-	    
-	/* 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++)
-	    printf_P(PSTR("%d\r\n"), buf[i]);
-#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;
-	}
-	    
-	printf_P(PSTR("%d.%02d\r\n"), temp, tfrac);
-    } else if (cmd.buf[0] == 's' && cmd.buf[1] == 'r') {
+    } else if (!strncasecmp_P((char *)cmd.buf, PSTR("sr"), 2)) {
 	memset(ROM, 0, 8);
 
 	i = OWFirst(ROM, 1, 0);
@@ -460,86 +411,129 @@
 
 	    i = OWNext(ROM, 1, 0);
 	} while (1);
-    } else if (cmd.buf[0] == 'i' && cmd.buf[1] == 'n') {
+    } else if (!strncasecmp_P((char *)cmd.buf, PSTR("in"), 2)) {
+	uint8_t inp;
+	    
 	switch (tolower(cmd.buf[3])) {
 	    case 'a':
-		crc = PINA;
+		inp = PINA;
 		break;
 		
 	    case 'b':
-		crc = PINB;
+		inp = PINB;
 		break;
 		
 	    case 'c':
-		crc = PINC;
+		inp = PINC;
 		break;
 		
 	    case 'd':
-		crc = PIND;
+		inp = PIND;
+		break;
+		
+	    default:
+		printf_P(PSTR("Unknown port\r\n"));
+		return;
+	}
+	printf_P(PSTR("0x%02x\r\n"), inp);
+    } else if (!strncasecmp_P((char *)cmd.buf, PSTR("ou"), 2)) {
+	char port;
+	int val;
+	
+	if (sscanf_P((char *)cmd.buf, PSTR("ou %c %x"), &port, &val) != 2) {
+	    printf_P(PSTR("Unable to parse ou arguments\r\n"));
+	    return;
+	}
+	
+	switch (port) {
+	    case 'a':
+		PORTA = val & 0xff;
+		break;
+		
+	    case 'b':
+		PORTB = val & 0xff;
+		break;
+		
+	    case 'c':
+		PORTC = val & 0xff;
+		break;
+		
+	    case 'd':
+		PORTD = val & 0xff;
 		break;
 		
 	    default:
 		printf_P(PSTR("Unknown port\r\n"));
 		return;
 	}
-	printf_P(PSTR("0x%02x\r\n"), crc);
-    } 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:
-		printf_P(PSTR("Unknown port\r\n"));
-		return;
+	printf_P(PSTR("PORT%c <= 0x%02x\r\n"), toupper(port), val);
+    } else if (!strncasecmp_P((char *)cmd.buf, PSTR("dd"), 2)) {
+	char port;
+	uint8_t val;
+	int num;
+	
+	num = sscanf_P((char *)cmd.buf, PSTR("dd %c %x"), &port, &val);
+	
+	if (num != 2 && num != 3) {
+	    printf_P(PSTR("Unable to parse dd arguments\r\n"));
+	    return;
 	}
-	printf_P(PSTR("PORT%c <= 0x%02x\r\n"), toupper(cmd.buf[4]), crc);
-    } 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;
+	
+	if (num == 2) {
+	    switch (port) {
+		case 'a':
+		    val = DDRA;
+		    break;
+
+		case 'b':
+		    val = DDRB;
+		    break;
+
+		case 'c':
+		    val = DDRC;
+		    break;
+
+		case 'd':
+		    val = DDRD;
+		    break;
 		
-	    case 'c':
-		DDRC = crc;
-		break;
+		default:
+		    printf_P(PSTR("Unknown port\r\n"));
+		    return;
+	    }
+	    printf_P(PSTR("DDR%c => 0x%02x\r\n"), toupper(port), val);
+	} else {
+	    switch (port) {
+		case 'a':
+		    DDRA = val & 0xff;
+		    break;
+		
+		case 'b':
+		    DDRB = val & 0xff;
+		    break;
 		
-	    case 'd':
-		DDRD = crc;
-		break;
+		case 'c':
+		    DDRC = val & 0xff;
+		    break;
+		
+		case 'd':
+		    DDRD = val & 0xff;
+		    break;
 		
-	    default:
-		printf_P(PSTR("Unknown port\r\n"));
-		return;
+		default:
+		    printf_P(PSTR("Unknown port\r\n"));
+		    return;
+	    }
+	    printf_P(PSTR("DDR%c <= 0x%02x\r\n"), toupper(port), val);
 	}
-	printf_P(PSTR("0x%02x\r\n"), crc);
-    } else if (cmd.buf[0] == 't' && cmd.buf[1] == 'c') {
+    } else if (!strncasecmp_P((char *)cmd.buf, PSTR("tc"), 2)) {
 	tempctrl_cmd((char *)cmd.buf);
 #ifdef WITHUSB
-    } else if (cmd.buf[0] == 'u' && cmd.buf[1] == 's') {
+    } else if (!strncasecmp_P((char *)cmd.buf, PSTR("us"), 2)) {
 	usb_gendata();
 #endif
     } else {
-      badcmd:
-	printf_P(PSTR("Unknown command, ? for a list\r\n"));
+	printf_P(PSTR("Unknown command, help for a list\r\n"));
     }
 }