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;
266 const uint32_t pageSize = 128;
269 uint32_t pageAddress = address;
270 uint32_t numPages = (uint32_t)ceil((
double)maxBytes/(double)pageSize);
272 uint32_t bytesLeftToTransfer = maxBytes;
273 uint32_t bytesTransfered = 0;
278 uint32_t lastPercent = 0;
279 for(uint32_t p=0;p<numPages;p++)
281 vector<uint8_t> commandSequence;
283 FlashFixAddress(pageAddress, commandSequence);
285 uint32_t bytesToTransfer = pageSize;
286 if (bytesLeftToTransfer < pageSize)
287 bytesToTransfer = bytesLeftToTransfer;
289 vector<uint8_t> dummyInput;
290 SpiTransfer(commandSequence, dummyInput, data, bytesToTransfer);
293 bytesLeftToTransfer -= bytesToTransfer;
294 pageAddress += pageSize;
296 bytesTransfered += bytesToTransfer;
313 const uint32_t pageSize = 128;
316 uint32_t maxWrite = maxBytes;
317 if (maxWrite > data.size())
318 maxWrite = (uint32_t)data.size();
320 std::vector<uint8_t> dummyOutput;
322 uint32_t pageAddress = address;
323 uint32_t numPages = (uint32_t)ceil((
double)maxWrite/(double)pageSize);
325 uint32_t bytesTransfered = 0;
330 uint32_t lastPercent = 0;
331 for(uint32_t p=0;p<numPages;p++)
333 vector<uint8_t> commandSequence;
335 FlashFixAddress(pageAddress, commandSequence);
337 vector<uint8_t> pageData;
338 for(
unsigned i=0;i<pageSize;i++)
340 uint32_t offset = (p*pageSize)+i;
341 if (offset >= data.size())
344 pageData.push_back(data.at(offset));
348 SpiEnableWrite(
true);
350 SpiTransfer(commandSequence, pageData, dummyOutput, (uint32_t)pageData.size());
354 SpiEnableWrite(
false);
356 pageAddress += pageSize;
357 bytesTransfered +=
static_cast<uint32_t
>(pageData.size());
377 uint32_t test1Addr = 0x20000;
378 uint32_t test1ExpectedSector = 32;
381 uint32_t test2Addr = 0x1F000;
382 uint32_t test2ExpectedSector = 31;
385 uint32_t test3Addr = 0x1FF0000;
386 uint32_t test3ExpectedSector = 541;
410 vector<uint8_t> commandSequence;
411 commandSequence.push_back(cmd);
412 FlashFixAddress(address, commandSequence);
414 uint32_t lastPercent = 0;
416 if (
mVerbose && endSector > startSector)
420 SpiEnableWrite(
true);
422 vector<uint8_t> dummyInput;
423 vector<uint8_t> dummyOutput;
424 SpiTransfer(commandSequence, dummyInput, dummyOutput, bytes);
431 if (endSector > startSector)
433 uint32_t numSectors = endSector-startSector;
438 uint32_t start = startSector;
439 while (start < endSector)
445 vector<uint8_t> commandSequence2;
446 commandSequence2.push_back(cmd);
447 FlashFixAddress(sectorAddress, commandSequence2);
450 SpiEnableWrite(
true);
453 SpiTransfer(commandSequence2, dummyInput, dummyOutput, bytes);
457 SpiEnableWrite(
false);
459 uint32_t curProgress = start-startSector;
477 vector<uint8_t> verifyData;
478 bool readGood =
Read(address, verifyData, uint32_t(dataWritten.size()));
480 if (readGood ==
false)
509 uint32_t
retVal = 0xffffffff;
528 bool CNTV2AxiSpiFlash::NTV2DeviceOk()
530 if (mDevice.
IsOpen() ==
false)
538 void CNTV2AxiSpiFlash::SpiReset()
547 uint8_t bankAddressVal=0;
551 bool CNTV2AxiSpiFlash::SpiResetFifos()
556 uint32_t spi_ctrl_val=0x1e6;
560 void CNTV2AxiSpiFlash::SpiEnableWrite(
bool enable)
585 bool CNTV2AxiSpiFlash::FlashDeviceInfo(uint8_t& manufactureID, uint8_t& memInerfaceType,
586 uint8_t& memDensity, uint8_t& sectorArchitecture,
589 vector<uint8_t> commandSequence;
592 vector<uint8_t> dummyInput;
593 vector<uint8_t> resultData;
594 bool result = SpiTransfer(commandSequence, dummyInput, resultData, 6);
595 if (result && resultData.size() >= 6)
597 manufactureID = resultData.at(0);
598 memInerfaceType = resultData.at(1);
599 memDensity = resultData.at(2);
600 sectorArchitecture = resultData.at(4);
601 familyID = resultData.at(5);
607 bool CNTV2AxiSpiFlash::FlashReadConfig(uint8_t& configValue)
609 vector<uint8_t> commandSequence;
612 vector<uint8_t> dummyInput;
613 vector<uint8_t> resultData;
614 bool result = SpiTransfer(commandSequence, dummyInput, resultData, 1);
615 if (result && resultData.size() > 0)
617 configValue = resultData.at(0);
622 bool CNTV2AxiSpiFlash::FlashReadStatus(uint8_t& statusValue)
624 vector<uint8_t> commandSequence;
627 vector<uint8_t> dummyInput;
628 vector<uint8_t> resultData;
629 bool result = SpiTransfer(commandSequence, dummyInput, resultData, 1);
630 if (result && resultData.size() > 0)
632 statusValue = resultData.at(0);
637 bool CNTV2AxiSpiFlash::FlashReadBankAddress(uint8_t& bankAddressVal)
639 if(mManufactureID != 0x20)
641 vector<uint8_t> commandSequence;
644 vector<uint8_t> dummyInput;
645 vector<uint8_t> resultData;
646 bool result = SpiTransfer(commandSequence, dummyInput, resultData, 1);
647 if (result && resultData.size() > 0)
649 bankAddressVal = resultData.at(0);
656 bool CNTV2AxiSpiFlash::FlashWriteBankAddress(
const uint8_t bankAddressVal)
658 if (mManufactureID != 0x20)
660 vector<uint8_t> commandSequence;
663 vector<uint8_t> input;
664 input.push_back(bankAddressVal);
665 std::vector<uint8_t> dummyOutput;
666 return SpiTransfer(commandSequence, input, dummyOutput, 1);
671 void CNTV2AxiSpiFlash::FlashFixAddress(
const uint32_t address, std::vector<uint8_t>& commandSequence)
675 commandSequence.push_back((address & (0xff000000)) >> 24);
676 commandSequence.push_back((address & (0x00ff0000)) >> 16);
677 commandSequence.push_back((address & (0x0000ff00)) >> 8);
678 commandSequence.push_back((address & (0x000000ff)) >> 0);
681 void CNTV2AxiSpiFlash::SpiSendFIFOData()
689 uint32_t spi_ctrl_val = 0;
692 spi_ctrl_val &= ~0x100;
696 bool txFIFOEmpty =
false;
697 uint32_t notEmptyCount = 0;
698 while(!txFIFOEmpty && notEmptyCount < 1000)
700 uint32_t Tx_Empty = 0;
702 txFIFOEmpty = Tx_Empty ?
true :
false;
713 spi_ctrl_val |= 0x100;
718 bool CNTV2AxiSpiFlash::SpiTransfer(std::vector<uint8_t> commandSequence,
719 const std::vector<uint8_t> inputData,
720 std::vector<uint8_t>& outputData, uint32_t maxByteCutoff)
726 if (commandSequence.empty())
735 uint32_t numDummyBytes = 0;
736 for(
unsigned i=0;i<commandSequence.size();++i)
753 else if (inputData.empty() ==
false)
757 uint32_t maxWrite = maxByteCutoff;
758 if (maxWrite > inputData.size())
759 maxWrite = (uint32_t)inputData.size();
761 for(uint32_t i=0;i<maxWrite;++i)
775 for(uint32_t i=0;i<=maxByteCutoff;++i)
786 bool rxFIFOEmpty =
false;
787 uint32_t notEmptyCount = 0;
788 while(!rxFIFOEmpty && notEmptyCount < 1000)
794 if (notEmptyCount >= numDummyBytes && notEmptyCount <= (maxByteCutoff + numDummyBytes))
796 outputData.push_back(val);
803 uint32_t Rx_Empty = 0;
805 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)