Mercurial > ~darius > hgwebdir.cgi > stm32temp
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 */ +}