#ifndef STA_SENSORS_W25Q128_HPP #define STA_SENSORS_W25Q128_HPP #include #include #include #include namespace sta { /** * @brief * */ enum class BlockSize { _32KB, _64KB }; /** * @brief * */ enum class ChipState { NORMAL, POWERED_DOWN }; /** * @brief * */ enum class AddressMode { _24BIT, _32BIT }; /** * @brief * */ enum class ChunkSize { PAGE, SECTOR, BLOCK_32KB, BLOCK_64KB }; class W25Qxx { public: /** * @brief Signature for delay msec function. */ using DelayUsFunc = void (*)(uint32_t); /** * @brief Driver class for the W25QXX flash storage series. * * @param device A SPI device handle from sta-core. * @param delay A microsecond delay function. * @param addrMode Choose between 24 Bit and 32 Bit addressing. * @param mutex A mutex for thread safety if the flash chip is used by multiple threads. Defaults to a always free mutex. */ W25Qxx(SPIDevice * device, DelayUsFunc delay, AddressMode addrMode = AddressMode::_24BIT, Mutex * mutex = Mutex::ALWAYS_FREE); /** * @brief Initialize the flash chip. * * @return uint8_t Returns 1 if successful, 0 otherwise. */ uint8_t init(); /** * @brief Checks if the flash is busy writing or erasing. * * @return bool Returns true if the flash is busy, false otherwise. */ bool isBusy(); /** * @brief Set the Address Mode object * * @param addrMode * @return uint8_t */ uint8_t setAddressMode(AddressMode addrMode); /** * @brief Get the Address Mode object * * @return AddressMode */ AddressMode getAddressMode(); /** * @brief Get the chip ID * * @return uint8_t */ uint8_t getChipID(); /** * @brief Get the flash chip's manufacturer ID. * * @return uint8_t */ uint8_t getManufacturerID(); /** * @brief Get the Unique I D object * * @return uint64_t */ 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? public: /* * Read / Write operations */ /** * @brief * * @param addr * @param buffer * @param length * @return uint8_t */ uint8_t readData(uint32_t address, uint8_t * buffer, size_t length, bool fast = true); /** * @brief * * @param addr * @param buffer * @param length * @return uint8_t */ uint8_t pageProgram(uint32_t address, uint8_t * buffer, size_t length); uint8_t sectorProgram(uint32_t 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 number of the sector to erase. Here, 0 is the first sector, 1 the second and so on. * @return bool Returns 1 if the operation was successful, 0 otherwise. */ uint8_t sectorErase(uint32_t address, bool blocking = false); /** * @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(uint32_t 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 uint8_t lockBlock(uint32_t address); // Indiv Block / Sector unlock uint8_t unlockBlock(uint32_t address); // Indiv Block / Sector lock read // Global Block / Sector lock // Global Block / Sector unlock private: /** * @brief * * @param instruction * @param data * @param length * @param arguments * @param arg_length * @return uint8_t */ uint8_t busWrite(uint8_t instruction, const uint8_t * data = nullptr, size_t length = 0, uint8_t * arguments = nullptr, size_t arg_length = 0, uint32_t delayCsHigh = 0); /** * @brief * * @param instruction * @param data * @param length * @param arguments * @param arg_length * @return uint8_t */ 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(); /** * @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); private: SPIDevice * device_; DelayUsFunc delay_; Mutex * mutex_; ChipState state_; AddressMode addrMode_; }; } // namespace sta #endif // STA_SENSORS_W25Q128_HPP