28 #include "SPIMemory.h"
36 #if defined (ARDUINO_ARCH_SAMD) || defined(ARCH_STM32)
37 SPIFram(uint8_t cs = CS, SPIClass *spiinterface=&SPI);
38 #elif defined (BOARD_RTL8195A)
44 bool begin(uint32_t flashChipSize = 0);
45 void setClock(uint32_t clockSpeed);
46 bool libver(uint8_t *b1, uint8_t *b2, uint8_t *b3);
47 uint8_t error(
bool verbosity =
false);
48 uint16_t getManID(
void);
49 uint32_t getJEDECID(
void);
50 uint64_t getUniqueID(
void);
51 uint32_t getAddress(uint16_t size);
52 uint16_t sizeofStr(String &inputStr);
53 uint32_t getCapacity(
void);
54 float functionRunTime(
void);
56 bool writeByte(uint32_t _addr, uint8_t data,
bool errorCheck =
true);
57 uint8_t readByte(uint32_t _addr,
bool fastRead =
false);
59 bool writeByteArray(uint32_t _addr, uint8_t *data_buffer,
size_t bufferSize,
bool errorCheck =
true);
60 bool readByteArray(uint32_t _addr, uint8_t *data_buffer,
size_t bufferSize,
bool fastRead =
false);
62 bool writeChar(uint32_t _addr, int8_t data,
bool errorCheck =
true);
63 int8_t readChar(uint32_t _addr,
bool fastRead =
false);
65 bool writeCharArray(uint32_t _addr,
char *data_buffer,
size_t bufferSize,
bool errorCheck =
true);
66 bool readCharArray(uint32_t _addr,
char *data_buffer,
size_t buffer_size,
bool fastRead =
false);
68 bool writeShort(uint32_t _addr, int16_t data,
bool errorCheck =
true);
69 int16_t readShort(uint32_t _addr,
bool fastRead =
false);
71 bool writeWord(uint32_t _addr, uint16_t data,
bool errorCheck =
true);
72 uint16_t readWord(uint32_t _addr,
bool fastRead =
false);
74 bool writeLong(uint32_t _addr, int32_t data,
bool errorCheck =
true);
75 int32_t readLong(uint32_t _addr,
bool fastRead =
false);
77 bool writeULong(uint32_t _addr, uint32_t data,
bool errorCheck =
true);
78 uint32_t readULong(uint32_t _addr,
bool fastRead =
false);
80 bool writeFloat(uint32_t _addr,
float data,
bool errorCheck =
true);
81 float readFloat(uint32_t _addr,
bool fastRead =
false);
83 bool writeStr(uint32_t _addr, String &data,
bool errorCheck =
true);
84 bool readStr(uint32_t _addr, String &data,
bool fastRead =
false);
87 template <
class T>
bool writeAnything(uint32_t _addr,
const T& data,
bool errorCheck =
true);
88 template <
class T>
bool readAnything(uint32_t _addr, T& data,
bool fastRead =
false);
90 bool eraseSection(uint32_t _addr, uint32_t _sz);
103 unsigned _createMask(
unsigned a,
unsigned b);
104 void _troubleshoot(uint8_t _code,
bool printoverride =
false);
106 bool _disableGlobalBlockProtect(
void);
107 bool _isChipPoweredDown(
void);
108 bool _prep(uint32_t _addr, uint32_t size = 0);
109 bool _startSPIBus(
void);
110 bool _beginSPI(uint8_t opcode);
111 bool _noSuspend(
void);
112 bool _notPrevWritten(uint32_t _addr, uint32_t size = 1);
113 bool _writeEnable(
bool _troubleshootEnable =
true);
114 bool _writeDisable(
void);
115 bool _getJedecId(
void);
116 bool _chipID(uint32_t flashChipSize = 0);
117 bool _transferAddress(
void);
118 bool _addressCheck(uint32_t _addr, uint32_t size = 1);
119 uint8_t _nextByte(
char IOType, uint8_t data = NULLBYTE);
120 uint16_t _nextInt(uint16_t = NULLINT);
121 void _nextBuf(uint8_t opcode, uint8_t *data_buffer, uint32_t size);
122 uint8_t _readStat1(
void);
123 template <
class T>
bool _write(uint32_t _addr,
const T& value, uint32_t _sz,
bool errorCheck, uint8_t _dataType);
124 template <
class T>
bool _read(uint32_t _addr, T& value, uint32_t _sz,
bool fastRead =
false, uint8_t _dataType = 0x00);
126 template <
class T>
bool _writeErrorCheck(uint32_t _addr,
const T& value, uint32_t _sz, uint8_t _dataType = 0x00);
128 #ifdef SPI_HAS_TRANSACTION
129 SPISettings _settings;
133 #if !defined (BOARD_RTL8195A)
139 volatile uint8_t *cs_port;
141 bool chipPoweredDown =
false;
142 bool SPIBusState =
false;
143 bool _loopedOver =
false;
144 uint8_t cs_mask, errorcode, stat1, stat2, stat3, _SPCR, _SPSR, _a0, _a1, _a2;
147 float _spifuncruntime = 0;
148 uint32_t _chipCapacity;
152 uint8_t manufacturerID;
158 uint32_t currentAddress, _currentAddress = 0;
159 uint32_t _addressOverflow =
false;
160 uint8_t _uniqueID[8];
162 const uint8_t _supportedManID[1] = {RAMTRON_FRAM_MANID};
174 template <
class T>
bool SPIFram::writeAnything(uint32_t _addr,
const T& data,
bool errorCheck) {
175 return _write(_addr, data,
sizeof(data), errorCheck, _STRUCT_);
183 template <
class T>
bool SPIFram::readAnything(uint32_t _addr, T& data,
bool fastRead) {
184 return _read(_addr, data,
sizeof(data), fastRead);
189 template <
class T>
bool SPIFram::_writeErrorCheck(uint32_t _addr,
const T& value, uint32_t _sz, uint8_t _dataType) {
190 if (!_addressCheck(_addr, _sz)) {
193 const uint8_t* p = (
const uint8_t*)(
const void*)&value;
211 _nextByte(WRITE, READDATA);
213 for (uint16_t i = 0; i < _sz; i++) {
214 if (*p++ != _nextByte(READ)) {
234 template <
class T>
bool SPIFram::_write(uint32_t _addr,
const T& value, uint32_t _sz,
bool errorCheck, uint8_t _dataType) {
237 _spifuncruntime = micros();
240 uint32_t _addrIn = _addr;
241 if(_isChipPoweredDown() || !_addressCheck(_addrIn, _sz) || !_notPrevWritten(_addrIn, _sz) || !_writeEnable()) {
244 _addrIn = _currentAddress;
247 const uint8_t* p = ((
const uint8_t*)(
const void*)&value);
250 uint32_t length = _sz;
251 uint16_t maxBytes = SPI_PAGESIZE-(_addrIn % SPI_PAGESIZE);
257 _nextByte(WRITE, PAGEPROG);
260 if (maxBytes > length) {
261 for (uint16_t i = 0; i < length; ++i) {
262 _nextByte(WRITE, *p++);
268 uint16_t data_offset = 0;
271 writeBufSz = (length<=maxBytes) ? length : maxBytes;
273 for (uint16_t i = 0; i < writeBufSz; ++i) {
274 _nextByte(WRITE, *p++);
277 if (!_addressOverflow) {
278 _currentAddress += writeBufSz;
281 if (data_offset >= _addressOverflow) {
282 _currentAddress = 0x00;
283 _addressOverflow =
false;
286 data_offset += writeBufSz;
287 length -= writeBufSz;
288 maxBytes = SPI_PAGESIZE;
289 if(!_writeEnable()) {
292 }
while (length > 0);
302 _retVal = _writeErrorCheck(_addr, value, _sz, _dataType);
305 _spifuncruntime = micros() - _spifuncruntime;
316 template <
class T>
bool SPIFram::_read(uint32_t _addr, T& value, uint32_t _sz,
bool fastRead, uint8_t _dataType) {
318 _spifuncruntime = micros();
321 if(_isChipPoweredDown() || !_addressCheck(_addr, _sz)) {
325 uint8_t* p = (uint8_t*)(
void*)&value;
327 if (_dataType == _STRING_) {
330 _nextBuf(READDATA, (uint8_t*) &(*_inChar), _sz);
332 for (uint16_t i = 0; i < _sz; i++) {
339 _nextByte(WRITE, FASTREAD);
342 _nextByte(WRITE, READDATA);
345 for (uint16_t i = 0; i < _sz; i++) {
346 *p++ =_nextByte(READ);
352 _spifuncruntime = micros() - _spifuncruntime;