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;
110 return reportedSectorSize;
123 if (sectorSizeBytes == 0)
129 if (address < 0x20000)
132 sector = address / sector4kSizeBytes;
137 sector += (address-0x20000) / sectorSizeBytes;
142 sector = address / sectorSizeBytes;
158 address += (sector - 32) * sectorSizeBytes;
163 address = sector * sectorSizeBytes;
190 #define wait_for_flash_status_ready() { uint8_t fs=0x00; do { FlashReadStatus(fs); } while(fs & 0x1); }
193 :
CNTV2SpiFlash(verbose), mBaseByteAddress(0x300000), mSize(0), mSectorSize(0)
195 mSpiResetReg = (mBaseByteAddress + 0x40) / 4;
196 mSpiControlReg = (mBaseByteAddress + 0x60) / 4;
197 mSpiStatusReg = (mBaseByteAddress + 0x64) / 4;
198 mSpiWriteReg = (mBaseByteAddress + 0x68) / 4;
199 mSpiReadReg = (mBaseByteAddress + 0x6c) / 4;
200 mSpiSlaveReg = (mBaseByteAddress + 0x70) / 4;
201 mSpiGlobalIntReg = (mBaseByteAddress + 0x1c) / 4;
206 uint8_t manufactureID;
207 uint8_t memInerfaceType;
209 uint8_t sectorArchitecture;
211 bool good = FlashDeviceInfo(manufactureID, memInerfaceType, memDensity, sectorArchitecture, familyID);
216 case 0x18: mSize = 16 * 1024 * 1024;
break;
217 case 0x19: mSize = 32 * 1024 * 1024;
break;
218 case 0x20: mSize = 64 * 1024 * 1024;
break;
219 default: mSize = 0;
break;
222 sectorArchitecture &= 0x03;
223 switch(sectorArchitecture)
227 mSectorSize = (manufactureID == 0x20) ? 64 * 1024 : 256 * 1024;
230 case 0x01: mSectorSize = 64 * 1024;
break;
231 default: mSectorSize = 0;
break;
234 mManufactureID = manufactureID;
265 const uint32_t pageSize = 128;
268 uint32_t pageAddress = address;
269 uint32_t numPages = (uint32_t)ceil((
double)maxBytes/(double)pageSize);
271 uint32_t bytesLeftToTransfer = maxBytes;
272 uint32_t bytesTransfered = 0;
277 uint32_t lastPercent = 0;
278 for(uint32_t p=0;p<numPages;p++)
280 vector<uint8_t> commandSequence;
282 FlashFixAddress(pageAddress, commandSequence);
284 uint32_t bytesToTransfer = pageSize;
285 if (bytesLeftToTransfer < pageSize)
286 bytesToTransfer = bytesLeftToTransfer;
288 vector<uint8_t> dummyInput;
289 SpiTransfer(commandSequence, dummyInput, data, bytesToTransfer);
292 bytesLeftToTransfer -= bytesToTransfer;
293 pageAddress += pageSize;
295 bytesTransfered += bytesToTransfer;
312 const uint32_t pageSize = 128;
315 uint32_t maxWrite = maxBytes;
316 if (maxWrite > data.size())
317 maxWrite = (uint32_t)data.size();
319 std::vector<uint8_t> dummyOutput;
321 uint32_t pageAddress = address;
322 uint32_t numPages = (uint32_t)ceil((
double)maxWrite/(double)pageSize);
324 uint32_t bytesTransfered = 0;
329 uint32_t lastPercent = 0;
330 for(uint32_t p=0;p<numPages;p++)
332 vector<uint8_t> commandSequence;
334 FlashFixAddress(pageAddress, commandSequence);
336 vector<uint8_t> pageData;
337 for(
unsigned i=0;i<pageSize;i++)
339 uint32_t offset = (p*pageSize)+i;
340 if (offset >= data.size())
343 pageData.push_back(data.at(offset));
347 SpiEnableWrite(
true);
349 SpiTransfer(commandSequence, pageData, dummyOutput, (uint32_t)pageData.size());
353 SpiEnableWrite(
false);
355 pageAddress += pageSize;
356 bytesTransfered +=
static_cast<uint32_t
>(pageData.size());
376 uint32_t test1Addr = 0x20000;
377 uint32_t test1ExpectedSector = 32;
380 uint32_t test2Addr = 0x1F000;
381 uint32_t test2ExpectedSector = 31;
384 uint32_t test3Addr = 0x1FF0000;
385 uint32_t test3ExpectedSector = 541;
409 vector<uint8_t> commandSequence;
410 commandSequence.push_back(cmd);
411 FlashFixAddress(address, commandSequence);
413 uint32_t lastPercent = 0;
415 if (
mVerbose && endSector > startSector)
419 SpiEnableWrite(
true);
421 vector<uint8_t> dummyInput;
422 vector<uint8_t> dummyOutput;
423 SpiTransfer(commandSequence, dummyInput, dummyOutput, bytes);
430 if (endSector > startSector)
432 uint32_t numSectors = endSector-startSector;
437 uint32_t start = startSector;
438 while (start < endSector)
444 vector<uint8_t> commandSequence2;
445 commandSequence2.push_back(cmd);
446 FlashFixAddress(sectorAddress, commandSequence2);
449 SpiEnableWrite(
true);
452 SpiTransfer(commandSequence2, dummyInput, dummyOutput, bytes);
456 SpiEnableWrite(
false);
458 uint32_t curProgress = start-startSector;
476 vector<uint8_t> verifyData;
477 bool readGood =
Read(address, verifyData, uint32_t(dataWritten.size()));
479 if (readGood ==
false)
508 uint32_t retVal = 0xffffffff;
527 bool CNTV2AxiSpiFlash::NTV2DeviceOk()
529 if (mDevice.IsOpen() ==
false)
537 void CNTV2AxiSpiFlash::SpiReset()
546 uint8_t bankAddressVal=0;
549 bool CNTV2AxiSpiFlash::SpiResetFifos()
554 uint32_t spi_ctrl_val=0x1e6;
558 void CNTV2AxiSpiFlash::SpiEnableWrite(
bool enable)
583 bool CNTV2AxiSpiFlash::FlashDeviceInfo(uint8_t& manufactureID, uint8_t& memInerfaceType,
584 uint8_t& memDensity, uint8_t& sectorArchitecture,
587 vector<uint8_t> commandSequence;
590 vector<uint8_t> dummyInput;
591 vector<uint8_t> resultData;
592 bool result = SpiTransfer(commandSequence, dummyInput, resultData, 6);
593 if (result && resultData.size() >= 6)
595 manufactureID = resultData.at(0);
596 memInerfaceType = resultData.at(1);
597 memDensity = resultData.at(2);
598 sectorArchitecture = resultData.at(4);
599 familyID = resultData.at(5);
605 bool CNTV2AxiSpiFlash::FlashReadConfig(uint8_t& configValue)
607 vector<uint8_t> commandSequence;
610 vector<uint8_t> dummyInput;
611 vector<uint8_t> resultData;
612 bool result = SpiTransfer(commandSequence, dummyInput, resultData, 1);
613 if (result && resultData.size() > 0)
615 configValue = resultData.at(0);
620 bool CNTV2AxiSpiFlash::FlashReadStatus(uint8_t& statusValue)
622 vector<uint8_t> commandSequence;
625 vector<uint8_t> dummyInput;
626 vector<uint8_t> resultData;
627 bool result = SpiTransfer(commandSequence, dummyInput, resultData, 1);
628 if (result && resultData.size() > 0)
630 statusValue = resultData.at(0);
635 bool CNTV2AxiSpiFlash::FlashReadBankAddress(uint8_t& bankAddressVal)
637 if(mManufactureID != 0x20)
639 vector<uint8_t> commandSequence;
642 vector<uint8_t> dummyInput;
643 vector<uint8_t> resultData;
644 bool result = SpiTransfer(commandSequence, dummyInput, resultData, 1);
645 if (result && resultData.size() > 0)
647 bankAddressVal = resultData.at(0);
654 bool CNTV2AxiSpiFlash::FlashWriteBankAddress(
const uint8_t bankAddressVal)
656 if (mManufactureID != 0x20)
658 vector<uint8_t> commandSequence;
661 vector<uint8_t> input;
662 input.push_back(bankAddressVal);
663 std::vector<uint8_t> dummyOutput;
664 return SpiTransfer(commandSequence, input, dummyOutput, 1);
669 void CNTV2AxiSpiFlash::FlashFixAddress(
const uint32_t address, std::vector<uint8_t>& commandSequence)
673 commandSequence.push_back((address & (0xff000000)) >> 24);
674 commandSequence.push_back((address & (0x00ff0000)) >> 16);
675 commandSequence.push_back((address & (0x0000ff00)) >> 8);
676 commandSequence.push_back((address & (0x000000ff)) >> 0);
679 void CNTV2AxiSpiFlash::SpiSendFIFOData()
687 uint32_t spi_ctrl_val = 0;
690 spi_ctrl_val &= ~0x100;
694 bool txFIFOEmpty =
false;
695 uint32_t notEmptyCount = 0;
696 while(!txFIFOEmpty && notEmptyCount < 1000)
698 uint32_t Tx_Empty = 0;
700 txFIFOEmpty = Tx_Empty ?
true :
false;
711 spi_ctrl_val |= 0x100;
716 bool CNTV2AxiSpiFlash::SpiTransfer(std::vector<uint8_t> commandSequence,
717 const std::vector<uint8_t> inputData,
718 std::vector<uint8_t>& outputData, uint32_t maxByteCutoff)
724 if (commandSequence.empty())
733 uint32_t dummyVal = 0;
734 uint32_t numDummyBytes = 0;
735 for(
unsigned i=0;i<commandSequence.size();++i)
752 else if (inputData.empty() ==
false)
756 uint32_t maxWrite = maxByteCutoff;
757 if (maxWrite > inputData.size())
758 maxWrite = (uint32_t)inputData.size();
760 for(uint32_t i=0;i<maxWrite;++i)
774 for(uint32_t i=0;i<=maxByteCutoff;++i)
785 bool rxFIFOEmpty =
false;
786 uint32_t notEmptyCount = 0;
787 while(!rxFIFOEmpty && notEmptyCount < 1000)
793 if (notEmptyCount >= numDummyBytes && notEmptyCount <= (maxByteCutoff + numDummyBytes))
795 outputData.push_back(val);
802 uint32_t Rx_Empty = 0;
804 rxFIFOEmpty = Rx_Empty ?
true :
false;