ugfx/boards/base/Mikromedia-Plus-STM32-M4/ChibiOS_Board/flash_memory.c

128 lines
3.4 KiB
C
Raw Normal View History

#include "hal.h"
#include "flash_memory.h"
static const unsigned short _SERIAL_FLASH_CMD_RDID = 0x9F; // 25P80
static const unsigned short _SERIAL_FLASH_CMD_READ = 0x03;
static const unsigned short _SERIAL_FLASH_CMD_WRITE = 0x02;
static const unsigned short _SERIAL_FLASH_CMD_WREN = 0x06;
static const unsigned short _SERIAL_FLASH_CMD_RDSR = 0x05;
static const unsigned short _SERIAL_FLASH_CMD_ERASE = 0xC7; // 25P80
static const unsigned short _SERIAL_FLASH_CMD_EWSR = 0x06; // 25P80
static const unsigned short _SERIAL_FLASH_CMD_WRSR = 0x01;
static const unsigned short _SERIAL_FLASH_CMD_SER = 0xD8; //25P80
static const SPIConfig flash_spicfg = {
0,
GPIOD,
GPIOD_FLASH_CS,
0
};
bool flash_is_write_busy(void) {
static gU8 is_write_busy_cmd[1];
is_write_busy_cmd[0] = _SERIAL_FLASH_CMD_RDSR;
gU8 result[1];
spiAcquireBus(&SPID3);
spiStart(&SPID3, &flash_spicfg);
spiSelect(&SPID3);
spiSend(&SPID3, sizeof(is_write_busy_cmd), is_write_busy_cmd);
spiReceive(&SPID3, sizeof(result), result);
spiUnselect(&SPID3);
spiReleaseBus(&SPID3);
return result[0]&0x01;
}
void flash_write_enable(void) {
spiAcquireBus(&SPID3);
spiStart(&SPID3, &flash_spicfg);
spiSelect(&SPID3);
spiSend(&SPID3, 1, &_SERIAL_FLASH_CMD_WREN);
spiUnselect(&SPID3);
spiReleaseBus(&SPID3);
}
void flash_sector_erase(gU32 sector) {
flash_write_enable();
static gU8 sector_erase_cmd[4];
sector_erase_cmd[0] = _SERIAL_FLASH_CMD_SER;
sector_erase_cmd[1] = (sector >> 16) & 0xFF;
sector_erase_cmd[2] = (sector >> 8) & 0xFF;
sector_erase_cmd[3] = sector & 0xFF;
spiAcquireBus(&SPID3);
spiStart(&SPID3, &flash_spicfg);
spiSelect(&SPID3);
spiSend(&SPID3, sizeof(sector_erase_cmd), sector_erase_cmd);
spiUnselect(&SPID3);
spiReleaseBus(&SPID3);
/* wait for complete */
while(flash_is_write_busy());
}
void flash_read(gU32 address, gMemSize bytes, gU8 *out) {
static gU8 sector_read_cmd[4];
sector_read_cmd[0] = _SERIAL_FLASH_CMD_READ;
sector_read_cmd[1] = (address >> 16) & 0xFF;
sector_read_cmd[2] = (address >> 8) & 0xFF;
sector_read_cmd[3] = address & 0xFF;
spiAcquireBus(&SPID3);
spiStart(&SPID3, &flash_spicfg);
spiSelect(&SPID3);
spiSend(&SPID3, sizeof(sector_read_cmd), sector_read_cmd);
spiReceive(&SPID3, bytes, out);
spiUnselect(&SPID3);
spiReleaseBus(&SPID3);
}
void flash_write(gU32 address, gMemSize bytes, const gU8 *data) {
static gU8 flash_write_cmd[4];
flash_write_enable();
flash_write_cmd[0] = _SERIAL_FLASH_CMD_WRITE;
flash_write_cmd[1] = (address >> 16) & 0xFF;
flash_write_cmd[2] = (address >> 8) & 0xFF;
flash_write_cmd[3] = address & 0xFF;
spiAcquireBus(&SPID3);
spiStart(&SPID3, &flash_spicfg);
spiSelect(&SPID3);
spiSend(&SPID3, sizeof(flash_write_cmd), flash_write_cmd);
spiSend(&SPID3, bytes, data);
spiUnselect(&SPID3);
spiReleaseBus(&SPID3);
/* wait for complete */
while(flash_is_write_busy());
}
bool flash_tp_calibrated(void) {
gU8 out[1];
flash_read(0x0F0000, 1, out);
return (out[0] == 0x01);
}
void flash_tp_calibration_save(gU16 instance, const gU8 *calbuf, gMemSize sz) {
if (instance) return;
flash_sector_erase(0x0F0000);
gU8 calibrated = 0x01;
flash_write(0x0F0000, 1, &calibrated);
flash_write(0x0F0001, sz, calbuf);
}
const char *flash_tp_calibration_load(gU16 instance) {
static gU8 foo[24];
if (instance) return 0;
if (!flash_tp_calibrated()) return 0;
flash_read(0x0F0001, 24, foo);
return (char *)foo;
}