AJA NTV2 SDK  17.0.1.1246
NTV2 SDK 17.0.1.1246
ntv2konaflashprogram.cpp
Go to the documentation of this file.
1 /* SPDX-License-Identifier: MIT */
7 #include "ntv2konaflashprogram.h"
8 #include "ntv2endian.h"
9 #include "ntv2registersmb.h"
10 #include "ajabase/system/debug.h"
12 #include "ajabase/common/common.h"
13 #include <ctime>
14 #ifdef MSWindows
15  #pragma warning(disable: 4305) // Initialization warnings.
16  #pragma warning(disable: 4309)
17  #pragma warning(disable: 4800)
18  #pragma warning(disable: 4996)
19 #endif
20 
21 #define ENUM_CASE_RETURN_VAL_OR_ENUM_STR(condition, retail_name, enum_name)\
22  case(enum_name): return condition ? retail_name : #enum_name
23 
24 using namespace std;
25 
26 #define KFPDBUG(__x__) AJA_sDEBUG (AJA_DebugUnit_Firmware, AJAFUNC << ": " << __x__)
27 #define KFPWARN(__x__) AJA_sWARNING (AJA_DebugUnit_Firmware, AJAFUNC << ": " << __x__)
28 #define KFPERR(__x__) do {ostringstream oss; oss << AJAFUNC << ": " << __x__; cerr << "## ERROR: " << oss.str() << endl; AJA_sERROR (AJA_DebugUnit_Firmware, oss.str());} while(false)
29 #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)
30 
31 
32 string MacAddr::AsString(void) const
33 {
34  ostringstream oss;
35  oss << xHEX0N(uint16_t(mac[0]),2) << ":" << xHEX0N(uint16_t(mac[1]),2) << ":" << xHEX0N(uint16_t(mac[2]),2)
36  << ":" << xHEX0N(uint16_t(mac[3]),2) << ":" << xHEX0N(uint16_t(mac[4]),2) << ":" << xHEX0N(uint16_t(mac[5]),2);
37  return oss.str();
38 }
39 
41 
43 
44 string CNTV2KonaFlashProgram::FlashBlockIDToString (const FlashBlockID inID, const bool inShortDisplay)
45 {
46  switch (inID)
47  {
48  ENUM_CASE_RETURN_VAL_OR_ENUM_STR(inShortDisplay, "Main", MAIN_FLASHBLOCK);
49  ENUM_CASE_RETURN_VAL_OR_ENUM_STR(inShortDisplay, "FailSafe", FAILSAFE_FLASHBLOCK);
50  ENUM_CASE_RETURN_VAL_OR_ENUM_STR(inShortDisplay, "Auto", AUTO_FLASHBLOCK);
51  ENUM_CASE_RETURN_VAL_OR_ENUM_STR(inShortDisplay, "SOC1", SOC1_FLASHBLOCK);
52  ENUM_CASE_RETURN_VAL_OR_ENUM_STR(inShortDisplay, "SOC2", SOC2_FLASHBLOCK);
53  ENUM_CASE_RETURN_VAL_OR_ENUM_STR(inShortDisplay, "Mac", MAC_FLASHBLOCK);
54  ENUM_CASE_RETURN_VAL_OR_ENUM_STR(inShortDisplay, "MCS", MCS_INFO_BLOCK);
55  ENUM_CASE_RETURN_VAL_OR_ENUM_STR(inShortDisplay, "License", LICENSE_BLOCK);
56  }
57  return "";
58 }
59 
60 
62  : CNTV2Card (),
63  _bitFileSize (0),
64  _flashSize (0),
65  _bankSize (0),
66  _sectorSize (0),
67  _mainOffset (0),
68  _failSafeOffset (0),
69  _macOffset (0),
70  _mcsInfoOffset (0),
71  _licenseOffset (0),
72  _soc1Offset (0),
73  _soc2Offset (0),
74  _numSectorsMain (0),
75  _numSectorsSOC1 (0),
76  _numSectorsSOC2 (0),
77  _numSectorsFailSafe (0),
78  _numBytes (0),
79  _flashID (MAIN_FLASHBLOCK),
80  _deviceID (0),
81  _bQuiet (false),
82  _mcsStep (0),
83  _failSafePadding (0),
84  _spiFlash (AJA_NULL),
85  _hasExtendedCommandSupport (false)
86 {
87 }
88 
90  : CNTV2Card (boardNumber),
91  _bitFileSize (0),
92  _flashSize (0),
93  _bankSize (0),
94  _sectorSize (0),
95  _mainOffset (0),
96  _failSafeOffset (0),
97  _macOffset (0),
98  _mcsInfoOffset (0),
99  _licenseOffset (0),
100  _soc1Offset (0),
101  _soc2Offset (0),
102  _numSectorsMain (0),
103  _numSectorsSOC1 (0),
104  _numSectorsSOC2 (0),
105  _numSectorsFailSafe (0),
106  _numBytes (0),
107  _flashID (MAIN_FLASHBLOCK),
108  _deviceID (0),
109  _bQuiet (false),
110  _mcsStep (0),
111  _failSafePadding (0),
112  _spiFlash (AJA_NULL),
113  _hasExtendedCommandSupport (false)
114 {
116 }
117 
119 {
120  if (_spiFlash)
121  delete _spiFlash;
122 }
123 
125 {
126  _bQuiet = true;
127  if (_spiFlash)
128  {
129  _spiFlash->SetVerbosity(false);
130  }
131 }
132 
134 {
135  ULWord theCommand = (ULWord)inCommand;
137  theCommand |= BIT_16;
138 
139  return WriteRegister(kRegXenaxFlashControlStatus, theCommand);
140 }
141 
143 {
144  if (!IsIPDevice())
145  return false;
146  bool resetOK(false);
147  // Hold MB in reset
148  if ((GetDeviceID() == DEVICE_ID_IOIP_2022) ||
151  resetOK = WriteRegister(SAREK_REGS + kRegSarekControl, 0x02);
152  else if (GetDeviceID() == DEVICE_ID_KONAIP_2022 ||
155  resetOK = WriteRegister(SAREK_REGS + kRegSarekControl, 0x01);
156  // Take SPI bus control
157  return resetOK && WriteRegister(SAREK_REGS + kRegSarekSpiSelect, 0x01);
158 }
159 
160 bool CNTV2KonaFlashProgram::IsInstalledFWRunning (bool & outIsRunning, ostream & outMsgs)
161 {
162  UWord runningYear(0), runningMonth(0), runningDay(0);
163  outIsRunning = false;
164 
165  // Get running FW date...
166  if (!GetRunningFirmwareDate (runningYear, runningMonth, runningDay))
167  {
169  outMsgs << "## WARNING: Failed to get running firmware date/time" << endl;
170  return false;
171  }
172 
173  // Convert running FW date to time_t...
174  std::tm tm; ::memset(&tm, 0, sizeof(tm)); // zero
175  tm.tm_year = int(runningYear) - 1900; // Year
176  tm.tm_mon = int(runningMonth) - 1; // Month
177  tm.tm_mday = int(runningDay); // Day
178  tm.tm_hour = 11; // near mid-day
179  tm.tm_isdst = 0; // Standard time (not DST)
180  std::time_t tRunning (std::mktime(&tm));
181 
182  // Read & parse Main installed FW header...
184  {outMsgs << "## WARNING: Failed to ReadHeader or ParseHeader" << endl; return false;}
185 
186  string installedBuildDate(GetDate());
187  // TEST: same as running FW date: ostringstream oss; oss << DEC(runningYear) << "/" << DEC0N(runningMonth,2) << "/" << DEC0N(runningDay+0,2); installedBuildDate = oss.str();
188  // TEST: 1 day past running FW date: ostringstream oss; oss << DEC(runningYear) << "/" << DEC0N(runningMonth,2) << "/" << DEC0N(runningDay+1,2); installedBuildDate = oss.str();
189  // TEST: 2 days past running FW date: ostringstream oss; oss << DEC(runningYear) << "/" << DEC0N(runningMonth,2) << "/" << DEC0N(runningDay+2,2); installedBuildDate = oss.str();
190  if (installedBuildDate.empty() || installedBuildDate.length() < 10 || installedBuildDate.at(4) != '/')
191  {outMsgs << "## WARNING: Bad installed firmware date '" << installedBuildDate << "'" << endl; return false;}
192 
193  // Convert installed FW date to time_t...
194  tm.tm_year = int(aja::stol(installedBuildDate.substr(0, 4))) - 1900; // Year
195  tm.tm_mon = int(aja::stol(installedBuildDate.substr(5, 2))) - 1; // Month
196  tm.tm_mday = int(aja::stol(installedBuildDate.substr(8, 2))); // Day
197  tm.tm_hour = 11; // near mid-day
198  tm.tm_isdst = 0; // Standard time (not DST)
199  std::time_t tInstalled (std::mktime(&tm));
200 
201  // Calculate seconds between the two dates...
202  ULWord secsApart (ULWord(::difftime(tInstalled, tRunning)));
203  if (secsApart == 0)
204  outIsRunning = true; // Same date
205  else if (secsApart <= 86400) // Call them equal even within a day apart
206  {outMsgs << "## WARNING: Installed firmware date is 1 day past running firmware date" << endl; outIsRunning = true;}
207  return true;
208 }
209 
210 bool CNTV2KonaFlashProgram::SetBoard(UWord boardNumber, uint32_t index)
211 {
212  if (!AsNTV2DriverInterfaceRef(*this).Open(boardNumber))
213  return false;
214 
215  if (!SetDeviceProperties())
216  return false;
217 
218  //For manufacturing use the leds to code the board number
219  uint32_t ledMask = BIT(16)+BIT(17);
220  uint32_t ledShift = 16;
221  return WriteRegister(kRegGlobalControl, index, ledMask, ledShift);
222 
223 }
224 
226 {
227  bool knownChip = false;
228  bool status = false;
229 
231 
232 // case 0x00202018://STMircro
233 // case 0x00012018://CYPRESS S25FL128
234 // case 0x00C22018://Macronix
235 // T-Tap
236 // IoExpress
237 // IoXT
238 // Kona Lhe+
239 // Kona 3G
240 // Kona 3G Quad
241 // Corvid 1
242 // Corvid 22
243 // Corvid 24
244 // Corvid 3G
245 
246 // case 0x00010220://CYPRESS f25fl512
247 // Kona IP 2022
248 // Kona IP 2110
249 // IoIP 2022
250 // IoIP 2110
251 // Io4K+
252 
253 // case 0x009d6019://ISSI
254 // No Product 6/27/18
255 
256 // case 0x00C84018://GIGADEVICE GD25Q127CFIG
257 // case 0x00EF4018://WINBOND W25Q128
258 // T-Tap
259 // IoExpress
260 // IoXT
261 // Kona Lhe+
262 // Kona 3G
263 // Kona 3G Quad
264 // Corvid 1
265 // Corvid 22
266 // Corvid 24
267 // Corvid 3G
268 
269 // case 0x00010219://CYPRESS S25FL256
270 // Kona 1
271 // Kona HDMI
272 // Kona 4
273 // Kona 4 UFC
274 // Corvid 44
275 // Corvid 88
276 // Corvid HBR
277 // Corvid HEVC
278 
279  switch(_deviceID)
280  {
281  case 0x00202018://STMircro
282  case 0x00C22018://Macronix
283  _flashSize = 16 * 1024 * 1024;
284  _bankSize = 16 * 1024 * 1024;
285  _sectorSize = 256 * 1024;
286  _failSafePadding = 1;
287  knownChip = true;
288  break;
289  case 0x00010220://CYPRESS f25fl512
290  _flashSize = 64 * 1024 * 1024;
291  _bankSize = 16 * 1024 * 1024;
292  _sectorSize = 256 * 1024;
293  _failSafePadding = 1;
294  knownChip = true;
295  break;
296  case 0x009d6019://ISSI
297  _flashSize = 64 * 1024 * 1024;
298  _bankSize = 16 * 1024 * 1024;
299  _sectorSize = 64 * 1024;
300  _failSafePadding = 4;
301  knownChip = true;
302  break;
303  case 0x0020ba20://Micron MT25QL512ABB
304  _flashSize = 64 * 1024 * 1024;
305  _bankSize = 16 * 1024 * 1024;
306  _sectorSize = 64 * 1024;
307  _failSafePadding = 4;
309  knownChip = true;
310  break;
311  case 0x00C84018://GIGADEVICE GD25Q127CFIG
312  case 0x00EF4018://WINBOND W25Q128
313  case 0x00012018://CYPRESS S25FL128
314  _flashSize = 16 * 1024 * 1024;
315  _bankSize = 16 * 1024 * 1024;
316  _sectorSize = 64 * 1024;
317  _failSafePadding = 4;
318  knownChip = true;
319  break;
320  case 0x00010219://CYPRESS S25FL256
321  _flashSize = 32 * 1024 * 1024;
322  _bankSize = 16 * 1024 * 1024;
323  _sectorSize = 64 * 1024;
324  _failSafePadding = 4;
325  knownChip = true;
326  break;
327  default:
328  _flashSize = 0;
329  _bankSize = 0;
330  _sectorSize = 0;
331  knownChip = false;
332  break;
333  }
334 
335  if(!knownChip)
336  return false;
337 
339  {
340  default:
341  case 1:
342  //This includes legacy boards such as LHi, Corvid 1...
343  //SPI is devided up into 4 logical blocks of 4M each
344  //Without history explained main is at offset 0 and failsafe is at offset 12
347  _mainOffset = 0;
348  _failSafeOffset = 12 * 1024 * 1024;
349  _macOffset = _bankSize - (2 * _sectorSize);
350  status = true;
351  break;
352  case 2:
355  _mainOffset = 0;
356  _failSafeOffset = 8 * 1024 * 1024;
357  _macOffset = _bankSize - (2 * _sectorSize);
358  status = true;
359  break;
360  case 3:
361  if (_deviceID == 0x010220)
362  {
363  //This is actually SPI v4 but needed this for spoofing Kona4
368  _mainOffset = 0;
369  _soc1Offset = 0;
370  _soc2Offset = 0;
371  _failSafeOffset = 0;// but is really 16*1024*1024;
372  _macOffset = _bankSize - (2 * _sectorSize);
375  status = true;
376  }
377  else
378  {
379  //SPIV3 This gets a little weird both main and failsafe have an offset of 0
380  //and the real offset is controlled by a bank selector switch in firmware
383  _mainOffset = 0;
384  _failSafeOffset = 0;// but is really 16*1024*1024;
385  _macOffset = _bankSize - (2 * _sectorSize);
388  status = true;
389  }
390  break;
391  case 4:
392  //SPIV4 is a bigger SPIv3 2x
397  _mainOffset = 0;
398  _soc1Offset = 0;
399  _soc2Offset = 0;
400  _failSafeOffset = 0;// but is really 16*1024*1024;
401  _macOffset = _bankSize - (2 * _sectorSize);
404  status = true;
405  break;
406  case 5:
407  case 6:
410  _mainOffset = 0;
411  _failSafeOffset = 0;// but is really 32*1024*1024;
412  status = true;
413  break;
414  }
415 
416  if (_spiFlash)
417  {
418  delete _spiFlash;
420  }
421 
423  {
424  _spiFlash = new CNTV2AxiSpiFlash(GetIndexNumber(), !_bQuiet);
425  }
426 
427  return status;
428 }
429 
430 bool CNTV2KonaFlashProgram::SetBitFile (const string & inBitfileName, ostream & outMsgs, const FlashBlockID blockID)
431 {
433  _bitFileName = inBitfileName;
434 
435  if (blockID == AUTO_FLASHBLOCK)
437  else if (blockID >= MAIN_FLASHBLOCK && blockID <= FAILSAFE_FLASHBLOCK)
438  _flashID = blockID;
439  else
440  {outMsgs << "Invalid flash block ID " << DEC(blockID); return false;}
441 
442  FILE* pFile = AJA_NULL;
443  struct stat fsinfo;
444  stat(inBitfileName.c_str(), &fsinfo);
445  _bitFileSize = uint32_t(fsinfo.st_size);
446  pFile = fopen(inBitfileName.c_str(), "rb");
447  if (!pFile)
448  {outMsgs << "Cannot open bitfile '" << inBitfileName << "'"; return false;}
449 
450  // +_256 for fastFlash Programming
452  {outMsgs << "Allocate " << DEC(_bitFileSize+512) << "-byte buffer failed"; return false;}
453  _bitFileBuffer.Fill(0xFFFFFFFF);
454 
455  fseek(pFile, 0, SEEK_SET);
456  fread(_bitFileBuffer, 1, _bitFileSize, pFile);
457  fclose(pFile);
458 
459  // Parse header to make sure this is a xilinx bitfile.
460  if (!_parser.ParseHeader(_bitFileBuffer, outMsgs))
461  return false;
462 
463  if (!SetDeviceProperties())
464  {outMsgs << "Device not recognized"; return false;}
465  return true;
466 }
467 
469 {
471  if (bitFileName.find("_fs_") != string::npos)
473 }
474 
476 {
477  uint32_t baseAddress (GetBaseAddressForProgramming(blockID));
478  SetFlashBlockIDBank(blockID);
479  NTV2Buffer bitFileHeader(MAXBITFILE_HEADERSIZE);
480  const uint32_t dwordSizeCount (bitFileHeader.GetByteCount() / 4);
481  for (uint32_t count(0); count < dwordSizeCount; count++, baseAddress += 4)
482  {
483  WriteRegister(kRegXenaxFlashAddress, baseAddress);
486  ReadRegister(kRegXenaxFlashDOUT, bitFileHeader.U32(int(count)));
487  }
488  ostringstream msgs;
489  const bool status (_parser.ParseHeader(bitFileHeader, msgs));
490  SetBankSelect(BANK_0); // Make sure to reset bank to lower
491  return status;
492 }
493 
495 {
496  if (_spiFlash)
497  {
498  vector<uint8_t> mcsInfoData;
499  bool oldVerboseMode = _spiFlash->GetVerbosity();
500  _spiFlash->SetVerbosity(false);
501  uint32_t offset = _spiFlash->Offset(SPI_FLASH_SECTION_MCSINFO);
502  if (_spiFlash->Read(offset, mcsInfoData, MAXMCSINFOSIZE))
503  {
504  _spiFlash->SetVerbosity(oldVerboseMode);
505  _mcsInfo.assign(mcsInfoData.begin(), mcsInfoData.end());
506  }
507  else
508  {
509  _spiFlash->SetVerbosity(oldVerboseMode);
510  return false;
511  }
512  }
513  else
514  {
515  if (_deviceID != 0x010220 || !IsIPDevice())
516  return false;
517  uint32_t baseAddress = _mcsInfoOffset;
519 
520  NTV2Buffer mcsInfoPtr(MAXMCSINFOSIZE);
521  uint32_t dwordSizeCount (MAXMCSINFOSIZE / 4);
522  for (uint32_t count(0); count < dwordSizeCount; count++, baseAddress += 4)
523  {
524  WriteRegister(kRegXenaxFlashAddress, baseAddress);
527  ReadRegister(kRegXenaxFlashDOUT, mcsInfoPtr.U32(int(count)));
528  if (mcsInfoPtr.U32(int(count)) == 0)
529  break;
530  }
531  _mcsInfo = reinterpret_cast<const char*>(mcsInfoPtr.GetHostPointer());
532  SetBankSelect(BANK_0); // Make sure to reset bank to lower
533  }
534  // Fix up _mcsInfo...
535  size_t ffPos(_mcsInfo.find("\xFF\xFF"));
536  if (ffPos != string::npos)
537  _mcsInfo = _mcsInfo.substr(0, ffPos); // Lop off "\xFF\xFF...", if present
538  return true;
539 }
540 
541 std::string CNTV2KonaFlashProgram::Program(bool fullVerify)
542 {
543  if (!_bitFileBuffer)
544  return "Bitfile not open";
545 
546  if (!IsOpen())
547  return "Device not open";
548 
549  uint32_t baseAddress(GetBaseAddressForProgramming(_flashID));
550  switch (_flashID)
551  {
556  default: break;
557  }
558 
560 
562 
563  uint32_t* bitFilePtr = _bitFileBuffer;
564  uint32_t twoFixtysixBlockSizeCount ((_bitFileSize + 256) / 256);
565  uint32_t percentComplete(0);
567  WriteRegister(kVRegFlashSize, twoFixtysixBlockSizeCount);
568  for (uint32_t count(0); count < twoFixtysixBlockSizeCount; count++, baseAddress += 256, bitFilePtr += 64)
569  {
570  if (::NTV2DeviceGetSPIFlashVersion(_boardID) >= 5 && baseAddress == _bankSize)
571  {
572  baseAddress = 0;
574  }
575  FastProgramFlash256(baseAddress, bitFilePtr);
576  percentComplete = (count*100)/twoFixtysixBlockSizeCount;
577 
579  if (!_bQuiet)
580  cout << "Program status: " << DEC(percentComplete) << "% \r" << flush;
581  }
582  if (!_bQuiet)
583  cout << "Program status: 100% " << endl;
584 
586  if (!VerifyFlash(_flashID, fullVerify))
587  {
589  return "Program Didn't Verify";
590  }
591 
592  // Protect Device
598 
605 
607  return "";
608 }
609 
610 bool CNTV2KonaFlashProgram::ProgramFlashValue(uint32_t address, uint32_t value)
611 {
618 
619  return true;
620 }
621 
622 bool CNTV2KonaFlashProgram::FastProgramFlash256(uint32_t address, uint32_t* buffer)
623 {
626  for ( uint32_t count=0; count < 64; count++ )
627  {
628  WriteRegister(kRegXenaxFlashDIN, *buffer++);
629  }
633 
634  return true;
635 }
636 
638 {
639  uint32_t deviceID = 0;
640  if (IsOpen ())
641  {
644  ReadRegister(kRegXenaxFlashDOUT, deviceID);
645  }
646  return (deviceID & 0xFFFFFF);
647 }
648 
650 {
651  if (!IsOpen())
652  return false;
653  SetFlashBlockIDBank(blockID);
654 
660  uint32_t percentComplete = 0;
661 
662  uint32_t numSectors = GetNumberOfSectors(blockID);
663  WriteRegister(kVRegFlashSize,numSectors);
664 
665  uint32_t baseAddress = GetBaseAddressForProgramming(blockID);
666  uint32_t bankCount = 0;
667  for (uint32_t sectorCount = 0; sectorCount < numSectors; sectorCount++ )
668  {
669  if (::NTV2DeviceGetSPIFlashVersion(_boardID) >= 5 && sectorCount*_sectorSize == _bankSize)
670  {
671  switch(blockID)
672  {
673  default:
674  case MAIN_FLASHBLOCK:
676  break;
677  case FAILSAFE_FLASHBLOCK:
679  break;
680  }
681  bankCount++;
682  }
683  EraseSector(baseAddress + ((sectorCount - (_numSectorsMain* bankCount)) * _sectorSize));
684  percentComplete = (sectorCount*100)/numSectors;
685  WriteRegister(kVRegFlashStatus, sectorCount);
686  if (!_bQuiet)
687  cout << "Erase status: " << DEC(percentComplete) << "%\r" << flush;
688  }
689  WriteRegister(kVRegFlashStatus,numSectors);
690  if (!_bQuiet)
691  cout << "Erase status: 100% " << endl;
692  //if ( !CheckFlashErasedWithBlockID(flashBlockNumber))
693  //throw "Erase didn't work";
694  return SetBankSelect(BANK_0);
695 }
696 
697 bool CNTV2KonaFlashProgram::EraseSector (uint32_t sectorAddress)
698 {
699  WriteRegister(kRegXenaxFlashAddress, sectorAddress);
703  return WaitForFlashNOTBusy();
704 }
705 
707 { (void) chip; // unused
717  return WaitForFlashNOTBusy();
718 }
719 
720 bool CNTV2KonaFlashProgram::VerifyFlash (FlashBlockID flashID, bool fullVerify)
721 {
722  uint32_t errorCount = 0;
723  uint32_t baseAddress = GetBaseAddressForProgramming(flashID);
724  uint32_t* bitFilePtr = _bitFileBuffer;
725  uint32_t dwordSizeCount ((_bitFileSize + 4) / 4);
726  uint32_t percentComplete(0), lastPercentComplete(999);
727 
730  WriteRegister(kVRegFlashSize, dwordSizeCount);
731  for (uint32_t count = 0; count < dwordSizeCount; )
732  {
733  if (::NTV2DeviceGetSPIFlashVersion(_boardID) >= 5 && baseAddress == _bankSize)
734  {
735  baseAddress = 0;
737  }
738  WriteRegister(kRegXenaxFlashAddress, baseAddress);
741  uint32_t flashValue;
742  ReadRegister(kRegXenaxFlashDOUT, flashValue);
743  uint32_t bitFileValue = *bitFilePtr;
744  if (flashValue != bitFileValue)
745  {
746  cerr << "Error " << DEC(count) << " E(" << HEX0N(bitFileValue,8) << "),R(" << HEX0N(flashValue,8) << ")" << endl;
747  errorCount++;
748  if (errorCount > 1)
749  break;
750  }
751  percentComplete = (count*100)/dwordSizeCount;
753  if (!_bQuiet)
754  {
755  if (percentComplete != lastPercentComplete)
756  {
757  cout << "Program verify: " << DEC(percentComplete) << "%\r" << flush;
758  lastPercentComplete = percentComplete;
759  }
760  }
761  count += fullVerify ? 1 : 64;
762  baseAddress += fullVerify ? 4 : 256;
763  bitFilePtr += fullVerify ? 1 : 64;
764  }
765 
767 
768  if (errorCount)
769  {
770  if (!_bQuiet)
771  cout << "Program verify failed: " << DEC(percentComplete) << "%" << endl;
772  return false;
773  }
774  if (!_bQuiet)
775  cout << "Program verify: 100% " << endl;
776  return true;
777 }
778 
779 bool CNTV2KonaFlashProgram::ReadFlash (NTV2Buffer & outBuffer, const FlashBlockID inFlashID, CNTV2FlashProgress & inFlashProgress)
780 {
781  uint32_t baseAddress(GetBaseAddressForProgramming(inFlashID));
782  const uint32_t numDWords((_bitFileSize+4)/4);
783  if (outBuffer.GetByteCount() < numDWords*4)
784  {
785  if (outBuffer.GetByteCount() && !outBuffer.IsAllocatedBySDK())
786  {KFPERR("Unable to resize target buffer (not alloc'd by SDK)"); return false;}
787  if (!outBuffer.Allocate(numDWords * 4))
788  {KFPERR("Failed to allocate " << DEC(numDWords*4) << "-byte target buffer"); return false;}
789  }
790 
791  size_t lastPercent(0), percent(0);
792  inFlashProgress.UpdatePercentage(lastPercent);
793  switch (_flashID)
794  {
795  default:
796  case MAIN_FLASHBLOCK:
798  break;
799  case FAILSAFE_FLASHBLOCK:
801  break;
802  }
804  WriteRegister(kVRegFlashSize, numDWords);
805  KFPDBUG("About to read " << xHEX0N(numDWords*4,8) << "(" << DEC(numDWords*4) << ") bytes from '" << FlashBlockIDToString(inFlashID, /*compact*/true) << "' address " << xHEX0N(baseAddress,8));
806  for (uint32_t dword(0); dword < numDWords; )
807  {
808  if (::NTV2DeviceGetSPIFlashVersion(_boardID) >= 5 && baseAddress == _bankSize)
809  {
810  baseAddress = 0;
811  switch (_flashID)
812  {
813  default:
814  case MAIN_FLASHBLOCK:
816  break;
817  case FAILSAFE_FLASHBLOCK:
819  break;
820  }
821  }
822  WriteRegister(kRegXenaxFlashAddress, baseAddress);
825  uint32_t flashValue;
826  ReadRegister(kRegXenaxFlashDOUT, flashValue);
827  outBuffer.U32(int(dword)) = flashValue;
829 
830  dword += 1;
831  percent = dword * 100 / numDWords;
832  if (percent != lastPercent)
833  if (!inFlashProgress.UpdatePercentage(percent))
834  {SetBankSelect(BANK_0); KFPERR("Cancelled at " << DEC(percent) << "% addr=" << xHEX0N(baseAddress,8) << " dword=" << DEC(dword)); return false;}
835  lastPercent = percent;
836  if ((dword % 0x10000) == 0) cerr << xHEX0N(dword,8) << " of " << xHEX0N(numDWords,8) << endl;
837  baseAddress += 4;
838  }
840  inFlashProgress.UpdatePercentage(100);
841  KFPNOTE("Successfully read " << xHEX0N(numDWords*4,8) << "(" << DEC(numDWords*4) << ") bytes from '" << FlashBlockIDToString(inFlashID, /*compact*/true) << "' address " << xHEX0N(baseAddress,8));
842  return true;
843 }
844 
846 {
847  bool busy = true;
848  int i = 0;
849  uint32_t regValue;
850  while (i < 1)
851  {
852  ReadRegister(kRegBoardID, regValue);
853  i++;
854  }
855  regValue = 0;
856  do
857  {
859  if (!(regValue & BIT(8)))
860  {
861  busy = false;
862  break;
863  }
864  } while (busy);
865 
866  return !busy; // Return true if wait was successful
867 }
868 
870 {
871  bool status = true;
872  uint32_t baseAddress = GetBaseAddressForProgramming(flashID);
873  uint32_t numSectors = GetNumberOfSectors(flashID);
874  uint32_t dwordSizeCount = (numSectors*_sectorSize)/4;
875  uint32_t percentComplete = 0;
876  SetFlashBlockIDBank(flashID);
877 
878  for (uint32_t count = 0; count < dwordSizeCount; count++, baseAddress += 4)
879  {
880  WriteRegister(kRegXenaxFlashAddress, baseAddress);
883  uint32_t flashValue;
884  ReadRegister(kRegXenaxFlashDOUT, flashValue);
885  if ( flashValue != 0xFFFFFFFF )
886  {
887  count = dwordSizeCount;
888  status = false;
889  continue;
890  }
891  percentComplete = (count*100)/dwordSizeCount;
892  if(!_bQuiet)
893  cout << "Erase verify: " << DEC(percentComplete) << "%\r" << flush;
894  }
895  if(!_bQuiet && status == true)
896  cout << "Erase verify: 100% " << endl;
897 
899 
900  return status;
901 }
902 
903 void CNTV2KonaFlashProgram::SRecordOutput (const char *pSRecord)
904 {
905  cout << pSRecord << endl;
906 }
907 
908 bool CNTV2KonaFlashProgram::CreateSRecord(bool bChangeEndian)
909 {
910  uint32_t baseAddress = 0;
911  char sRecord[100];
912  uint32_t partitionOffset = 0;
913 
914  SRecordOutput("S0030000FC");
915 
916  for ( uint32_t count = 0; count < _flashSize; count+=32)
917  {
918  if (ROMHasBankSelect() && count % _bankSize == 0)
919  {
920  baseAddress = 0;
921  partitionOffset = count;
922  switch (partitionOffset)
923  {
924  default:
925  case 0x00000000: SetBankSelect(BANK_0); break;
926  case 0x01000000: SetBankSelect(BANK_1); break;
927  case 0x02000000: SetBankSelect(BANK_2); break;
928  case 0x03000000: SetBankSelect(BANK_3); break;
929  }
930  }
931 
932  uint32_t recordSize = 32;
933  if((_flashSize - count) < recordSize)
934  recordSize = _flashSize - count;
935 
936 
937  UByte checksum = 0;
938 
939  sRecord[0] = 'S';
940  sRecord[1] = '3';
941 
942  uint32_t cc (recordSize + 5);
943  sprintf(&sRecord[2], "%02x", cc);
944  checksum += cc;
945 
946  uint32_t addr = baseAddress+partitionOffset;
947  UWord aa = ((addr >> 24) &0xff);
948  sprintf(&sRecord[4], "%02x", aa);
949  checksum += aa;
950 
951  aa = ((addr >> 16) & 0xff);
952  sprintf (&sRecord[6],"%02x", aa);
953  checksum += aa;
954 
955  aa = ((addr >> 8) & 0xff);
956  sprintf (&sRecord[8],"%02x", aa);
957  checksum += aa;
958 
959  aa = (addr & 0xff);
960  sprintf (&sRecord[10],"%02x", aa);
961  checksum += aa;
962 
963  uint32_t i = 0;
964  int32_t index = 12;
965  while(i < recordSize)
966  {
970  uint32_t flashValue;
971  ReadRegister(kRegXenaxFlashDOUT, flashValue);
972  if(bChangeEndian)
973  flashValue = NTV2EndianSwap32(flashValue);
974 
975  UWord dd = (flashValue & 0xff);
976  sprintf(&sRecord[index], "%02x", dd);
977  checksum += dd;
978 
979  dd = ((flashValue >> 8) & 0xff);
980  sprintf(&sRecord[index+2], "%02x", dd);
981  checksum += dd;
982 
983  dd = ((flashValue >> 16) & 0xff);
984  sprintf(&sRecord[index+4], "%02x", dd);
985  checksum += dd;
986 
987  dd = ((flashValue >> 24) & 0xff);
988  sprintf(&sRecord[index+6], "%02x", dd);
989  checksum += dd;
990 
991  i += 4;
992  index += 8;
993  baseAddress += 4;
994  }
995  checksum = ~checksum;
996  sprintf(&sRecord[index], "%02x", checksum);
997 
998  SRecordOutput(sRecord);
999  }
1000 
1002 
1003  SRecordOutput ("S705FFF001000A");
1004 
1005  return true;
1006 }
1007 
1009 {
1010  uint32_t baseAddress = 0;
1011  char sRecord[100];
1012  uint32_t partitionOffset = 0;
1013 
1014  SRecordOutput("S0030000FC");
1015 
1016  for (uint32_t count = 0; count < _bankSize; count += 32)
1017  {
1018  if (ROMHasBankSelect())
1019  {
1020  SetBankSelect(bankID);
1021  }
1022 
1023  uint32_t recordSize = 32;
1024  if ((_flashSize - count) < recordSize)
1025  recordSize = _flashSize - count;
1026 
1027  UByte checksum = 0;
1028 
1029  sRecord[0] = 'S';
1030  sRecord[1] = '3';
1031 
1032  UWord cc (UWord(recordSize) + 5);
1033  sprintf(&sRecord[2], "%02x", cc);
1034  checksum += cc;
1035 
1036  uint32_t addr = baseAddress + partitionOffset;
1037  UWord aa = ((addr >> 24) & 0xff);
1038  sprintf(&sRecord[4], "%02x", aa);
1039  checksum += aa;
1040 
1041  aa = ((addr >> 16) & 0xff);
1042  sprintf(&sRecord[6], "%02x", aa);
1043  checksum += aa;
1044 
1045  aa = ((addr >> 8) & 0xff);
1046  sprintf(&sRecord[8], "%02x", aa);
1047  checksum += aa;
1048 
1049  aa = (addr & 0xff);
1050  sprintf(&sRecord[10], "%02x", aa);
1051  checksum += aa;
1052 
1053  uint32_t i = 0;
1054  int32_t index = 12;
1055  while (i < recordSize)
1056  {
1057  WriteRegister(kRegXenaxFlashAddress, baseAddress);
1060  uint32_t flashValue;
1061  ReadRegister(kRegXenaxFlashDOUT, flashValue);
1062  //flashValue = NTV2EndianSwap32(flashValue);
1063 
1064  UWord dd = (flashValue & 0xff);
1065  sprintf(&sRecord[index], "%02x", dd);
1066  checksum += dd;
1067 
1068  dd = ((flashValue >> 8) & 0xff);
1069  sprintf(&sRecord[index + 2], "%02x", dd);
1070  checksum += dd;
1071 
1072  dd = ((flashValue >> 16) & 0xff);
1073  sprintf(&sRecord[index + 4], "%02x", dd);
1074  checksum += dd;
1075 
1076  dd = ((flashValue >> 24) & 0xff);
1077  sprintf(&sRecord[index + 6], "%02x", dd);
1078  checksum += dd;
1079 
1080  i += 4;
1081  index += 8;
1082  baseAddress += 4;
1083  }
1084  checksum = ~checksum;
1085  sprintf(&sRecord[index], "%02x", checksum);
1086 
1087  SRecordOutput(sRecord);
1088  }
1089 
1091 
1092  SRecordOutput("S705FFF001000A");
1093 
1094  return true;
1095 }
1096 
1098 {
1099  char iRecord[100];
1100  int32_t recordSize = 16;
1101  UWord baseAddress = 0x0000;
1102  UByte checksum = 0;
1103  UByte recordType = 0x00;
1104  UByte byteCount = 0x10;
1105 
1106  uint32_t i2cVal = 0x02000050;
1107 
1108  for(int32_t x = 0; x < 16; x++)
1109  {
1110  int32_t i= 0;
1111  int32_t index = 0;
1112  checksum = 0;
1113 
1114  iRecord[0] = ':';
1115 
1116  sprintf(&iRecord[1], "%02x", byteCount);
1117  checksum += byteCount;
1118 
1119  UWord addr = baseAddress;
1120  UByte aa = ((addr >> 8) & 0xff);
1121  sprintf(&iRecord[3], "%02x", aa);
1122  checksum += aa;
1123 
1124  aa = ((addr) & 0xff);
1125  sprintf(&iRecord[5], "%02x", aa);
1126  checksum += aa;
1127 
1128  sprintf (&iRecord[7], "%02x", recordType);
1129 
1130  index = 9;
1131 
1132  while(i<recordSize)
1133  {
1135 
1136  AJATime::Sleep(100);
1137 
1138  uint32_t flashValue;
1139  ReadRegister(kRegFS1I2C1Data, flashValue);
1140 
1141  UByte dd = ((flashValue >> 8) & 0xff);
1142  sprintf(&iRecord[index], "%02x", dd);
1143  checksum += dd;
1144 
1145  i++;
1146  index+=2;
1147  i2cVal += 0x00000100;
1148  }
1149 
1150  baseAddress += 0x0010;
1151  checksum = (checksum ^ 0xFF)+1;
1152  sprintf(&iRecord[index], "%02x", checksum);
1153 
1154  SRecordOutput(iRecord);
1155  }
1156 
1157  SRecordOutput(":00000001FF");
1158 
1159  return true;
1160 
1161 }
1162 
1164 {
1165  if(!IsIPDevice())
1166  return false;
1167 
1168  if (!mac1 || !mac2)
1169  return false;
1170 
1171  if (_spiFlash)
1172  {
1173  vector<uint8_t> macData;
1174  macData.push_back(mac1->mac[3]);
1175  macData.push_back(mac1->mac[2]);
1176  macData.push_back(mac1->mac[1]);
1177  macData.push_back(mac1->mac[0]);
1178  macData.push_back(0);
1179  macData.push_back(0);
1180  macData.push_back(mac1->mac[5]);
1181  macData.push_back(mac1->mac[4]);
1182 
1183  macData.push_back(mac2->mac[3]);
1184  macData.push_back(mac2->mac[2]);
1185  macData.push_back(mac2->mac[1]);
1186  macData.push_back(mac2->mac[0]);
1187  macData.push_back(0);
1188  macData.push_back(0);
1189  macData.push_back(mac2->mac[5]);
1190  macData.push_back(mac2->mac[4]);
1191 
1192  bool oldVerboseMode = _spiFlash->GetVerbosity();
1193  _spiFlash->SetVerbosity(false);
1194  uint32_t offset = _spiFlash->Offset(SPI_FLASH_SECTION_MAC);
1195  _spiFlash->Erase(offset, uint32_t(macData.size()));
1196  if (_spiFlash->Write(offset, macData, uint32_t(macData.size())))
1197  {
1198  _spiFlash->SetVerbosity(oldVerboseMode);
1199  return true;
1200  }
1201  else
1202  {
1203  _spiFlash->SetVerbosity(oldVerboseMode);
1204  return false;
1205  }
1206  }
1207  else
1208  {
1209  uint32_t baseAddress = _macOffset;
1210 
1212 
1214 
1215 
1216  uint32_t lo = 0;
1217  lo |= uint32_t((mac1->mac[0]) << 24) & 0xff000000;
1218  lo |= uint32_t((mac1->mac[1]) << 16) & 0x00ff0000;
1219  lo |= uint32_t((mac1->mac[2]) << 8) & 0x0000ff00;
1220  lo |= uint32_t(mac1->mac[3]) & 0x000000ff;
1221 
1222  uint32_t hi = 0;
1223  hi |= uint32_t((mac1->mac[4]) << 24) & 0xff000000;
1224  hi |= uint32_t((mac1->mac[5]) << 16) & 0x00ff0000;
1225 
1226  uint32_t lo2 = 0;
1227  lo2 |= uint32_t((mac2->mac[0]) << 24) & 0xff000000;
1228  lo2 |= uint32_t((mac2->mac[1]) << 16) & 0x00ff0000;
1229  lo2 |= uint32_t((mac2->mac[2]) << 8) & 0x0000ff00;
1230  lo2 |= uint32_t(mac2->mac[3]) & 0x000000ff;
1231 
1232  uint32_t hi2 = 0;
1233  hi2 |= uint32_t((mac2->mac[4]) << 24) & 0xff000000;
1234  hi2 |= uint32_t((mac2->mac[5]) << 16) & 0x00ff0000;
1235 
1236 
1237  ProgramFlashValue(baseAddress, lo);
1238  baseAddress += 4;
1239  ProgramFlashValue(baseAddress, hi);
1240  baseAddress += 4;
1241  ProgramFlashValue(baseAddress, lo2);
1242  baseAddress += 4;
1243  ProgramFlashValue(baseAddress, hi2);
1244 
1250 
1252 
1253  return true;
1254  }
1255 }
1256 
1258 {
1259  uint32_t lo;
1260  uint32_t hi;
1261  uint32_t lo2;
1262  uint32_t hi2;
1263 
1264  if(!IsIPDevice())
1265  return false;
1266 
1267  if (_spiFlash)
1268  {
1269  vector<uint8_t> macData;
1270  bool oldVerboseMode = _spiFlash->GetVerbosity();
1271  _spiFlash->SetVerbosity(false);
1272  uint32_t offset = _spiFlash->Offset(SPI_FLASH_SECTION_MAC);
1273  if (_spiFlash->Read(offset, macData, 16))
1274  {
1275  _spiFlash->SetVerbosity(oldVerboseMode);
1276  if (macData.size() < 16)
1277  return false;
1278 
1279  mac1.mac[0] = macData.at(3);
1280  mac1.mac[1] = macData.at(2);
1281  mac1.mac[2] = macData.at(1);
1282  mac1.mac[3] = macData.at(0);
1283  mac1.mac[4] = macData.at(7);
1284  mac1.mac[5] = macData.at(6);
1285 
1286  mac2.mac[0] = macData.at(8+3);
1287  mac2.mac[1] = macData.at(8+2);
1288  mac2.mac[2] = macData.at(8+1);
1289  mac2.mac[3] = macData.at(8+0);
1290  mac2.mac[4] = macData.at(8+7);
1291  mac2.mac[5] = macData.at(8+6);
1292  return true;
1293  }
1294  else
1295  {
1296  _spiFlash->SetVerbosity(oldVerboseMode);
1297  return false;
1298  }
1299  }
1300  else
1301  {
1302  uint32_t baseAddress = GetBaseAddressForProgramming(MAC_FLASHBLOCK);
1304 
1305  WriteRegister(kRegXenaxFlashAddress, baseAddress);
1309  baseAddress += 4;
1310 
1311  WriteRegister(kRegXenaxFlashAddress, baseAddress);
1315  baseAddress += 4;
1316 
1317  WriteRegister(kRegXenaxFlashAddress, baseAddress);
1321  baseAddress += 4;
1322 
1323  WriteRegister(kRegXenaxFlashAddress, baseAddress);
1327 
1329 
1330  //if (lo == 0xffffffff && hi == 0xffffffff && lo2 == 0xffffffff && hi2 == 0xffffffff)
1331  //return false;
1332 
1333  mac1.mac[0] = (lo & 0xff000000) >> 24;
1334  mac1.mac[1] = (lo & 0x00ff0000) >> 16;
1335  mac1.mac[2] = (lo & 0x0000ff00) >> 8;
1336  mac1.mac[3] = lo & 0x000000ff;
1337  mac1.mac[4] = (hi & 0xff000000) >> 24;
1338  mac1.mac[5] = (hi & 0x00ff0000) >> 16;
1339 
1340  mac2.mac[0] = (lo2 & 0xff000000) >> 24;
1341  mac2.mac[1] = (lo2 & 0x00ff0000) >> 16;
1342  mac2.mac[2] = (lo2 & 0x0000ff00) >> 8;
1343  mac2.mac[3] = lo2 & 0x000000ff;
1344  mac2.mac[4] = (hi2 & 0xff000000) >> 24;
1345  mac2.mac[5] = (hi2 & 0x00ff0000) >> 16;
1346  }
1347 
1348  return true;
1349 }
1350 
1351 bool CNTV2KonaFlashProgram::ProgramLicenseInfo (const string & licenseString)
1352 {
1353  if(!IsIPDevice())
1354  return false;
1355 
1356  if (_spiFlash)
1357  {
1358  vector<uint8_t> licenseData;
1359  for (string::const_iterator it(licenseString.begin()); it != licenseString.end(); ++it)
1360  licenseData.push_back(uint8_t(*it));
1361  licenseData.push_back(0);
1362 
1363  bool oldVerboseMode = _spiFlash->GetVerbosity();
1364  _spiFlash->SetVerbosity(false);
1365  uint32_t offset = _spiFlash->Offset(SPI_FLASH_SECTION_LICENSE);
1366  _spiFlash->Erase(offset, uint32_t(licenseData.size()));
1367  if (_spiFlash->Write(offset, licenseData, uint32_t(licenseData.size())))
1368  _spiFlash->SetVerbosity(oldVerboseMode);
1369  else
1370  {
1371  _spiFlash->SetVerbosity(oldVerboseMode);
1372  return false;
1373  }
1374  }
1375  else
1376  {
1377 
1379 
1381 
1383 
1384  size_t len (licenseString.size());
1385  size_t words ((len/4) + 2);
1386  NTV2Buffer data8(words*4);
1387  ULWord * data32 = data8;
1388  data8.Fill(0x0000);
1389  strcat(data8,licenseString.c_str());
1390 
1392 
1393  for (size_t i(0); i < words; i++)
1394  {
1395  ProgramFlashValue(sectorAddress, data32[i]);
1396  sectorAddress += 4;
1397  }
1398 
1399  // Protect Device
1411  }
1412  return true;
1413 }
1414 
1415 bool CNTV2KonaFlashProgram::ReadLicenseInfo(string& serialString)
1416 {
1417  const uint32_t maxSize = 100;
1418 
1419  if(!IsIPDevice())
1420  return false;
1421 
1422  if (_spiFlash)
1423  {
1424  vector<uint8_t> licenseData;
1425  bool oldVerboseMode = _spiFlash->GetVerbosity();
1426  uint32_t offset = _spiFlash->Offset(SPI_FLASH_SECTION_LICENSE);
1427  _spiFlash->SetVerbosity(false);
1428  if (_spiFlash->Read(offset, licenseData, maxSize))
1429  {
1430  _spiFlash->SetVerbosity(oldVerboseMode);
1431  serialString = "";
1432  if (licenseData.size() < 4)
1433  return false;
1434  else if (licenseData[0] == 0xff && licenseData[1] == 0xff && licenseData[2] == 0xff && licenseData[3] == 0xff)
1435  return false;
1436  else
1437  {
1438  serialString.assign(licenseData.begin(), licenseData.end());
1439 
1440  // remove any trailing nulls
1441  size_t found = serialString.find('\0');
1442  if (found != string::npos)
1443  serialString.resize(found);
1444  }
1445  }
1446  else
1447  {
1448  _spiFlash->SetVerbosity(oldVerboseMode);
1449  return false;
1450  }
1451  }
1452  else
1453  {
1454  ULWord license[maxSize];
1455  memset (license,0x0,sizeof(license));
1456 
1457  uint32_t baseAddress = GetBaseAddressForProgramming(LICENSE_BLOCK);
1459 
1460  bool terminated = false;
1461  bool good = false;
1462  for(uint32_t i = 0; i < maxSize; i++)
1463  {
1464  WriteRegister(kRegXenaxFlashAddress,baseAddress);
1467  ReadRegister(kRegXenaxFlashDOUT, license[i]);
1468  if (license[i] == 0xffffffff)
1469  {
1470  good = true; // uninitialized memory
1471  break;
1472  }
1473  if (license[i] == 0)
1474  {
1475  good = true;
1476  terminated = true;
1477  break;
1478  }
1479  baseAddress += 4;
1480  }
1481 
1482  std::string res;
1483  if (terminated)
1484  res = reinterpret_cast<char*>(license);
1485 
1486  serialString = res;
1487  return good;
1488  }
1489  return true;
1490 }
1491 
1493 {
1494  if (ROMHasBankSelect())
1495  {
1498  WriteRegister(kRegXenaxFlashAddress, uint32_t(bankNumber));
1499 
1502  KFPDBUG ("selected bank: " << ReadBankSelect());
1503  }
1504  return true;
1505 }
1506 
1508 {
1509  uint32_t bankNumber = 0;
1510  if (ROMHasBankSelect())
1511  {
1514  ReadRegister(kRegXenaxFlashDOUT, bankNumber);
1515  }
1516  return bankNumber&0xf;
1517 }
1518 
1519 bool CNTV2KonaFlashProgram::SetMCSFile (const string & inMCSFileName)
1520 {
1521  if (!_bQuiet)
1522  cout << "Parsing MCS File" << endl;
1523  return _mcsFile.Open(inMCSFileName.c_str());
1524 }
1525 
1527 {
1528  if (!_mcsFile.isReady())
1529  {cerr << "MCS bitfile not open" << endl; return false;}
1530  if (!IsOpen())
1531  {cerr << "Device not open" << endl; return false;}
1532 
1533  if (_spiFlash)
1534  {
1535  if (!_mcsFile.isReady())
1536  {cerr << "MCS file not ready" << endl; return false;}
1537 
1538  // now the main FPGA part
1540 
1541  vector<uint8_t> fpgaData;
1542  uint16_t fpgaPartitionOffset = 0;
1543 
1544  _mcsFile.GetPartition(fpgaData, 0x0000, fpgaPartitionOffset, false);
1545  _bitFileSize = uint32_t(fpgaData.size());
1546  // +_256 for fastFlash Programming
1548  _bitFileBuffer.Fill(0xFFFFFFFF);
1549  ::memcpy(_bitFileBuffer, &fpgaData[0], _bitFileSize);
1550 
1551  // Parse header to make sure this is a xilinx bitfile.
1552  ostringstream msgs;
1553  if (!_parser.ParseHeader(_bitFileBuffer, msgs))
1554  {cerr << "Can't parse header" << endl << msgs.str() << endl; return false;}
1555 
1556  // handle the fpga part
1557  string msg = Program(verify);
1558  // handle the SOC part
1559  return ProgramSOC(verify);
1560  }
1561 
1562  bool hasErasedSOCs = false;
1563  uint16_t linearOffsetToBankOffset = 0x0000;
1564  uint16_t basePartitionAddress = linearOffsetToBankOffset;
1565  bool bPartitionValid = true;
1566  uint32_t partitionCount = 0;
1567  while (bPartitionValid)
1568  {
1572 
1573  uint16_t partitionOffset = 0;
1574  FlashBlockID blockID = MAIN_FLASHBLOCK;
1575  ParsePartitionFromFileLines(basePartitionAddress, partitionOffset);
1576  if (basePartitionAddress < 0x0100)
1577  {
1578  blockID = MAIN_FLASHBLOCK;
1579  linearOffsetToBankOffset = 0x0000;
1580  //Program Main
1581  if (!_bQuiet)
1582  cout << "Erase Main Bitfile Bank" << endl;
1586  }
1587  else if (basePartitionAddress >= 0x0100 && basePartitionAddress < 0x0200)
1588  {
1589  blockID = MCS_INFO_BLOCK;
1590  linearOffsetToBankOffset = 0x0100;
1591  //Program Comment
1592  if (!_bQuiet)
1593  cout << "Erase Package Info Block" << endl;
1597  }
1598  else if (basePartitionAddress >= 0x0200 && basePartitionAddress < 0x0400)
1599  {
1600  if (!hasErasedSOCs)
1601  {
1602  if (!_bQuiet)
1603  cout << "Erase SOC Bank 1" << endl;
1606  if (!_bQuiet)
1607  cout << "Erase SOC Bank 2" << endl;
1610  hasErasedSOCs = true;
1611  }
1612  if (basePartitionAddress >= 0x0200 && basePartitionAddress < 0x0300)
1613  {
1614  blockID = SOC1_FLASHBLOCK;
1615  linearOffsetToBankOffset = 0x0200;
1617  }
1618  else
1619  {
1620  blockID = SOC2_FLASHBLOCK;
1621  linearOffsetToBankOffset = 0x0300;
1623  }
1624  }
1625  else
1626  {
1627  break;
1628  }
1629 
1630  uint16_t baseOffset = basePartitionAddress - linearOffsetToBankOffset;
1631  uint32_t programOffset = uint32_t(baseOffset) << 16 | partitionOffset;
1632 
1633  if (_bankSize == 0)
1634  {
1635  bPartitionValid = false;
1636  break;
1637  }
1638 
1639  SetFlashBlockIDBank(blockID);
1640 
1641  uint32_t baseAddress = GetBaseAddressForProgramming(blockID) + programOffset;
1642  if (blockID == MCS_INFO_BLOCK)
1643  baseAddress = _mcsInfoOffset;
1644  uint32_t bufferIndex = 0;
1645  uint32_t blockSize = 512;
1646  uint32_t dwordsPerBlock = blockSize / 4;
1647  uint32_t totalBlockCount ((uint32_t(_partitionBuffer.size()) + blockSize) / blockSize);
1648  uint32_t percentComplete = 0;
1649 
1650  WriteRegister(kVRegFlashSize, totalBlockCount);
1651  for (uint32_t blockCount = 0; blockCount < totalBlockCount; blockCount++)
1652  {
1653  WriteRegister(kVRegFlashStatus,blockCount);
1654  if (baseAddress == 0x01000000 && blockCount > 0 && blockID == SOC1_FLASHBLOCK)
1655  {
1656  blockID = SOC2_FLASHBLOCK;
1657  SetFlashBlockIDBank(blockID);
1658  baseAddress = GetBaseAddressForProgramming(blockID);
1660  }
1661  uint32_t remainderBytes = static_cast<uint32_t>(_partitionBuffer.size() - bufferIndex);
1664 
1665  for (uint32_t dwordCount = 0; dwordCount < dwordsPerBlock; dwordCount++)
1666  {
1667  uint32_t partitionValue = 0xFFFFFFFF;
1668  if (remainderBytes >= 4)
1669  {
1670  partitionValue = uint32_t(_partitionBuffer[bufferIndex + 0]) << 24 |
1671  uint32_t(_partitionBuffer[bufferIndex + 1]) << 16 |
1672  uint32_t(_partitionBuffer[bufferIndex + 2]) << 8 |
1673  uint32_t(_partitionBuffer[bufferIndex + 3]);
1674  bufferIndex += 4;
1675  remainderBytes -= 4;
1676  }
1677  else
1678  {
1679  switch (remainderBytes)
1680  {
1681  case 3:
1682  partitionValue = 0xff;
1683  partitionValue |= uint32_t(_partitionBuffer[bufferIndex + 0]) << 24;
1684  partitionValue |= uint32_t(_partitionBuffer[bufferIndex + 1]) << 16;
1685  partitionValue |= uint32_t(_partitionBuffer[bufferIndex + 2]) << 8;
1686  break;
1687  case 2:
1688  partitionValue = 0xffff;
1689  partitionValue |= uint32_t(_partitionBuffer[bufferIndex + 0]) << 24;
1690  partitionValue |= uint32_t(_partitionBuffer[bufferIndex + 1]) << 16;
1691  break;
1692  case 1:
1693  partitionValue = 0xffffff;
1694  partitionValue |= uint32_t(_partitionBuffer[bufferIndex + 0]) << 24;
1695  break;
1696  default:
1697  break;
1698  }
1699  remainderBytes = 0;
1700  }
1701  partitionValue = NTV2EndianSwap32(partitionValue);
1702  WriteRegister(kRegXenaxFlashDIN, partitionValue);
1703  }
1704  WriteRegister(kRegXenaxFlashAddress, baseAddress);
1706 
1708 
1709  baseAddress += blockSize;
1710 
1711  percentComplete = (blockCount * 100) / totalBlockCount;
1712  if (!_bQuiet)
1713  cout << "Partition " << DEC(partitionCount) << " program status: " << DEC(percentComplete) << "%\r" << flush;
1714  }
1715  if (!_bQuiet)
1716  cout << "Partition " << DEC(partitionCount) << " program status: 100% " << endl;
1717 
1718  if (verify)
1719  {
1720  switch (blockID)
1721  {
1722  default:
1723  case MAIN_FLASHBLOCK:
1725  break;
1726  case SOC1_FLASHBLOCK:
1728  break;
1729  case SOC2_FLASHBLOCK:
1731  break;
1732  case MCS_INFO_BLOCK:
1734  break;
1735  }
1736 
1737  if (!VerifySOCPartition(blockID, programOffset))
1738  {
1740  cerr << "Verify Error" << endl;
1741  return false;
1742  }
1743  }
1744  partitionCount++;
1745 
1746  IntelRecordInfo recordInfo;
1747  _mcsFile.GetCurrentParsedRecord(recordInfo);
1748  if (recordInfo.recordType != IRT_ELAR)
1749  bPartitionValid = false;
1750  else
1751  basePartitionAddress = recordInfo.linearAddress;
1752 
1753  }
1754 
1755  //Protect Device
1761 
1768 
1770  return true;
1771 }
1772 
1773 bool CNTV2KonaFlashProgram::ProgramSOC (const bool verify)
1774 {
1775  if (!_mcsFile.isReady())
1776  {cerr << "MCS bitfile not open" << endl; return false;}
1777 
1778  if (_spiFlash)
1779  {
1780  if (!IsOpen())
1781  {cerr << "Device not open" << endl; return false;}
1782  if (!_mcsFile.isReady())
1783  {cerr << "MCS bitfile not ready" << endl; return false;}
1784 
1785  vector<uint8_t> ubootData;
1786  vector<uint8_t> imageData;
1787  vector<uint8_t> mcsInfoData;
1788  uint16_t ubootPartitionOffset = 0;
1789  uint16_t imagePartitionOffset = 0;
1790  uint16_t mcsInfoPartitionOffset = 0;
1791  _mcsFile.GetPartition(ubootData, 0x0400, ubootPartitionOffset, false);
1792  if (ubootData.empty())
1793  {cerr << "Could not find uboot data in MCS file" << endl; return false;}
1794 
1795  _mcsFile.GetPartition(imageData, 0x0410, imagePartitionOffset, false);
1796  if (imageData.empty())
1797  {cerr << "Could not find kernel data in MCS file" << endl; return false;}
1798 
1799  _mcsFile.GetPartition(mcsInfoData, 0x05F4, mcsInfoPartitionOffset, false);
1800  if (mcsInfoData.empty())
1801  {cerr << "Could not find mcs info in MCS file" << endl; return false;}
1802 
1803  uint32_t ubootFlashOffset = _spiFlash->Offset(SPI_FLASH_SECTION_UBOOT);
1804  uint32_t imageFlashOffset = _spiFlash->Offset(SPI_FLASH_SECTION_KERNEL);
1805  uint32_t mcsFlashOffset = _spiFlash->Offset(SPI_FLASH_SECTION_MCSINFO);
1806 
1807  uint32_t ubootSize = uint32_t(ubootData.size());
1808  uint32_t imageSize = uint32_t(imageData.size());
1809  uint32_t mcsInfoSize = uint32_t(mcsInfoData.size());
1810 
1811  // erase uboot
1812  _spiFlash->Erase(ubootFlashOffset, ubootSize);
1813 
1814  // write uboot
1815  _spiFlash->Write(ubootFlashOffset, ubootData, ubootSize);
1816 
1817  // verify uboot
1818  if (verify)
1819  _spiFlash->Verify(ubootFlashOffset, ubootData);
1820 
1821  // erase image
1822  _spiFlash->Erase(imageFlashOffset, imageSize);
1823 
1824  // write image
1825  _spiFlash->Write(imageFlashOffset, imageData, imageSize);
1826 
1827  // verify image
1828  if (verify)
1829  _spiFlash->Verify(imageFlashOffset, imageData);
1830 
1831  // erase mcs info
1832  _spiFlash->Erase(mcsFlashOffset, mcsInfoSize);
1833 
1834  // write mcs info
1835  _spiFlash->Write(mcsFlashOffset, mcsInfoData, mcsInfoSize);
1836 
1837  // verify mcs info
1838  if (verify)
1839  _spiFlash->Verify(mcsFlashOffset, mcsInfoData);
1840  return true;
1841  } // if _spiFlash
1842 
1843  // Not _spiFlash:
1844  if (!IsOpen())
1845  {cerr << "Device not open" << endl; return false;}
1846  if (!_bQuiet)
1847  cout << "Erase SOC Bank 1" << endl;
1849  if (!_bQuiet)
1850  cout << "Erase SOC Bank 2" << endl;
1852 
1853  //1st partition is assumed to be at 32M mark
1854  //the 32bit address is 0x02000000
1855  //the ELAR address is 0x0200
1856  uint16_t partition32M = 0x0200;
1857  uint16_t basePartitionAddress = partition32M;
1858  bool bPartitionValid = true;
1859  uint32_t partitionCount = 0;
1860  while (bPartitionValid)
1861  {
1862  uint16_t partitionOffset = 0;
1863  ParsePartitionFromFileLines(basePartitionAddress, partitionOffset);
1864  uint16_t baseOffset = basePartitionAddress - partition32M;
1865  uint32_t programOffset = uint32_t(baseOffset) << 16 | partitionOffset;
1866 
1867  FlashBlockID blockID = SOC1_FLASHBLOCK;
1868  if (programOffset >= 0x01000000)
1869  blockID = SOC2_FLASHBLOCK;
1870 
1871  if (_bankSize == 0)
1872  return true;
1873 
1874  SetFlashBlockIDBank(blockID);
1875  uint32_t baseAddress = GetBaseAddressForProgramming(blockID) + programOffset;
1876  uint32_t bufferIndex = 0;
1877  uint32_t blockSize = 512;
1878  uint32_t dwordsPerBlock = blockSize / 4;
1879  uint32_t totalBlockCount = static_cast<uint32_t>((_partitionBuffer.size() + blockSize) / blockSize);
1880  uint32_t percentComplete = 0;
1881  for (uint32_t blockCount = 0; blockCount < totalBlockCount; blockCount++)
1882  {
1883  if (baseAddress == 0x01000000 && blockCount > 0)
1884  {
1886  baseAddress = GetBaseAddressForProgramming(blockID);
1887  }
1888  uint32_t remainderBytes = static_cast<uint32_t>(_partitionBuffer.size() - bufferIndex);
1891 
1892  for (uint32_t dwordCount = 0; dwordCount < dwordsPerBlock; dwordCount++)
1893  {
1894  uint32_t partitionValue = 0xFFFFFFFF;
1895  if (remainderBytes >= 4)
1896  {
1897  partitionValue = uint32_t(_partitionBuffer[bufferIndex + 0]) << 24 |
1898  uint32_t(_partitionBuffer[bufferIndex + 1]) << 16 |
1899  uint32_t(_partitionBuffer[bufferIndex + 2]) << 8 |
1900  uint32_t(_partitionBuffer[bufferIndex + 3]);
1901  bufferIndex += 4;
1902  remainderBytes -= 4;
1903  }
1904  else
1905  {
1906  switch (remainderBytes)
1907  {
1908  case 3:
1909  partitionValue = 0xff;
1910  partitionValue |= uint32_t(_partitionBuffer[bufferIndex + 0]) << 24;
1911  partitionValue |= uint32_t(_partitionBuffer[bufferIndex + 1]) << 16;
1912  partitionValue |= uint32_t(_partitionBuffer[bufferIndex + 2]) << 8;
1913  break;
1914  case 2:
1915  partitionValue = 0xffff;
1916  partitionValue |= uint32_t(_partitionBuffer[bufferIndex + 0]) << 24;
1917  partitionValue |= uint32_t(_partitionBuffer[bufferIndex + 1]) << 16;
1918  break;
1919  case 1:
1920  partitionValue = 0xffffff;
1921  partitionValue |= uint32_t(_partitionBuffer[bufferIndex + 0]) << 24;
1922  break;
1923  default:
1924  break;
1925  }
1926  remainderBytes = 0;
1927  }
1928  partitionValue = NTV2EndianSwap32(partitionValue);
1929  WriteRegister(kRegXenaxFlashDIN, partitionValue);
1930  } // for dwordCount
1931  WriteRegister(kRegXenaxFlashAddress, baseAddress);
1933 
1935 
1936  baseAddress += blockSize;
1937 
1938  percentComplete = (blockCount * 100) / totalBlockCount;
1939  if (!_bQuiet)
1940  cout << "Partition " << DEC(partitionCount+2) << " program status: " << DEC(percentComplete) << "%\r" << flush;
1941  } // for blockCount
1942  if (!_bQuiet)
1943  cout << "Partition " << DEC(partitionCount+2) << " program status: 100% " << endl;
1944 
1945  if (verify && !VerifySOCPartition(blockID, programOffset))
1946  {
1948  cerr << "Verify failed" << endl;
1949  return false;
1950  }
1951 
1952  partitionCount++;
1953  IntelRecordInfo recordInfo;
1954  _mcsFile.GetCurrentParsedRecord(recordInfo);
1955  if (recordInfo.recordType != IRT_ELAR)
1956  bPartitionValid = false;
1957  else
1958  basePartitionAddress = recordInfo.linearAddress;
1959  } // while bPartitionValid
1960 
1961  //Protect Device
1967 
1974  return true;
1975 }
1976 
1977 static bool getFileSize (const string & fileName, size_t & outSizeBytes)
1978 {
1979  outSizeBytes = 0;
1980  ifstream ifs(fileName.c_str(), ios::binary | ios::in);
1981  if (ifs.fail())
1982  return false; // open failed
1983  if (!ifs.seekg (0, ios::end))
1984  return false; // seek failed
1985  ifstream::pos_type curOffset(ifs.tellg());
1986  if (int(curOffset) == -1)
1987  return false;
1988  outSizeBytes = size_t(curOffset);
1989  return true;
1990 }
1991 
1992 bool CNTV2KonaFlashProgram::ProgramCustom (const string &sCustomFileName, const uint32_t addr, ostream & outMsgs)
1993 {
1994  if (!IsOpen())
1995  {outMsgs << "Device not open" << endl; return false;}
1996 
1997  if (_spiFlash)
1998  {
1999  vector<uint8_t> writeData;
2000  size_t sz(0), maxFlashSize(_spiFlash->Size());
2001  // open file and read data
2002  if (!getFileSize(sCustomFileName, sz))
2003  {outMsgs << "getFileSize failed for '" << sCustomFileName << "'" << endl; return false;}
2004  if (sz > maxFlashSize)
2005  {outMsgs << "File size " << DEC(sz) << " exceeds max flash size " << DEC(maxFlashSize) << endl; return false;}
2006 
2007  ifstream ifs(sCustomFileName.c_str(), ios::binary | ios::in);
2008  if (ifs.fail())
2009  {outMsgs << "Unable to open file '" << sCustomFileName << "'" << endl; return false;}
2010 
2011  writeData.resize(sz);
2012  ifs.read(reinterpret_cast<char*>(&writeData[0]), streamsize(sz));
2013  if (!ifs.good())
2014  {outMsgs << "Error reading data from file '" << sCustomFileName << "'" << endl; return false;}
2015 
2016  // erase flash
2017  uint32_t writeSize = uint32_t(writeData.size());
2018  bool eraseGood = _spiFlash->Erase(addr, writeSize);
2019  if (!eraseGood)
2020  {outMsgs << "Error erasing sectors, addr=" << xHEX0N(addr,8) << " length=" << DEC(writeSize) << endl; return false;}
2021 
2022  // write flash
2023  _spiFlash->Write(addr, writeData, writeSize);
2024 
2025  bool result = true, verify = true;
2026  if (verify)
2027  {
2028  result = _spiFlash->Verify(addr, writeData);
2029  }
2030  return result;
2031  } // if _spiFlash
2032  else
2033  {
2034  static const size_t MAX_CUSTOM_FILE_SIZE (8<<20); // 1M
2035  NTV2Buffer customFileBuffer(MAX_CUSTOM_FILE_SIZE);
2036  size_t customSize(0), sz(0);
2037 
2038  uint32_t bank(addr / _bankSize), offset(addr % _bankSize);
2039  if (offset + customSize > _bankSize)
2040  {outMsgs << "Custom write spans banks -- unsupported"; return false;}
2041  if (offset % _sectorSize)
2042  {outMsgs << "Write not on sector boundary -- unsupported"; return false;}
2043  if (!getFileSize(sCustomFileName, sz))
2044  {outMsgs << "Error getting file size for '" << sCustomFileName << "'"; return false;}
2045  if (sz > MAX_CUSTOM_FILE_SIZE)
2046  {outMsgs << "File size " << DEC(sz) << " exceeds max supported size " << DEC(MAX_CUSTOM_FILE_SIZE); return false;}
2047 
2048  ifstream ifs(sCustomFileName.c_str(), ios::binary | ios::in);
2049  if (!ifs.fail())
2050  {outMsgs << "Unable to open file '" << sCustomFileName << "'" << endl; return false;}
2051 
2052  customSize = size_t(ifs.readsome(customFileBuffer, streamsize(customFileBuffer.GetByteCount())));
2053  if (!customSize)
2054  {outMsgs << "No data read from custom file '" << sCustomFileName << "'" << endl; return false;}
2055 
2056  static const BankSelect BankIdxToBankSelect[] = {BANK_0, BANK_1, BANK_2, BANK_3};
2057 
2058  SetBankSelect(BankIdxToBankSelect[bank]);
2064 
2065  const uint32_t customSectors ((uint32_t(customSize) + _sectorSize - 1) / (_sectorSize));
2066  for (uint32_t i(0); i < customSectors; i++)
2067  {
2068  if (!_bQuiet)
2069  cout << "Erasing sectors - " << DECN(i,3) << " of " << DECN(customSectors,3) << "\r" << flush;
2070  EraseSector(offset + (i * _sectorSize));
2071  }
2072 
2075 
2076  uint32_t blockSize (512);
2077  uint32_t dwordsPerBlock (blockSize / 4);
2078  uint32_t totalBlockCount ((uint32_t(customSize) + blockSize - 1) / blockSize);
2079  uint32_t percentComplete (0);
2080  uint32_t baseAddress (offset);
2081  size_t remainderBytes (customSize);
2082  uint32_t bufferIndex (0);
2083  for (uint32_t blockCount(0); blockCount < totalBlockCount; blockCount++)
2084  {
2087 
2088  for (uint32_t dwordCount(0); dwordCount < dwordsPerBlock; dwordCount++)
2089  {
2090  uint32_t partitionValue = 0xFFFFFFFF;
2091  if (remainderBytes >= 4)
2092  {
2093  partitionValue = uint32_t(_customFileBuffer[bufferIndex + 0]) << 24
2094  | uint32_t(_customFileBuffer[bufferIndex + 1]) << 16
2095  | uint32_t(_customFileBuffer[bufferIndex + 2]) << 8
2096  | uint32_t(_customFileBuffer[bufferIndex + 3]);
2097  bufferIndex += 4;
2098  remainderBytes -= 4;
2099  }
2100  else switch (remainderBytes)
2101  {
2102  case 3:
2103  partitionValue = 0xff;
2104  partitionValue |= uint32_t(_customFileBuffer[bufferIndex + 0]) << 24;
2105  partitionValue |= uint32_t(_customFileBuffer[bufferIndex + 1]) << 16;
2106  partitionValue |= uint32_t(_customFileBuffer[bufferIndex + 2]) << 8;
2107  remainderBytes = 0;
2108  break;
2109  case 2:
2110  partitionValue = 0xffff;
2111  partitionValue |= uint32_t(_customFileBuffer[bufferIndex + 0]) << 24;
2112  partitionValue |= uint32_t(_customFileBuffer[bufferIndex + 1]) << 16;
2113  remainderBytes = 0;
2114  break;
2115  case 1:
2116  partitionValue = 0xffffff;
2117  partitionValue |= uint32_t(_customFileBuffer[bufferIndex + 0]) << 24;
2118  remainderBytes = 0;
2119  break;
2120  default:
2121  break;
2122  }
2123  partitionValue = NTV2EndianSwap32(partitionValue);
2124  WriteRegister(kRegXenaxFlashDIN, partitionValue);
2125  } // for each dword
2126  WriteRegister(kRegXenaxFlashAddress, baseAddress);
2129 
2130  baseAddress += blockSize;
2131 
2132  percentComplete = (blockCount * 100) / totalBlockCount;
2133  if (!_bQuiet)
2134  cout << "Program status: " << DEC(percentComplete) << "% (" << DECN(blockCount,4) << " of " << DECN(totalBlockCount,4) << " blocks)\r" << flush;
2135  } // for each block
2136 
2137  //Protect Device
2143 
2150  } // else !_spiFlash
2151  return true;
2152 }
2153 
2154 bool CNTV2KonaFlashProgram::ProgramKonaxMB (const string &sCustomFileName, const uint32_t addr, ostream & outMsgs)
2155 {
2157  {
2158  _spiFlash = new CNTV2AxiSpiFlash(GetIndexNumber(), !_bQuiet);
2159  }
2160  else
2161  return false;
2162 
2163  return ProgramCustom(sCustomFileName, addr, outMsgs);
2164 }
2165 
2167 {
2168  BankSelect bankID = BANK_0;
2169  switch (blockID)
2170  {
2171  case MAIN_FLASHBLOCK:
2172  bankID = BANK_0;
2173  break;
2174  case FAILSAFE_FLASHBLOCK:
2176  break;
2177  case MCS_INFO_BLOCK:
2178  case MAC_FLASHBLOCK:
2179  case LICENSE_BLOCK:
2180  bankID = BANK_1;
2181  break;
2182  case SOC1_FLASHBLOCK:
2183  bankID = BANK_2;
2184  break;
2185  case SOC2_FLASHBLOCK:
2186  bankID = BANK_3;
2187  break;
2188  default:
2189  return false;
2190  }
2191  return SetBankSelect(bankID);
2192 }
2193 
2195 {
2197 }
2198 
2199 void CNTV2KonaFlashProgram::ParsePartitionFromFileLines(uint32_t address, uint16_t & partitionOffset)
2200 {
2201  _partitionBuffer.clear();
2202  _partitionBuffer.resize(0);
2203  bool getnext = false;
2204  if (address != 0x0000 && address != 0x0200)
2205  getnext = true;
2206  _mcsFile.GetPartition(_partitionBuffer, uint16_t(address), partitionOffset, getnext);
2207  _bankSize = uint32_t(_partitionBuffer.size());
2208  return;
2209 }
2210 
2211 bool CNTV2KonaFlashProgram::VerifySOCPartition(FlashBlockID flashID, uint32_t flashBlockOffset)
2212 {
2213  SetFlashBlockIDBank(flashID);
2214 
2215  uint32_t errorCount = 0;
2216  uint32_t baseAddress = flashBlockOffset;
2217 
2218  uint32_t dwordsPerPartition = _bankSize / 4;
2219  uint32_t percentComplete = 0;
2220  uint32_t bufferIndex = 0;
2221  WriteRegister(kVRegFlashSize,dwordsPerPartition);
2222  for (uint32_t dwordCount = 0; dwordCount < dwordsPerPartition; dwordCount += 100)//dwordCount++)
2223  {
2224  WriteRegister(kVRegFlashStatus,dwordCount);
2225  WriteRegister(kRegXenaxFlashAddress, baseAddress);
2228  uint32_t flashValue;
2229  ReadRegister(kRegXenaxFlashDOUT, flashValue);
2230  uint32_t partitionValue = uint32_t(_partitionBuffer[bufferIndex + 0]) << 24
2231  | uint32_t(_partitionBuffer[bufferIndex + 1]) << 16
2232  | uint32_t(_partitionBuffer[bufferIndex + 2]) << 8
2233  | uint32_t(_partitionBuffer[bufferIndex + 3]);
2234  partitionValue = NTV2EndianSwap32(partitionValue);
2235  bufferIndex += 400;//4;
2236  baseAddress += 400;//4;
2237 
2238  if (flashValue != partitionValue)
2239  {
2240  cerr << "Error " << DEC(dwordCount) << " E(" << xHEX0N(partitionValue,8) << "),R(" << xHEX0N(flashValue,8) << ")" << endl;
2241  errorCount++;
2242  if (errorCount > 1)
2243  break;
2244  }
2245 
2246  percentComplete = (dwordCount * 100) / dwordsPerPartition;
2247  if (!_bQuiet)
2248  cout << "Program verify: " << DEC(percentComplete) << "%\r" << flush;
2249  }
2250 
2251  if (errorCount)
2252  {
2253  if (!_bQuiet)
2254  cerr << "Program verify failed: " << DEC(percentComplete) << "%" << endl;
2255  return false;
2256  }
2257  else if (!_bQuiet)
2258  cout << "Program verify: 100% " << endl;
2259  return true;
2260 }
2261 
2262 void CNTV2KonaFlashProgram::DisplayData(uint32_t address, uint32_t count)
2263 {
2264 #define WORDS_PER_LINE 4
2265 
2266  uint32_t bank = address / _bankSize;
2267  uint32_t offset = address % _bankSize;
2268  SetBankSelect(BankSelect(bank));
2269 
2270  char line[1024];
2271  memset(line, 0, 1024);
2272  char * pLine = &line[0];
2273  pLine += sprintf(pLine, "%08x: ", uint32_t((bank * _bankSize) + offset));
2274 
2275  int32_t lineCount = 0;
2276  for (uint32_t i = 0; i < count; i++, offset += 4)
2277  {
2281  uint32_t flashValue;
2282  ReadRegister(kRegXenaxFlashDOUT, flashValue);
2283  flashValue = NTV2EndianSwap32(flashValue);
2284  pLine += sprintf(pLine, "%08x ", uint32_t(flashValue));
2285  if (++lineCount == WORDS_PER_LINE)
2286  {
2287  if (!_bQuiet)
2288  cout << line << endl;
2289  memset(line, 0, 1024);
2290  pLine = &line[0];
2291  pLine += sprintf(pLine, "%08x: ", uint32_t((bank * _bankSize) + offset + 4));
2292  lineCount = 0;
2293  }
2294  }
2295  if (!_bQuiet && lineCount != 0)
2296  cout << line << endl;
2297 }
2298 
2299 bool CNTV2KonaFlashProgram::FullProgram (vector<uint8_t> & dataBuffer)
2300 {
2301  if (!IsOpen())
2302  return false;
2303  uint32_t baseAddress = 0;
2304  if (!_bQuiet)
2305  cout << "Erasing ROM" << endl;
2306  EraseChip();
2307  BankSelect currentBank = BANK_0;
2308  SetBankSelect(currentBank);
2309 
2310  uint32_t* bitFilePtr = reinterpret_cast<uint32_t*>(dataBuffer.data());
2311  uint32_t twoFixtysixBlockSizeCount = uint32_t((dataBuffer.size()+256)/256);
2312  uint32_t percentComplete = 0;
2314  WriteRegister(kVRegFlashSize, twoFixtysixBlockSizeCount);
2315  for ( uint32_t count = 0; count < twoFixtysixBlockSizeCount; count++, baseAddress += 256, bitFilePtr += 64 )
2316  {
2317  if (baseAddress == _bankSize)
2318  {
2319  baseAddress = 0;
2320  switch(currentBank)
2321  {
2322  case BANK_0: currentBank = BANK_1; break;
2323  case BANK_1: currentBank = BANK_2; break;
2324  case BANK_2: currentBank = BANK_3; break;
2325  case BANK_3: currentBank = BANK_0; break;
2326  }
2327  SetBankSelect(currentBank);
2328  }
2329  FastProgramFlash256(baseAddress, bitFilePtr);
2330  percentComplete = (count*100)/twoFixtysixBlockSizeCount;
2331 
2333  if(!_bQuiet && (count%100 == 0))
2334  cout << "Program status: " << DEC(percentComplete) << "%\r" << flush;
2335  }
2336  if(!_bQuiet)
2337  cout << "Program status: 100% " << endl;
2338 
2339  // Protect Device
2345 
2347 
2355  return true;
2356 }
2357 
2359 {
2360  MacAddr mac1, mac2;
2361  ReadMACAddresses(mac1, mac2);
2362  if(mac1.mac[1] != 0x0C || mac2.mac[1] != 0x0c)
2363  {
2364  if (!_bQuiet)
2365  cout << "Reprogramming the Mac Addresses!" << endl;
2366  string serialString;
2367  GetSerialNumberString(serialString);
2368  MakeMACsFromSerial(serialString.c_str(), &mac1, &mac2);
2369  return ProgramMACAddresses(&mac1, &mac2);
2370  }
2371  return true;
2372 }
2373 
2374 bool CNTV2KonaFlashProgram::MakeMACsFromSerial( const char *sSerialNumber, MacAddr *pMac1, MacAddr *pMac2)
2375 {
2376  // NOTE: We do both auto if either is auto
2377  // TODO: Check if this is an IP board, etc etc
2378  if (strstr(sSerialNumber, "demo") == sSerialNumber)
2379  { // If the serial number begins with demo
2380  int demoNum = 0;
2381  if (sscanf(sSerialNumber + 4, "%d", &demoNum) != 1)
2382  return false;
2383  if ((demoNum < 1) || (demoNum > 128))
2384  {cerr << "WARNING: Outside serial numbers demo0001 to demo0128" << endl; return false;}
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] = 0x88;
2389  pMac2->mac[4] = pMac1->mac[4] = 0x12;
2390  pMac1->mac[5] = uint8_t((demoNum - 1) * 2);
2391  pMac2->mac[5] = pMac1->mac[5] + 1;
2392  return true;
2393  }
2394  else if (strstr(sSerialNumber, "1IP") == sSerialNumber)
2395  { // If the serial number begins with 1IP
2396  // 00050 to 08241 (qty 8192) maps to A000 to DFFF (16384 addresses)
2397  // First 4 bytes are: 00:0c:17:42 and next 2 bytes are computed
2398  // as mac1=((serNo - 50)*2 + 0xA000) and
2399  // mac2 = mac1 + 1
2400  int serNum = 0;
2401  if (sscanf(sSerialNumber + 4, "%d", &serNum) != 1)
2402  return false;
2403  if ((serNum < 50) || (serNum > 8241))
2404  {cerr << "WARNING: Outside serial numbers 1IP00050 to 1IP08241" << endl; return false;}
2405 
2406  int mac16LSBs = (0xA000) + (serNum - 50) * 2;
2407 
2408  pMac2->mac[0] = pMac1->mac[0] = 0x0;
2409  pMac2->mac[1] = pMac1->mac[1] = 0x0c;
2410  pMac2->mac[2] = pMac1->mac[2] = 0x17;
2411  pMac2->mac[3] = pMac1->mac[3] = 0x42;
2412  pMac2->mac[4] = pMac1->mac[4] = uint8_t(mac16LSBs >> 8);
2413  pMac2->mac[5] = pMac1->mac[5] = mac16LSBs & 0x0ff;
2414  // The above byte will always be same for the second mac
2415  // based on above allocation
2416  pMac2->mac[5] = pMac1->mac[5] + 1;
2417  return true;
2418  }
2419  else if (strstr(sSerialNumber, "ENG") == sSerialNumber)
2420  { // ENG IoIp - if the serial starts with ENG
2421  // 0000 to 0127 (qty 128) maps to 1B00 to 1BFF (256 addresses)
2422  // First 4 bytes are: 00:0c:17:88 and next 2 bytes are computed
2423  // as mac1= (0x1B00) + (serNum * 2) and
2424  // mac2 = mac1 + 1
2425  int serNum = 0;
2426  if (sscanf(sSerialNumber + 5, "%d", &serNum) != 1)
2427  return false;
2428 
2429  if (serNum > 127)
2430  {cerr << "WARNING: Outside serial numbers ENG00000 to ENG00127" << endl; return false;}
2431 
2432  int mac16LSBs = (0x1B00) + (serNum * 2);
2433 
2434  pMac2->mac[0] = pMac1->mac[0] = 0x0;
2435  pMac2->mac[1] = pMac1->mac[1] = 0x0c;
2436  pMac2->mac[2] = pMac1->mac[2] = 0x17;
2437  pMac2->mac[3] = pMac1->mac[3] = 0x88;
2438  pMac2->mac[4] = pMac1->mac[4] = uint8_t(mac16LSBs >> 8);
2439  pMac2->mac[5] = pMac1->mac[5] = mac16LSBs & 0xff;
2440  // The above byte will always be same for the second mac
2441  // based on above allocation
2442  pMac2->mac[5] = pMac1->mac[5] + 1;
2443  return true;
2444  }
2445  else if (strstr(sSerialNumber, "6XT") == sSerialNumber)
2446  { // IoIP and DNxIP serial numbers
2447  // IoIP Gen 1 [6XT000250 - 6XT008441]
2448  // DNxIP Gen 1 [6XT200250 - 6XT208441]
2449  // IoIP Gen 2 [6XT100250 - 6XT108441]
2450  // DNxIP Gen 2 [6XT300250 - 6XT308441]
2451 
2452  int serNum = 0;
2453  if (sscanf(sSerialNumber + 4, "%d", &serNum) != 1)
2454  return false;
2455 
2456  if ((serNum < 250) || (serNum > 8441))
2457  {cerr << "WARNING: Outside serial numbers range 250 to 8441" << endl; return false;}
2458 
2459  // 0250 to 8441 (qty 8192) maps to 16384 addresses
2460  // First 3 bytes are: 00:0c:17 and next 3 bytes are computed
2461  int mac24LSBs = -1;
2462  if (strstr(sSerialNumber, "6XT0") == sSerialNumber)
2463  {
2464  mac24LSBs = (0x48A000) + ((serNum - 250) * 2);
2465  }
2466  else if (strstr(sSerialNumber, "6XT2") == sSerialNumber)
2467  {
2468  mac24LSBs = (0x48E000) + ((serNum - 250) * 2);
2469  }
2470  else if (strstr(sSerialNumber, "6XT1") == sSerialNumber)
2471  {
2472  mac24LSBs = (0x4B2000) + ((serNum - 250) * 2);
2473  }
2474  else if (strstr(sSerialNumber, "6XT3") == sSerialNumber)
2475  {
2476  mac24LSBs = (0x4B6000) + ((serNum - 250) * 2);
2477  }
2478  else
2479  {
2480  return false;
2481  }
2482 
2483  pMac2->mac[0] = pMac1->mac[0] = 0x0;
2484  pMac2->mac[1] = pMac1->mac[1] = 0x0c;
2485  pMac2->mac[2] = pMac1->mac[2] = 0x17;
2486  pMac2->mac[3] = pMac1->mac[3] = (mac24LSBs & 0xFF0000) >> 16;
2487  pMac2->mac[4] = pMac1->mac[4] = (mac24LSBs & 0x00FF00) >> 8;
2488  pMac2->mac[5] = pMac1->mac[5] = (mac24LSBs & 0x0000FF) >> 0;
2489  // The above byte will always be same for the second mac
2490  // based on above allocation
2491  pMac2->mac[5] = pMac1->mac[5] + 1;
2492  return true;
2493  }
2494  else
2495  cerr << "Unrecognized or unspecified serial number '" << sSerialNumber << "'" << endl;
2496  return false;
2497 }
2498 
2499 
2500 
2501 #ifdef MSWindows
2502 #pragma warning(default: 4800)
2503 #endif
CNTV2KonaFlashProgram::WriteCommand
bool WriteCommand(_FLASH_COMMAND inCommand)
Definition: ntv2konaflashprogram.cpp:133
CNTV2KonaFlashProgram::_numSectorsMain
uint32_t _numSectorsMain
Definition: ntv2konaflashprogram.h:169
CNTV2KonaFlashProgram::~CNTV2KonaFlashProgram
virtual ~CNTV2KonaFlashProgram()
Definition: ntv2konaflashprogram.cpp:118
CNTV2FlashProgress::UpdatePercentage
virtual bool UpdatePercentage(const size_t inPercentage)
Definition: ntv2konaflashprogram.h:43
CNTV2KonaFlashProgram::ReadLicenseInfo
bool ReadLicenseInfo(std::string &licenseString)
Definition: ntv2konaflashprogram.cpp:1415
BANK_0
@ BANK_0
Definition: ntv2enums.h:4199
kProgramStateEraseBank4
@ kProgramStateEraseBank4
Definition: ntv2publicinterface.h:4840
DEVICE_ID_KONAIP_2110
@ DEVICE_ID_KONAIP_2110
See KONA IP.
Definition: ntv2enums.h:70
kRegBoardID
@ kRegBoardID
Definition: ntv2publicinterface.h:124
BANK_2
@ BANK_2
Definition: ntv2enums.h:4201
CNTV2Card::SetWarmBootFirmwareReload
virtual bool SetWarmBootFirmwareReload(bool enable)
Definition: ntv2register.cpp:4446
BANK_1
@ BANK_1
Definition: ntv2enums.h:4200
DEVICE_IS_IOIP
#define DEVICE_IS_IOIP(__d__)
Definition: ntv2enums.h:131
CNTV2KonaFlashProgram::ProgramMACAddresses
bool ProgramMACAddresses(MacAddr *mac1, MacAddr *mac2)
Definition: ntv2konaflashprogram.cpp:1163
CNTV2KonaFlashProgram::SetMBReset
bool SetMBReset()
Definition: ntv2konaflashprogram.cpp:142
kRegFS1I2C1Data
@ kRegFS1I2C1Data
Definition: ntv2publicinterface.h:169
FAILSAFE_FLASHBLOCK
@ FAILSAFE_FLASHBLOCK
Definition: ntv2enums.h:4188
CNTV2KonaFlashProgram::FlashBlockIDToString
static std::string FlashBlockIDToString(const FlashBlockID inID, const bool inShortDisplay=false)
Definition: ntv2konaflashprogram.cpp:44
READID_COMMAND
@ READID_COMMAND
Definition: ntv2enums.h:4206
CNTV2MacDriverInterface::ReadRegister
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....
Definition: ntv2macdriverinterface.cpp:709
CNTV2KonaFlashProgram::GetNumberOfSectors
uint32_t GetNumberOfSectors(FlashBlockID flashBlockNumber)
Definition: ntv2konaflashprogram.h:132
MCS_INFO_BLOCK
@ MCS_INFO_BLOCK
Definition: ntv2enums.h:4193
CNTV2FlashProgress::nullUpdater
static CNTV2FlashProgress & nullUpdater
Definition: ntv2konaflashprogram.h:39
NTV2Buffer
A generic user-space buffer object that has an address and a length. Used most often to share an arbi...
Definition: ntv2publicinterface.h:5967
CNTV2MCSfile::Open
virtual bool Open(const std::string &inMCSFilePath)
Opens the bitfile at the given path, then parses its header.
Definition: ntv2mcsfile.cpp:73
kVRegFlashState
@ kVRegFlashState
Definition: ntv2virtualregisters.h:302
CNTV2KonaFlashProgram::_bitFileName
std::string _bitFileName
Definition: ntv2konaflashprogram.h:156
NTV2Buffer::GetByteCount
ULWord GetByteCount(void) const
Definition: ntv2publicinterface.h:6040
_FLASH_COMMAND
_FLASH_COMMAND
Definition: ntv2enums.h:4205
EXTENDEDADDRESS_COMMAND
@ EXTENDEDADDRESS_COMMAND
Definition: ntv2enums.h:4217
SOC1_FLASHBLOCK
@ SOC1_FLASHBLOCK
Definition: ntv2enums.h:4190
CNTV2MCSfile::GetPartition
virtual uint32_t GetPartition(UByteSequence &patitionBuffer, uint16_t baseELARaddress, uint16_t &partitionOffset, bool nextPartition=false)
Definition: ntv2mcsfile.cpp:463
CNTV2SpiFlash::Read
virtual bool Read(const uint32_t address, std::vector< uint8_t > &data, uint32_t maxBytes=1)=0
CNTV2KonaFlashProgram::_mainOffset
uint32_t _mainOffset
Definition: ntv2konaflashprogram.h:162
kProgramStateEraseMainFlashBlock
@ kProgramStateEraseMainFlashBlock
Definition: ntv2publicinterface.h:4831
CNTV2KonaFlashProgram::EraseChip
bool EraseChip(UWord chip=0)
Definition: ntv2konaflashprogram.cpp:706
CNTV2KonaFlashProgram::_parser
NTV2BitfileHeaderParser _parser
Definition: ntv2konaflashprogram.h:155
systemtime.h
Declares the AJATime class.
getFileSize
static bool getFileSize(const string &fileName, size_t &outSizeBytes)
Definition: ntv2konaflashprogram.cpp:1977
CNTV2KonaFlashProgram::_partitionBuffer
std::vector< uint8_t > _partitionBuffer
Definition: ntv2konaflashprogram.h:179
CNTV2KonaFlashProgram::SRecordOutput
static void SRecordOutput(const char *pSRecord)
Definition: ntv2konaflashprogram.cpp:903
NTV2Buffer::Deallocate
bool Deallocate(void)
Deallocates my user-space storage (if I own it – i.e. from a prior call to Allocate).
Definition: ntv2publicinterface.cpp:1588
DEVICE_ID_KONAIP_2110_RGB12
@ DEVICE_ID_KONAIP_2110_RGB12
See KONA IP.
Definition: ntv2enums.h:71
NTV2Buffer::U32
uint32_t U32(const int inIndex) const
Definition: ntv2publicinterface.h:6467
DEVICE_ID_IOIP_2022
@ DEVICE_ID_IOIP_2022
See Io IP.
Definition: ntv2enums.h:38
ntv2endian.h
Defines a number of handy byte-swapping macros.
CNTV2KonaFlashProgram::IsInstalledFWRunning
bool IsInstalledFWRunning(bool &outIsRunning, std::ostream &outErrorMsgs)
Definition: ntv2konaflashprogram.cpp:160
READEXTENDEDADDRESS_COMMAND
@ READEXTENDEDADDRESS_COMMAND
Definition: ntv2enums.h:4218
CNTV2KonaFlashProgram::SetBoard
virtual bool SetBoard(UWord boardNumber, uint32_t index=0)
Definition: ntv2konaflashprogram.cpp:210
CNTV2KonaFlashProgram::VerifyFlash
bool VerifyFlash(FlashBlockID flashBlockNumber, bool fullVerify=false)
Definition: ntv2konaflashprogram.cpp:720
CNTV2FlashProgress
Definition: ntv2konaflashprogram.h:36
CNTV2Card::GetRunningFirmwareDate
virtual bool GetRunningFirmwareDate(UWord &outYear, UWord &outMonth, UWord &outDay)
Reports the (local Pacific) build date of the currently-running firmware.
Definition: ntv2register.cpp:2330
BANKSELECT_COMMMAND
@ BANKSELECT_COMMMAND
Definition: ntv2enums.h:4215
CNTV2KonaFlashProgram::ReadHeader
bool ReadHeader(FlashBlockID flashBlock)
Definition: ntv2konaflashprogram.cpp:475
CNTV2KonaFlashProgram::ProgramFlashValue
bool ProgramFlashValue(uint32_t address, uint32_t value)
Definition: ntv2konaflashprogram.cpp:610
CNTV2KonaFlashProgram::FullProgram
bool FullProgram(std::vector< uint8_t > &dataBuffer)
Definition: ntv2konaflashprogram.cpp:2299
NTV2Buffer::Allocate
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...
Definition: ntv2publicinterface.cpp:1554
SECTORERASE_COMMAND
@ SECTORERASE_COMMAND
Definition: ntv2enums.h:4213
PAGEPROGRAM_COMMAND
@ PAGEPROGRAM_COMMAND
Definition: ntv2enums.h:4212
CNTV2KonaFlashProgram::CheckFlashErasedWithBlockID
bool CheckFlashErasedWithBlockID(FlashBlockID flashBlockNumber)
Definition: ntv2konaflashprogram.cpp:869
CNTV2KonaFlashProgram::ParsePartitionFromFileLines
void ParsePartitionFromFileLines(uint32_t address, uint16_t &partitionOffset)
Definition: ntv2konaflashprogram.cpp:2199
CNTV2KonaFlashProgram::EraseBlock
bool EraseBlock(FlashBlockID blockNumber)
Definition: ntv2konaflashprogram.cpp:649
MacAddr::AsString
std::string AsString(void) const
Definition: ntv2konaflashprogram.cpp:32
MacAddr::mac
uint8_t mac[6]
Definition: ntv2konaflashprogram.h:31
MAC_FLASHBLOCK
@ MAC_FLASHBLOCK
Definition: ntv2enums.h:4192
CNTV2DriverInterface::_boardID
NTV2DeviceID _boardID
My cached device ID.
Definition: ntv2driverinterface.h:674
CNTV2KonaFlashProgram::_customFileBuffer
uint8_t * _customFileBuffer
Definition: ntv2konaflashprogram.h:153
CNTV2KonaFlashProgram::_numSectorsSOC2
uint32_t _numSectorsSOC2
Definition: ntv2konaflashprogram.h:171
DEVICE_IS_KONAX
#define DEVICE_IS_KONAX(__d__)
Definition: ntv2enums.h:136
CNTV2KonaFlashProgram::_soc2Offset
uint32_t _soc2Offset
Definition: ntv2konaflashprogram.h:168
CNTV2KonaFlashProgram::_bQuiet
bool _bQuiet
Definition: ntv2konaflashprogram.h:176
AUTO_FLASHBLOCK
@ AUTO_FLASHBLOCK
Definition: ntv2enums.h:4189
CNTV2KonaFlashProgram::_failSafeOffset
uint32_t _failSafeOffset
Definition: ntv2konaflashprogram.h:163
CNTV2KonaFlashProgram::FastProgramFlash256
bool FastProgramFlash256(uint32_t address, uint32_t *buffer)
Definition: ntv2konaflashprogram.cpp:622
kVRegFlashSize
@ kVRegFlashSize
Definition: ntv2virtualregisters.h:300
ntv2registersmb.h
Defines the KonaIP/IoIP registers.
BIT_16
#define BIT_16
Definition: ajatypes.h:679
CNTV2KonaFlashProgram::_numSectorsFailSafe
uint32_t _numSectorsFailSafe
Definition: ntv2konaflashprogram.h:172
kProgramStateProgramBank3
@ kProgramStateProgramBank3
Definition: ntv2publicinterface.h:4838
kProgramStateProgramFlash
@ kProgramStateProgramFlash
Definition: ntv2publicinterface.h:4834
CNTV2KonaFlashProgram::ProgramFromMCS
bool ProgramFromMCS(bool verify)
Definition: ntv2konaflashprogram.cpp:1526
CNTV2SpiFlash::Verify
virtual bool Verify(const uint32_t address, const std::vector< uint8_t > &dataWritten)=0
CNTV2KonaFlashProgram::DisplayData
void DisplayData(uint32_t address, uint32_t len)
Definition: ntv2konaflashprogram.cpp:2262
IntelRecordInfo::linearAddress
uint16_t linearAddress
Definition: ntv2mcsfile.h:40
CNTV2SpiFlash::Write
virtual bool Write(const uint32_t address, const std::vector< uint8_t > data, uint32_t maxBytes=1)=0
CNTV2KonaFlashProgram::_numSectorsSOC1
uint32_t _numSectorsSOC1
Definition: ntv2konaflashprogram.h:170
FlashBlockID
FlashBlockID
Definition: ntv2enums.h:4185
CNTV2SpiFlash::Size
virtual uint32_t Size(SpiFlashSection sectionID=SPI_FLASH_SECTION_TOTAL)=0
CNTV2KonaFlashProgram::ProgramKonaxMB
bool ProgramKonaxMB(const std::string &sCustomFileName, const uint32_t addr, std::ostream &outMsgs)
Definition: ntv2konaflashprogram.cpp:2154
MAIN_FLASHBLOCK
@ MAIN_FLASHBLOCK
Definition: ntv2enums.h:4187
CNTV2KonaFlashProgram::ProgramCustom
bool ProgramCustom(const std::string &sCustomFileName, const uint32_t addr, std::ostream &outMsgs)
Definition: ntv2konaflashprogram.cpp:1992
AJATime::Sleep
static void Sleep(const int32_t inMilliseconds)
Suspends execution of the current thread for a given number of milliseconds.
Definition: systemtime.cpp:284
CNTV2KonaFlashProgram::CreateSRecord
bool CreateSRecord(bool bChangeEndian)
Definition: ntv2konaflashprogram.cpp:908
CNTV2KonaFlashProgram::CheckAndFixMACs
bool CheckAndFixMACs()
Definition: ntv2konaflashprogram.cpp:2358
CNTV2KonaFlashProgram::SetDeviceProperties
bool SetDeviceProperties()
Definition: ntv2konaflashprogram.cpp:225
CNTV2KonaFlashProgram::ReadBankSelect
uint32_t ReadBankSelect()
Definition: ntv2konaflashprogram.cpp:1507
CNTV2SpiFlash::Offset
virtual uint32_t Offset(SpiFlashSection sectionID=SPI_FLASH_SECTION_TOTAL)=0
ULWord
uint32_t ULWord
Definition: ajatypes.h:246
MCS_STEPS
#define MCS_STEPS
Definition: ntv2konaflashprogram.h:27
NTV2DeviceCanReportRunningFirmwareDate
bool NTV2DeviceCanReportRunningFirmwareDate(const NTV2DeviceID inDeviceID)
Definition: ntv2devicefeatures.hpp:6094
kRegXenaxFlashControlStatus
@ kRegXenaxFlashControlStatus
Definition: ntv2publicinterface.h:132
kProgramStateErasePackageInfo
@ kProgramStateErasePackageInfo
Definition: ntv2publicinterface.h:4843
CNTV2KonaFlashProgram::ReadFlash
bool ReadFlash(NTV2Buffer &outBuffer, const FlashBlockID flashID, CNTV2FlashProgress &inFlashProgress=CNTV2FlashProgress::nullUpdater)
Definition: ntv2konaflashprogram.cpp:779
AsNTV2DriverInterfaceRef
#define AsNTV2DriverInterfaceRef(_x_)
Definition: ntv2driverinterface.h:48
CNTV2KonaFlashProgram::ReadMACAddresses
bool ReadMACAddresses(MacAddr &mac1, MacAddr &mac2)
Definition: ntv2konaflashprogram.cpp:1257
CNTV2KonaFlashProgram::_bitFileBuffer
NTV2Buffer _bitFileBuffer
Definition: ntv2konaflashprogram.h:152
CNTV2KonaFlashProgram::MakeMACsFromSerial
bool MakeMACsFromSerial(const char *sSerialNumber, MacAddr *pMac1, MacAddr *pMac2)
Definition: ntv2konaflashprogram.cpp:2374
NTV2EndianSwap32
#define NTV2EndianSwap32(__val__)
Definition: ntv2endian.h:19
CNTV2KonaFlashProgram::_failSafePadding
uint32_t _failSafePadding
Definition: ntv2konaflashprogram.h:180
CNTV2KonaFlashProgram::_mcsFile
CNTV2MCSfile _mcsFile
Definition: ntv2konaflashprogram.h:178
CNTV2KonaFlashProgram::_mcsInfoOffset
uint32_t _mcsInfoOffset
Definition: ntv2konaflashprogram.h:165
NTV2Buffer::IsAllocatedBySDK
bool IsAllocatedBySDK(void) const
Definition: ntv2publicinterface.h:6046
kRegXenaxFlashDIN
@ kRegXenaxFlashDIN
Definition: ntv2publicinterface.h:134
kProgramStateEraseFailSafeFlashBlock
@ kProgramStateEraseFailSafeFlashBlock
Definition: ntv2publicinterface.h:4833
READFAST_COMMAND
@ READFAST_COMMAND
Definition: ntv2enums.h:4211
kRegSarekControl
#define kRegSarekControl
Definition: ntv2registersmb.h:73
CNTV2KonaFlashProgram::_flashID
FlashBlockID _flashID
Definition: ntv2konaflashprogram.h:174
CNTV2KonaFlashProgram::DetermineFlashTypeAndBlockNumberFromFileName
void DetermineFlashTypeAndBlockNumberFromFileName(const std::string &bitFileName)
Definition: ntv2konaflashprogram.cpp:468
CNTV2MCSfile::GetCurrentParsedRecord
virtual bool GetCurrentParsedRecord(IntelRecordInfo &recordInfo)
Definition: ntv2mcsfile.cpp:412
CNTV2Card::GetSerialNumberString
virtual bool GetSerialNumberString(std::string &outSerialNumberString)
Answers with a string that contains my human-readable serial number.
Definition: ntv2card.cpp:219
CNTV2KonaFlashProgram::ReadDeviceID
uint32_t ReadDeviceID()
Definition: ntv2konaflashprogram.cpp:637
aja::stol
long stol(const std::string &str, std::size_t *idx, int base)
Definition: common.cpp:127
SAREK_REGS
#define SAREK_REGS
Definition: ntv2registersmb.h:54
UWord
uint16_t UWord
Definition: ajatypes.h:244
kProgramStateProgramPackageInfo
@ kProgramStateProgramPackageInfo
Definition: ntv2publicinterface.h:4844
kProgramStateVerifyFlash
@ kProgramStateVerifyFlash
Definition: ntv2publicinterface.h:4835
SOC2_FLASHBLOCK
@ SOC2_FLASHBLOCK
Definition: ntv2enums.h:4191
CNTV2KonaFlashProgram::_macOffset
uint32_t _macOffset
Definition: ntv2konaflashprogram.h:164
kRegXenaxFlashAddress
@ kRegXenaxFlashAddress
Definition: ntv2publicinterface.h:133
LICENSE_BLOCK
@ LICENSE_BLOCK
Definition: ntv2enums.h:4194
ENUM_CASE_RETURN_VAL_OR_ENUM_STR
#define ENUM_CASE_RETURN_VAL_OR_ENUM_STR(condition, retail_name, enum_name)
Definition: ntv2konaflashprogram.cpp:21
DEVICE_ID_KONAIP_2022
@ DEVICE_ID_KONAIP_2022
See KONA IP.
Definition: ntv2enums.h:69
kProgramStateVerifyPackageInfo
@ kProgramStateVerifyPackageInfo
Definition: ntv2publicinterface.h:4845
NTV2DeviceROMHasBankSelect
bool NTV2DeviceROMHasBankSelect(const NTV2DeviceID inDeviceID)
Definition: ntv2devicefeatures.cpp:1123
CNTV2Card
I interrogate and control an AJA video/audio capture/playout device.
Definition: ntv2card.h:262
CNTV2SpiFlash::Erase
virtual bool Erase(const uint32_t address, uint32_t bytes)=0
KFPNOTE
#define KFPNOTE(__x__)
Definition: ntv2konaflashprogram.cpp:29
NTV2BitfileHeaderParser::ParseHeader
bool ParseHeader(const NTV2Buffer &inHdrBuffer, std::ostream &outMsgs)
Definition: ntv2bitfile.cpp:176
IntelRecordInfo::recordType
IntelRecordType recordType
Definition: ntv2mcsfile.h:42
kRegXenaxFlashDOUT
@ kRegXenaxFlashDOUT
Definition: ntv2publicinterface.h:135
CNTV2KonaFlashProgram::GetBaseAddressForProgramming
uint32_t GetBaseAddressForProgramming(FlashBlockID flashBlockNumber)
Definition: ntv2konaflashprogram.h:116
MAXBITFILE_HEADERSIZE
#define MAXBITFILE_HEADERSIZE
Definition: ntv2konaflashprogram.h:24
CNTV2KonaFlashProgram::CreateEDIDIntelRecord
bool CreateEDIDIntelRecord()
Definition: ntv2konaflashprogram.cpp:1097
SPI_FLASH_SECTION_MCSINFO
@ SPI_FLASH_SECTION_MCSINFO
Definition: ntv2spiinterface.h:17
kProgramStateVerifyBank3
@ kProgramStateVerifyBank3
Definition: ntv2publicinterface.h:4839
CNTV2KonaFlashProgram::CNTV2KonaFlashProgram
CNTV2KonaFlashProgram()
Definition: ntv2konaflashprogram.cpp:61
AJA_NULL
#define AJA_NULL
Definition: ajatypes.h:190
WORDS_PER_LINE
#define WORDS_PER_LINE
gNullUpdater
static CNTV2FlashProgress gNullUpdater
Definition: ntv2konaflashprogram.cpp:40
NTV2Buffer::GetHostPointer
void * GetHostPointer(void) const
Definition: ntv2publicinterface.h:6023
CNTV2KonaFlashProgram::ReadInfoString
bool ReadInfoString()
Definition: ntv2konaflashprogram.cpp:494
CNTV2KonaFlashProgram::_deviceID
uint32_t _deviceID
Definition: ntv2konaflashprogram.h:175
DEVICE_ID_IOIP_2110
@ DEVICE_ID_IOIP_2110
See Io IP.
Definition: ntv2enums.h:39
CNTV2KonaFlashProgram::GetDate
std::string GetDate(void) const
Definition: ntv2konaflashprogram.h:83
kVRegFlashStatus
@ kVRegFlashStatus
Definition: ntv2virtualregisters.h:301
KFPERR
#define KFPERR(__x__)
Definition: ntv2konaflashprogram.cpp:28
DEC
#define DEC(__x__)
Definition: ntv2publicinterface.h:5579
false
#define false
Definition: ntv2devicefeatures.h:25
common.h
Private include file for all ajabase sources.
UByte
uint8_t UByte
Definition: ajatypes.h:241
kRegSarekSpiSelect
#define kRegSarekSpiSelect
Definition: ntv2registersmb.h:75
SPI_FLASH_SECTION_UBOOT
@ SPI_FLASH_SECTION_UBOOT
Definition: ntv2spiinterface.h:14
CNTV2KonaFlashProgram::_licenseOffset
uint32_t _licenseOffset
Definition: ntv2konaflashprogram.h:166
HEX0N
#define HEX0N(__x__, __n__)
Definition: debug.cpp:1174
kRegFS1I2C1Address
@ kRegFS1I2C1Address
Definition: ntv2publicinterface.h:168
ntv2konaflashprogram.h
Declares the CNTV2KonaFlashProgram class.
WRITEENABLE_COMMAND
@ WRITEENABLE_COMMAND
Definition: ntv2enums.h:4207
BANK_3
@ BANK_3
Definition: ntv2enums.h:4202
CNTV2KonaFlashProgram::_spiFlash
CNTV2SpiFlash * _spiFlash
Definition: ntv2konaflashprogram.h:181
IRT_ELAR
@ IRT_ELAR
Definition: ntv2mcsfile.h:26
kProgramStateProgramBank4
@ kProgramStateProgramBank4
Definition: ntv2publicinterface.h:4841
CNTV2KonaFlashProgram::Program
std::string Program(bool fullVerify=false)
Definition: ntv2konaflashprogram.cpp:541
CNTV2AxiSpiFlash
Definition: ntv2spiinterface.h:45
SPI_FLASH_SECTION_MAC
@ SPI_FLASH_SECTION_MAC
Definition: ntv2spiinterface.h:18
CNTV2KonaFlashProgram::VerifySOCPartition
bool VerifySOCPartition(FlashBlockID flashID, uint32_t FlashBlockOffset)
Definition: ntv2konaflashprogram.cpp:2211
CNTV2KonaFlashProgram::_bitFileSize
uint32_t _bitFileSize
Definition: ntv2konaflashprogram.h:154
CNTV2KonaFlashProgram::NextMcsStep
int32_t NextMcsStep()
Definition: ntv2konaflashprogram.h:99
kProgramStateVerifyBank4
@ kProgramStateVerifyBank4
Definition: ntv2publicinterface.h:4842
CNTV2MCSfile::isReady
virtual bool isReady(void) const
Definition: ntv2mcsfile.cpp:51
CHIPERASE_COMMAND
@ CHIPERASE_COMMAND
Definition: ntv2enums.h:4214
CNTV2KonaFlashProgram::_flashSize
uint32_t _flashSize
Definition: ntv2konaflashprogram.h:159
CNTV2DriverInterface::GetDeviceID
virtual NTV2DeviceID GetDeviceID(void)
Definition: ntv2driverinterface.cpp:371
READBANKSELECT_COMMAND
@ READBANKSELECT_COMMAND
Definition: ntv2enums.h:4216
CNTV2KonaFlashProgram::_mcsInfo
std::string _mcsInfo
Definition: ntv2konaflashprogram.h:157
CNTV2KonaFlashProgram::ProgramSOC
bool ProgramSOC(bool verify=true)
Definition: ntv2konaflashprogram.cpp:1773
CNTV2KonaFlashProgram::SetMCSFile
bool SetMCSFile(const std::string &sMCSFileName)
Definition: ntv2konaflashprogram.cpp:1519
CNTV2KonaFlashProgram::SetBankSelect
bool SetBankSelect(BankSelect bankNumber)
Definition: ntv2konaflashprogram.cpp:1492
WRITESTATUS_COMMAND
@ WRITESTATUS_COMMAND
Definition: ntv2enums.h:4210
CNTV2KonaFlashProgram::EraseSector
bool EraseSector(uint32_t sectorAddress)
Definition: ntv2konaflashprogram.cpp:697
CNTV2KonaFlashProgram::SetFlashBlockIDBank
bool SetFlashBlockIDBank(FlashBlockID blockID)
Definition: ntv2konaflashprogram.cpp:2166
NTV2Buffer::Fill
bool Fill(const T &inValue)
Fills me with the given scalar value.
Definition: ntv2publicinterface.h:6192
CNTV2KonaFlashProgram::CreateBankRecord
bool CreateBankRecord(BankSelect bankID)
Definition: ntv2konaflashprogram.cpp:1008
CNTV2SpiFlash::SetVerbosity
virtual void SetVerbosity(bool verbose)
Definition: ntv2spiinterface.h:36
SPI_FLASH_SECTION_LICENSE
@ SPI_FLASH_SECTION_LICENSE
Definition: ntv2spiinterface.h:16
IntelRecordInfo
Definition: ntv2mcsfile.h:30
MacAddr
Definition: ntv2konaflashprogram.h:29
CNTV2KonaFlashProgram::_hasExtendedCommandSupport
bool _hasExtendedCommandSupport
Definition: ntv2konaflashprogram.h:182
BIT
#define BIT(_x_)
Definition: ajatypes.h:654
xHEX0N
#define xHEX0N(__x__, __n__)
Definition: ntv2publicinterface.h:5578
DEVICE_ID_IOIP_2110_RGB12
@ DEVICE_ID_IOIP_2110_RGB12
See Io IP.
Definition: ntv2enums.h:40
CNTV2KonaFlashProgram::SetBitFile
bool SetBitFile(const std::string &inBitfileName, std::ostream &outMsgs, const FlashBlockID blockNumber=AUTO_FLASHBLOCK)
Definition: ntv2konaflashprogram.cpp:430
CNTV2KonaFlashProgram::WaitForFlashNOTBusy
bool WaitForFlashNOTBusy()
Definition: ntv2konaflashprogram.cpp:845
CNTV2KonaFlashProgram::ROMHasBankSelect
bool ROMHasBankSelect()
Definition: ntv2konaflashprogram.cpp:2194
CNTV2SpiFlash::GetVerbosity
virtual bool GetVerbosity()
Definition: ntv2spiinterface.h:37
CNTV2MacDriverInterface::WriteRegister
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...
Definition: ntv2macdriverinterface.cpp:754
CNTV2KonaFlashProgram::_sectorSize
uint32_t _sectorSize
Definition: ntv2konaflashprogram.h:161
CNTV2KonaFlashProgram::SetQuietMode
void SetQuietMode()
Definition: ntv2konaflashprogram.cpp:124
CNTV2KonaFlashProgram::ProgramLicenseInfo
bool ProgramLicenseInfo(const std::string &licenseString)
Definition: ntv2konaflashprogram.cpp:1351
CNTV2KonaFlashProgram::_bankSize
uint32_t _bankSize
Definition: ntv2konaflashprogram.h:160
KFPDBUG
#define KFPDBUG(__x__)
Definition: ntv2konaflashprogram.cpp:26
debug.h
Declares the AJADebug class.
MAXMCSINFOSIZE
#define MAXMCSINFOSIZE
Definition: ntv2konaflashprogram.h:25
BankSelect
BankSelect
Definition: ntv2enums.h:4197
CNTV2KonaFlashProgram::_soc1Offset
uint32_t _soc1Offset
Definition: ntv2konaflashprogram.h:167
kProgramStateCalculating
@ kProgramStateCalculating
Definition: ntv2publicinterface.h:4846
kProgramStateEraseBank3
@ kProgramStateEraseBank3
Definition: ntv2publicinterface.h:4837
NTV2DeviceGetSPIFlashVersion
UWord NTV2DeviceGetSPIFlashVersion(const NTV2DeviceID inDeviceID)
Definition: ntv2devicefeatures.hpp:12190
DECN
#define DECN(__x__, __n__)
Definition: ntv2publicinterface.h:5580
kRegGlobalControl
@ kRegGlobalControl
Definition: ntv2publicinterface.h:73
SPI_FLASH_SECTION_KERNEL
@ SPI_FLASH_SECTION_KERNEL
Definition: ntv2spiinterface.h:15