#ifndef STA_SENSORS_W25Q128_HPP #define STA_SENSORS_W25Q128_HPP #include #include namespace sta { class W25Qxx { enum class BlockSize { _32KB, _64KB }; // TODO decide address size at compile time? Use sta/config.hpp? union Address32 { uint32_t value; uint8_t buffer[4]; uint8_t page[3]; }; union Address24 { uint32_t value; uint8_t dummy; uint8_t buffer[3]; uint8_t page[2]; }; enum class ChipState { NORMAL, POWERED_DOWN }; public: W25Qxx(SPIDevice * device); uint8_t init(); uint8_t getChipID(); uint8_t getManufacturerID(); uint64_t getUniqueID(); // TODO: SFDP register? /** * @brief Puts the chip into power-down state which significantly reduces power consumption. * * @remarks Every instruction but the releasePowerDown instruction are ignored in this state, * allowing for maximum write protection. * * @return uint8_t Returns 1 if the operation was successful, 0 otherwise. */ uint8_t powerDown(); /** * @brief * * @return uint8_t */ uint8_t releasePowerDown(); // enable reset // reset device // Extended address register read / write? // Enter 4-Byte address mode // Exit 4-Byte address mode public: /* * Status registers. */ /** * @brief Read one of the flash's status registers. * * @param regID The ID of the status register. Can only be 1, 2 or 3. * @param status_byte A pointer to the variable to write the state into. * @return uint8_t Returns 1 if successful, 0 otherwise. */ uint8_t readStatusRegister(uint8_t regID, uint8_t * status_byte); /** * @brief Write into one of the chip's status registers. * * @param regID The ID of the status register. Can only be 1, 2 or 3. * @param status_byte The byte to write into the status register. * @param nonvolatile If set to true, this setting will be restored after power off. * @return uint8_t Returns 1 if successful, 0 otherwise. */ uint8_t writeStatusRegister(uint8_t regID, uint8_t * status_byte, bool nonvolatile = false); /** * @brief Checks if the flash is busy writing or erasing. * * @return bool Returns true if the flash is busy, false otherwise. */ bool isBusy(); public: /* * Read / Write operations */ /** * @brief * * @param addr * @param buffer * @param length * @return uint8_t */ uint8_t readData(Address32 address, uint8_t * buffer, size_t length, bool fast = true); /** * @brief * * @param addr * @param buffer * @param length * @return uint8_t */ uint8_t pageProgram(Address32 address, uint8_t * buffer, size_t length); public: /* * Erase operations */ /** * @brief Sets all memory within a specified sector (4 KByte) to 1s. * * @remarks Afterwards, the device won't accept any instructions for a duration T_SE. This can be checked * by reading the busy bit. * * @param address The address of the sector to erase. * @return bool Returns 1 if the operation was successful, 0 otherwise. */ uint8_t sectorErase(Address32 address); /** * @brief Sets all memory within a specified block (32/64 KByte) to 1s. * * @remarks Afterwards, the device won't accept any instructions for a duration T_SE. This can be checked * by reading the busy bit. * * @param address The address of the block to erase. * @param blockSize The size of the block (32KByte vs 64KByte) * @return uint8_t Returns 1 if the operation was successful, 0 otherwise. */ uint8_t blockErase(Address32 address, BlockSize blockSize); /** * @brief Sets all memory on the chip to 1s. * * @return uint8_t Returns 1 if the operation was successful, 0 otherwise. */ uint8_t chipErase(); /** * @brief Suspends an ongoing sector or block erase operation. * * @remarks Chip erase operations cannot be suspended. * * @return uin8t_t Returns 1 if the operation was successful, 0 otherwise. */ uint8_t suspendErase(); /** * @brief Resumes a suspended sector or block erase operation. * * @return uint8_t Returns 1 if the operation was successful, 0 otherwise. */ uint8_t resumeErase(); // TODO: Read SUS bit public: // Erase security registers // Program security registers // Read security registers // Indiv Block / Sector lock // Indiv Block / Sector unlock // Indiv Block / Sector lock read // Global Block / Sector lock // Global Block / Sector unlock private: uint8_t busWrite(uint8_t instruction, const uint8_t * data = nullptr, size_t length = 0, uint8_t * arguments = nullptr, size_t arg_length = 0); uint8_t busRead(uint8_t instruction, uint8_t * data, size_t length, uint8_t * arguments = nullptr, size_t arg_length = 0); /** * @brief Checks if the flash is write enabled. * * @return bool Returns true if the flash is write enabled, false otherwise. */ bool isWriteEnabled(); uint8_t writeEnable(); uint8_t writeDisable(); uint8_t writeVolatileEnable(); private: SPIDevice * device_; ChipState state_; }; } // namespace sta #endif // STA_SENSORS_W25Q128_HPP