Added first implementations

This commit is contained in:
dario 2024-02-07 23:50:06 +01:00
parent c5caf6bd5e
commit 839382790c
3 changed files with 272 additions and 0 deletions

View File

@ -0,0 +1,76 @@
#ifndef STA_SENSORS_W25Q128_HPP
#define STA_SENSORS_W25Q128_HPP
#include <sta/bus/spi/device.hpp>
#include <sta/sensors/w25qxx_defs.hpp>
namespace sta
{
class W25Qxx
{
public:
W25Qxx(SPIDevice * device);
uint8_t init();
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();
/**
* @brief Checks if the flash is write enabled.
*
* @return bool Returns true if the flash is write enabled, false otherwise.
*/
bool isWriteEnabled();
public:
uint8_t readData(const uint8_t * addr, uint8_t * buffer, size_t length);
uint8_t pageProgram(const uint8_t * addr, uint8_t * buffer, size_t length);
private:
uint8_t busWrite(uint8_t instruction, const uint8_t * data = nullptr, size_t length = 0);
uint8_t busRead(uint8_t instruction, uint8_t * data, size_t length);
uint8_t writeEnable();
uint8_t writeVolatileEnable();
uint8_t writeDisable();
SPIDevice * device_;
};
} // namespace sta
#endif // STA_SENSORS_W25Q128_HPP

View File

@ -0,0 +1,60 @@
#ifndef STA_SENSORS_W25QXX_DEFS_HPP
#define STA_SENSORS_W25QXX_DEFS_HPP
// W25Qxx-specific instructions
#define W25QXX_WRITE_ENABLE 0x06
#define W25QXX_VOL_SR_WRITE_ENABLE 0x06
#define W25QXX_WRITE_DISABLE 0x04
// Status register read/write instructions.
#define W25QXX_STATUS_REG_1_READ 0x05
#define W25QXX_STATUS_REG_1_WRITE 0x01
#define W25QXX_STATUS_REG_2_READ 0x35
#define W25QXX_STATUS_REG_2_WRITE 0x31
#define W25QXX_STATUS_REG_3_READ 0x15
#define W25QXX_STATUS_REG_3_WRITE 0x11
// Erase memory
#define W25QXX_CHIP_ERASE 0xC7
#define W25QXX_ERASE_SUSPEND_PROG 0x75
#define W25QXX_ERASE_RESUME_PROG 0x7A
// Power management
#define W25QXX_POWER_DOWN 0xB9
#define W25QXX_RELEASE_POWER_DOWN 0xAB
// ID reading
#define W25QXX_DEVICE_ID 0x90
#define W25QXX_JEDEC_ID 0x9F
#define W25QXX_READ_UNIQUE_ID 0x4B
#define W25QXX_GLOBAL_BLOCK_LOCK 0x7E
#define W25QXX_GLOBAL_BLOCK_UNLOCK 0x98
#define W25QXX_QPI_MODE 0x38
#define W25QXX_ENABLE_RESET 0x66
#define W25QXX_RESET_DEVICE 0x99
#define W25QXX_PAGE_PROGAM 0x02
#define W25QXX_QUAD_PAGE_PROGAM 0x32
#define W25QXX_SECTOR_ERASE 0x20
#define W25QXX_BLOCK_ERASE 0xD8
#define W25QXX_FAST_READ 0x03
#define W25QXX_FAST_READ_DUAL_OUT 0x3B
#define W25QXX_FAST_READ_QUAD_OUT 0x6B
#define W25QXX_SFDP_REG 0x5A
#define W25QXX_ERASE_SEC_REG 0x44
#define W25QXX_PROGRAM_SEC_REG 0x42
// Lock locking/unlocking/reading for individual blocks
#define W25QXX_INDIV_BLOCK_LOCK 0x36
#define W25QXX_INDIV_BLOCK_UNLOCK 0x39
#define W25QXX_READ_BLOCK_LOCK 0x3D
#define W25QXX_FAST_READ_DUAL
#endif // STA_SENSORS_W25QXX_DEFS_HPP

136
src/w25qxx.cpp Normal file
View File

@ -0,0 +1,136 @@
#include <sta/sensors/w25qxx.hpp>
namespace sta
{
W25Qxx::W25Qxx(SPIDevice * device)
: device_{device}
{
}
uint8_t W25Qxx::init()
{
return 1;
}
bool W25Qxx::isBusy()
{
uint8_t status = 0;
readStatusRegister(1, &status);
return (0x01 & status) == 0x01;
}
uint8_t
uint8_t W25Qxx::readData(const uint8_t * addr, uint8_t * buffer, size_t length)
{
device_->beginTransmission();
const uint8_t instruction = W25QXX_FAST_READ;
device_->transfer(&instruction, 1);
device_->transfer(addr, 3);
device_->receive(buffer, length);
return 1;
}
uint8_t W25Qxx::busWrite(uint8_t instruction, const uint8_t * data /* = nullptr */, size_t length /* = 0 */)
{
return 1;
}
uint8_t W25Qxx::busRead(uint8_t instruction, uint8_t * data, size_t length)
{
return 1;
}
uint8_t W25Qxx::writeEnable()
{
return busWrite(W25QXX_WRITE_ENABLE);
}
uint8_t W25Qxx::writeVolatileEnable()
{
return busWrite(W25QXX_VOL_SR_WRITE_ENABLE);
}
uint8_t W25Qxx::writeDisable()
{
return busWrite(W25QXX_WRITE_DISABLE);
}
uint8_t W25Qxx::readStatusRegister(uint8_t regID, uint8_t * status_byte)
{
if (regID == 1)
{
return busRead(W25QXX_STATUS_REG_1_READ, status_byte, 1);
}
if (regID == 2)
{
return busRead(W25QXX_STATUS_REG_2_READ, status_byte, 1);
}
if (regID == 3)
{
return busRead(W25QXX_STATUS_REG_3_READ, status_byte, 1);
}
return 0;
}
uint8_t W25Qxx::writeStatusRegister(uint8_t regID, uint8_t * status_byte, bool nonvolatile /* = false */)
{
if (!writeEnable())
{
return 0;
}
if (!nonvolatile)
{
uint8_t rslt = writeVolatileEnable();
if (rslt == 0)
{
return 0;
}
}
if (regID == 1)
{
return busRead(W25QXX_STATUS_REG_1_READ, status_byte, 1);
}
if (regID == 2)
{
return busRead(W25QXX_STATUS_REG_2_READ, status_byte, 1);
}
if (regID == 3)
{
return busRead(W25QXX_STATUS_REG_3_READ, status_byte, 1);
}
return 0;
}
uint8_t W25Qxx::pageProgram(const uint8_t * addr, uint8_t * buffer, size_t length)
{
if (!writeEnable())
{
return 0;
}
device_->beginTransmission();
uint8_t instruction = W25QXX_PAGE_PROGAM;
device_->transfer(&instruction, 1);
device_->transfer(buffer, length);
device_->endTransmission();
return 1;
}
} // namespace sta