14 #pragma warning(disable: 4305) // Initialization warnings. 15 #pragma warning(disable: 4309) 16 #pragma warning(disable: 4800) 17 #pragma warning(disable: 4996) 20 #define ENUM_CASE_RETURN_VAL_OR_ENUM_STR(condition, retail_name, enum_name)\ 21 case(enum_name): return condition ? retail_name : #enum_name 23 #define MAXBITFILE_HEADERSIZE 512 27 #define KFPDBUG(__x__) AJA_sDEBUG (AJA_DebugUnit_Firmware, AJAFUNC << ": " << __x__) 28 #define KFPWARN(__x__) AJA_sWARNING (AJA_DebugUnit_Firmware, AJAFUNC << ": " << __x__) 29 #define KFPERR(__x__) do {ostringstream oss; oss << AJAFUNC << ": " << __x__; cerr << "## ERROR: " << oss.str() << endl; AJA_sERROR (AJA_DebugUnit_Firmware, oss.str());} while(false) 30 #define KFPNOTE(__x__) do {ostringstream oss; oss << AJAFUNC << ": " << __x__; if (!_bQuiet) cout << "## NOTE: " << oss.str() << endl; AJA_sNOTICE (AJA_DebugUnit_Firmware, oss.str());} while(false) 32 #define FWDBUG(__x__) AJA_sDEBUG (AJA_DebugUnit_Firmware, AJAFUNC << ": " << __x__) 33 #define FWINFO(__x__) AJA_sINFO (AJA_DebugUnit_Firmware, AJAFUNC << ": " << __x__) 34 #define FWWARN(__x__) AJA_sWARNING (AJA_DebugUnit_Firmware, AJAFUNC << ": " << __x__) 35 #define FWFAIL(__x__) AJA_sERROR (AJA_DebugUnit_Firmware, AJAFUNC << ": " << __x__) 36 #define FWNOTE(__x__) AJA_sNOTICE (AJA_DebugUnit_Firmware, AJAFUNC << ": " << __x__) 37 #define FAIL(_p_) ostringstream e; e << _p_; FWFAIL(e.str()); 39 #if 0 // IoIP/KonaIP10g purge 43 oss <<
xHEX0N(uint16_t(mac[0]),2) <<
":" <<
xHEX0N(uint16_t(mac[1]),2) <<
":" <<
xHEX0N(uint16_t(mac[2]),2)
44 <<
":" <<
xHEX0N(uint16_t(mac[3]),2) <<
":" <<
xHEX0N(uint16_t(mac[4]),2) <<
":" <<
xHEX0N(uint16_t(mac[5]),2);
47 #endif // IoIP/KonaIP10g purge 86 _numSectorsFailSafe (0),
94 _hasExtendedCommandSupport (
false)
121 bool CNTV2KonaFlashProgram::SetMBReset()
123 if (!features().CanDoIP())
130 resetOK = WriteRegister(SAREK_REGS + kRegSarekControl, 0x02);
134 resetOK = WriteRegister(SAREK_REGS + kRegSarekControl, 0x01);
136 return resetOK && WriteRegister(SAREK_REGS + kRegSarekSpiSelect, 0x01);
141 UWord runningYear(0), runningMonth(0), runningDay(0);
142 outIsRunning =
false;
148 outMsgs <<
"## WARNING: Failed to get running firmware date/time" << endl;
153 std::tm tm; ::memset(&tm, 0,
sizeof(tm));
154 tm.tm_year = int(runningYear) - 1900;
155 tm.tm_mon = int(runningMonth) - 1;
156 tm.tm_mday = int(runningDay);
159 std::time_t tRunning (std::mktime(&tm));
163 {outMsgs <<
"## WARNING: Failed to ReadHeader or ParseHeader" << endl;
return false;}
165 string installedBuildDate(
GetDate());
169 if (installedBuildDate.empty() || installedBuildDate.length() < 10 || installedBuildDate.at(4) !=
'/')
170 {outMsgs <<
"## WARNING: Bad installed firmware date '" << installedBuildDate <<
"'" << endl;
return false;}
173 tm.tm_year = int(
aja::stol(installedBuildDate.substr(0, 4))) - 1900;
174 tm.tm_mon = int(
aja::stol(installedBuildDate.substr(5, 2))) - 1;
175 tm.tm_mday = int(
aja::stol(installedBuildDate.substr(8, 2)));
178 std::time_t tInstalled (std::mktime(&tm));
181 ULWord secsApart (
ULWord(::difftime(tInstalled, tRunning)));
184 else if (secsApart <= 86400)
185 {outMsgs <<
"## WARNING: Installed firmware date is 1 day past running firmware date" << endl; outIsRunning =
true;}
204 bool knownChip =
false;
417 {outMsgs <<
"Invalid flash block ID " <<
DEC(blockID);
return false;}
421 stat(inBitfileName.c_str(), &fsinfo);
423 pFile = fopen(inBitfileName.c_str(),
"rb");
425 {outMsgs <<
"Cannot open bitfile '" << inBitfileName <<
"'";
return false;}
429 {outMsgs <<
"Allocate " <<
DEC(
_bitFileSize+512) <<
"-byte buffer failed";
return false;}
432 fseek(pFile, 0, SEEK_SET);
442 {outMsgs <<
"Device not recognized";
return false;}
449 if (bitFileName.find(
"_fs_") != string::npos)
458 const int dwordSizeCount (
int(bitFileHeader.
GetByteCount()) / 4);
459 for (
int count(0); status && count < dwordSizeCount; count++, baseAddress += 4)
469 #if 0 // IoIP/KonaIP10g purge 470 bool CNTV2KonaFlashProgram::ReadInfoString()
474 vector<uint8_t> mcsInfoData;
481 _mcsInfo.assign(mcsInfoData.begin(), mcsInfoData.end());
491 if (
_deviceID != 0x010220 || !features().CanDoIP())
498 for (uint32_t count(0); count < dwordSizeCount; count++, baseAddress += 4)
504 if (mcsInfoPtr.U32(
int(count)) == 0)
507 _mcsInfo =
reinterpret_cast<const char*
>(mcsInfoPtr.GetHostPointer());
511 size_t ffPos(
_mcsInfo.find(
"\xFF\xFF"));
512 if (ffPos != string::npos)
516 #endif // IoIP/KonaIP10g purge 520 return "Bitfile not open";
523 return "Device not open";
540 uint32_t twoFixtysixBlockSizeCount ((
_bitFileSize + 256) / 256);
541 uint32_t percentComplete(0);
544 for (uint32_t count(0); count < twoFixtysixBlockSizeCount; count++, baseAddress += 256, bitFilePtr += 64)
552 percentComplete = (count*100)/twoFixtysixBlockSizeCount;
556 cout <<
"Program status: " <<
DEC(percentComplete) <<
"% \r" << flush;
559 cout <<
"Program status: 100% " << endl;
565 return "Program Didn't Verify";
602 for ( uint32_t count=0; count < 64; count++ )
615 uint32_t deviceID = 0;
622 return (deviceID & 0xFFFFFF);
636 uint32_t percentComplete = 0;
642 uint32_t bankCount = 0;
643 for (uint32_t sectorCount = 0; sectorCount < numSectors; sectorCount++ )
660 percentComplete = (sectorCount*100)/numSectors;
663 cout <<
"Erase status: " <<
DEC(percentComplete) <<
"%\r" << flush;
667 cout <<
"Erase status: 100% " << endl;
698 uint32_t errorCount = 0;
702 uint32_t percentComplete(0), lastPercentComplete(999);
707 for (uint32_t count = 0; count < dwordSizeCount; )
719 uint32_t bitFileValue = *bitFilePtr;
720 if (flashValue != bitFileValue)
722 cerr <<
"Error " <<
DEC(count) <<
" E(" <<
HEX0N(bitFileValue,8) <<
"),R(" <<
HEX0N(flashValue,8) <<
")" << endl;
727 percentComplete = (count*100)/dwordSizeCount;
731 if (percentComplete != lastPercentComplete)
733 cout <<
"Program verify: " <<
DEC(percentComplete) <<
"%\r" << flush;
734 lastPercentComplete = percentComplete;
737 count += fullVerify ? 1 : 64;
738 baseAddress += fullVerify ? 4 : 256;
739 bitFilePtr += fullVerify ? 1 : 64;
747 cout <<
"Program verify failed: " <<
DEC(percentComplete) <<
"%" << endl;
751 cout <<
"Program verify: 100% " << endl;
762 {
KFPERR(
"Unable to resize target buffer (not alloc'd by SDK)");
return false;}
763 if (!outBuffer.
Allocate(numDWords * 4))
764 {
KFPERR(
"Failed to allocate " <<
DEC(numDWords*4) <<
"-byte target buffer");
return false;}
767 size_t lastPercent(0), percent(0);
782 for (uint32_t dword(0); dword < numDWords; )
803 outBuffer.
U32(
int(dword)) = flashValue;
807 percent = dword * 100 / numDWords;
808 if (percent != lastPercent)
811 lastPercent = percent;
812 if ((dword % 0x10000) == 0) cerr <<
xHEX0N(dword,8) <<
" of " <<
xHEX0N(numDWords,8) << endl;
835 if (!(regValue &
BIT(8)))
850 uint32_t dwordSizeCount = (numSectors*
_sectorSize)/4;
851 uint32_t percentComplete = 0;
854 for (uint32_t count = 0; count < dwordSizeCount; count++, baseAddress += 4)
861 if ( flashValue != 0xFFFFFFFF )
863 count = dwordSizeCount;
867 percentComplete = (count*100)/dwordSizeCount;
869 cout <<
"Erase verify: " <<
DEC(percentComplete) <<
"%\r" << flush;
872 cout <<
"Erase verify: 100% " << endl;
882 uint32_t baseAddress = 0;
884 uint32_t partitionOffset = 0;
886 cout <<
"S0030000FC" << endl;
888 for ( uint32_t count = 0; count <
_flashSize; count+=32)
894 partitionOffset = count;
895 switch (partitionOffset)
905 uint32_t recordSize = 32;
914 uint32_t cc (recordSize + 5);
918 uint32_t addr = baseAddress+partitionOffset;
919 UWord aa = ((addr >> 24) &0xff);
923 aa = ((addr >> 16) & 0xff);
927 aa = ((addr >> 8) & 0xff);
937 while(i < recordSize)
947 UWord dd = (flashValue & 0xff);
951 dd = ((flashValue >> 8) & 0xff);
955 dd = ((flashValue >> 16) & 0xff);
959 dd = ((flashValue >> 24) & 0xff);
967 checksum = ~checksum;
970 cout << sRec.str() << endl;
975 cout <<
"S705FFF001000A" << endl;
982 uint32_t baseAddress = 0;
984 uint32_t partitionOffset = 0;
986 cout <<
"S0030000FC" << endl;
988 for (uint32_t count = 0; count <
_bankSize; count += 32)
995 uint32_t recordSize = 32;
1004 sRec <<
Hex0N(cc,2);
1007 uint32_t addr = baseAddress + partitionOffset;
1008 UWord aa = ((addr >> 24) & 0xff);
1009 sRec <<
Hex0N(aa,2);
1012 aa = ((addr >> 16) & 0xff);
1013 sRec <<
Hex0N(aa,2);
1016 aa = ((addr >> 8) & 0xff);
1017 sRec <<
Hex0N(aa,2);
1021 sRec <<
Hex0N(aa,2);
1026 while (i < recordSize)
1031 uint32_t flashValue;
1035 UWord dd = (flashValue & 0xff);
1036 sRec <<
Hex0N(dd,2);
1039 dd = ((flashValue >> 8) & 0xff);
1040 sRec <<
Hex0N(dd,2);
1043 dd = ((flashValue >> 16) & 0xff);
1044 sRec <<
Hex0N(dd,2);
1047 dd = ((flashValue >> 24) & 0xff);
1048 sRec <<
Hex0N(dd,2);
1055 checksum = ~checksum;
1058 cout << sRec.str() << endl;
1063 cout <<
"S705FFF001000A" << endl;
1071 int32_t recordSize = 16;
1072 UWord baseAddress = 0x0000;
1074 UByte recordType = 0x00;
1075 UByte byteCount = 0x10;
1077 uint32_t i2cVal = 0x02000050;
1079 for(int32_t x = 0; x < 16; x++)
1088 checksum += byteCount;
1090 UWord addr = baseAddress;
1091 UByte aa = ((addr >> 8) & 0xff);
1095 aa = ((addr) & 0xff);
1109 uint32_t flashValue;
1112 UByte dd = ((flashValue >> 8) & 0xff);
1118 i2cVal += 0x00000100;
1121 baseAddress += 0x0010;
1122 checksum = (checksum ^ 0xFF)+1;
1125 cout << iRec.str() << endl;
1128 cout <<
":00000001FF" << endl;
1144 vector<uint8_t> macData;
1145 macData.push_back(mac1->
mac[3]);
1146 macData.push_back(mac1->
mac[2]);
1147 macData.push_back(mac1->
mac[1]);
1148 macData.push_back(mac1->
mac[0]);
1149 macData.push_back(0);
1150 macData.push_back(0);
1151 macData.push_back(mac1->
mac[5]);
1152 macData.push_back(mac1->
mac[4]);
1154 macData.push_back(mac2->
mac[3]);
1155 macData.push_back(mac2->
mac[2]);
1156 macData.push_back(mac2->
mac[1]);
1157 macData.push_back(mac2->
mac[0]);
1158 macData.push_back(0);
1159 macData.push_back(0);
1160 macData.push_back(mac2->
mac[5]);
1161 macData.push_back(mac2->
mac[4]);
1188 lo |= uint32_t((mac1->
mac[0]) << 24) & 0xff000000;
1189 lo |= uint32_t((mac1->
mac[1]) << 16) & 0x00ff0000;
1190 lo |= uint32_t((mac1->
mac[2]) << 8) & 0x0000ff00;
1191 lo |= uint32_t(mac1->
mac[3]) & 0x000000ff;
1194 hi |= uint32_t((mac1->
mac[4]) << 24) & 0xff000000;
1195 hi |= uint32_t((mac1->
mac[5]) << 16) & 0x00ff0000;
1198 lo2 |= uint32_t((mac2->
mac[0]) << 24) & 0xff000000;
1199 lo2 |= uint32_t((mac2->
mac[1]) << 16) & 0x00ff0000;
1200 lo2 |= uint32_t((mac2->
mac[2]) << 8) & 0x0000ff00;
1201 lo2 |= uint32_t(mac2->
mac[3]) & 0x000000ff;
1204 hi2 |= uint32_t((mac2->
mac[4]) << 24) & 0xff000000;
1205 hi2 |= uint32_t((mac2->
mac[5]) << 16) & 0x00ff0000;
1235 vector<uint8_t> macData;
1242 if (macData.size() < 16)
1245 mac1.
mac[0] = macData.at(3);
1246 mac1.
mac[1] = macData.at(2);
1247 mac1.
mac[2] = macData.at(1);
1248 mac1.
mac[3] = macData.at(0);
1249 mac1.
mac[4] = macData.at(7);
1250 mac1.
mac[5] = macData.at(6);
1252 mac2.
mac[0] = macData.at(8+3);
1253 mac2.
mac[1] = macData.at(8+2);
1254 mac2.
mac[2] = macData.at(8+1);
1255 mac2.
mac[3] = macData.at(8+0);
1256 mac2.
mac[4] = macData.at(8+7);
1257 mac2.
mac[5] = macData.at(8+6);
1268 uint32_t lo, hi, lo2, hi2;
1300 mac1.
mac[0] = (lo & 0xff000000) >> 24;
1301 mac1.
mac[1] = (lo & 0x00ff0000) >> 16;
1302 mac1.
mac[2] = (lo & 0x0000ff00) >> 8;
1303 mac1.
mac[3] = lo & 0x000000ff;
1304 mac1.
mac[4] = (hi & 0xff000000) >> 24;
1305 mac1.
mac[5] = (hi & 0x00ff0000) >> 16;
1307 mac2.
mac[0] = (lo2 & 0xff000000) >> 24;
1308 mac2.
mac[1] = (lo2 & 0x00ff0000) >> 16;
1309 mac2.
mac[2] = (lo2 & 0x0000ff00) >> 8;
1310 mac2.
mac[3] = lo2 & 0x000000ff;
1311 mac2.
mac[4] = (hi2 & 0xff000000) >> 24;
1312 mac2.
mac[5] = (hi2 & 0x00ff0000) >> 16;
1324 vector<uint8_t> licenseData;
1325 for (string::const_iterator it(licenseString.begin()); it != licenseString.end(); ++it)
1326 licenseData.push_back(uint8_t(*it));
1327 licenseData.push_back(0);
1333 if (
_spiFlash->
Write(offset, licenseData, uint32_t(licenseData.size())))
1349 size_t len (licenseString.size());
1350 size_t words ((len/4) + 2);
1354 strcat(data8,licenseString.c_str());
1358 for (
size_t i(0); i < words; i++)
1382 const uint32_t maxSize = 100;
1388 vector<uint8_t> licenseData;
1396 if (licenseData.size() < 4)
1398 else if (licenseData[0] == 0xff && licenseData[1] == 0xff && licenseData[2] == 0xff && licenseData[3] == 0xff)
1402 serialString.assign(licenseData.begin(), licenseData.end());
1405 size_t found = serialString.find(
'\0');
1406 if (found != string::npos)
1407 serialString.resize(found);
1419 memset (license,0x0,
sizeof(license));
1424 bool terminated =
false;
1426 for(uint32_t i = 0; i < maxSize; i++)
1432 if (license[i] == 0xffffffff)
1437 if (license[i] == 0)
1448 res =
reinterpret_cast<char*
>(license);
1460 if (
int(bankNumber) >
int(
BANK_3))
1475 uint32_t bankNumber = 0;
1482 return bankNumber&0xf;
1485 bool CNTV2KonaFlashProgram::SetMCSFile (
const string & inMCSFileName)
1488 cout <<
"Parsing MCS File" << endl;
1489 return _mcsFile.Open(inMCSFileName.c_str());
1492 bool CNTV2KonaFlashProgram::ProgramFromMCS(
bool verify)
1494 if (!_mcsFile.isReady())
1495 {cerr <<
"MCS bitfile not open" << endl;
return false;}
1497 {cerr <<
"Device not open" << endl;
return false;}
1501 if (!_mcsFile.isReady())
1502 {cerr <<
"MCS file not ready" << endl;
return false;}
1507 vector<uint8_t> fpgaData;
1508 uint16_t fpgaPartitionOffset = 0;
1510 _mcsFile.GetPartition(fpgaData, 0x0000, fpgaPartitionOffset,
false);
1520 {cerr <<
"Can't parse header" << endl << msgs.str() << endl;
return false;}
1525 return ProgramSOC(verify);
1528 bool hasErasedSOCs =
false;
1529 uint16_t linearOffsetToBankOffset = 0x0000;
1530 uint16_t basePartitionAddress = linearOffsetToBankOffset;
1531 bool bPartitionValid =
true;
1532 uint32_t partitionCount = 0;
1533 while (bPartitionValid)
1539 uint16_t partitionOffset = 0;
1541 ParsePartitionFromFileLines(basePartitionAddress, partitionOffset);
1542 if (basePartitionAddress < 0x0100)
1545 linearOffsetToBankOffset = 0x0000;
1548 cout <<
"Erase Main Bitfile Bank" << endl;
1553 else if (basePartitionAddress >= 0x0100 && basePartitionAddress < 0x0200)
1556 linearOffsetToBankOffset = 0x0100;
1559 cout <<
"Erase Package Info Block" << endl;
1564 else if (basePartitionAddress >= 0x0200 && basePartitionAddress < 0x0400)
1569 cout <<
"Erase SOC Bank 1" << endl;
1573 cout <<
"Erase SOC Bank 2" << endl;
1576 hasErasedSOCs =
true;
1578 if (basePartitionAddress >= 0x0200 && basePartitionAddress < 0x0300)
1581 linearOffsetToBankOffset = 0x0200;
1587 linearOffsetToBankOffset = 0x0300;
1596 uint16_t baseOffset = basePartitionAddress - linearOffsetToBankOffset;
1597 uint32_t programOffset = uint32_t(baseOffset) << 16 | partitionOffset;
1601 bPartitionValid =
false;
1610 uint32_t bufferIndex = 0;
1611 uint32_t blockSize = 512;
1612 uint32_t dwordsPerBlock = blockSize / 4;
1613 uint32_t totalBlockCount ((uint32_t(
_partitionBuffer.size()) + blockSize) / blockSize);
1614 uint32_t percentComplete = 0;
1617 for (uint32_t blockCount = 0; blockCount < totalBlockCount; blockCount++)
1620 if (baseAddress == 0x01000000 && blockCount > 0 && blockID ==
SOC1_FLASHBLOCK)
1627 uint32_t remainderBytes =
static_cast<uint32_t
>(
_partitionBuffer.size() - bufferIndex);
1631 for (uint32_t dwordCount = 0; dwordCount < dwordsPerBlock; dwordCount++)
1633 uint32_t partitionValue = 0xFFFFFFFF;
1634 if (remainderBytes >= 4)
1641 remainderBytes -= 4;
1645 switch (remainderBytes)
1648 partitionValue = 0xff;
1654 partitionValue = 0xffff;
1659 partitionValue = 0xffffff;
1675 baseAddress += blockSize;
1677 percentComplete = (blockCount * 100) / totalBlockCount;
1679 cout <<
"Partition " <<
DEC(partitionCount) <<
" program status: " <<
DEC(percentComplete) <<
"%\r" << flush;
1682 cout <<
"Partition " <<
DEC(partitionCount) <<
" program status: 100% " << endl;
1703 if (!VerifySOCPartition(blockID, programOffset))
1706 cerr <<
"Verify Error" << endl;
1712 IntelRecordInfo recordInfo;
1713 _mcsFile.GetCurrentParsedRecord(recordInfo);
1714 if (recordInfo.recordType != IRT_ELAR)
1715 bPartitionValid =
false;
1717 basePartitionAddress = recordInfo.linearAddress;
1739 bool CNTV2KonaFlashProgram::ProgramSOC (
const bool verify)
1741 if (!_mcsFile.isReady())
1742 {cerr <<
"MCS bitfile not open" << endl;
return false;}
1747 {cerr <<
"Device not open" << endl;
return false;}
1748 if (!_mcsFile.isReady())
1749 {cerr <<
"MCS bitfile not ready" << endl;
return false;}
1751 vector<uint8_t> ubootData;
1752 vector<uint8_t> imageData;
1753 vector<uint8_t> mcsInfoData;
1754 uint16_t ubootPartitionOffset = 0;
1755 uint16_t imagePartitionOffset = 0;
1756 uint16_t mcsInfoPartitionOffset = 0;
1757 _mcsFile.GetPartition(ubootData, 0x0400, ubootPartitionOffset,
false);
1758 if (ubootData.empty())
1759 {cerr <<
"Could not find uboot data in MCS file" << endl;
return false;}
1761 _mcsFile.GetPartition(imageData, 0x0410, imagePartitionOffset,
false);
1762 if (imageData.empty())
1763 {cerr <<
"Could not find kernel data in MCS file" << endl;
return false;}
1765 _mcsFile.GetPartition(mcsInfoData, 0x05F4, mcsInfoPartitionOffset,
false);
1766 if (mcsInfoData.empty())
1767 {cerr <<
"Could not find mcs info in MCS file" << endl;
return false;}
1773 uint32_t ubootSize = uint32_t(ubootData.size());
1774 uint32_t imageSize = uint32_t(imageData.size());
1775 uint32_t mcsInfoSize = uint32_t(mcsInfoData.size());
1811 {cerr <<
"Device not open" << endl;
return false;}
1813 cout <<
"Erase SOC Bank 1" << endl;
1816 cout <<
"Erase SOC Bank 2" << endl;
1822 uint16_t partition32M = 0x0200;
1823 uint16_t basePartitionAddress = partition32M;
1824 bool bPartitionValid =
true;
1825 uint32_t partitionCount = 0;
1826 while (bPartitionValid)
1828 uint16_t partitionOffset = 0;
1829 ParsePartitionFromFileLines(basePartitionAddress, partitionOffset);
1830 uint16_t baseOffset = basePartitionAddress - partition32M;
1831 uint32_t programOffset = uint32_t(baseOffset) << 16 | partitionOffset;
1834 if (programOffset >= 0x01000000)
1842 uint32_t bufferIndex = 0;
1843 uint32_t blockSize = 512;
1844 uint32_t dwordsPerBlock = blockSize / 4;
1845 uint32_t totalBlockCount =
static_cast<uint32_t
>((
_partitionBuffer.size() + blockSize) / blockSize);
1846 uint32_t percentComplete = 0;
1847 for (uint32_t blockCount = 0; blockCount < totalBlockCount; blockCount++)
1849 if (baseAddress == 0x01000000 && blockCount > 0)
1854 uint32_t remainderBytes =
static_cast<uint32_t
>(
_partitionBuffer.size() - bufferIndex);
1858 for (uint32_t dwordCount = 0; dwordCount < dwordsPerBlock; dwordCount++)
1860 uint32_t partitionValue = 0xFFFFFFFF;
1861 if (remainderBytes >= 4)
1868 remainderBytes -= 4;
1872 switch (remainderBytes)
1875 partitionValue = 0xff;
1881 partitionValue = 0xffff;
1886 partitionValue = 0xffffff;
1902 baseAddress += blockSize;
1904 percentComplete = (blockCount * 100) / totalBlockCount;
1906 cout <<
"Partition " <<
DEC(partitionCount+2) <<
" program status: " <<
DEC(percentComplete) <<
"%\r" << flush;
1909 cout <<
"Partition " <<
DEC(partitionCount+2) <<
" program status: 100% " << endl;
1911 if (verify && !VerifySOCPartition(blockID, programOffset))
1914 cerr <<
"Verify failed" << endl;
1919 IntelRecordInfo recordInfo;
1920 _mcsFile.GetCurrentParsedRecord(recordInfo);
1921 if (recordInfo.recordType != IRT_ELAR)
1922 bPartitionValid =
false;
1924 basePartitionAddress = recordInfo.linearAddress;
1943 static bool getFileSize (
const string & fileName,
size_t & outSizeBytes)
1946 ifstream ifs(fileName.c_str(), ios::binary | ios::in);
1951 ifstream::pos_type curOffset(ifs.tellg());
1952 if (
int(curOffset) == -1)
1954 outSizeBytes = size_t(curOffset);
1961 {outMsgs <<
"Device not open" << endl;
return false;}
1965 vector<uint8_t> writeData;
1969 {outMsgs <<
"getFileSize failed for '" << sCustomFileName <<
"'" << endl;
return false;}
1970 if (sz > maxFlashSize)
1971 {outMsgs <<
"File size " <<
DEC(sz) <<
" exceeds max flash size " <<
DEC(maxFlashSize) << endl;
return false;}
1973 ifstream ifs(sCustomFileName.c_str(), ios::binary | ios::in);
1975 {outMsgs <<
"Unable to open file '" << sCustomFileName <<
"'" << endl;
return false;}
1977 writeData.resize(sz);
1978 ifs.read(reinterpret_cast<char*>(&writeData[0]), streamsize(sz));
1980 {outMsgs <<
"Error reading data from file '" << sCustomFileName <<
"'" << endl;
return false;}
1983 uint32_t writeSize = uint32_t(writeData.size());
1986 {outMsgs <<
"Error erasing sectors, addr=" <<
xHEX0N(addr,8) <<
" length=" <<
DEC(writeSize) << endl;
return false;}
1991 bool result =
true, verify =
true;
2000 static const size_t MAX_CUSTOM_FILE_SIZE (8<<20);
2001 NTV2Buffer customFileBuffer(MAX_CUSTOM_FILE_SIZE);
2002 size_t customSize(0), sz(0);
2006 {outMsgs <<
"Custom write spans banks -- unsupported";
return false;}
2008 {outMsgs <<
"Write not on sector boundary -- unsupported";
return false;}
2010 {outMsgs <<
"Error getting file size for '" << sCustomFileName <<
"'";
return false;}
2011 if (sz > MAX_CUSTOM_FILE_SIZE)
2012 {outMsgs <<
"File size " <<
DEC(sz) <<
" exceeds max supported size " <<
DEC(MAX_CUSTOM_FILE_SIZE);
return false;}
2014 ifstream ifs(sCustomFileName.c_str(), ios::binary | ios::in);
2016 {outMsgs <<
"Unable to open file '" << sCustomFileName <<
"'" << endl;
return false;}
2018 customSize = size_t(ifs.readsome(customFileBuffer, streamsize(customFileBuffer.
GetByteCount())));
2020 {outMsgs <<
"No data read from custom file '" << sCustomFileName <<
"'" << endl;
return false;}
2032 for (uint32_t i(0); i < customSectors; i++)
2035 cout <<
"Erasing sectors - " <<
DECN(i,3) <<
" of " <<
DECN(customSectors,3) <<
"\r" << flush;
2042 uint32_t blockSize (512);
2043 uint32_t dwordsPerBlock (blockSize / 4);
2044 uint32_t totalBlockCount ((uint32_t(customSize) + blockSize - 1) / blockSize);
2045 uint32_t percentComplete (0);
2046 uint32_t baseAddress (offset);
2047 size_t remainderBytes (customSize);
2048 uint32_t bufferIndex (0);
2049 for (uint32_t blockCount(0); blockCount < totalBlockCount; blockCount++)
2054 for (uint32_t dwordCount(0); dwordCount < dwordsPerBlock; dwordCount++)
2056 uint32_t partitionValue = 0xFFFFFFFF;
2057 if (remainderBytes >= 4)
2064 remainderBytes -= 4;
2066 else switch (remainderBytes)
2069 partitionValue = 0xff;
2076 partitionValue = 0xffff;
2082 partitionValue = 0xffffff;
2096 baseAddress += blockSize;
2098 percentComplete = (blockCount * 100) / totalBlockCount;
2100 cout <<
"Program status: " <<
DEC(percentComplete) <<
"% (" <<
DECN(blockCount,4) <<
" of " <<
DECN(totalBlockCount,4) <<
" blocks)\r" << flush;
2165 void CNTV2KonaFlashProgram::ParsePartitionFromFileLines(uint32_t address, uint16_t & partitionOffset)
2169 bool getnext =
false;
2170 if (address != 0x0000 && address != 0x0200)
2177 bool CNTV2KonaFlashProgram::VerifySOCPartition(
FlashBlockID flashID, uint32_t flashBlockOffset)
2181 uint32_t errorCount = 0;
2182 uint32_t baseAddress = flashBlockOffset;
2184 uint32_t dwordsPerPartition =
_bankSize / 4;
2185 uint32_t percentComplete = 0;
2186 uint32_t bufferIndex = 0;
2188 for (uint32_t dwordCount = 0; dwordCount < dwordsPerPartition; dwordCount += 100)
2194 uint32_t flashValue;
2196 uint32_t partitionValue = uint32_t(
_partitionBuffer[bufferIndex + 0]) << 24
2204 if (flashValue != partitionValue)
2206 cerr <<
"Error " <<
DEC(dwordCount) <<
" E(" <<
xHEX0N(partitionValue,8) <<
"),R(" <<
xHEX0N(flashValue,8) <<
")" << endl;
2212 percentComplete = (dwordCount * 100) / dwordsPerPartition;
2214 cout <<
"Program verify: " <<
DEC(percentComplete) <<
"%\r" << flush;
2220 cerr <<
"Program verify failed: " <<
DEC(percentComplete) <<
"%" << endl;
2224 cout <<
"Program verify: 100% " << endl;
2230 const uint32_t WORDS_PER_LINE(4);
2231 uint32_t addr(address), bank(999), offset(addr %
_bankSize);
2234 uint32_t lineCount(0);
2235 for (uint32_t words(0); words < wordCount; words++, offset += 4, addr += 4)
2238 if (newBank != bank)
2250 uint32_t flashValue;
2253 cout <<
Hex0N(flashValue,8) <<
" ";
2254 if (++lineCount == WORDS_PER_LINE)
2270 uint32_t baseAddress = 0;
2272 cout <<
"Erasing ROM" << endl;
2277 uint32_t* bitFilePtr =
reinterpret_cast<uint32_t*
>(dataBuffer.data());
2278 uint32_t twoFixtysixBlockSizeCount = uint32_t((dataBuffer.size()+256)/256);
2279 uint32_t percentComplete = 0;
2282 for ( uint32_t count = 0; count < twoFixtysixBlockSizeCount; count++, baseAddress += 256, bitFilePtr += 64 )
2298 percentComplete = (count*100)/twoFixtysixBlockSizeCount;
2301 if(!
_bQuiet && (count%100 == 0))
2302 cout <<
"Program status: " <<
DEC(percentComplete) <<
"%\r" << flush;
2305 cout <<
"Program status: 100% " << endl;
2328 bool canReboot =
false;
2335 bool CNTV2KonaFlashProgram::CheckAndFixMACs()
2339 if(mac1.
mac[1] != 0x0C || mac2.
mac[1] != 0x0c)
2342 cout <<
"Reprogramming the Mac Addresses!" << endl;
2343 string serialString;
2344 GetSerialNumberString(serialString);
2345 MakeMACsFromSerial(serialString.c_str(), &mac1, &mac2);
2351 bool CNTV2KonaFlashProgram::MakeMACsFromSerial(
const char *sSerialNumber,
MacAddr *pMac1,
MacAddr *pMac2)
2355 if (strstr(sSerialNumber,
"demo") == sSerialNumber)
2358 if (sscanf(sSerialNumber + 4,
"%d", &demoNum) != 1)
2360 if ((demoNum < 1) || (demoNum > 128))
2361 {cerr <<
"WARNING: Outside serial numbers demo0001 to demo0128" << endl;
return false;}
2362 pMac2->
mac[0] = pMac1->
mac[0] = 0x0;
2363 pMac2->
mac[1] = pMac1->
mac[1] = 0x0c;
2364 pMac2->
mac[2] = pMac1->
mac[2] = 0x17;
2365 pMac2->
mac[3] = pMac1->
mac[3] = 0x88;
2366 pMac2->
mac[4] = pMac1->
mac[4] = 0x12;
2367 pMac1->
mac[5] = uint8_t((demoNum - 1) * 2);
2368 pMac2->
mac[5] = pMac1->
mac[5] + 1;
2371 else if (strstr(sSerialNumber,
"1IP") == sSerialNumber)
2378 if (sscanf(sSerialNumber + 4,
"%d", &serNum) != 1)
2380 if ((serNum < 50) || (serNum > 8241))
2381 {cerr <<
"WARNING: Outside serial numbers 1IP00050 to 1IP08241" << endl;
return false;}
2383 int mac16LSBs = (0xA000) + (serNum - 50) * 2;
2385 pMac2->
mac[0] = pMac1->
mac[0] = 0x0;
2386 pMac2->
mac[1] = pMac1->
mac[1] = 0x0c;
2387 pMac2->
mac[2] = pMac1->
mac[2] = 0x17;
2388 pMac2->
mac[3] = pMac1->
mac[3] = 0x42;
2389 pMac2->
mac[4] = pMac1->
mac[4] = uint8_t(mac16LSBs >> 8);
2390 pMac2->
mac[5] = pMac1->
mac[5] = mac16LSBs & 0x0ff;
2393 pMac2->
mac[5] = pMac1->
mac[5] + 1;
2396 else if (strstr(sSerialNumber,
"ENG") == sSerialNumber)
2403 if (sscanf(sSerialNumber + 5,
"%d", &serNum) != 1)
2407 {cerr <<
"WARNING: Outside serial numbers ENG00000 to ENG00127" << endl;
return false;}
2409 int mac16LSBs = (0x1B00) + (serNum * 2);
2411 pMac2->
mac[0] = pMac1->
mac[0] = 0x0;
2412 pMac2->
mac[1] = pMac1->
mac[1] = 0x0c;
2413 pMac2->
mac[2] = pMac1->
mac[2] = 0x17;
2414 pMac2->
mac[3] = pMac1->
mac[3] = 0x88;
2415 pMac2->
mac[4] = pMac1->
mac[4] = uint8_t(mac16LSBs >> 8);
2416 pMac2->
mac[5] = pMac1->
mac[5] = mac16LSBs & 0xff;
2419 pMac2->
mac[5] = pMac1->
mac[5] + 1;
2422 else if (strstr(sSerialNumber,
"6XT") == sSerialNumber)
2430 if (sscanf(sSerialNumber + 4,
"%d", &serNum) != 1)
2433 if ((serNum < 250) || (serNum > 8441))
2434 {cerr <<
"WARNING: Outside serial numbers range 250 to 8441" << endl;
return false;}
2439 if (strstr(sSerialNumber,
"6XT0") == sSerialNumber)
2441 mac24LSBs = (0x48A000) + ((serNum - 250) * 2);
2443 else if (strstr(sSerialNumber,
"6XT2") == sSerialNumber)
2445 mac24LSBs = (0x48E000) + ((serNum - 250) * 2);
2447 else if (strstr(sSerialNumber,
"6XT1") == sSerialNumber)
2449 mac24LSBs = (0x4B2000) + ((serNum - 250) * 2);
2451 else if (strstr(sSerialNumber,
"6XT3") == sSerialNumber)
2453 mac24LSBs = (0x4B6000) + ((serNum - 250) * 2);
2460 pMac2->
mac[0] = pMac1->
mac[0] = 0x0;
2461 pMac2->
mac[1] = pMac1->
mac[1] = 0x0c;
2462 pMac2->
mac[2] = pMac1->
mac[2] = 0x17;
2463 pMac2->
mac[3] = pMac1->
mac[3] = (mac24LSBs & 0xFF0000) >> 16;
2464 pMac2->
mac[4] = pMac1->
mac[4] = (mac24LSBs & 0x00FF00) >> 8;
2465 pMac2->
mac[5] = pMac1->
mac[5] = (mac24LSBs & 0x0000FF) >> 0;
2468 pMac2->
mac[5] = pMac1->
mac[5] + 1;
2472 cerr <<
"Unrecognized or unspecified serial number '" << sSerialNumber <<
"'" << endl;
2478 #pragma warning(default: 4800) static std::string FlashBlockIDToString(const FlashBlockID inID, const bool inShortDisplay=(0))
long stol(const std::string &str, std::size_t *idx, int base)
uint32_t GetBaseAddressForProgramming(FlashBlockID flashBlockNumber)
bool CreateEDIDIntelRecord()
bool Allocate(const size_t inByteCount, const bool inPageAligned=false)
Allocates (or re-allocates) my user-space storage using the given byte count. I assume full responsib...
I interrogate and control an AJA video/audio capture/playout device.
Declares the AJADebug class.
size_t GetByteCount(void) const
uint32_t U32(const int inIndex) const
#define DEVICE_IS_KONAX(__d__)
Declares the AJATime class.
void DisplayData(const uint32_t address, const uint32_t len)
std::string GetDate(void) const
#define DEVICE_IS_IOIP(__d__)
Defines a number of handy byte-swapping macros.
virtual uint32_t Size(SpiFlashSection sectionID=SPI_FLASH_SECTION_TOTAL)=0
CNTV2SpiFlash * _spiFlash
virtual class DeviceCapabilities & features(void)
bool EraseSector(uint32_t sectorAddress)
bool SetBankSelect(BankSelect bankNumber)
virtual bool Verify(const uint32_t address, const std::vector< uint8_t > &dataWritten)=0
virtual bool Read(const uint32_t address, std::vector< uint8_t > &data, uint32_t maxBytes=1)=0
bool CanReportRunningFirmwareDate(void)
static bool getFileSize(const string &fileName, size_t &outSizeBytes)
virtual bool Erase(const uint32_t address, uint32_t bytes)=0
#define NTV2_ASSERT(_expr_)
bool Fill(const T &inValue)
Fills me with the given scalar value.
bool Deallocate(void)
Deallocates my user-space storage (if I own it – i.e. from a prior call to Allocate).
bool SetBitFile(const std::string &inBitfileName, std::ostream &outMsgs, const FlashBlockID blockNumber=AUTO_FLASHBLOCK)
std::string Program(bool fullVerify=(0))
bool WaitForFlashNOTBusy()
bool IsAllocatedBySDK(void) const
virtual bool IsOpen(void) const
bool SetFlashBlockIDBank(FlashBlockID blockID)
bool CreateBankRecord(BankSelect bankID)
ULWord GetSPIFlashVersion(void)
bool VerifyFlash(FlashBlockID flashBlockNumber, bool fullVerify=(0))
virtual bool Write(const uint32_t address, const std::vector< uint8_t > data, uint32_t maxBytes=1)=0
bool _hasExtendedCommandSupport
virtual bool SetBoard(uint32_t index=0)
static void Sleep(const int32_t inMilliseconds)
Suspends execution of the current thread for a given number of milliseconds.
std::string AsString(void) const
virtual ~CNTV2KonaFlashProgram()
bool ReadLicenseInfo(std::string &licenseString)
bool ProgramLicenseInfo(const std::string &licenseString)
static CNTV2FlashProgress gNullUpdater
virtual NTV2DeviceID GetDeviceID(void)
bool WriteCommand(_FLASH_COMMAND inCommand)
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...
#define MAXBITFILE_HEADERSIZE
Describes a user-space buffer on the host computer. I have an address and a length, plus some optional attributes (allocated by SDK?, page-aligned? etc.).
bool ROMHasBankSelect(void)
NTV2BitfileHeaderParser _parser
bool ProgramMACAddresses(MacAddr *mac1, MacAddr *mac2)
virtual bool GetVerbosity()
uint32_t GetNumberOfSectors(FlashBlockID flashBlockNumber)
bool ReadHeader(FlashBlockID flashBlock)
#define NTV2_UNUSED(__p__)
bool ProgramFlashValue(uint32_t address, uint32_t value)
bool EraseChip(UWord chip=0)
bool FullProgram(std::vector< uint8_t > &dataBuffer)
std::vector< uint8_t > _partitionBuffer
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...
virtual uint32_t Offset(SpiFlashSection sectionID=SPI_FLASH_SECTION_TOTAL)=0
#define xHEX0N(__x__, __n__)
bool FastProgramFlash256(uint32_t address, uint32_t *buffer)
uint8_t * _customFileBuffer
bool IsInstalledFWRunning(bool &outIsRunning, std::ostream &outErrorMsgs)
bool SetWarmBootFirmwareReload(bool enable)
Declares the CNTV2KonaFlashProgram class.
CNTV2KonaFlashProgram(CNTV2Card &card)
#define ENUM_CASE_RETURN_VAL_OR_ENUM_STR(condition, retail_name, enum_name)
bool CheckFlashErasedWithBlockID(FlashBlockID flashBlockNumber)
Private include file for all ajabase sources.
virtual bool CanWarmBootFPGA(bool &outCanWarmBoot)
Answers whether or not the FPGA can be reloaded without powering off.
virtual bool UpdatePercentage(const size_t inPercentage)
bool EraseBlock(FlashBlockID blockNumber)
#define HEX0N(__x__, __n__)
bool SetDeviceProperties()
bool ReadFlash(NTV2Buffer &outBuffer, const FlashBlockID flashID, CNTV2FlashProgress &inFlashProgress=CNTV2FlashProgress::nullUpdater)
uint32_t _numSectorsFailSafe
NTV2Buffer _bitFileBuffer
virtual void SetVerbosity(bool verbose)
#define DECN(__x__, __n__)
uint32_t _failSafePadding
#define Hex0N(__x__, __n__)
bool ProgramKonaxMB(const std::string &sCustomFileName, const uint32_t addr, std::ostream &outMsgs)
void DetermineFlashTypeAndBlockNumberFromFileName(const std::string &bitFileName)
bool ProgramCustom(const std::string &sCustomFileName, const uint32_t addr, std::ostream &outMsgs)
#define NTV2EndianSwap32(__val__)
bool CreateSRecord(bool bChangeEndian)
uint32_t ReadBankSelect()
virtual bool GetRunningFirmwareDate(UWord &outYear, UWord &outMonth, UWord &outDay)
Reports the (local Pacific) build date of the currently-running firmware.
static CNTV2FlashProgress & nullUpdater
bool ReadMACAddresses(MacAddr &mac1, MacAddr &mac2)