21 static bool verify_vectors(
const std::vector<uint8_t> &dataWritten,
const std::vector<uint8_t> &dataRead,
bool verbose =
false)
25 if (equal(dataWritten.begin(), dataWritten.end(), dataRead.begin()))
34 pair<vector<uint8_t>::const_iterator, vector<uint8_t>::const_iterator> p;
35 p = mismatch(dataWritten.begin(), dataWritten.end(), dataRead.begin());
36 int64_t byteMismatchOffset = distance(dataWritten.begin(), p.first);
37 ostringstream ossWrite;
38 ossWrite <<
"0x" << std::setw(2) << std::setfill(
'0') << hex << (int)*p.first;
39 ostringstream ossRead;
40 ossRead <<
"0x" << std::setw(2) << std::setfill(
'0') << hex << (int)*p.second;
42 ++p.first; ++p.second;
43 p = mismatch(p.first, dataWritten.end(), p.second);
46 while(p.first != dataWritten.end() && p.second != dataRead.end())
49 ++p.first; ++p.second;
50 p = mismatch(p.first, dataWritten.end(), p.second);
53 cout <<
"Verifying write of: " << dataWritten.size() <<
" bytes, failed at byte index: " << byteMismatchOffset <<
54 ", byte written to device should be: " << ossWrite.str() <<
", byte read back from device is: " << ossRead.str() <<
".\n" <<
55 "There are " << errorCount <<
" other mismatches after this." << endl;
62 inline void print_flash_status(
const string& label, uint32_t curValue, uint32_t maxValue, uint32_t& lastPercentage)
67 uint32_t percentage = (uint32_t)(((
double)curValue/(
double)maxValue)*100.0);
68 if (percentage != lastPercentage)
70 lastPercentage = percentage;
71 cout << label <<
" status: " << dec << lastPercentage <<
"% \r" << flush;
77 cout << label <<
" status: 100% " << endl;
112 return reportedSectorSize;
125 if (sectorSizeBytes == 0)
131 if (address < 0x20000)
134 sector = address / sector4kSizeBytes;
139 sector += (address-0x20000) / sectorSizeBytes;
144 sector = address / sectorSizeBytes;
160 address += (sector - 32) * sectorSizeBytes;
165 address = sector * sectorSizeBytes;
192 #define wait_for_flash_status_ready() { uint8_t fs=0x00; do { FlashReadStatus(fs); } while(fs & 0x1); }
195 :
CNTV2SpiFlash(verbose), mBaseByteAddress(0x300000), mSize(0), mSectorSize(0)
197 mSpiResetReg = (mBaseByteAddress + 0x40) / 4;
198 mSpiControlReg = (mBaseByteAddress + 0x60) / 4;
199 mSpiStatusReg = (mBaseByteAddress + 0x64) / 4;
200 mSpiWriteReg = (mBaseByteAddress + 0x68) / 4;
201 mSpiReadReg = (mBaseByteAddress + 0x6c) / 4;
202 mSpiSlaveReg = (mBaseByteAddress + 0x70) / 4;
203 mSpiGlobalIntReg = (mBaseByteAddress + 0x1c) / 4;
208 uint8_t manufactureID;
209 uint8_t memInerfaceType;
211 uint8_t sectorArchitecture;
213 bool good = FlashDeviceInfo(manufactureID, memInerfaceType, memDensity, sectorArchitecture, familyID);
218 case 0x18: mSize = 16 * 1024 * 1024;
break;
219 case 0x19: mSize = 32 * 1024 * 1024;
break;
220 case 0x20: mSize = 64 * 1024 * 1024;
break;
221 default: mSize = 0;
break;
224 sectorArchitecture &= 0x03;
225 switch(sectorArchitecture)
229 mSectorSize = (manufactureID == 0x20) ? 64 * 1024 : 256 * 1024;
232 case 0x01: mSectorSize = 64 * 1024;
break;
233 default: mSectorSize = 0;
break;
236 mManufactureID = manufactureID;
268 const uint32_t pageSize = 128;
271 uint32_t pageAddress = address;
272 uint32_t numPages = (uint32_t)ceil((
double)maxBytes/(double)pageSize);
274 uint32_t bytesLeftToTransfer = maxBytes;
275 uint32_t bytesTransfered = 0;
280 uint32_t lastPercent = 0;
281 for(uint32_t p=0;p<numPages;p++)
283 vector<uint8_t> commandSequence;
285 FlashFixAddress(pageAddress, commandSequence);
287 uint32_t bytesToTransfer = pageSize;
288 if (bytesLeftToTransfer < pageSize)
289 bytesToTransfer = bytesLeftToTransfer;
291 vector<uint8_t> dummyInput;
292 SpiTransfer(commandSequence, dummyInput, data, bytesToTransfer);
295 bytesLeftToTransfer -= bytesToTransfer;
296 pageAddress += pageSize;
298 bytesTransfered += bytesToTransfer;
315 const uint32_t pageSize = 128;
318 uint32_t maxWrite = maxBytes;
319 if (maxWrite > data.size())
320 maxWrite = (uint32_t)data.size();
322 std::vector<uint8_t> dummyOutput;
324 uint32_t pageAddress = address;
325 uint32_t numPages = (uint32_t)ceil((
double)maxWrite/(double)pageSize);
327 uint32_t bytesTransfered = 0;
332 uint32_t lastPercent = 0;
333 for(uint32_t p=0;p<numPages;p++)
335 vector<uint8_t> commandSequence;
337 FlashFixAddress(pageAddress, commandSequence);
339 vector<uint8_t> pageData;
340 for(
unsigned i=0;i<pageSize;i++)
342 uint32_t offset = (p*pageSize)+i;
343 if (offset >= data.size())
346 pageData.push_back(data.at(offset));
350 SpiEnableWrite(
true);
352 SpiTransfer(commandSequence, pageData, dummyOutput, (uint32_t)pageData.size());
356 SpiEnableWrite(
false);
358 pageAddress += pageSize;
359 bytesTransfered +=
static_cast<uint32_t
>(pageData.size());
379 uint32_t test1Addr = 0x20000;
380 uint32_t test1ExpectedSector = 32;
383 uint32_t test2Addr = 0x1F000;
384 uint32_t test2ExpectedSector = 31;
387 uint32_t test3Addr = 0x1FF0000;
388 uint32_t test3ExpectedSector = 541;
412 vector<uint8_t> commandSequence;
413 commandSequence.push_back(cmd);
414 FlashFixAddress(address, commandSequence);
416 uint32_t lastPercent = 0;
418 if (
mVerbose && endSector > startSector)
422 SpiEnableWrite(
true);
424 vector<uint8_t> dummyInput;
425 vector<uint8_t> dummyOutput;
426 SpiTransfer(commandSequence, dummyInput, dummyOutput, bytes);
433 if (endSector > startSector)
435 uint32_t numSectors = endSector-startSector;
440 uint32_t start = startSector;
441 while (start < endSector)
447 vector<uint8_t> commandSequence2;
448 commandSequence2.push_back(cmd);
449 FlashFixAddress(sectorAddress, commandSequence2);
452 SpiEnableWrite(
true);
455 SpiTransfer(commandSequence2, dummyInput, dummyOutput, bytes);
459 SpiEnableWrite(
false);
461 uint32_t curProgress = start-startSector;
479 vector<uint8_t> verifyData;
480 bool readGood =
Read(address, verifyData, uint32_t(dataWritten.size()));
482 if (readGood ==
false)
511 uint32_t retVal = 0xffffffff;
530 bool CNTV2AxiSpiFlash::NTV2DeviceOk()
532 if (mDevice.IsOpen() ==
false)
540 void CNTV2AxiSpiFlash::SpiReset()
549 uint8_t bankAddressVal=0;
553 bool CNTV2AxiSpiFlash::SpiResetFifos()
558 uint32_t spi_ctrl_val=0x1e6;
562 void CNTV2AxiSpiFlash::SpiEnableWrite(
bool enable)
587 bool CNTV2AxiSpiFlash::FlashDeviceInfo(uint8_t& manufactureID, uint8_t& memInerfaceType,
588 uint8_t& memDensity, uint8_t& sectorArchitecture,
591 vector<uint8_t> commandSequence;
594 vector<uint8_t> dummyInput;
595 vector<uint8_t> resultData;
596 bool result = SpiTransfer(commandSequence, dummyInput, resultData, 6);
597 if (result && resultData.size() >= 6)
599 manufactureID = resultData.at(0);
600 memInerfaceType = resultData.at(1);
601 memDensity = resultData.at(2);
602 sectorArchitecture = resultData.at(4);
603 familyID = resultData.at(5);
609 bool CNTV2AxiSpiFlash::FlashReadConfig(uint8_t& configValue)
611 vector<uint8_t> commandSequence;
614 vector<uint8_t> dummyInput;
615 vector<uint8_t> resultData;
616 bool result = SpiTransfer(commandSequence, dummyInput, resultData, 1);
617 if (result && resultData.size() > 0)
619 configValue = resultData.at(0);
624 bool CNTV2AxiSpiFlash::FlashReadStatus(uint8_t& statusValue)
626 vector<uint8_t> commandSequence;
629 vector<uint8_t> dummyInput;
630 vector<uint8_t> resultData;
631 bool result = SpiTransfer(commandSequence, dummyInput, resultData, 1);
632 if (result && resultData.size() > 0)
634 statusValue = resultData.at(0);
639 bool CNTV2AxiSpiFlash::FlashReadBankAddress(uint8_t& bankAddressVal)
641 if(mManufactureID != 0x20)
643 vector<uint8_t> commandSequence;
646 vector<uint8_t> dummyInput;
647 vector<uint8_t> resultData;
648 bool result = SpiTransfer(commandSequence, dummyInput, resultData, 1);
649 if (result && resultData.size() > 0)
651 bankAddressVal = resultData.at(0);
658 bool CNTV2AxiSpiFlash::FlashWriteBankAddress(
const uint8_t bankAddressVal)
660 if (mManufactureID != 0x20)
662 vector<uint8_t> commandSequence;
665 vector<uint8_t> input;
666 input.push_back(bankAddressVal);
667 std::vector<uint8_t> dummyOutput;
668 return SpiTransfer(commandSequence, input, dummyOutput, 1);
673 void CNTV2AxiSpiFlash::FlashFixAddress(
const uint32_t address, std::vector<uint8_t>& commandSequence)
677 commandSequence.push_back((address & (0xff000000)) >> 24);
678 commandSequence.push_back((address & (0x00ff0000)) >> 16);
679 commandSequence.push_back((address & (0x0000ff00)) >> 8);
680 commandSequence.push_back((address & (0x000000ff)) >> 0);
683 void CNTV2AxiSpiFlash::SpiSendFIFOData()
691 uint32_t spi_ctrl_val = 0;
694 spi_ctrl_val &= ~0x100;
698 bool txFIFOEmpty =
false;
699 uint32_t notEmptyCount = 0;
700 while(!txFIFOEmpty && notEmptyCount < 1000)
702 uint32_t Tx_Empty = 0;
704 txFIFOEmpty = Tx_Empty ?
true :
false;
715 spi_ctrl_val |= 0x100;
720 bool CNTV2AxiSpiFlash::SpiTransfer(std::vector<uint8_t> commandSequence,
721 const std::vector<uint8_t> inputData,
722 std::vector<uint8_t>& outputData, uint32_t maxByteCutoff)
728 if (commandSequence.empty())
737 uint32_t numDummyBytes = 0;
738 for(
unsigned i=0;i<commandSequence.size();++i)
755 else if (inputData.empty() ==
false)
759 uint32_t maxWrite = maxByteCutoff;
760 if (maxWrite > inputData.size())
761 maxWrite = (uint32_t)inputData.size();
763 for(uint32_t i=0;i<maxWrite;++i)
777 for(uint32_t i=0;i<=maxByteCutoff;++i)
788 bool rxFIFOEmpty =
false;
789 uint32_t notEmptyCount = 0;
790 while(!rxFIFOEmpty && notEmptyCount < 1000)
796 if (notEmptyCount >= numDummyBytes && notEmptyCount <= (maxByteCutoff + numDummyBytes))
798 outputData.push_back(val);
805 uint32_t Rx_Empty = 0;
807 rxFIFOEmpty = Rx_Empty ?
true :
false;