// // Created by cfif on 16.09.22. // #include "Flash_MT29F2G01ABAGDWB.h" #include "SystemDelayInterface.h" // Чтение регистров uint8_t spi_flash_read_reg(tSpiPortIO *flashIO, uint16_t address, uint32_t timeout) { uint16_t operation = 0x0F; uint16_t back; SpiPortChipSelect(flashIO, timeout); SpiPortTransmit(flashIO, &operation, timeout); SpiPortReceive(flashIO, &back, timeout); SpiPortTransmit(flashIO, &address, timeout); SpiPortReceive(flashIO, &back, timeout); SpiPortTransmit(flashIO, &address, timeout); SpiPortReceive(flashIO, &back, timeout); SpiPortChipRelease(flashIO, timeout); return back; } uint8_t spi_flash_read_status(tSpiPortIO *flashIO, uint32_t timeout) { uint16_t operation = 0x0F; uint16_t address = 0xC0; uint16_t back; SpiPortChipSelect(flashIO, timeout); SpiPortTransmit(flashIO, &operation, timeout); SpiPortReceive(flashIO, &back, timeout); SpiPortTransmit(flashIO, &address, timeout); SpiPortReceive(flashIO, &back, timeout); uint32_t endMs = SystemGetMs() + timeout; uint16_t status = 1; // Ожидание готовности while ((status) && (endMs > SystemGetMs())) { SpiPortTransmit(flashIO, &address, timeout); SpiPortReceive(flashIO, &status, timeout); } SpiPortChipRelease(flashIO, timeout); if (endMs < SystemGetMs()) return 0xFF; return status; } uint16_t spi_flash_read_id(tSpiPortIO *flashIO, uint32_t timeout) { uint16_t operation = 0x9F; uint16_t dummy = 0x00; uint16_t back; uint8_t id1; uint8_t id2; SpiPortChipSelect(flashIO, timeout); SpiPortTransmit(flashIO, &operation, timeout); SpiPortReceive(flashIO, &back, timeout); SpiPortTransmit(flashIO, &dummy, timeout); SpiPortReceive(flashIO, &back, timeout); SpiPortTransmit(flashIO, &dummy, timeout); SpiPortReceive(flashIO, &back, timeout); id1 = back; SpiPortTransmit(flashIO, &dummy, timeout); SpiPortReceive(flashIO, &back, timeout); id2 = back; SpiPortChipRelease(flashIO, timeout); return (id2 << 8) | id1; } // Запись регистров void spi_flash_write_reg(tSpiPortIO *flashIO, uint16_t address, uint16_t reg, uint32_t timeout) { uint16_t operation = 0x1F; uint16_t back; SpiPortChipSelect(flashIO, timeout); SpiPortTransmit(flashIO, &operation, timeout); SpiPortReceive(flashIO, &back, timeout); SpiPortTransmit(flashIO, &address, timeout); SpiPortReceive(flashIO, &back, timeout); SpiPortTransmit(flashIO, ®, timeout); SpiPortReceive(flashIO, &back, timeout); SpiPortChipRelease(flashIO, timeout); } // Стирание uint8_t spi_flash_erase(tSpiPortIO *flashIO, uint16_t addr, uint32_t timeout) { uint16_t reg; uint16_t back; uint16_t address; // Команда разрешения записи SpiPortChipSelect(flashIO, timeout); reg = 0x06; SpiPortTransmit(flashIO, ®, timeout); SpiPortReceive(flashIO, &back, timeout); SpiPortChipRelease(flashIO, timeout); // Команда стирания блока 64 SpiPortChipSelect(flashIO, timeout); reg = 0xD8; SpiPortTransmit(flashIO, ®, timeout); SpiPortReceive(flashIO, &back, timeout); // Запись адреса (флеш) for (int i=2; i>=0; --i) { address = ((uint8_t*)&addr)[i]; SpiPortTransmit(flashIO, &address, timeout); SpiPortReceive(flashIO, &back, timeout); } SpiPortChipRelease(flashIO, timeout); uint8_t status = spi_flash_read_status(flashIO, timeout); if (status != 0) return status; // Команда запрещения записи // SpiPortChipSelect(flashIO, timeout); // reg = 0x04; // SpiPortTransmit(flashIO, ®, timeout); // SpiPortReceive(flashIO, &back, timeout); // SpiPortChipRelease(flashIO, timeout); return status; } void spi_flash_unblock(tSpiPortIO *flashIO, uint32_t timeout) { uint16_t id1 = spi_flash_read_id(flashIO, timeout); uint16_t B0_1 = spi_flash_read_reg(flashIO, 0xB0, timeout); uint16_t A0_1 = spi_flash_read_reg(flashIO, 0xA0, timeout); spi_flash_write_reg(flashIO, 0xB0, 0, timeout); spi_flash_write_reg(flashIO, 0xA0, 0, timeout); uint16_t id2 = spi_flash_read_id(flashIO, timeout); uint16_t B0_2 = spi_flash_read_reg(flashIO, 0xB0, timeout); uint16_t A0_2 = spi_flash_read_reg(flashIO, 0xA0, timeout); uint16_t a = 0; } // Максиальная длина равна 2176 uint8_t spi_flash_page_read(tSpiPortIO *flashIO, uint32_t addr, uint8_t* bufRead, uint32_t total_len, uint32_t timeout) { uint16_t reg; uint16_t address; uint16_t addressCache; uint16_t back; SpiPortChipSelect(flashIO, timeout); // Команда чтения в кэш reg = 0x13; SpiPortTransmit(flashIO, ®, timeout); SpiPortReceive(flashIO, &back, timeout); // Запись адреса (флеш) for (int i=2; i>=0; --i) { address = ((uint8_t*)&addr)[i]; SpiPortTransmit(flashIO, &address, timeout); SpiPortReceive(flashIO, &back, timeout); } SpiPortChipRelease(flashIO, timeout); uint8_t status = spi_flash_read_status(flashIO, timeout); if (status != 0) return status; SpiPortChipSelect(flashIO, timeout); // Команда чтения из кэш reg = 0x03; SpiPortTransmit(flashIO, ®, timeout); SpiPortReceive(flashIO, &back, timeout); // Запись адреса (кэш) addressCache = (((addr >> 6) & 1) << 12); for (int i=1; i>=0; --i) { address = ((uint8_t*)&addressCache)[i]; SpiPortTransmit(flashIO, &address, timeout); SpiPortReceive(flashIO, &back, timeout); } // Запись байта ожидания SpiPortTransmit(flashIO, &address, timeout); SpiPortReceive(flashIO, &back, timeout); // Чтение данных for (uint32_t i=0; i> 6) & 1) << 12); for (int i=1; i>=0; --i) { address = ((uint8_t*)&addressCache)[i]; SpiPortTransmit(flashIO, &address, timeout); SpiPortReceive(flashIO, &back, timeout); } // Запись данных for (uint32_t i=0; i=0; --i) { address = ((uint8_t*)&addr)[i]; SpiPortTransmit(flashIO, &address, timeout); SpiPortReceive(flashIO, &back, timeout); } SpiPortChipRelease(flashIO, timeout); status = spi_flash_read_status(flashIO, timeout); if (status != 0) return status; //SystemDelayMs(100); // Команда запрещения записи // SpiPortChipSelect(flashIO, timeout); // reg = 0x04; // SpiPortTransmit(flashIO, ®, timeout); // SpiPortReceive(flashIO, &back, timeout); // SpiPortChipRelease(flashIO, timeout); return status; }