changeset 21:bd8e2cf04034

- Add flash erase, write & read commands (needs more work). - Split the buffer into argv/argc to make sub commands simpler.
author Daniel O'Connor <darius@dons.net.au>
date Thu, 15 Nov 2012 23:40:51 +1030
parents 35cf31794a42
children 198ac9d95770
files flash.c flash.h main.c
diffstat 3 files changed, 317 insertions(+), 161 deletions(-) [+]
line wrap: on
line diff
--- a/flash.c	Wed Nov 14 12:47:10 2012 +1030
+++ b/flash.c	Thu Nov 15 23:40:51 2012 +1030
@@ -1,4 +1,7 @@
+#include <stdio.h>
 #include <stdint.h>
+#include <string.h>
+#include <stdlib.h>
 
 #include "stm32f10x.h"
 #include "spi.h"
@@ -7,6 +10,105 @@
 #define FL_SELECT()	GPIO_ResetBits(GPIOA, GPIO_Pin_4)
 #define FL_DESELECT()	GPIO_SetBits(GPIOA, GPIO_Pin_4)
 
+static const char *flstattbl[] = {
+    "BUSY",
+    "WEL",
+    "BP0",
+    "BP1",
+    "BP2",
+    "BP3",
+    "AAI",
+    "BPL"
+};
+		
+void
+flashcmd(char **argv, int argc) {
+    uint8_t status, tmp;
+
+    if (argc == 0) {
+	fputs("No command specified\r\n", stdout);
+	return;
+    }
+    
+    if (!strcmp(argv[0], "str")) {
+	status = flashreadstatus();
+	fputs("Status = ", stdout);
+	for (unsigned int i = 0; i < sizeof(flstattbl) / sizeof(flstattbl[0]); i++)
+	    if (status & 1 << i) {
+		fputs(flstattbl[i], stdout);
+		fputs(" ", stdout);
+	    }
+	printf("(0x%02x)\r\n", status);
+    } else if (!strcmp(argv[0], "stw")) {
+	if (argc != 2) {
+	    fputs("Incorrect number of arguments\r\n", stdout);
+	    return;
+	}
+	tmp = atoi(argv[1]);
+	flashwritestatus(tmp);
+	status = flashreadstatus();
+	printf("Wrote 0x%02x to status, now 0x%02x\r\n", tmp, status);
+    } else if (!strcmp(argv[0], "er")) {
+	if (argc != 2) {
+	    fputs("Incorrect number of arguments\r\n", stdout);
+	    return;
+	}
+	tmp = atoi(argv[1]);
+	flash4kerase(tmp);
+	printf("Erased 0x%x\r\n", tmp);
+    } else if (!strcmp(argv[0], "rd")) {
+	if (argc != 2) {
+	    fputs("Incorrect number of arguments\r\n", stdout);
+	    return;
+	}
+	tmp = atoi(argv[1]);
+
+	for (int i = 0; i < 16; i++)
+	    printf("Read 0x%02x from 0x%06x\r\n", flashread(tmp + i), tmp + i);
+	fputs("\r\n", stdout);
+    } else if (!strcmp(argv[0], "wr")) {
+	if (argc != 2) {
+	    fputs("Incorrect number of arguments\r\n", stdout);
+	    return;
+	}
+
+	tmp = atoi(argv[1]);
+
+	for (int i = 0; i < 16; i++) {
+	    printf("Writing 0x%02x to 0x%06x\r\n", tmp + i, i);
+	    flashwrite(tmp + i, i);
+	}
+	
+    } else if (!strcmp(argv[0], "id")) {
+	printf("Flash ID = 0x%04hx (expect 0xbf41)\r\n", flashreadid());
+    } else {
+	fputs("Unknown sub command\r\n", stdout);
+	return;
+    }
+}
+
+void
+flash4kerase(uint32_t addr) {
+    uint8_t	cnt;
+    
+    flashenablewrite();			/* Enable writing */
+    
+    FL_SELECT();			/* Select device */
+
+    SPI_WriteByte(FL_4KERASE);		/* Send command */
+    SPI_WriteByte((addr & 0x00ff0000) >> 16);
+    SPI_WriteByte((addr & 0x0000ff00) >> 8);
+    SPI_WriteByte((addr & 0x000000ff)); /* Send address */
+  
+    FL_DESELECT();
+    
+    /* Wait for not BUSY */
+    for (cnt = 0; (flashreadstatus() & FL_BUSY) != 0; cnt++)
+	;
+
+    //printf("cnt = %d\r\n", cnt);
+}
+
 uint16_t
 flashreadid(void) {
     uint8_t	fac, dev;
@@ -25,6 +127,15 @@
     return fac << 8 | dev;
 }
 
+void
+flashenablewrite(void) {
+    FL_SELECT();			/* Select device */
+
+    SPI_WriteByte(FL_WREN);		/* Send command */
+  
+    FL_DESELECT();			/* De-select device */
+}
+
 uint8_t
 flashreadstatus(void) {
     uint8_t	status;
@@ -55,3 +166,34 @@
     FL_DESELECT();			/* De-select device */
 }
 
+uint8_t
+flashread(uint32_t addr) {
+    uint8_t	data;
+    
+    FL_SELECT();			/* Select device */
+
+    SPI_WriteByte(FL_READ);		/* Send command */
+    SPI_WriteByte((addr & 0x00ff0000) >> 16);
+    SPI_WriteByte((addr & 0x0000ff00) >> 8);
+    SPI_WriteByte((addr & 0x000000ff)); /* Send address */
+    data = SPI_WriteByte(0x00);		/* Read data */
+  
+    FL_DESELECT();			/* De-select device */
+
+    return data;
+}
+
+void
+flashwrite(uint32_t addr, uint8_t data) {
+    flashenablewrite();			/* Enable writes */
+
+    FL_SELECT();			/* Select device */
+
+    SPI_WriteByte(FL_BYTEPROG);		/* Send command */
+    SPI_WriteByte((addr & 0x00ff0000) >> 16);
+    SPI_WriteByte((addr & 0x0000ff00) >> 8);
+    SPI_WriteByte((addr & 0x000000ff)); /* Send address */
+    SPI_WriteByte(data);		/* Write data */
+  
+    FL_DESELECT();			/* De-select device */
+}
--- a/flash.h	Wed Nov 14 12:47:10 2012 +1030
+++ b/flash.h	Thu Nov 15 23:40:51 2012 +1030
@@ -1,16 +1,25 @@
+void		flashcmd(char **, int);
 uint16_t	flashreadid(void);
 uint8_t		flashreadstatus(void);
 void		flashwritestatus(uint8_t status);
 void		flashwritectl(int enable);
+void		flash4kerase(uint32_t addr);
+uint8_t		flashread(uint32_t addr);
+void		flashenablewrite(void);
+void		flashwrite(uint32_t addr, uint8_t data);
 
+#define FL_BUSY		(1<<0)
+#define FL_WEL		(1<<1)
 #define FL_BP0		(1<<2)
 #define FL_BP1		(1<<3)
 #define FL_BP2		(1<<4)
 #define FL_BP3		(1<<5)
+#define FL_AAI		(1<<6)
 #define FL_BPL		(1<<7)
 
 #define FL_READ		0x03
 #define FL_HSREAD	0x0b
+#define FL_4KERASE	0x20
 #define FL_32KERASE	0x52
 #define FL_64KERASE	0xd8
 #define FL_CHIPERASE	0x60
--- a/main.c	Wed Nov 14 12:47:10 2012 +1030
+++ b/main.c	Thu Nov 15 23:40:51 2012 +1030
@@ -18,8 +18,10 @@
 #include "main.h"
 #include "touch.h"
 
+#define MAXARGS		10
+#define LINEBUF		40
 typedef struct {
-    char		buf[40];
+    char		*buf;
     volatile uint8_t	state;
     uint8_t		len;
 } consbuf_t;
@@ -93,7 +95,7 @@
 	
 	cmd.state++;
 	/* Over flow? */
-	if (cmd.state == ((sizeof(cmd.buf) / sizeof(cmd.buf[0])) - 1)) {
+	if (cmd.state == LINEBUF - 1) {
 	    fputs("\r\nLine too long", stdout);
 	    cmd.state = 0;
 	    continue;
@@ -101,17 +103,17 @@
     }
 }
 
-
 int
 main(void) {
-    char	buf[40];
+    char	buf[40], *argv[MAXARGS], **ap, *tmp;
+    int		argc;
     struct tm	nowtm;
     time_t	now;
     uint16_t	x, y, x1, y1, z1, z2, r, c, rx, ry;
     float	t, t2;
-    char	col;
 		
     cmd.state = cmd.len = 0;
+    cmd.buf = malloc(LINEBUF);
     
     /* Init hardware - configure IO ports and external peripherals */
     hw_init();
@@ -154,174 +156,177 @@
 	while (cmd.state != 255)
 	    ;
 	
-	if (cmd.len > 0) {
-	    if (!strncmp("gc", cmd.buf, 2)) {
-		now = time(NULL);
-		gmtime_r(&now, &nowtm);
-		strftime(buf, sizeof(buf) - 1, "%Y/%m/%d %H:%M:%S UTC", &nowtm);
-		printf("Time is %s (%d)\r\n", buf, (int)now);
-	    } else if (!strncmp("sc ", cmd.buf, 3)) {
-		struct timeval tv;
-		tv.tv_sec = atoi(cmd.buf + 3);
-		tv.tv_usec = 0;
-		settimeofday(&tv, NULL);
-	    } else if (!strncmp("read", cmd.buf, 4)) {
-		printf("PB5 = %d\r\n", GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_15));
-	    } else if (!strncmp("touch", cmd.buf, 5)) {
-		for (int i = 0; i < 10; i++) {
-		    tp_getcoords(&x, &y, &z1, &z2, &t, &t2);
-		    printf("X = %5d Y = %5d Z1 = %5d Z2 = %5d T = %7.2f T2 = %7.2f\r\n", x, y, z1, z2, t, t2);
-		}
-	    } else if (!strncmp("fl", cmd.buf, 2)) {
-		uint8_t status;
-		char *flstattbl[] = {
-		    "BUSY",
-		    "WEL",
-		    "BP0",
-		    "BP1",
-		    "BP2",
-		    "BP3",
-		    "AAI",
-		    "BPL"
-		};
-		
-		printf("Flash ID = 0x%04hx (expect 0xbf41)\r\n", flashreadid());
-		status = flashreadstatus();
-
-		fputs("Status = ", stdout);
-		for (unsigned int i = 0; i < sizeof(flstattbl) / sizeof(flstattbl[0]); i++)
-		    if (status & 1 << i) {
-			fputs(flstattbl[i], stdout);
-			fputs(" ", stdout);
-		    }
-		printf("(0x%02x)\r\n", status);
-
-		flashwritestatus(0x00);
-		
-		status = flashreadstatus();
-
-		fputs("Status = ", stdout);
-		for (unsigned int i = 0; i < sizeof(flstattbl) / sizeof(flstattbl[0]); i++)
-		    if (status & 1 << i) {
-			fputs(flstattbl[i], stdout);
-			fputs(" ", stdout);
-		    }
-		printf("(0x%02x)\r\n", status);
-	    } else if (!strncmp("pwm ", cmd.buf, 4)) {
-		lcd_setpwm(atoi(cmd.buf + 4));
-	    } else if (!strncmp("timing", cmd.buf, 6)) {
-		fputs("Timing..\r\n", stdout);
-		delay(10000);
-		fputs("Done\r\n", stdout);
-	    } else if (!strncmp("circ ", cmd.buf, 5)) {
-		if (sscanf(cmd.buf, "circ %hu %hu %hu %c", &x, &y, &r, &col) != 4) {
-		    printf("Unable to parse circ args\r\n");
-		    goto out;
-		}
-
-		c = lcd_parsecol(col);
-		lcd_circle(x, y, r, 0, c);
-	    } else if (!strncmp("ellip ", cmd.buf, 6)) {
-		if (sscanf(cmd.buf, "ellip %hu %hu %hu %hu %c", &x, &y, &rx, &ry, &col) != 5) {
-		    printf("Unable to parse circ args\r\n");
-		    goto out;
-		}
-
-		c = lcd_parsecol(col);
-		lcd_ellipse(x, y, rx, ry, 0, c);
-	    } else if (!strncmp("line ", cmd.buf, 5)) {
-		if (sscanf(cmd.buf, "line %hu %hu %hu %hu %c", &x, &y, &x1, &y1, &col) != 5) {
-		    printf("Unable to parse line args\r\n");
-		    goto out;
-		}
+	if (cmd.len < 1)
+	    goto out;
+	
+	/* Split command string on space/tab boundaries into argv/argc */
+	argc = 0;
+	tmp = cmd.buf;
+	for (ap = argv; (*ap = strsep(&cmd.buf, " \t")) != NULL;) {
+	    if (**ap != '\0') {
+		argc++;
+		if (++ap >= &argv[MAXARGS])
+		    break;
+	    }
+	}
+	/* Reset the buffer pointer after strsep() has mangled it */
+	cmd.buf = tmp;
 
-		c = lcd_parsecol(col);
-		lcd_line(x, y, x1, y1, c);
-	    } else if (!strncmp("delay", cmd.buf, 5)) {
-		GPIO_InitTypeDef GPIO_InitStructure;
-		
-		GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
-		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
-		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
-		GPIO_Init(GPIOE, &GPIO_InitStructure);
+	if (!strcmp("gc", argv[0])) {
+	    now = time(NULL);
+	    gmtime_r(&now, &nowtm);
+	    strftime(buf, sizeof(buf) - 1, "%Y/%m/%d %H:%M:%S UTC", &nowtm);
+	    printf("Time is %s (%d)\r\n", buf, (int)now);
+	} else if (!strcmp("sc", argv[0])) {
+	    struct timeval tv;
+	    if (argc != 2) {
+		fputs("Incorrect number of arguments\r\n", stdout);
+		goto out;
+	    }
+	    
+	    tv.tv_sec = atoi(argv[1]);
+	    tv.tv_usec = 0;
+	    settimeofday(&tv, NULL);
+	} else if (!strcmp("read", argv[0])) {
+	    printf("PB5 = %d\r\n", GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_15));
+	} else if (!strcmp("touch", argv[0])) {
+	    for (int i = 0; i < 10; i++) {
+		tp_getcoords(&x, &y, &z1, &z2, &t, &t2);
+		printf("X = %5d Y = %5d Z1 = %5d Z2 = %5d T = %7.2f T2 = %7.2f\r\n", x, y, z1, z2, t, t2);
+	    }
+	} else if (!strcmp("fl", argv[0])) {
+	    flashcmd(argv + 1, argc - 1);
+	} else if (!strcmp("pwm", argv[0])) {
+	    lcd_setpwm(atoi(argv[1]));
+	} else if (!strcmp("timing", argv[0])) {
+	    fputs("Timing..\r\n", stdout);
+	    delay(10000);
+	    fputs("Done\r\n", stdout);
+	} else if (!strcmp("circ", argv[0])) {
+	    if (argc != 5) {
+		fputs("Unable to parse circ args\r\n", stdout);
+		goto out;
+	    }
+	    x = atoi(argv[1]);
+	    y = atoi(argv[2]);
+	    r = atoi(argv[3]);
+	    c = lcd_parsecol(argv[4][0]);
+	    lcd_circle(x, y, r, 0, c);
+	} else if (!strncmp("ellip", cmd.buf, 6)) {
+	    if (argc != 5) {
+		fputs("Unable to parse ellip args\r\n", stdout);
+		goto out;
+	    }
 
-		for (x = 0; x < 100; x++) {
-		    GPIO_SetBits(GPIOE, GPIO_Pin_2);
-		    delay(30);
-		    GPIO_ResetBits(GPIOE, GPIO_Pin_2);
-		    delay(60);
-		}
-	    } else if (!strncmp("rs", cmd.buf, 2)) {
-		printf("Reset got %d\r\n", OWTouchReset());
-	    } else if (!strncmp("sr", cmd.buf, 2)) {
-		uint8_t	ROM[8];
-		int8_t	i;
-	
-		memset(ROM, 0, 8);
+	    x = atoi(argv[1]);
+	    y = atoi(argv[2]);
+	    rx = atoi(argv[3]);
+	    ry = atoi(argv[4]);
+	    c = lcd_parsecol(argv[5][0]);
 
-		i = OWFirst(ROM, 1, 0);
-		do {
-		    switch (i) {
-			case OW_NOMODULES:
-			case OW_FOUND:
-			    break;
-		    
-			case OW_BADWIRE:
-			case OW_NOPRESENCE:
-			case OW_BADCRC:
-			default:
-			    printf("Err %d\r\n", i);
-			    break;
-		    }
+	    lcd_ellipse(x, y, rx, ry, 0, c);
+	} else if (!strncmp("line", cmd.buf, 5)) {
+	    if (argc != 5) {
+		fputs("Unable to parse line args\r\n", stdout);
+		goto out;
+	    }
+
+	    x = atoi(argv[1]);
+	    y = atoi(argv[2]);
+	    x1 = atoi(argv[3]);
+	    y1 = atoi(argv[4]);
+	    c = lcd_parsecol(argv[5][0]);
+
+	    lcd_line(x, y, x1, y1, c);
+	} else if (!strcmp("delay", argv[0])) {
+	    GPIO_InitTypeDef GPIO_InitStructure;
 		
-		    if (i != OW_FOUND)
-			break;
-
-		    for (i = 0; i < 8; i++)
-			printf("%02x%s", ROM[i], i == 7 ? "\r\n" : ":");
+	    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
+	    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+	    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
+	    GPIO_Init(GPIOE, &GPIO_InitStructure);
 
-		    i = OWNext(ROM, 1, 0);
-		} while (1);
-	    } else if (!strncmp("rb", cmd.buf, 2)) {
-		printf("Read bit returned %d\r\n", OWReadBit());
-	    } else if (!strncmp("wb ", cmd.buf, 3)) {
-		x = atoi(cmd.buf + 3);
-		OWWriteBit(x);
-		printf("Wrote %d\r\n", x);
-	    } else if (!strncasecmp(cmd.buf, "te ", 3)) {
-		uint8_t	ROM[8];
-		int16_t	res;
+	    for (x = 0; x < 100; x++) {
+		GPIO_SetBits(GPIOE, GPIO_Pin_2);
+		delay(30);
+		GPIO_ResetBits(GPIOE, GPIO_Pin_2);
+		delay(60);
+	    }
+	} else if (!strcmp("rs", argv[0])) {
+	    printf("Reset got %d\r\n", OWTouchReset());
+	} else if (!strcmp("sr", argv[0])) {
+	    uint8_t	ROM[8];
+	    int8_t	i;
 	
-		if (sscanf(cmd.buf, "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("Unable to parse ROM ID\r\n");
-		    goto out;
-		}
+	    memset(ROM, 0, 8);
 
-		res = OWGetTemp(ROM);
-		switch (res) {
-		    case OW_TEMP_WRONG_FAM:
-			printf("ROM specified isn't a temperature sensor\r\n");
+	    i = OWFirst(ROM, 1, 0);
+	    do {
+		switch (i) {
+		    case OW_NOMODULES:
+		    case OW_FOUND:
 			break;
-
-		    case OW_TEMP_CRC_ERR:
-			printf("CRC mismatch\r\n");
-			break;
-
-		    case OW_TEMP_NO_ROM:
-			printf("No ROM found\r\n");
-			break;
-
+		    
+		    case OW_BADWIRE:
+		    case OW_NOPRESENCE:
+		    case OW_BADCRC:
 		    default:
-			printf("%hd.%02hd\r\n", GETWHOLE(res), GETFRAC(res));
+			printf("Err %d\r\n", i);
 			break;
 		}
-	    } else if (!strncmp("zz", cmd.buf, 2)) {
-		NVIC_SystemReset();
-	    } else {
-		printf("Unknown command\r\n");
+		
+		if (i != OW_FOUND)
+		    break;
+
+		for (i = 0; i < 8; i++)
+		    printf("%02x%s", ROM[i], i == 7 ? "\r\n" : ":");
+
+		i = OWNext(ROM, 1, 0);
+	    } while (1);
+	} else if (!strcmp("rb", argv[0])) {
+	    printf("Read bit returned %d\r\n", OWReadBit());
+	} else if (!strcmp("wb", argv[0])) {
+	    if (argc != 2) {
+		fputs("Incorrect number of arguments\r\n", stdout);
+		goto out;
 	    }
+	    
+	    x = atoi(argv[1]);
+	    OWWriteBit(x);
+	    printf("Wrote %d\r\n", x);
+	} else if (!strcmp("te", argv[0])) {
+	    uint8_t	ROM[8];
+	    int16_t	res;
+	
+	    if (sscanf(argv[1], "%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) {
+		fputs("Unable to parse ROM ID\r\n", stdout);
+		goto out;
+	    }
+
+	    res = OWGetTemp(ROM);
+	    switch (res) {
+		case OW_TEMP_WRONG_FAM:
+		    printf("ROM specified isn't a temperature sensor\r\n");
+		    break;
+
+		case OW_TEMP_CRC_ERR:
+		    printf("CRC mismatch\r\n");
+		    break;
+
+		case OW_TEMP_NO_ROM:
+		    printf("No ROM found\r\n");
+		    break;
+
+		default:
+		    printf("%hd.%02hd\r\n", GETWHOLE(res), GETFRAC(res));
+		    break;
+	    }
+	} else if (!strcmp("zz", argv[0])) {
+	    NVIC_SystemReset();
+	} else {
+	    printf("Unknown command\r\n");
 	}
       out:
 	cmd.state = 0;