/** * @file spi_flash.h * @brief W25Q64 SPI Flash driver for OTA buffer storage */ #ifndef _SPI_FLASH_H_ #define _SPI_FLASH_H_ #include #include /* W25Q64 commands */ #define FLASH_CMD_WRITE_ENABLE 0x06 #define FLASH_CMD_WRITE_DISABLE 0x04 #define FLASH_CMD_READ_STATUS1 0x05 #define FLASH_CMD_READ_STATUS2 0x35 #define FLASH_CMD_PAGE_PROGRAM 0x02 #define FLASH_CMD_READ_DATA 0x03 #define FLASH_CMD_FAST_READ 0x0B #define FLASH_CMD_SECTOR_ERASE 0x20 /* 4KB sector */ #define FLASH_CMD_BLOCK_ERASE_32K 0x52 #define FLASH_CMD_BLOCK_ERASE_64K 0xD8 #define FLASH_CMD_CHIP_ERASE 0xC7 #define FLASH_CMD_POWER_DOWN 0xB9 #define FLASH_CMD_RELEASE_PD_ID 0xAB #define FLASH_CMD_MFR_ID 0x90 #define FLASH_CMD_JEDEC_ID 0x9F /* Status register bits */ #define FLASH_SR_BUSY 0x01 #define FLASH_SR_WEL 0x02 #define FLASH_SR_BP0 0x04 #define FLASH_SR_BP1 0x08 #define FLASH_SR_BP2 0x10 #define FLASH_SR_BP3 0x20 #define FLASH_SR_TB 0x40 #define FLASH_SR_SRP 0x80 /* Geometry */ #define FLASH_PAGE_SIZE 256 #define FLASH_SECTOR_SIZE 4096 #define FLASH_BLOCK32_SIZE 32768 #define FLASH_BLOCK64_SIZE 65536 #define FLASH_TOTAL_SIZE (8 * 1024 * 1024) /* 8MB */ /** * @brief Initialize SPI Flash (SPI2 on G474) */ void FLASH_Init(void); /** * @brief Read JEDEC ID to verify presence * @return 24-bit JEDEC ID (0xEF4017 for W25Q64) */ uint32_t FLASH_ReadJEDEC(void); /** * @brief Erase a 4KB sector * @param addr Sector-aligned address * @return true on success */ bool FLASH_EraseSector(uint32_t addr); /** * @brief Erase a 64KB block * @param addr Block-aligned address * @return true on success */ bool FLASH_EraseBlock64(uint32_t addr); /** * @brief Erase entire chip * @return true on success */ bool FLASH_ChipErase(void); /** * @brief Write data to flash (page-aligned writes) * * @param addr Destination address (must be within flash range) * @param data Source data buffer * @param len Length to write (max 256 per write) * @return true on success */ bool FLASH_Write(uint32_t addr, const uint8_t *data, uint32_t len); /** * @brief Read data from flash * * @param addr Source address * @param data Output buffer * @param len Length to read */ void FLASH_Read(uint32_t addr, uint8_t *data, uint32_t len); /** * @brief Read multiple bytes via fast read * * @param addr Source address * @param data Output buffer * @param len Length to read */ void FLASH_FastRead(uint32_t addr, uint8_t *data, uint32_t len); /** * @brief Wait for previous operation to complete (poll BUSY bit) * @param timeout_ms Timeout in milliseconds (0 = no timeout) * @return true if complete, false if timeout */ bool FLASH_WaitBusy(uint32_t timeout_ms); /** * @brief Enter power-down mode (save power when not in use) */ void FLASH_PowerDown(void); /** * @brief Release power-down mode */ void FLASH_ReleasePowerDown(void); /** * @brief Check if flash is busy */ static inline bool FLASH_IsBusy(void) { uint8_t sr; /* Poll status register */ /* (Implemented in .c using SPI transaction) */ extern uint8_t FLASH_ReadStatusReg1(void); return (FLASH_ReadStatusReg1() & FLASH_SR_BUSY) != 0; } #endif /* _SPI_FLASH_H_ */