diff flash.c @ 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 58d76cf522ff
children a9cc07caa801
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 */
+}