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;
267 const uint32_t pageSize = 128;
270 uint32_t pageAddress = address;
271 uint32_t numPages = (uint32_t)ceil((
double)maxBytes/(double)pageSize);
273 uint32_t bytesLeftToTransfer = maxBytes;
274 uint32_t bytesTransfered = 0;
279 uint32_t lastPercent = 0;
280 for(uint32_t p=0;p<numPages;p++)
282 vector<uint8_t> commandSequence;
284 FlashFixAddress(pageAddress, commandSequence);
286 uint32_t bytesToTransfer = pageSize;
287 if (bytesLeftToTransfer < pageSize)
288 bytesToTransfer = bytesLeftToTransfer;
290 vector<uint8_t> dummyInput;
291 SpiTransfer(commandSequence, dummyInput, data, bytesToTransfer);
294 bytesLeftToTransfer -= bytesToTransfer;
295 pageAddress += pageSize;
297 bytesTransfered += bytesToTransfer;
314 const uint32_t pageSize = 128;
317 uint32_t maxWrite = maxBytes;
318 if (maxWrite > data.size())
319 maxWrite = (uint32_t)data.size();
321 std::vector<uint8_t> dummyOutput;
323 uint32_t pageAddress = address;
324 uint32_t numPages = (uint32_t)ceil((
double)maxWrite/(double)pageSize);
326 uint32_t bytesTransfered = 0;
331 uint32_t lastPercent = 0;
332 for(uint32_t p=0;p<numPages;p++)
334 vector<uint8_t> commandSequence;
336 FlashFixAddress(pageAddress, commandSequence);
338 vector<uint8_t> pageData;
339 for(
unsigned i=0;i<pageSize;i++)
341 uint32_t offset = (p*pageSize)+i;
342 if (offset >= data.size())
345 pageData.push_back(data.at(offset));
349 SpiEnableWrite(
true);
351 SpiTransfer(commandSequence, pageData, dummyOutput, (uint32_t)pageData.size());
355 SpiEnableWrite(
false);
357 pageAddress += pageSize;
358 bytesTransfered +=
static_cast<uint32_t
>(pageData.size());
378 uint32_t test1Addr = 0x20000;
379 uint32_t test1ExpectedSector = 32;
382 uint32_t test2Addr = 0x1F000;
383 uint32_t test2ExpectedSector = 31;
386 uint32_t test3Addr = 0x1FF0000;
387 uint32_t test3ExpectedSector = 541;
411 vector<uint8_t> commandSequence;
412 commandSequence.push_back(cmd);
413 FlashFixAddress(address, commandSequence);
415 uint32_t lastPercent = 0;
417 if (
mVerbose && endSector > startSector)
421 SpiEnableWrite(
true);
423 vector<uint8_t> dummyInput;
424 vector<uint8_t> dummyOutput;
425 SpiTransfer(commandSequence, dummyInput, dummyOutput, bytes);
432 if (endSector > startSector)
434 uint32_t numSectors = endSector-startSector;
439 uint32_t start = startSector;
440 while (start < endSector)
446 vector<uint8_t> commandSequence2;
447 commandSequence2.push_back(cmd);
448 FlashFixAddress(sectorAddress, commandSequence2);
451 SpiEnableWrite(
true);
454 SpiTransfer(commandSequence2, dummyInput, dummyOutput, bytes);
458 SpiEnableWrite(
false);
460 uint32_t curProgress = start-startSector;
478 vector<uint8_t> verifyData;
479 bool readGood =
Read(address, verifyData, uint32_t(dataWritten.size()));
481 if (readGood ==
false)
510 uint32_t retVal = 0xffffffff;
529 bool CNTV2AxiSpiFlash::NTV2DeviceOk()
531 if (mDevice.IsOpen() ==
false)
539 void CNTV2AxiSpiFlash::SpiReset()
548 uint8_t bankAddressVal=0;
552 bool CNTV2AxiSpiFlash::SpiResetFifos()
557 uint32_t spi_ctrl_val=0x1e6;
561 void CNTV2AxiSpiFlash::SpiEnableWrite(
bool enable)
586 bool CNTV2AxiSpiFlash::FlashDeviceInfo(uint8_t& manufactureID, uint8_t& memInerfaceType,
587 uint8_t& memDensity, uint8_t& sectorArchitecture,
590 vector<uint8_t> commandSequence;
593 vector<uint8_t> dummyInput;
594 vector<uint8_t> resultData;
595 bool result = SpiTransfer(commandSequence, dummyInput, resultData, 6);
596 if (result && resultData.size() >= 6)
598 manufactureID = resultData.at(0);
599 memInerfaceType = resultData.at(1);
600 memDensity = resultData.at(2);
601 sectorArchitecture = resultData.at(4);
602 familyID = resultData.at(5);
608 bool CNTV2AxiSpiFlash::FlashReadConfig(uint8_t& configValue)
610 vector<uint8_t> commandSequence;
613 vector<uint8_t> dummyInput;
614 vector<uint8_t> resultData;
615 bool result = SpiTransfer(commandSequence, dummyInput, resultData, 1);
616 if (result && resultData.size() > 0)
618 configValue = resultData.at(0);
623 bool CNTV2AxiSpiFlash::FlashReadStatus(uint8_t& statusValue)
625 vector<uint8_t> commandSequence;
628 vector<uint8_t> dummyInput;
629 vector<uint8_t> resultData;
630 bool result = SpiTransfer(commandSequence, dummyInput, resultData, 1);
631 if (result && resultData.size() > 0)
633 statusValue = resultData.at(0);
638 bool CNTV2AxiSpiFlash::FlashReadBankAddress(uint8_t& bankAddressVal)
640 if(mManufactureID != 0x20)
642 vector<uint8_t> commandSequence;
645 vector<uint8_t> dummyInput;
646 vector<uint8_t> resultData;
647 bool result = SpiTransfer(commandSequence, dummyInput, resultData, 1);
648 if (result && resultData.size() > 0)
650 bankAddressVal = resultData.at(0);
657 bool CNTV2AxiSpiFlash::FlashWriteBankAddress(
const uint8_t bankAddressVal)
659 if (mManufactureID != 0x20)
661 vector<uint8_t> commandSequence;
664 vector<uint8_t> input;
665 input.push_back(bankAddressVal);
666 std::vector<uint8_t> dummyOutput;
667 return SpiTransfer(commandSequence, input, dummyOutput, 1);
672 void CNTV2AxiSpiFlash::FlashFixAddress(
const uint32_t address, std::vector<uint8_t>& commandSequence)
676 commandSequence.push_back((address & (0xff000000)) >> 24);
677 commandSequence.push_back((address & (0x00ff0000)) >> 16);
678 commandSequence.push_back((address & (0x0000ff00)) >> 8);
679 commandSequence.push_back((address & (0x000000ff)) >> 0);
682 void CNTV2AxiSpiFlash::SpiSendFIFOData()
690 uint32_t spi_ctrl_val = 0;
693 spi_ctrl_val &= ~0x100;
697 bool txFIFOEmpty =
false;
698 uint32_t notEmptyCount = 0;
699 while(!txFIFOEmpty && notEmptyCount < 1000)
701 uint32_t Tx_Empty = 0;
703 txFIFOEmpty = Tx_Empty ?
true :
false;
714 spi_ctrl_val |= 0x100;
719 bool CNTV2AxiSpiFlash::SpiTransfer(std::vector<uint8_t> commandSequence,
720 const std::vector<uint8_t> inputData,
721 std::vector<uint8_t>& outputData, uint32_t maxByteCutoff)
727 if (commandSequence.empty())
736 uint32_t numDummyBytes = 0;
737 for(
unsigned i=0;i<commandSequence.size();++i)
754 else if (inputData.empty() ==
false)
758 uint32_t maxWrite = maxByteCutoff;
759 if (maxWrite > inputData.size())
760 maxWrite = (uint32_t)inputData.size();
762 for(uint32_t i=0;i<maxWrite;++i)
776 for(uint32_t i=0;i<=maxByteCutoff;++i)
787 bool rxFIFOEmpty =
false;
788 uint32_t notEmptyCount = 0;
789 while(!rxFIFOEmpty && notEmptyCount < 1000)
795 if (notEmptyCount >= numDummyBytes && notEmptyCount <= (maxByteCutoff + numDummyBytes))
797 outputData.push_back(val);
804 uint32_t Rx_Empty = 0;
806 rxFIFOEmpty = Rx_Empty ?
true :
false;