2022-02-16 21:42:29 +01:00
|
|
|
#include "drivers/SpiNorFlash.h"
|
|
|
|
#include <hal/nrf_gpio.h>
|
|
|
|
#include <libraries/log/nrf_log.h>
|
|
|
|
#include "drivers/Spi.h"
|
2022-05-15 22:15:19 +02:00
|
|
|
#include <filesystem>
|
|
|
|
#include <iostream>
|
2022-05-15 22:46:07 +02:00
|
|
|
#include <stdexcept>
|
2022-02-16 21:42:29 +01:00
|
|
|
|
|
|
|
using namespace Pinetime::Drivers;
|
|
|
|
|
2022-05-15 22:15:19 +02:00
|
|
|
SpiNorFlash::SpiNorFlash(const std::string& memoryFilePath) : memoryFilePath{memoryFilePath} {
|
|
|
|
namespace fs = std::filesystem;
|
|
|
|
fs::path f{ memoryFilePath };
|
|
|
|
if (fs::exists(f)) {
|
|
|
|
memoryFile = std::fstream(memoryFilePath, std::ios::binary | std::fstream::in | std::fstream::out);
|
|
|
|
} else {
|
|
|
|
memoryFile = std::fstream(memoryFilePath, std::ios::trunc | std::ios::binary | std::fstream::in | std::fstream::out);
|
|
|
|
memoryFile.seekp(memorySize - 1);
|
|
|
|
memoryFile.write("", 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
SpiNorFlash::~SpiNorFlash() {
|
|
|
|
if (memoryFile.is_open()) {
|
|
|
|
memoryFile.close();
|
|
|
|
}
|
2022-02-16 21:42:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void SpiNorFlash::Init() {
|
|
|
|
device_id = ReadIdentificaion();
|
|
|
|
NRF_LOG_INFO(
|
|
|
|
"[SpiNorFlash] Manufacturer : %d, Memory type : %d, memory density : %d", device_id.manufacturer, device_id.type, device_id.density);
|
|
|
|
}
|
|
|
|
|
|
|
|
void SpiNorFlash::Uninit() {
|
|
|
|
}
|
|
|
|
|
|
|
|
void SpiNorFlash::Sleep() {
|
|
|
|
NRF_LOG_INFO("[SpiNorFlash] Sleep")
|
|
|
|
}
|
|
|
|
|
|
|
|
void SpiNorFlash::Wakeup() {
|
|
|
|
NRF_LOG_INFO("[SpiNorFlash] Wakeup")
|
|
|
|
}
|
|
|
|
|
|
|
|
SpiNorFlash::Identification SpiNorFlash::ReadIdentificaion() {
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
|
|
|
uint8_t SpiNorFlash::ReadStatusRegister() {
|
2022-05-15 22:15:19 +02:00
|
|
|
return 0;
|
2022-02-16 21:42:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
bool SpiNorFlash::WriteInProgress() {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool SpiNorFlash::WriteEnabled() {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint8_t SpiNorFlash::ReadConfigurationRegister() {
|
2022-05-15 22:15:19 +02:00
|
|
|
return 0;
|
2022-02-16 21:42:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void SpiNorFlash::Read(uint32_t address, uint8_t* buffer, size_t size) {
|
2022-05-15 22:15:19 +02:00
|
|
|
static_assert(sizeof(uint8_t) == sizeof(char));
|
2022-05-15 22:46:07 +02:00
|
|
|
if (address + size * sizeof(uint8_t) > memorySize) {
|
|
|
|
throw std::runtime_error("SpiNorFlash::Read out of bounds");
|
|
|
|
}
|
2022-05-15 22:15:19 +02:00
|
|
|
memoryFile.seekp(address);
|
|
|
|
memoryFile.read(reinterpret_cast<char *>(buffer), size);
|
2022-02-16 21:42:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void SpiNorFlash::WriteEnable() {
|
2022-05-15 22:15:19 +02:00
|
|
|
|
2022-02-16 21:42:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void SpiNorFlash::SectorErase(uint32_t sectorAddress) {
|
2022-05-15 22:15:19 +02:00
|
|
|
|
2022-02-16 21:42:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
uint8_t SpiNorFlash::ReadSecurityRegister() {
|
2022-05-15 22:15:19 +02:00
|
|
|
return 0;
|
2022-02-16 21:42:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
bool SpiNorFlash::ProgramFailed() {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool SpiNorFlash::EraseFailed() {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SpiNorFlash::Write(uint32_t address, const uint8_t* buffer, size_t size) {
|
2022-05-15 22:46:07 +02:00
|
|
|
if (address + size * sizeof(uint8_t) > memorySize) {
|
|
|
|
throw std::runtime_error("SpiNorFlash::Write out of bounds");
|
|
|
|
}
|
2022-05-15 22:15:19 +02:00
|
|
|
memoryFile.seekp(address);
|
|
|
|
memoryFile.write(reinterpret_cast<const char *>(buffer), size);
|
|
|
|
memoryFile.flush();
|
2022-02-16 21:42:29 +01:00
|
|
|
}
|