30 #include "SPIMemory.h"
36 #if defined (ARDUINO_ARCH_SAMD) || defined(ARCH_STM32) || defined(ARDUINO_ARCH_ESP32)
37 SPIFlash(uint8_t cs = CS, SPIClass *spiinterface=&SPI);
38 #elif defined (BOARD_RTL8195A)
45 bool begin(uint32_t flashChipSize = 0);
46 #ifdef SPI_HAS_TRANSACTION
47 void setClock(uint32_t clockSpeed);
49 void setClock(uint8_t clockdiv);
51 bool libver(uint8_t *b1, uint8_t *b2, uint8_t *b3);
52 bool sfdpPresent(
void);
53 uint8_t error(
bool verbosity =
false);
54 uint16_t getManID(
void);
55 uint32_t getJEDECID(
void);
56 uint64_t getUniqueID(
void);
57 uint32_t getAddress(uint16_t size);
58 uint16_t sizeofStr(String &inputStr);
59 uint32_t getCapacity(
void);
60 uint32_t getMaxPage(
void);
61 float functionRunTime(
void);
63 bool writeByte(uint32_t _addr, uint8_t data,
bool errorCheck =
true);
64 uint8_t readByte(uint32_t _addr,
bool fastRead =
false);
66 bool writeByteArray(uint32_t _addr, uint8_t *data_buffer,
size_t bufferSize,
bool errorCheck =
true);
67 bool readByteArray(uint32_t _addr, uint8_t *data_buffer,
size_t bufferSize,
bool fastRead =
false);
69 bool writeChar(uint32_t _addr, int8_t data,
bool errorCheck =
true);
70 int8_t readChar(uint32_t _addr,
bool fastRead =
false);
72 bool writeCharArray(uint32_t _addr,
char *data_buffer,
size_t bufferSize,
bool errorCheck =
true);
73 bool readCharArray(uint32_t _addr,
char *data_buffer,
size_t buffer_size,
bool fastRead =
false);
75 bool writeShort(uint32_t _addr, int16_t data,
bool errorCheck =
true);
76 int16_t readShort(uint32_t _addr,
bool fastRead =
false);
78 bool writeWord(uint32_t _addr, uint16_t data,
bool errorCheck =
true);
79 uint16_t readWord(uint32_t _addr,
bool fastRead =
false);
81 bool writeLong(uint32_t _addr, int32_t data,
bool errorCheck =
true);
82 int32_t readLong(uint32_t _addr,
bool fastRead =
false);
84 bool writeULong(uint32_t _addr, uint32_t data,
bool errorCheck =
true);
85 uint32_t readULong(uint32_t _addr,
bool fastRead =
false);
87 bool writeFloat(uint32_t _addr,
float data,
bool errorCheck =
true);
88 float readFloat(uint32_t _addr,
bool fastRead =
false);
90 bool writeStr(uint32_t _addr, String &data,
bool errorCheck =
true);
91 bool readStr(uint32_t _addr, String &data,
bool fastRead =
false);
94 template <
class T>
bool writeAnything(uint32_t _addr,
const T& data,
bool errorCheck =
true);
95 template <
class T>
bool readAnything(uint32_t _addr, T& data,
bool fastRead =
false);
97 bool eraseSection(uint32_t _addr, uint32_t _sz);
98 bool eraseSector(uint32_t _addr);
99 bool eraseBlock32K(uint32_t _addr);
100 bool eraseBlock64K(uint32_t _addr);
101 bool eraseChip(
void);
103 bool suspendProg(
void);
104 bool resumeProg(
void);
105 bool powerDown(
void);
115 unsigned _createMask(
unsigned a,
unsigned b);
116 void _troubleshoot(uint8_t _code,
bool printoverride =
false);
118 bool _disableGlobalBlockProtect(
void);
119 bool _isChipPoweredDown(
void);
120 bool _prep(uint8_t opcode, uint32_t _addr, uint32_t size = 0);
121 bool _startSPIBus(
void);
122 bool _beginSPI(uint8_t opcode);
123 bool _noSuspend(
void);
124 bool _notBusy(uint32_t timeout = BUSY_TIMEOUT);
125 bool _notPrevWritten(uint32_t _addr, uint32_t size = 1);
126 bool _writeEnable(
bool _troubleshootEnable =
true);
127 bool _writeDisable(
void);
128 bool _getJedecId(
void);
129 bool _getManId(uint8_t *b1, uint8_t *b2);
130 bool _chipID(uint32_t flashChipSize = 0);
131 bool _transferAddress(
void);
132 bool _addressCheck(uint32_t _addr, uint32_t size = 1);
133 bool _enable4ByteAddressing(
void);
134 bool _disable4ByteAddressing(
void);
135 uint8_t _nextByte(
char IOType, uint8_t data = NULLBYTE);
136 uint16_t _nextInt(uint16_t = NULLINT);
137 void _nextBuf(uint8_t opcode, uint8_t *data_buffer, uint32_t size);
138 uint8_t _readStat1(
void);
139 uint8_t _readStat2(
void);
140 uint8_t _readStat3(
void);
141 bool _getSFDPTable(uint32_t _tableAddress, uint8_t *data_buffer, uint8_t numberOfDWords);
142 bool _getSFDPData(uint32_t _address, uint8_t *data_buffer, uint8_t numberOfBytes);
143 uint32_t _getSFDPdword(uint32_t _tableAddress, uint8_t dWordNumber);
144 uint16_t _getSFDPint(uint32_t _tableAddress, uint8_t dWordNumber, uint8_t startByte);
145 uint8_t _getSFDPbyte(uint32_t _tableAddress, uint8_t dWordNumber, uint8_t byteNumber);
146 bool _getSFDPbit(uint32_t _tableAddress, uint8_t dWordNumber, uint8_t bitNumber);
147 uint32_t _getSFDPTableAddr(uint32_t paramHeaderNum);
148 uint32_t _calcSFDPEraseTimeUnits(uint8_t _unitBits);
149 bool _checkForSFDP(
void);
150 void _getSFDPEraseParam(
void);
151 void _getSFDPProgramTimeParam(
void);
152 bool _getSFDPFlashParam(
void);
153 template <
class T>
bool _write(uint32_t _addr,
const T& value, uint32_t _sz,
bool errorCheck, uint8_t _dataType);
154 template <
class T>
bool _read(uint32_t _addr, T& value, uint32_t _sz,
bool fastRead =
false, uint8_t _dataType = 0x00);
156 template <
class T>
bool _writeErrorCheck(uint32_t _addr,
const T& value, uint32_t _sz, uint8_t _dataType = 0x00);
158 #ifdef SPI_HAS_TRANSACTION
159 SPISettings _settings;
160 bool _SPISettingsSet =
false;
168 #if !defined (BOARD_RTL8195A)
186 volatile uint8_t *cs_port;
188 bool SPIBusState =
false;
189 bool chipPoweredDown =
false;
190 bool address4ByteEnabled =
false;
191 bool _loopedOver =
false;
192 uint8_t cs_mask, errorcode, stat1, stat2, stat3, _SPCR, _SPSR, _a0, _a1, _a2;
195 float _spifuncruntime = 0;
200 uint8_t manufacturerID;
201 uint8_t memoryTypeID;
211 } kb4Erase, kb32Erase, kb64Erase, kb256Erase, chipErase;
212 uint8_t _noOfParamHeaders, _noOfBasicParamDwords;
213 uint16_t _eraseTimeMultiplier, _prgmTimeMultiplier, _pageSize;
214 uint32_t currentAddress, _currentAddress = 0;
215 uint32_t _addressOverflow =
false;
216 uint32_t _BasicParamTableAddr, _SectorMapParamTableAddr, _byteFirstPrgmTime, _byteAddnlPrgmTime, _pagePrgmTime;
217 uint8_t _uniqueID[8];
218 const uint8_t _capID[18] =
219 {0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x41, 0x42, 0x43, 0x4B, 0x00, 0x01, 0x13, 0x37};
221 const uint32_t _memSize[18] =
222 {KB(64), KB(128), KB(256), KB(512), MB(1), MB(2), MB(4), MB(8), MB(16), MB(32), MB(2), MB(4), MB(8), MB(8), KB(256), KB(512), MB(4), KB(512)};
225 const uint8_t _supportedManID[9] = {WINBOND_MANID, MICROCHIP_MANID, CYPRESS_MANID, ADESTO_MANID, MICRON_MANID, ON_MANID, GIGA_MANID, AMIC_MANID, MACRONIX_MANID};
227 const uint8_t _altChipEraseReq[3] = {A25L512, M25P40, SST26};
239 template <
class T>
bool SPIFlash::writeAnything(uint32_t _addr,
const T& data,
bool errorCheck) {
240 return _write(_addr, data,
sizeof(data), errorCheck, _STRUCT_);
248 template <
class T>
bool SPIFlash::readAnything(uint32_t _addr, T& data,
bool fastRead) {
249 return _read(_addr, data,
sizeof(data), fastRead);
254 template <
class T>
bool SPIFlash::_writeErrorCheck(uint32_t _addr,
const T& value, uint32_t _sz, uint8_t _dataType) {
255 if (_isChipPoweredDown() || !_addressCheck(_addr, _sz) || !_notBusy()) {
258 const uint8_t* p = (
const uint8_t*)(
const void*)&value;
276 _nextByte(WRITE, READDATA);
278 for (uint16_t i = 0; i < _sz; i++) {
279 if (*p++ != _nextByte(READ)) {
299 template <
class T>
bool SPIFlash::_write(uint32_t _addr,
const T& value, uint32_t _sz,
bool errorCheck, uint8_t _dataType) {
302 _spifuncruntime = micros();
305 uint32_t _addrIn = _addr;
306 if (!_prep(PAGEPROG, _addrIn, _sz)) {
309 _addrIn = _currentAddress;
312 const uint8_t* p = ((
const uint8_t*)(
const void*)&value);
315 uint32_t length = _sz;
316 uint16_t maxBytes = SPI_PAGESIZE-(_addrIn % SPI_PAGESIZE);
322 _nextByte(WRITE, PAGEPROG);
325 if (maxBytes > length) {
326 for (uint16_t i = 0; i < length; ++i) {
327 _nextByte(WRITE, *p++);
333 uint16_t data_offset = 0;
336 writeBufSz = (length<=maxBytes) ? length : maxBytes;
337 if(_currentAddress % SPI_PAGESIZE==0){
339 _nextByte(WRITE, PAGEPROG);
342 for (uint16_t i = 0; i < writeBufSz; ++i) {
343 _nextByte(WRITE, *p++);
346 if (!_addressOverflow) {
347 _currentAddress += writeBufSz;
350 if (data_offset >= _addressOverflow) {
351 _currentAddress = 0x00;
352 _addressOverflow =
false;
355 data_offset += writeBufSz;
356 length -= writeBufSz;
357 maxBytes = SPI_PAGESIZE;
358 if(!_notBusy() || !_writeEnable()) {
361 }
while (length > 0);
367 _spifuncruntime = micros() - _spifuncruntime;
374 _retVal = _writeErrorCheck(_addr, value, _sz, _dataType);
377 _spifuncruntime = micros() - _spifuncruntime;
388 template <
class T>
bool SPIFlash::_read(uint32_t _addr, T& value, uint32_t _sz,
bool fastRead, uint8_t _dataType) {
390 _spifuncruntime = micros();
392 if (!_prep(READDATA, _addr, _sz)) {
396 uint8_t* p = (uint8_t*)(
void*)&value;
398 if (_dataType == _STRING_) {
402 _nextBuf(READDATA, (uint8_t*) &(*_inChar), _sz);
404 for (uint16_t i = 0; i < _sz; i++) {
416 for (uint16_t i = 0; i < _sz; i++) {
417 *p++ =_nextByte(READ);
423 _spifuncruntime = micros() - _spifuncruntime;
Definition: SPIFlash.h:32