Mercurial > ~darius > hgwebdir.cgi > stm32temp
diff flash.c @ 25:a9cc07caa801
Add stream read/write commands.
author | Daniel O'Connor <darius@dons.net.au> |
---|---|
date | Sat, 17 Nov 2012 12:18:24 +1030 |
parents | bd8e2cf04034 |
children | 74efdb21ae5d |
line wrap: on
line diff
--- a/flash.c Sat Nov 17 12:17:58 2012 +1030 +++ b/flash.c Sat Nov 17 12:18:24 2012 +1030 @@ -2,6 +2,7 @@ #include <stdint.h> #include <string.h> #include <stdlib.h> +#include <assert.h> #include "stm32f10x.h" #include "spi.h" @@ -20,7 +21,14 @@ "AAI", "BPL" }; - + +#define RW_IDLE 0 +#define RW_RUNNING 1 +#define RW_IDLE 0 + +static int writestate = RW_IDLE; +static int readstate = RW_IDLE; + void flashcmd(char **argv, int argc) { uint8_t status, tmp; @@ -63,8 +71,12 @@ } tmp = atoi(argv[1]); + flashstartread(tmp); + for (int i = 0; i < 16; i++) - printf("Read 0x%02x from 0x%06x\r\n", flashread(tmp + i), tmp + i); + printf("Read 0x%02x from 0x%06x\r\n", flashreadbyte(), tmp + i); + flashstopread(); + fputs("\r\n", stdout); } else if (!strcmp(argv[0], "wr")) { if (argc != 2) { @@ -74,11 +86,17 @@ 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); + for (int i = 0; i < 16; i += 2) { + uint16_t data; + data = ((i + 1) << 8) | i; + printf("Writing 0x%04x to 0x%06x\r\n", data, tmp + i); + + if (i == 0) + flashstartwrite(tmp, data); + else + flashwriteword(data); } - + flashstopwrite(); } else if (!strcmp(argv[0], "id")) { printf("Flash ID = 0x%04hx (expect 0xbf41)\r\n", flashreadid()); } else { @@ -89,19 +107,24 @@ 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 */ + SPI_WriteByte(addr >> 16); /* Send address */ + SPI_WriteByte(addr >> 8); + SPI_WriteByte(addr); FL_DESELECT(); + flashwait(); +} + +void +flashwait(void) { + uint8_t cnt; + /* Wait for not BUSY */ for (cnt = 0; (flashreadstatus() & FL_BUSY) != 0; cnt++) ; @@ -173,9 +196,9 @@ 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 */ + SPI_WriteByte(addr >> 16); /* Send address */ + SPI_WriteByte(addr >> 8); + SPI_WriteByte(addr); data = SPI_WriteByte(0x00); /* Read data */ FL_DESELECT(); /* De-select device */ @@ -190,10 +213,111 @@ 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(addr >> 16); /* Send address */ + SPI_WriteByte(addr >> 8); + SPI_WriteByte(addr); SPI_WriteByte(data); /* Write data */ FL_DESELECT(); /* De-select device */ + } + +/* + * fStream reading looks like so + * + */ + +void +flashstartread(uint32_t addr) { + assert(readstate == RW_IDLE); + + FL_SELECT(); /* Select device */ + + SPI_WriteByte(FL_READ); /* Send command */ + SPI_WriteByte(addr >> 16); /* Send address */ + SPI_WriteByte(addr >> 8); + SPI_WriteByte(addr); + + readstate = RW_RUNNING; +} + +uint8_t +flashreadbyte(void) { + assert(readstate == RW_RUNNING); + return SPI_WriteByte(0x00); /* Read data */ +} + +void +flashstopread(void) { + assert(readstate == RW_RUNNING); + + FL_DESELECT(); + + readstate = RW_IDLE; +} + +/* + * Auto increment writing looks like so + * + * Enable writing CS, WREN, nCS + * Send start address & first data word CS, AAI + addr + data, nCS + * Send subsequent words wait for nBUSY, CS, AAI + data, nCS + * ... + * Disable writing CS, WRDI, nCS + * + * XXX: EBSY command links SO to flash busy state, I don't think the + * STM32 could sample it without switching out of SPI mode. + */ +void +flashstartwrite(uint32_t addr, uint16_t data) { + assert(writestate == RW_IDLE); + + flashenablewrite(); /* Enable writes */ + + FL_SELECT(); /* Select device */ + + SPI_WriteByte(FL_AAIWP); /* Send command */ + SPI_WriteByte(addr >> 16); + SPI_WriteByte(addr >> 8); + SPI_WriteByte(addr & 0xff); /* Send address */ + + SPI_WriteByte(data & 0xff); /* Write LSB */ + SPI_WriteByte(data >> 8); /* Write MSB */ + + FL_DESELECT(); + + writestate = RW_RUNNING; +} + +void +flashwriteword(uint16_t data) { + assert(writestate == RW_RUNNING); + + flashwait(); /* Wait until not busy */ + + FL_SELECT(); /* Select device */ + + SPI_WriteByte(FL_AAIWP); /* Send command */ + SPI_WriteByte(data & 0xff); /* Write LSB */ + SPI_WriteByte(data >> 8); /* Write MSB */ + + FL_DESELECT(); /* De-select device */ +} + +void +flashstopwrite(void) { + assert(writestate == RW_RUNNING); + + flashwait(); /* Wait until not busy */ + + FL_SELECT(); /* Select device */ + + SPI_WriteByte(FL_WRDI); /* Send command */ + + FL_DESELECT(); /* Deselect device */ + + flashwait(); /* Wait until not busy */ + + writestate = RW_IDLE; +} +