Updated implementation for driver

This commit is contained in:
dario
2024-02-11 14:12:49 +01:00
parent 839382790c
commit 517510c204
3 changed files with 296 additions and 32 deletions

View File

@@ -1,12 +1,16 @@
#include <sta/sensors/w25qxx.hpp>
#include <string.h>
#include <sta/debug/assert.hpp>
namespace sta
{
W25Qxx::W25Qxx(SPIDevice * device)
: device_{device}
: device_{device},
state_{ChipState::NORMAL}
{
STA_ASSERT(device != nullptr);
}
uint8_t W25Qxx::init()
@@ -16,6 +20,41 @@ namespace sta
return 1;
}
uint8_t W25Qxx::getChipID()
{
uint8_t buffer[4];
busRead(W25QXX_RELEASE_POWER_DOWN, buffer, 3);
return buffer[3];
}
uint8_t W25Qxx::getManufacturerID()
{
Address24 address = {0};
uint8_t id;
busRead(W25QXX_JEDEC_ID, &id, 1, address.buffer, 3);
return id;
}
uint64_t W25Qxx::getUniqueID()
{
uint8_t dummy[4];
uint8_t id[8];
busRead(W25QXX_READ_UNIQUE_ID, id, 8, dummy, 4);
uint64_t id_complete;
for (size_t i; i < 8; i++)
{
id_complete |= id[i] << (7-i) * 8;
}
return id_complete;
}
bool W25Qxx::isBusy()
{
uint8_t status = 0;
@@ -24,26 +63,46 @@ namespace sta
return (0x01 & status) == 0x01;
}
uint8_t
uint8_t W25Qxx::readData(const uint8_t * addr, uint8_t * buffer, size_t length)
uint8_t W25Qxx::readData(Address32 addr, uint8_t * buffer, size_t length, bool fast /* = true */)
{
device_->beginTransmission();
const uint8_t instruction = W25QXX_FAST_READ;
uint8_t instruction = fast ? W25QXX_FAST_READ : W25QXX_FAST_READ;
device_->transfer(&instruction, 1);
device_->transfer(addr, 3);
// In fast mode we have to send a 8 dummy clock cycles first.
if (fast)
{
uint8_t dummy = 0;
device_->transfer(&dummy, 1);
}
device_->transfer(addr.buffer, sizeof(addr));
device_->receive(buffer, length);
device_->endTransmission();
return 1;
}
uint8_t W25Qxx::busWrite(uint8_t instruction, const uint8_t * data /* = nullptr */, size_t length /* = 0 */)
uint8_t W25Qxx::pageProgram(Address32 addr, uint8_t * buffer, size_t length)
{
if (!writeEnable())
{
return 0;
}
// TODO: sizeof(addr)-1 doesn't work for 24 bit addresses.
return busWrite(W25QXX_PAGE_PROGAM, buffer, length, addr.page, sizeof(addr)-1);
// TODO: Does this reset the writeEnable bit?
}
uint8_t W25Qxx::busWrite(uint8_t instruction, const uint8_t * data /* = nullptr */, size_t length /* = 0 */, uint8_t * arguments /* = nullptr */, size_t arg_length /* = 0 */)
{
return 1;
}
uint8_t W25Qxx::busRead(uint8_t instruction, uint8_t * data, size_t length)
uint8_t W25Qxx::busRead(uint8_t instruction, uint8_t * data, size_t length, uint8_t * arguments /* = nullptr */, size_t arg_length /* = 0 */)
{
return 1;
}
@@ -118,19 +177,70 @@ namespace sta
return 0;
}
uint8_t W25Qxx::pageProgram(const uint8_t * addr, uint8_t * buffer, size_t length)
bool W25Qxx::isWriteEnabled()
{
}
uint8_t W25Qxx::sectorErase(Address32 address)
{
if (!writeEnable())
{
return 0;
}
device_->beginTransmission();
uint8_t instruction = W25QXX_PAGE_PROGAM;
device_->transfer(&instruction, 1);
device_->transfer(buffer, length);
device_->endTransmission();
return busWrite(W25QXX_SECTOR_ERASE, address.buffer, sizeof(address));
}
return 1;
uint8_t W25Qxx::blockErase(Address32 address, BlockSize blockSize)
{
if (!writeEnable())
{
return 0;
}
if (blockSize == BlockSize::_32KB)
{
return busWrite(W25QXX_BLOCK_ERASE_32_KB, address.buffer, sizeof(address));
}
else
{
return busWrite(W25QXX_BLOCK_ERASE_64_KB, address.buffer, sizeof(address));
}
}
uint8_t W25Qxx::chipErase()
{
if (!writeEnable())
{
return 0;
}
return busWrite(W25QXX_CHIP_ERASE);
}
uint8_t W25Qxx::suspendErase()
{
return busWrite(W25QXX_ERASE_SUSPEND_PROG);
}
uint8_t W25Qxx::resumeErase()
{
return busWrite(W25QXX_ERASE_RESUME_PROG);
}
uint8_t W25Qxx::powerDown()
{
return busWrite(W25QXX_POWER_DOWN);
}
uint8_t W25Qxx::releasePowerDown()
{
if (state_ == ChipState::POWERED_DOWN)
{
return busWrite(W25QXX_RELEASE_POWER_DOWN);
}
return 0;
}
} // namespace sta