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;
269 const uint32_t pageSize = 128;
272 uint32_t pageAddress = address;
273 uint32_t numPages = (uint32_t)ceil((
double)maxBytes/(double)pageSize);
275 uint32_t bytesLeftToTransfer = maxBytes;
276 uint32_t bytesTransfered = 0;
281 uint32_t lastPercent = 0;
282 for(uint32_t p=0;p<numPages;p++)
284 vector<uint8_t> commandSequence;
286 FlashFixAddress(pageAddress, commandSequence);
288 uint32_t bytesToTransfer = pageSize;
289 if (bytesLeftToTransfer < pageSize)
290 bytesToTransfer = bytesLeftToTransfer;
292 vector<uint8_t> dummyInput;
293 SpiTransfer(commandSequence, dummyInput, data, bytesToTransfer);
296 bytesLeftToTransfer -= bytesToTransfer;
297 pageAddress += pageSize;
299 bytesTransfered += bytesToTransfer;
316 const uint32_t pageSize = 128;
319 uint32_t maxWrite = maxBytes;
320 if (maxWrite > data.size())
321 maxWrite = (uint32_t)data.size();
323 std::vector<uint8_t> dummyOutput;
325 uint32_t pageAddress = address;
326 uint32_t numPages = (uint32_t)ceil((
double)maxWrite/(double)pageSize);
328 uint32_t bytesTransfered = 0;
333 uint32_t lastPercent = 0;
334 for(uint32_t p=0;p<numPages;p++)
336 vector<uint8_t> commandSequence;
338 FlashFixAddress(pageAddress, commandSequence);
340 vector<uint8_t> pageData;
341 for(
unsigned i=0;i<pageSize;i++)
343 uint32_t offset = (p*pageSize)+i;
344 if (offset >= data.size())
347 pageData.push_back(data.at(offset));
351 SpiEnableWrite(
true);
353 SpiTransfer(commandSequence, pageData, dummyOutput, (uint32_t)pageData.size());
357 SpiEnableWrite(
false);
359 pageAddress += pageSize;
360 bytesTransfered +=
static_cast<uint32_t
>(pageData.size());
380 uint32_t test1Addr = 0x20000;
381 uint32_t test1ExpectedSector = 32;
384 uint32_t test2Addr = 0x1F000;
385 uint32_t test2ExpectedSector = 31;
388 uint32_t test3Addr = 0x1FF0000;
389 uint32_t test3ExpectedSector = 541;
413 vector<uint8_t> commandSequence;
414 commandSequence.push_back(cmd);
415 FlashFixAddress(address, commandSequence);
417 uint32_t lastPercent = 0;
419 if (
mVerbose && endSector > startSector)
423 SpiEnableWrite(
true);
425 vector<uint8_t> dummyInput;
426 vector<uint8_t> dummyOutput;
427 SpiTransfer(commandSequence, dummyInput, dummyOutput, bytes);
434 if (endSector > startSector)
436 uint32_t numSectors = endSector-startSector;
441 uint32_t start = startSector;
442 while (start < endSector)
448 vector<uint8_t> commandSequence2;
449 commandSequence2.push_back(cmd);
450 FlashFixAddress(sectorAddress, commandSequence2);
453 SpiEnableWrite(
true);
456 SpiTransfer(commandSequence2, dummyInput, dummyOutput, bytes);
460 SpiEnableWrite(
false);
462 uint32_t curProgress = start-startSector;
480 vector<uint8_t> verifyData;
481 bool readGood =
Read(address, verifyData, uint32_t(dataWritten.size()));
483 if (readGood ==
false)
512 uint32_t
retVal = 0xffffffff;
531 bool CNTV2AxiSpiFlash::NTV2DeviceOk()
533 if (mDevice.
IsOpen() ==
false)
541 void CNTV2AxiSpiFlash::SpiReset()
550 uint8_t bankAddressVal=0;
554 bool CNTV2AxiSpiFlash::SpiResetFifos()
559 uint32_t spi_ctrl_val=0x1e6;
563 void CNTV2AxiSpiFlash::SpiEnableWrite(
bool enable)
588 bool CNTV2AxiSpiFlash::FlashDeviceInfo(uint8_t& manufactureID, uint8_t& memInerfaceType,
589 uint8_t& memDensity, uint8_t& sectorArchitecture,
592 vector<uint8_t> commandSequence;
595 vector<uint8_t> dummyInput;
596 vector<uint8_t> resultData;
597 bool result = SpiTransfer(commandSequence, dummyInput, resultData, 6);
598 if (result && resultData.size() >= 6)
600 manufactureID = resultData.at(0);
601 memInerfaceType = resultData.at(1);
602 memDensity = resultData.at(2);
603 sectorArchitecture = resultData.at(4);
604 familyID = resultData.at(5);
610 bool CNTV2AxiSpiFlash::FlashReadConfig(uint8_t& configValue)
612 vector<uint8_t> commandSequence;
615 vector<uint8_t> dummyInput;
616 vector<uint8_t> resultData;
617 bool result = SpiTransfer(commandSequence, dummyInput, resultData, 1);
618 if (result && resultData.size() > 0)
620 configValue = resultData.at(0);
625 bool CNTV2AxiSpiFlash::FlashReadStatus(uint8_t& statusValue)
627 vector<uint8_t> commandSequence;
630 vector<uint8_t> dummyInput;
631 vector<uint8_t> resultData;
632 bool result = SpiTransfer(commandSequence, dummyInput, resultData, 1);
633 if (result && resultData.size() > 0)
635 statusValue = resultData.at(0);
640 bool CNTV2AxiSpiFlash::FlashReadBankAddress(uint8_t& bankAddressVal)
642 if(mManufactureID != 0x20)
644 vector<uint8_t> commandSequence;
647 vector<uint8_t> dummyInput;
648 vector<uint8_t> resultData;
649 bool result = SpiTransfer(commandSequence, dummyInput, resultData, 1);
650 if (result && resultData.size() > 0)
652 bankAddressVal = resultData.at(0);
659 bool CNTV2AxiSpiFlash::FlashWriteBankAddress(
const uint8_t bankAddressVal)
661 if (mManufactureID != 0x20)
663 vector<uint8_t> commandSequence;
666 vector<uint8_t> input;
667 input.push_back(bankAddressVal);
668 std::vector<uint8_t> dummyOutput;
669 return SpiTransfer(commandSequence, input, dummyOutput, 1);
674 void CNTV2AxiSpiFlash::FlashFixAddress(
const uint32_t address, std::vector<uint8_t>& commandSequence)
678 commandSequence.push_back((address & (0xff000000)) >> 24);
679 commandSequence.push_back((address & (0x00ff0000)) >> 16);
680 commandSequence.push_back((address & (0x0000ff00)) >> 8);
681 commandSequence.push_back((address & (0x000000ff)) >> 0);
684 void CNTV2AxiSpiFlash::SpiSendFIFOData()
692 uint32_t spi_ctrl_val = 0;
695 spi_ctrl_val &= ~0x100;
699 bool txFIFOEmpty =
false;
700 uint32_t notEmptyCount = 0;
701 while(!txFIFOEmpty && notEmptyCount < 1000)
703 uint32_t Tx_Empty = 0;
705 txFIFOEmpty = Tx_Empty ?
true :
false;
716 spi_ctrl_val |= 0x100;
721 bool CNTV2AxiSpiFlash::SpiTransfer(std::vector<uint8_t> commandSequence,
722 const std::vector<uint8_t> inputData,
723 std::vector<uint8_t>& outputData, uint32_t maxByteCutoff)
729 if (commandSequence.empty())
738 uint32_t numDummyBytes = 0;
739 for(
unsigned i=0;i<commandSequence.size();++i)
756 else if (inputData.empty() ==
false)
760 uint32_t maxWrite = maxByteCutoff;
761 if (maxWrite > inputData.size())
762 maxWrite = (uint32_t)inputData.size();
764 for(uint32_t i=0;i<maxWrite;++i)
778 for(uint32_t i=0;i<=maxByteCutoff;++i)
789 bool rxFIFOEmpty =
false;
790 uint32_t notEmptyCount = 0;
791 while(!rxFIFOEmpty && notEmptyCount < 1000)
797 if (notEmptyCount >= numDummyBytes && notEmptyCount <= (maxByteCutoff + numDummyBytes))
799 outputData.push_back(val);
806 uint32_t Rx_Empty = 0;
808 rxFIFOEmpty = Rx_Empty ?
true :
false;
Defines the KonaIP/IoIP registers.
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.
const uint32_t CYPRESS_FLASH_READ_CONFIG_COMMAND
virtual bool Open(const UWord inDeviceIndex)
Opens a local/physical AJA device so it can be monitored/controlled.
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...
CNTV2AxiSpiFlash(int index=0, bool verbose=(0))
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)
Declares the CNTV2MCSfile class.
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)