mirror of
https://git.intern.spaceteamaachen.de/ALPAKA/driver-w25qxxx.git
synced 2025-06-10 18:45:59 +00:00
338 lines
9.4 KiB
C++
338 lines
9.4 KiB
C++
#ifndef STA_SENSORS_W25Q128_HPP
|
|
#define STA_SENSORS_W25Q128_HPP
|
|
|
|
#include <sta/bus/spi/device.hpp>
|
|
//#include <sta/devices/stm32/bus/spi.hpp>
|
|
#include <sta/mutex.hpp>
|
|
|
|
#include <sta/drivers/w25qxx_defs.hpp>
|
|
|
|
#include <functional>
|
|
|
|
|
|
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();
|
|
|
|
uint32_t getChunkBytes(ChunkSize size);
|
|
|
|
/**
|
|
* @brief
|
|
*
|
|
* @note
|
|
*
|
|
* @param criterion
|
|
* @param size
|
|
* @return uint32_t
|
|
*/
|
|
|
|
|
|
/**
|
|
* @brief Find the first memory section not satisfying a given criterion using a binary search.
|
|
*
|
|
* @note This function assumes that there is a page n such that every page before n satisfies the criterion, while every page after that doesn't.
|
|
*
|
|
* @param criterion A function evaluating the criterion on a page.
|
|
* @param size The size of the memory section. Has to be one of the predefined sizes.
|
|
* @param startAddr The start address of the segment to search. Defaults to the chip's start address.
|
|
* @param endAddr The end address of the segment to search. Defaults to the chip's end address.
|
|
* @return uint32_t The last address such that the criterion is satisfied.
|
|
*/
|
|
uint32_t findLast(std::function<bool(uint8_t*)> criterion, ChunkSize size, uint32_t startAddr = 0, uint32_t endAddr = W25QXX_32B_MEM_SIZE);
|
|
|
|
/**
|
|
* @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);
|
|
|
|
/**
|
|
* @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
|