Mercurial > ~darius > hgwebdir.cgi > stm32temp
diff spiflash.c @ 83:05ba84c7da97
Add a flash layer for compatibility (in future).
Fix SPI flash block writing.
White space fixes.
author | Daniel O'Connor <darius@dons.net.au> |
---|---|
date | Mon, 02 Mar 2015 14:32:08 +1030 |
parents | 1a4573062b37 |
children |
line wrap: on
line diff
--- a/spiflash.c Mon Mar 02 14:31:16 2015 +1030 +++ b/spiflash.c Mon Mar 02 14:32:08 2015 +1030 @@ -27,108 +27,20 @@ static int writestate = RW_IDLE; static int readstate = RW_IDLE; -#if 0 -void -spiflashcmd(int argc, char **argv) { - uint8_t status, tmp, len; - uint32_t addr; - - if (argc == 0) { - fputs("No command specified\n", stdout); - return; - } - - if (!strcmp(argv[0], "str")) { - status = spiflashreadstatus(); - 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)\n", status); - } else if (!strcmp(argv[0], "stw")) { - if (argc != 2) { - fputs("Incorrect number of arguments\n", stdout); - return; - } - tmp = atoi(argv[1]); - spiflashwritestatus(tmp); - status = spiflashreadstatus(); - printf("Wrote 0x%02x to status, now 0x%02x\n", tmp, status); - } else if (!strcmp(argv[0], "er")) { - if (argc != 2) { - fputs("Incorrect number of arguments\n", stdout); - return; - } - addr = atoi(argv[1]); - spiflash4kerase(addr); - printf("Erased 0x%x\n", (unsigned int)addr); - } else if (!strcmp(argv[0], "rd")) { - if (argc < 2) { - fputs("Incorrect number of arguments\n", stdout); - return; - } - - addr = atoi(argv[1]); - if (argc > 2) - len = atoi(argv[2]); - else - len = 16; - - spiflashstartread(addr); - - for (uint32_t i = 0; i < len; i++) - printf("Read 0x%02x from 0x%06x\n", spiflashreadbyte(), (unsigned int)(addr + i)); - spiflashstopread(); - - fputs("\n", stdout); - } else if (!strcmp(argv[0], "wr")) { - if (argc < 2) { - fputs("Incorrect number of arguments\n", stdout); - return; - } - - addr = atoi(argv[1]); - - if (argc > 2) - len = atoi(argv[2]); - else - len = 16; - - for (int i = 0; i < 16; i += 2) { - uint16_t data; - data = ((i + 1) << 8) | i; - printf("Writing 0x%04x to 0x%06x\n", data, (unsigned int)(addr + i)); - - if (i == 0) - spiflashstartwrite(addr, data); - else - spiflashwriteword(data); - } - spiflashstopwrite(); - } else if (!strcmp(argv[0], "id")) { - printf("Flash ID = 0x%04hx (expect 0xbf41)\n", spiflashreadid()); - } else { - fputs("Unknown sub command\n", stdout); - return; - } -} -#endif void spiflash4kerase(uint32_t addr) { - spiflashenablewrite(); /* Enable writing */ - + spiflashenablewrite(); /* Enable writing */ + FL_SELECT(); /* Select device */ SPI_WriteByte(FL_4KERASE); /* Send command */ SPI_WriteByte(addr >> 16); /* Send address */ SPI_WriteByte(addr >> 8); SPI_WriteByte(addr); - + FL_DESELECT(); - + //fputs("4k erase ", stdout); spiflashwait(); } @@ -136,7 +48,7 @@ void spiflashwait(void) { uint8_t cnt; - + /* Wait for not BUSY */ for (cnt = 0; (spiflashreadstatus() & FL_BUSY) != 0; cnt++) ; @@ -147,7 +59,7 @@ uint16_t spiflashreadid(void) { uint8_t fac, dev; - + FL_SELECT(); /* Select device */ SPI_WriteByte(FL_RDID); /* Send command */ @@ -156,7 +68,7 @@ SPI_WriteByte(0x00); fac = SPI_WriteByte(0x00); /* Read ID */ dev = SPI_WriteByte(0x00); - + FL_DESELECT(); /* De-select device */ return fac << 8 | dev; @@ -167,20 +79,20 @@ FL_SELECT(); /* Select device */ SPI_WriteByte(FL_WREN); /* Send command */ - + FL_DESELECT(); /* De-select device */ } uint8_t spiflashreadstatus(void) { uint8_t status; - + FL_SELECT(); /* Select device */ SPI_WriteByte(FL_RDSR); /* Send command */ SPI_WriteByte(0x00); /* Send dummy byte for address cycle */ status = SPI_WriteByte(0x00); /* Read status */ - + FL_DESELECT(); /* De-select device */ return status; @@ -195,7 +107,7 @@ FL_DESELECT(); /* Actually write status */ - FL_SELECT(); /* Re-select device for new command */ + FL_SELECT(); /* Re-select device for new command */ SPI_WriteByte(FL_WRSR); /* Send command */ SPI_WriteByte(status); /* Send data byte */ FL_DESELECT(); /* De-select device */ @@ -204,7 +116,7 @@ uint8_t spiflashread(uint32_t addr) { uint8_t data; - + FL_SELECT(); /* Select device */ SPI_WriteByte(FL_READ); /* Send command */ @@ -212,7 +124,7 @@ SPI_WriteByte(addr >> 8); SPI_WriteByte(addr); data = SPI_WriteByte(0x00); /* Read data */ - + FL_DESELECT(); /* De-select device */ return data; @@ -230,7 +142,7 @@ SPI_WriteByte(addr >> 8); SPI_WriteByte(addr); SPI_WriteByte(data); /* Write data */ - + FL_DESELECT(); /* De-select device */ } @@ -243,7 +155,7 @@ void spiflashstartread(uint32_t addr) { assert(readstate == RW_IDLE); - + FL_SELECT(); /* Select device */ SPI_WriteByte(FL_READ); /* Send command */ @@ -269,7 +181,7 @@ readstate = RW_IDLE; } -/* +/* * Auto increment writing looks like so * * Enable writing CS, WREN, nCS @@ -284,8 +196,8 @@ void spiflashstartwrite(uint32_t addr, uint16_t data) { assert(writestate == RW_IDLE); - - spiflashenablewrite(); /* Enable writes */ + + spiflashenablewrite(); /* Enable writes */ FL_SELECT(); /* Select device */ @@ -305,7 +217,7 @@ void spiflashwriteword(uint16_t data) { assert(writestate == RW_RUNNING); - + //fputs("write word ", stdout); spiflashwait(); /* Wait until not busy */ @@ -339,17 +251,22 @@ int spiflashreadblock(uint32_t addr, uint32_t len, void *_data) { - uint8_t *data = _data; - uint32_t flashcrc, ramcrc; + uint32_t *data = _data; + uint32_t flashcrc, ramcrc, tmp; /* Must be a multiple of 4 due to CRC check */ assert(len % 4 == 0); spiflashstartread(addr); - CRC_ResetDR(); - for (int i = len; i > 0; i--) { - *data = spiflashreadbyte(); - CRC_CalcCRC(*data); + CRC_ResetDR(); + for (int i = len; i > 0; i -= 4) { + tmp = spiflashreadbyte() | + spiflashreadbyte() << 8 | + spiflashreadbyte() << 16 | + spiflashreadbyte() << 24; + + *data = tmp; + CRC_CalcCRC(tmp); data++; } @@ -361,8 +278,8 @@ spiflashstopread(); ramcrc = CRC_GetCRC(); - - /* printf("RAM CRC 0x%08x Flash CRC 0x%08x\n", (uint)ramcrc, (uint)flashcrc); */ + + //printf("RAM CRC 0x%08x Flash CRC 0x%08x\n", (uint)ramcrc, (uint)flashcrc); if (ramcrc == flashcrc) return 1; else @@ -371,14 +288,20 @@ uint32_t spiflashcrcblock(uint32_t addr, uint32_t len) { + uint32_t tmp; + assert(len % 4 == 0); - CRC_ResetDR(); + CRC_ResetDR(); spiflashstartread(addr); - for (int i = len; i > 0; i--) - CRC_CalcCRC(spiflashreadbyte()); - + for (; len > 0; len -= 4) { + tmp = spiflashreadbyte() | + spiflashreadbyte() << 8 | + spiflashreadbyte() << 16 | + spiflashreadbyte() << 24; + CRC_CalcCRC(tmp); + } spiflashstopread(); return CRC_GetCRC(); @@ -387,54 +310,60 @@ int spiflashwriteblock(uint32_t addr, uint32_t len, void *_data) { uint16_t *data = _data; - uint32_t crc, vcrc; - + uint32_t crc, vcrc, tmp; + //printf("Writing %u bytes to 0x%06x\n", (uint)len, (uint)addr); - + /* Ensure data is * - 16 bit aligned * - a multiple of 32 bits in length (for CRCs, the flash only need 16 bits) - * - not longer than a sector + * - not longer than a sector */ assert(addr % 2 == 0); assert(len % 4 == 0); assert(len <= 4096); - + /* Disable write protect */ spiflashwritestatus(0x00); /* Erase sector */ spiflash4kerase(addr); - - CRC_ResetDR(); /* Write data */ - for (uint i = 0; i < len / 2; i++) { + CRC_ResetDR(); + for (uint i = 0; i < len / 2; i++) { + //printf("0x%04x: %04x\n", i, *data); if (i == 0) spiflashstartwrite(addr, *data); else spiflashwriteword(*data); - CRC_CalcCRC(*data); + + if (i % 2 == 0) + tmp = *data; + else { + tmp |= *data << 16; + CRC_CalcCRC(tmp); + } data++; } - /* Calculate CRC */ - crc = CRC_GetCRC(); - - //printf("CRC is 0x%08x\n", (uint)crc); - - /* Write CRC */ - spiflashwriteword(crc); - spiflashwriteword(crc >> 16); - - spiflashstopwrite(); + /* Calculate CRC */ + crc = CRC_GetCRC(); + //printf("CRC is 0x%08x\n", (uint)crc); + + /* Write CRC */ + spiflashwriteword(crc); + spiflashwriteword(crc >> 16); - /* Read back and check CRC */ - vcrc = spiflashcrcblock(addr, len); - if (vcrc != crc) - return 1; - else - return 0; + spiflashstopwrite(); + + /* Read back and check CRC */ + vcrc = spiflashcrcblock(addr, len); + //printf("CRC read back as 0x%08x\n", (uint)vcrc); + if (vcrc != crc) + return 1; + else + return 0; } void