Mercurial > ~darius > hgwebdir.cgi > stm32temp
view 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 source
#include <stdio.h> #include <stdint.h> #include <string.h> #include <stdlib.h> #include "stm32f10x.h" #include "spi.h" #include "flash.h" #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; FL_SELECT(); /* Select device */ SPI_WriteByte(FL_RDID); /* Send command */ SPI_WriteByte(0x00); /* Send address cycles (ID data starts at 0) */ SPI_WriteByte(0x00); SPI_WriteByte(0x00); fac = SPI_WriteByte(0x00); /* Read ID */ dev = SPI_WriteByte(0x00); FL_DESELECT(); /* De-select device */ 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; 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; } void flashwritestatus(uint8_t status) { /* Enable status write */ FL_SELECT(); /* Select device */ SPI_WriteByte(FL_EWSR); /* Send command */ SPI_WriteByte(0x00); /* Send data byte */ FL_DESELECT(); /* Actually write status */ 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 */ } 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 */ }