Browse Source

Flash write functions for LittleFS

teensy4-core
PaulStoffregen 4 years ago
parent
commit
8ad7ce6b54
1 changed files with 10 additions and 9 deletions
  1. +10
    -9
      teensy4/eeprom.c

+ 10
- 9
teensy4/eeprom.c View File

// Conversation about how this code works & what the upper limits are // Conversation about how this code works & what the upper limits are
// https://forum.pjrc.com/threads/57377?p=214566&viewfull=1#post214566 // https://forum.pjrc.com/threads/57377?p=214566&viewfull=1#post214566


static void flash_write(void *addr, const void *data, uint32_t len);
static void flash_erase_sector(void *addr);
// To be called from LittleFS_Program, any other use at your own risk!
void eepromemu_flash_write(void *addr, const void *data, uint32_t len);
void eepromemu_flash_erase_sector(void *addr);


static uint8_t initialized=0; static uint8_t initialized=0;
static uint16_t sector_index[FLASH_SECTORS]; static uint16_t sector_index[FLASH_SECTORS];
if (sector_index[sector] < 2048) { if (sector_index[sector] < 2048) {
//printf("ee_wr, writing\n"); //printf("ee_wr, writing\n");
uint16_t newdata = offset | (data << 8); uint16_t newdata = offset | (data << 8);
flash_write(end, &newdata, 2);
eepromemu_flash_write(end, &newdata, 2);
sector_index[sector] = sector_index[sector] + 1; sector_index[sector] = sector_index[sector] + 1;
} else { } else {
//printf("ee_wr, erase then write\n"); //printf("ee_wr, erase then write\n");
} }
buf[offset] = data; buf[offset] = data;
p = (uint16_t *)(FLASH_BASEADDR + sector * 4096); p = (uint16_t *)(FLASH_BASEADDR + sector * 4096);
flash_erase_sector(p);
eepromemu_flash_erase_sector(p);
index = 0; index = 0;
for (i=0; i < 256; i++) { for (i=0; i < 256; i++) {
if (buf[i] != 0xFF) { if (buf[i] != 0xFF) {
// TODO: combining these to larger write // TODO: combining these to larger write
// would (probably) be more efficient // would (probably) be more efficient
uint16_t newval = i | (buf[i] << 8); uint16_t newval = i | (buf[i] << 8);
flash_write(p + index, &newval, 2);
eepromemu_flash_write(p + index, &newval, 2);
index = index + 1; index = index + 1;
} }
} }
} }


// write bytes into flash memory (which is already erased to 0xFF) // write bytes into flash memory (which is already erased to 0xFF)
static void flash_write(void *addr, const void *data, uint32_t len)
void eepromemu_flash_write(void *addr, const void *data, uint32_t len)
{ {
__disable_irq(); __disable_irq();
FLEXSPI_LUTKEY = FLEXSPI_LUTKEY_VALUE; FLEXSPI_LUTKEY = FLEXSPI_LUTKEY_VALUE;
FLEXSPI_LUT60 = LUT0(CMD_SDR, PINS1, 0x32) | LUT1(ADDR_SDR, PINS1, 24); // 32 = quad write FLEXSPI_LUT60 = LUT0(CMD_SDR, PINS1, 0x32) | LUT1(ADDR_SDR, PINS1, 24); // 32 = quad write
FLEXSPI_LUT61 = LUT0(WRITE_SDR, PINS4, 1); FLEXSPI_LUT61 = LUT0(WRITE_SDR, PINS4, 1);
FLEXSPI_IPTXFCR = FLEXSPI_IPTXFCR_CLRIPTXF; // clear tx fifo FLEXSPI_IPTXFCR = FLEXSPI_IPTXFCR_CLRIPTXF; // clear tx fifo
FLEXSPI_IPCR0 = (uint32_t)addr & 0x007FFFFF;
FLEXSPI_IPCR0 = (uint32_t)addr & 0x00FFFFFF;
FLEXSPI_IPCR1 = FLEXSPI_IPCR1_ISEQID(15) | FLEXSPI_IPCR1_IDATSZ(len); FLEXSPI_IPCR1 = FLEXSPI_IPCR1_ISEQID(15) | FLEXSPI_IPCR1_IDATSZ(len);
FLEXSPI_IPCMD = FLEXSPI_IPCMD_TRG; FLEXSPI_IPCMD = FLEXSPI_IPCMD_TRG;
const uint8_t *src = (const uint8_t *)data; const uint8_t *src = (const uint8_t *)data;
} }


// erase a 4K sector // erase a 4K sector
static void flash_erase_sector(void *addr)
void eepromemu_flash_erase_sector(void *addr)
{ {
__disable_irq(); __disable_irq();
FLEXSPI_LUTKEY = FLEXSPI_LUTKEY_VALUE; FLEXSPI_LUTKEY = FLEXSPI_LUTKEY_VALUE;
while (!(FLEXSPI_INTR & FLEXSPI_INTR_IPCMDDONE)) ; // wait while (!(FLEXSPI_INTR & FLEXSPI_INTR_IPCMDDONE)) ; // wait
FLEXSPI_INTR = FLEXSPI_INTR_IPCMDDONE; FLEXSPI_INTR = FLEXSPI_INTR_IPCMDDONE;
FLEXSPI_LUT60 = LUT0(CMD_SDR, PINS1, 0x20) | LUT1(ADDR_SDR, PINS1, 24); // 20 = sector erase FLEXSPI_LUT60 = LUT0(CMD_SDR, PINS1, 0x20) | LUT1(ADDR_SDR, PINS1, 24); // 20 = sector erase
FLEXSPI_IPCR0 = (uint32_t)addr & 0x007FF000;
FLEXSPI_IPCR0 = (uint32_t)addr & 0x00FFF000;
FLEXSPI_IPCR1 = FLEXSPI_IPCR1_ISEQID(15); FLEXSPI_IPCR1 = FLEXSPI_IPCR1_ISEQID(15);
FLEXSPI_IPCMD = FLEXSPI_IPCMD_TRG; FLEXSPI_IPCMD = FLEXSPI_IPCMD_TRG;
while (!(FLEXSPI_INTR & FLEXSPI_INTR_IPCMDDONE)) ; // wait while (!(FLEXSPI_INTR & FLEXSPI_INTR_IPCMDDONE)) ; // wait

Loading…
Cancel
Save