18 static bool verify_vectors(
const std::vector<uint8_t> &dataWritten,
const std::vector<uint8_t> &dataRead,
bool verbose =
false)
22 if (equal(dataWritten.begin(), dataWritten.end(), dataRead.begin()))
31 pair<vector<uint8_t>::const_iterator, vector<uint8_t>::const_iterator> p;
32 p = mismatch(dataWritten.begin(), dataWritten.end(), dataRead.begin());
33 int64_t byteMismatchOffset = distance(dataWritten.begin(), p.first);
34 ostringstream ossWrite;
35 ossWrite <<
"0x" << std::setw(2) << std::setfill(
'0') << hex << (int)*p.first;
36 ostringstream ossRead;
37 ossRead <<
"0x" << std::setw(2) << std::setfill(
'0') << hex << (int)*p.second;
39 ++p.first; ++p.second;
40 p = mismatch(p.first, dataWritten.end(), p.second);
43 while(p.first != dataWritten.end() && p.second != dataRead.end())
46 ++p.first; ++p.second;
47 p = mismatch(p.first, dataWritten.end(), p.second);
50 cout <<
"Verifying write of: " << dataWritten.size() <<
" bytes, failed at byte index: " << byteMismatchOffset <<
51 ", byte written to device should be: " << ossWrite.str() <<
", byte read back from device is: " << ossRead.str() <<
".\n" <<
52 "There are " << errorCount <<
" other mismatches after this." << endl;
59 inline void print_flash_status(
const string& label, uint32_t curValue, uint32_t maxValue, uint32_t& lastPercentage)
64 uint32_t percentage = (uint32_t)(((
double)curValue/(
double)maxValue)*100.0);
65 if (percentage != lastPercentage)
67 lastPercentage = percentage;
68 cout << label <<
" status: " << dec << lastPercentage <<
"% \r" << flush;
74 cout << label <<
" status: 100% " << endl;
109 return reportedSectorSize;
122 if (sectorSizeBytes == 0)
128 if (address < 0x20000)
131 sector = address / sector4kSizeBytes;
136 sector += (address-0x20000) / sectorSizeBytes;
141 sector = address / sectorSizeBytes;
157 address += (sector - 32) * sectorSizeBytes;
162 address = sector * sectorSizeBytes;
189 #define wait_for_flash_status_ready() { uint8_t fs=0x00; do { FlashReadStatus(fs); } while(fs & 0x1); } 193 mDevice(card), 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;
205 uint8_t manufactureID;
206 uint8_t memInerfaceType;
208 uint8_t sectorArchitecture;
210 bool good = FlashDeviceInfo(manufactureID, memInerfaceType, memDensity, sectorArchitecture, familyID);
215 case 0x18: mSize = 16 * 1024 * 1024;
break;
216 case 0x19: mSize = 32 * 1024 * 1024;
break;
217 case 0x20: mSize = 64 * 1024 * 1024;
break;
218 default: mSize = 0;
break;
221 sectorArchitecture &= 0x03;
222 switch(sectorArchitecture)
226 mSectorSize = (manufactureID == 0x20) ? 64 * 1024 : 256 * 1024;
229 case 0x01: mSectorSize = 64 * 1024;
break;
230 default: mSectorSize = 0;
break;
233 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;
bool has_4k_start_sectors(const uint32_t reportedSectorSize)
virtual ~CNTV2AxiSpiFlash()
const uint32_t CYPRESS_FLASH_WRITEBANK_COMMAND
static bool DeviceSupported(NTV2DeviceID deviceId)
I interrogate and control an AJA video/audio capture/playout device.
CNTV2AxiSpiFlash(CNTV2Card &card, bool verbose=(0))
const uint32_t CYPRESS_FLASH_READ_CONFIG_COMMAND
Declares the CNTV2SpiFlash and CNTV2AxiSpiFlash classes.
static uint32_t address_for_sector(uint32_t sectorSizeBytes, uint32_t sector)
virtual uint32_t Offset(SpiFlashSection sectionID=SPI_FLASH_SECTION_TOTAL)
const uint32_t CYPRESS_FLASH_READFAST_COMMAND
const uint32_t CYPRESS_FLASH_READBANK_COMMAND
virtual uint32_t Size(SpiFlashSection sectionID=SPI_FLASH_SECTION_TOTAL)
NTV2DeviceID
Identifies a specific AJA NTV2 device model number. The NTV2DeviceID is actually the PROM part number...
virtual bool IsOpen(void) const
const uint32_t CYPRESS_FLASH_READ_STATUS_COMMAND
void print_flash_status_final(const string &label)
virtual bool Erase(const uint32_t address, uint32_t bytes)
static uint32_t sector_for_address(uint32_t sectorSizeBytes, uint32_t address)
uint32_t make_spi_ready(CNTV2Card &device)
#define wait_for_flash_status_ready()
virtual NTV2DeviceID GetDeviceID(void)
static uint32_t erase_cmd_for_sector(const uint32_t reportedSectorSize, const uint32_t sector)
const uint32_t CYPRESS_FLASH_READ_JEDEC_ID_COMMAND
virtual bool ReadRegister(const ULWord inRegNum, ULWord &outValue, const ULWord inMask=0xFFFFFFFF, const ULWord inShift=0)
Reads all or part of the 32-bit contents of a specific register (real or virtual) on the AJA device...
ProgramState programstate_for_address(uint32_t address, int mode)
virtual bool Read(const uint32_t address, std::vector< uint8_t > &data, uint32_t maxBytes=1)
#define NTV2_UNUSED(__p__)
virtual bool WriteRegister(const ULWord inRegNum, const ULWord inValue, const ULWord inMask=0xFFFFFFFF, const ULWord inShift=0)
Updates or replaces all or part of the 32-bit contents of a specific register (real or virtual) on th...
void print_flash_status(const string &label, uint32_t curValue, uint32_t maxValue, uint32_t &lastPercentage)
static bool verify_vectors(const std::vector< uint8_t > &dataWritten, const std::vector< uint8_t > &dataRead, bool verbose=(0))
const uint32_t CYPRESS_FLASH_SECTOR_ERASE_COMMAND
const uint32_t CYPRESS_FLASH_SECTOR4K_ERASE_COMMAND
static uint32_t size_for_sector_number(const uint32_t reportedSectorSize, const uint32_t sector)
const uint32_t CYPRESS_FLASH_WRITEENABLE_COMMAND
const uint32_t CYPRESS_FLASH_PAGE_PROGRAM_COMMAND
virtual bool Write(const uint32_t address, const std::vector< uint8_t > data, uint32_t maxBytes=1)
virtual bool Verify(const uint32_t address, const std::vector< uint8_t > &dataWritten)