AJA NTV2 SDK  17.5.0.1242
NTV2 SDK 17.5.0.1242
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  _spiFlash->SetVerbosity(false);
129 }
130 
132 {
133  ULWord theCommand = (ULWord)inCommand;
135  theCommand |= BIT_16;
136 
137  return WriteRegister(kRegXenaxFlashControlStatus, theCommand);
138 }
139 
141 {
142  if (!IsIPDevice())
143  return false;
144  bool resetOK(false);
145  // Hold MB in reset
146  if ((GetDeviceID() == DEVICE_ID_IOIP_2022) ||
149  resetOK = WriteRegister(SAREK_REGS + kRegSarekControl, 0x02);
150  else if (GetDeviceID() == DEVICE_ID_KONAIP_2022 ||
153  resetOK = WriteRegister(SAREK_REGS + kRegSarekControl, 0x01);
154  // Take SPI bus control
155  return resetOK && WriteRegister(SAREK_REGS + kRegSarekSpiSelect, 0x01);
156 }
157 
158 bool CNTV2KonaFlashProgram::IsInstalledFWRunning (bool & outIsRunning, ostream & outMsgs)
159 {
160  UWord runningYear(0), runningMonth(0), runningDay(0);
161  outIsRunning = false;
162 
163  // Get running FW date...
164  if (!GetRunningFirmwareDate (runningYear, runningMonth, runningDay))
165  {
167  outMsgs << "## WARNING: Failed to get running firmware date/time" << endl;
168  return false;
169  }
170 
171  // Convert running FW date to time_t...
172  std::tm tm; ::memset(&tm, 0, sizeof(tm)); // zero
173  tm.tm_year = int(runningYear) - 1900; // Year
174  tm.tm_mon = int(runningMonth) - 1; // Month
175  tm.tm_mday = int(runningDay); // Day
176  tm.tm_hour = 11; // near mid-day
177  tm.tm_isdst = 0; // Standard time (not DST)
178  std::time_t tRunning (std::mktime(&tm));
179 
180  // Read & parse Main installed FW header...
182  {outMsgs << "## WARNING: Failed to ReadHeader or ParseHeader" << endl; return false;}
183 
184  string installedBuildDate(GetDate());
185  // TEST: same as running FW date: ostringstream oss; oss << DEC(runningYear) << "/" << DEC0N(runningMonth,2) << "/" << DEC0N(runningDay+0,2); installedBuildDate = oss.str();
186  // TEST: 1 day past running FW date: ostringstream oss; oss << DEC(runningYear) << "/" << DEC0N(runningMonth,2) << "/" << DEC0N(runningDay+1,2); installedBuildDate = oss.str();
187  // TEST: 2 days past running FW date: ostringstream oss; oss << DEC(runningYear) << "/" << DEC0N(runningMonth,2) << "/" << DEC0N(runningDay+2,2); installedBuildDate = oss.str();
188  if (installedBuildDate.empty() || installedBuildDate.length() < 10 || installedBuildDate.at(4) != '/')
189  {outMsgs << "## WARNING: Bad installed firmware date '" << installedBuildDate << "'" << endl; return false;}
190 
191  // Convert installed FW date to time_t...
192  tm.tm_year = int(aja::stol(installedBuildDate.substr(0, 4))) - 1900; // Year
193  tm.tm_mon = int(aja::stol(installedBuildDate.substr(5, 2))) - 1; // Month
194  tm.tm_mday = int(aja::stol(installedBuildDate.substr(8, 2))); // Day
195  tm.tm_hour = 11; // near mid-day
196  tm.tm_isdst = 0; // Standard time (not DST)
197  std::time_t tInstalled (std::mktime(&tm));
198 
199  // Calculate seconds between the two dates...
200  ULWord secsApart (ULWord(::difftime(tInstalled, tRunning)));
201  if (secsApart == 0)
202  outIsRunning = true; // Same date
203  else if (secsApart <= 86400) // Call them equal even within a day apart
204  {outMsgs << "## WARNING: Installed firmware date is 1 day past running firmware date" << endl; outIsRunning = true;}
205  return true;
206 }
207 
209 {
210  if (!IsOpen())
211  return false;
212 
213  if (!SetDeviceProperties())
214  return false;
215 
216  //For manufacturing use the leds to code the board number
217  uint32_t ledMask = BIT(16)+BIT(17);
218  uint32_t ledShift = 16;
219  return WriteRegister(kRegGlobalControl, index, ledMask, ledShift);
220 
221 }
222 
224 {
225  bool knownChip = false;
226  bool status = false;
227 
229 
230 // case 0x00202018://STMircro
231 // case 0x00012018://CYPRESS S25FL128
232 // case 0x00C22018://Macronix
233 // T-Tap
234 // IoExpress
235 // IoXT
236 // Kona Lhe+
237 // Kona 3G
238 // Kona 3G Quad
239 // Corvid 1
240 // Corvid 22
241 // Corvid 24
242 // Corvid 3G
243 
244 // case 0x00010220://CYPRESS f25fl512
245 // Kona IP 2022
246 // Kona IP 2110
247 // IoIP 2022
248 // IoIP 2110
249 // Io4K+
250 
251 // case 0x009d6019://ISSI
252 // No Product 6/27/18
253 
254 // case 0x00C84018://GIGADEVICE GD25Q127CFIG
255 // case 0x00EF4018://WINBOND W25Q128
256 // T-Tap
257 // IoExpress
258 // IoXT
259 // Kona Lhe+
260 // Kona 3G
261 // Kona 3G Quad
262 // Corvid 1
263 // Corvid 22
264 // Corvid 24
265 // Corvid 3G
266 
267 // case 0x00010219://CYPRESS S25FL256
268 // Kona 1
269 // Kona HDMI
270 // Kona 4
271 // Kona 4 UFC
272 // Corvid 44
273 // Corvid 88
274 // Corvid HBR
275 // Corvid HEVC
276 
277  switch(_deviceID)
278  {
279  case 0x00202018://STMircro
280  case 0x00C22018://Macronix
281  _flashSize = 16 * 1024 * 1024;
282  _bankSize = 16 * 1024 * 1024;
283  _sectorSize = 256 * 1024;
284  _failSafePadding = 1;
285  knownChip = true;
286  break;
287  case 0x00010220://CYPRESS f25fl512
288  _flashSize = 64 * 1024 * 1024;
289  _bankSize = 16 * 1024 * 1024;
290  _sectorSize = 256 * 1024;
291  _failSafePadding = 1;
292  knownChip = true;
293  break;
294  case 0x009d6019://ISSI
295  _flashSize = 64 * 1024 * 1024;
296  _bankSize = 16 * 1024 * 1024;
297  _sectorSize = 64 * 1024;
298  _failSafePadding = 4;
299  knownChip = true;
300  break;
301  case 0x0020ba20://Micron MT25QL512ABB
302  _flashSize = 64 * 1024 * 1024;
303  _bankSize = 16 * 1024 * 1024;
304  _sectorSize = 64 * 1024;
305  _failSafePadding = 4;
307  knownChip = true;
308  break;
309  case 0x00C84018://GIGADEVICE GD25Q127CFIG
310  case 0x00EF4018://WINBOND W25Q128
311  case 0x00012018://CYPRESS S25FL128
312  _flashSize = 16 * 1024 * 1024;
313  _bankSize = 16 * 1024 * 1024;
314  _sectorSize = 64 * 1024;
315  _failSafePadding = 4;
316  knownChip = true;
317  break;
318  case 0x00010219://CYPRESS S25FL256
319  _flashSize = 32 * 1024 * 1024;
320  _bankSize = 16 * 1024 * 1024;
321  _sectorSize = 64 * 1024;
322  _failSafePadding = 4;
323  knownChip = true;
324  break;
325  default:
326  _flashSize = 0;
327  _bankSize = 0;
328  _sectorSize = 0;
329  knownChip = false;
330  break;
331  }
332 
333  if(!knownChip)
334  return false;
335 
337  {
338  default:
339  case 1:
340  //This includes legacy boards such as LHi, Corvid 1...
341  //SPI is devided up into 4 logical blocks of 4M each
342  //Without history explained main is at offset 0 and failsafe is at offset 12
345  _mainOffset = 0;
346  _failSafeOffset = 12 * 1024 * 1024;
347  _macOffset = _bankSize - (2 * _sectorSize);
348  status = true;
349  break;
350  case 2:
353  _mainOffset = 0;
354  _failSafeOffset = 8 * 1024 * 1024;
355  _macOffset = _bankSize - (2 * _sectorSize);
356  status = true;
357  break;
358  case 3:
359  if (_deviceID == 0x010220)
360  {
361  //This is actually SPI v4 but needed this for spoofing Kona4
366  _mainOffset = 0;
367  _soc1Offset = 0;
368  _soc2Offset = 0;
369  _failSafeOffset = 0;// but is really 16*1024*1024;
370  _macOffset = _bankSize - (2 * _sectorSize);
373  status = true;
374  }
375  else
376  {
377  //SPIV3 This gets a little weird both main and failsafe have an offset of 0
378  //and the real offset is controlled by a bank selector switch in firmware
381  _mainOffset = 0;
382  _failSafeOffset = 0;// but is really 16*1024*1024;
383  _macOffset = _bankSize - (2 * _sectorSize);
386  status = true;
387  }
388  break;
389  case 4:
390  //SPIV4 is a bigger SPIv3 2x
395  _mainOffset = 0;
396  _soc1Offset = 0;
397  _soc2Offset = 0;
398  _failSafeOffset = 0;// but is really 16*1024*1024;
399  _macOffset = _bankSize - (2 * _sectorSize);
402  status = true;
403  break;
404  case 5:
405  case 6:
408  _mainOffset = 0;
409  _failSafeOffset = 0;// but is really 32*1024*1024;
410  status = true;
411  break;
412  }
413 
414  if (_spiFlash)
415  {
416  delete _spiFlash;
418  }
419 
421  {
422  _spiFlash = new CNTV2AxiSpiFlash(GetIndexNumber(), !_bQuiet);
423  }
424 
425  return status;
426 }
427 
428 bool CNTV2KonaFlashProgram::SetBitFile (const string & inBitfileName, ostream & outMsgs, const FlashBlockID blockID)
429 {
431  _bitFileName = inBitfileName;
432 
433  if (blockID == AUTO_FLASHBLOCK)
435  else if (blockID >= MAIN_FLASHBLOCK && blockID <= FAILSAFE_FLASHBLOCK)
436  _flashID = blockID;
437  else
438  {outMsgs << "Invalid flash block ID " << DEC(blockID); return false;}
439 
440  FILE* pFile = AJA_NULL;
441  struct stat fsinfo;
442  stat(inBitfileName.c_str(), &fsinfo);
443  _bitFileSize = uint32_t(fsinfo.st_size);
444  pFile = fopen(inBitfileName.c_str(), "rb");
445  if (!pFile)
446  {outMsgs << "Cannot open bitfile '" << inBitfileName << "'"; return false;}
447 
448  // +_256 for fastFlash Programming
450  {outMsgs << "Allocate " << DEC(_bitFileSize+512) << "-byte buffer failed"; return false;}
451  _bitFileBuffer.Fill(0xFFFFFFFF);
452 
453  fseek(pFile, 0, SEEK_SET);
454  size_t bytesRead = fread(_bitFileBuffer, 1, _bitFileSize, pFile);
455  NTV2_UNUSED(bytesRead);
456  fclose(pFile);
457 
458  // Parse header to make sure this is a xilinx bitfile.
459  if (!_parser.ParseHeader(_bitFileBuffer, outMsgs))
460  return false;
461 
462  if (!SetDeviceProperties())
463  {outMsgs << "Device not recognized"; return false;}
464  return true;
465 }
466 
468 {
470  if (bitFileName.find("_fs_") != string::npos)
472 }
473 
475 {
476  bool status (SetFlashBlockIDBank(blockID));
477  NTV2Buffer bitFileHeader(MAXBITFILE_HEADERSIZE);
478  uint32_t baseAddress (GetBaseAddressForProgramming(blockID));
479  const int dwordSizeCount (int(bitFileHeader.GetByteCount()) / 4);
480  for (int count(0); status && count < dwordSizeCount; count++, baseAddress += 4)
481  status = WriteRegister(kRegXenaxFlashAddress, baseAddress)
484  && ReadRegister(kRegXenaxFlashDOUT, bitFileHeader.U32(count));
485  ostringstream msgs;
486  if (status) status = _parser.ParseHeader(bitFileHeader, msgs);
487  SetBankSelect(BANK_0); // Make sure to reset bank to lower
488  return status;
489 }
490 
492 {
493  if (_spiFlash)
494  {
495  vector<uint8_t> mcsInfoData;
496  bool oldVerboseMode = _spiFlash->GetVerbosity();
497  _spiFlash->SetVerbosity(false);
498  uint32_t offset = _spiFlash->Offset(SPI_FLASH_SECTION_MCSINFO);
499  if (_spiFlash->Read(offset, mcsInfoData, MAXMCSINFOSIZE))
500  {
501  _spiFlash->SetVerbosity(oldVerboseMode);
502  _mcsInfo.assign(mcsInfoData.begin(), mcsInfoData.end());
503  }
504  else
505  {
506  _spiFlash->SetVerbosity(oldVerboseMode);
507  return false;
508  }
509  }
510  else
511  {
512  if (_deviceID != 0x010220 || !IsIPDevice())
513  return false;
514  uint32_t baseAddress = _mcsInfoOffset;
516 
517  NTV2Buffer mcsInfoPtr(MAXMCSINFOSIZE);
518  uint32_t dwordSizeCount (MAXMCSINFOSIZE / 4);
519  for (uint32_t count(0); count < dwordSizeCount; count++, baseAddress += 4)
520  {
521  WriteRegister(kRegXenaxFlashAddress, baseAddress);
524  ReadRegister(kRegXenaxFlashDOUT, mcsInfoPtr.U32(int(count)));
525  if (mcsInfoPtr.U32(int(count)) == 0)
526  break;
527  }
528  _mcsInfo = reinterpret_cast<const char*>(mcsInfoPtr.GetHostPointer());
529  SetBankSelect(BANK_0); // Make sure to reset bank to lower
530  }
531  // Fix up _mcsInfo...
532  size_t ffPos(_mcsInfo.find("\xFF\xFF"));
533  if (ffPos != string::npos)
534  _mcsInfo = _mcsInfo.substr(0, ffPos); // Lop off "\xFF\xFF...", if present
535  return true;
536 }
537 
538 std::string CNTV2KonaFlashProgram::Program(bool fullVerify)
539 {
540  if (!_bitFileBuffer)
541  return "Bitfile not open";
542 
543  if (!IsOpen())
544  return "Device not open";
545 
546  uint32_t baseAddress(GetBaseAddressForProgramming(_flashID));
547  switch (_flashID)
548  {
553  default: break;
554  }
555 
557 
559 
560  uint32_t* bitFilePtr = _bitFileBuffer;
561  uint32_t twoFixtysixBlockSizeCount ((_bitFileSize + 256) / 256);
562  uint32_t percentComplete(0);
564  WriteRegister(kVRegFlashSize, twoFixtysixBlockSizeCount);
565  for (uint32_t count(0); count < twoFixtysixBlockSizeCount; count++, baseAddress += 256, bitFilePtr += 64)
566  {
567  if (::NTV2DeviceGetSPIFlashVersion(_boardID) >= 5 && baseAddress == _bankSize)
568  {
569  baseAddress = 0;
571  }
572  FastProgramFlash256(baseAddress, bitFilePtr);
573  percentComplete = (count*100)/twoFixtysixBlockSizeCount;
574 
576  if (!_bQuiet)
577  cout << "Program status: " << DEC(percentComplete) << "% \r" << flush;
578  }
579  if (!_bQuiet)
580  cout << "Program status: 100% " << endl;
581 
583  if (!VerifyFlash(_flashID, fullVerify))
584  {
586  return "Program Didn't Verify";
587  }
588 
589  // Protect Device
595 
602 
604  return "";
605 }
606 
607 bool CNTV2KonaFlashProgram::ProgramFlashValue(uint32_t address, uint32_t value)
608 {
615 
616  return true;
617 }
618 
619 bool CNTV2KonaFlashProgram::FastProgramFlash256(uint32_t address, uint32_t* buffer)
620 {
623  for ( uint32_t count=0; count < 64; count++ )
624  {
625  WriteRegister(kRegXenaxFlashDIN, *buffer++);
626  }
630 
631  return true;
632 }
633 
635 {
636  uint32_t deviceID = 0;
637  if (IsOpen ())
638  {
641  ReadRegister(kRegXenaxFlashDOUT, deviceID);
642  }
643  return (deviceID & 0xFFFFFF);
644 }
645 
647 {
648  if (!IsOpen())
649  return false;
650  SetFlashBlockIDBank(blockID);
651 
657  uint32_t percentComplete = 0;
658 
659  uint32_t numSectors = GetNumberOfSectors(blockID);
660  WriteRegister(kVRegFlashSize,numSectors);
661 
662  uint32_t baseAddress = GetBaseAddressForProgramming(blockID);
663  uint32_t bankCount = 0;
664  for (uint32_t sectorCount = 0; sectorCount < numSectors; sectorCount++ )
665  {
666  if (::NTV2DeviceGetSPIFlashVersion(_boardID) >= 5 && sectorCount*_sectorSize == _bankSize)
667  {
668  switch(blockID)
669  {
670  default:
671  case MAIN_FLASHBLOCK:
673  break;
674  case FAILSAFE_FLASHBLOCK:
676  break;
677  }
678  bankCount++;
679  }
680  EraseSector(baseAddress + ((sectorCount - (_numSectorsMain* bankCount)) * _sectorSize));
681  percentComplete = (sectorCount*100)/numSectors;
682  WriteRegister(kVRegFlashStatus, sectorCount);
683  if (!_bQuiet)
684  cout << "Erase status: " << DEC(percentComplete) << "%\r" << flush;
685  }
686  WriteRegister(kVRegFlashStatus,numSectors);
687  if (!_bQuiet)
688  cout << "Erase status: 100% " << endl;
689  //if ( !CheckFlashErasedWithBlockID(flashBlockNumber))
690  //throw "Erase didn't work";
691  return SetBankSelect(BANK_0);
692 }
693 
694 bool CNTV2KonaFlashProgram::EraseSector (uint32_t sectorAddress)
695 {
696  WriteRegister(kRegXenaxFlashAddress, sectorAddress);
700  return WaitForFlashNOTBusy();
701 }
702 
704 { (void) chip; // unused
714  return WaitForFlashNOTBusy();
715 }
716 
717 bool CNTV2KonaFlashProgram::VerifyFlash (FlashBlockID flashID, bool fullVerify)
718 {
719  uint32_t errorCount = 0;
720  uint32_t baseAddress = GetBaseAddressForProgramming(flashID);
721  uint32_t* bitFilePtr = _bitFileBuffer;
722  uint32_t dwordSizeCount ((_bitFileSize + 4) / 4);
723  uint32_t percentComplete(0), lastPercentComplete(999);
724 
727  WriteRegister(kVRegFlashSize, dwordSizeCount);
728  for (uint32_t count = 0; count < dwordSizeCount; )
729  {
730  if (::NTV2DeviceGetSPIFlashVersion(_boardID) >= 5 && baseAddress == _bankSize)
731  {
732  baseAddress = 0;
734  }
735  WriteRegister(kRegXenaxFlashAddress, baseAddress);
738  uint32_t flashValue;
739  ReadRegister(kRegXenaxFlashDOUT, flashValue);
740  uint32_t bitFileValue = *bitFilePtr;
741  if (flashValue != bitFileValue)
742  {
743  cerr << "Error " << DEC(count) << " E(" << HEX0N(bitFileValue,8) << "),R(" << HEX0N(flashValue,8) << ")" << endl;
744  errorCount++;
745  if (errorCount > 1)
746  break;
747  }
748  percentComplete = (count*100)/dwordSizeCount;
750  if (!_bQuiet)
751  {
752  if (percentComplete != lastPercentComplete)
753  {
754  cout << "Program verify: " << DEC(percentComplete) << "%\r" << flush;
755  lastPercentComplete = percentComplete;
756  }
757  }
758  count += fullVerify ? 1 : 64;
759  baseAddress += fullVerify ? 4 : 256;
760  bitFilePtr += fullVerify ? 1 : 64;
761  }
762 
764 
765  if (errorCount)
766  {
767  if (!_bQuiet)
768  cout << "Program verify failed: " << DEC(percentComplete) << "%" << endl;
769  return false;
770  }
771  if (!_bQuiet)
772  cout << "Program verify: 100% " << endl;
773  return true;
774 }
775 
776 bool CNTV2KonaFlashProgram::ReadFlash (NTV2Buffer & outBuffer, const FlashBlockID inFlashID, CNTV2FlashProgress & inFlashProgress)
777 {
778  uint32_t baseAddress(GetBaseAddressForProgramming(inFlashID));
779  const uint32_t numDWords((_bitFileSize+4)/4);
780  if (outBuffer.GetByteCount() < numDWords*4)
781  {
782  if (outBuffer.GetByteCount() && !outBuffer.IsAllocatedBySDK())
783  {KFPERR("Unable to resize target buffer (not alloc'd by SDK)"); return false;}
784  if (!outBuffer.Allocate(numDWords * 4))
785  {KFPERR("Failed to allocate " << DEC(numDWords*4) << "-byte target buffer"); return false;}
786  }
787 
788  size_t lastPercent(0), percent(0);
789  inFlashProgress.UpdatePercentage(lastPercent);
790  switch (_flashID)
791  {
792  default:
793  case MAIN_FLASHBLOCK:
795  break;
796  case FAILSAFE_FLASHBLOCK:
798  break;
799  }
801  WriteRegister(kVRegFlashSize, numDWords);
802  KFPDBUG("About to read " << xHEX0N(numDWords*4,8) << "(" << DEC(numDWords*4) << ") bytes from '" << FlashBlockIDToString(inFlashID, /*compact*/true) << "' address " << xHEX0N(baseAddress,8));
803  for (uint32_t dword(0); dword < numDWords; )
804  {
805  if (::NTV2DeviceGetSPIFlashVersion(_boardID) >= 5 && baseAddress == _bankSize)
806  {
807  baseAddress = 0;
808  switch (_flashID)
809  {
810  default:
811  case MAIN_FLASHBLOCK:
813  break;
814  case FAILSAFE_FLASHBLOCK:
816  break;
817  }
818  }
819  WriteRegister(kRegXenaxFlashAddress, baseAddress);
822  uint32_t flashValue;
823  ReadRegister(kRegXenaxFlashDOUT, flashValue);
824  outBuffer.U32(int(dword)) = flashValue;
826 
827  dword += 1;
828  percent = dword * 100 / numDWords;
829  if (percent != lastPercent)
830  if (!inFlashProgress.UpdatePercentage(percent))
831  {SetBankSelect(BANK_0); KFPERR("Cancelled at " << DEC(percent) << "% addr=" << xHEX0N(baseAddress,8) << " dword=" << DEC(dword)); return false;}
832  lastPercent = percent;
833  if ((dword % 0x10000) == 0) cerr << xHEX0N(dword,8) << " of " << xHEX0N(numDWords,8) << endl;
834  baseAddress += 4;
835  }
837  inFlashProgress.UpdatePercentage(100);
838  KFPNOTE("Successfully read " << xHEX0N(numDWords*4,8) << "(" << DEC(numDWords*4) << ") bytes from '" << FlashBlockIDToString(inFlashID, /*compact*/true) << "' address " << xHEX0N(baseAddress,8));
839  return true;
840 }
841 
843 {
844  bool busy = true;
845  int i = 0;
846  uint32_t regValue;
847  while (i < 1)
848  {
849  ReadRegister(kRegBoardID, regValue);
850  i++;
851  }
852  regValue = 0;
853  do
854  {
856  if (!(regValue & BIT(8)))
857  {
858  busy = false;
859  break;
860  }
861  } while (busy);
862 
863  return !busy; // Return true if wait was successful
864 }
865 
867 {
868  bool status = true;
869  uint32_t baseAddress = GetBaseAddressForProgramming(flashID);
870  uint32_t numSectors = GetNumberOfSectors(flashID);
871  uint32_t dwordSizeCount = (numSectors*_sectorSize)/4;
872  uint32_t percentComplete = 0;
873  SetFlashBlockIDBank(flashID);
874 
875  for (uint32_t count = 0; count < dwordSizeCount; count++, baseAddress += 4)
876  {
877  WriteRegister(kRegXenaxFlashAddress, baseAddress);
880  uint32_t flashValue;
881  ReadRegister(kRegXenaxFlashDOUT, flashValue);
882  if ( flashValue != 0xFFFFFFFF )
883  {
884  count = dwordSizeCount;
885  status = false;
886  continue;
887  }
888  percentComplete = (count*100)/dwordSizeCount;
889  if(!_bQuiet)
890  cout << "Erase verify: " << DEC(percentComplete) << "%\r" << flush;
891  }
892  if(!_bQuiet && status == true)
893  cout << "Erase verify: 100% " << endl;
894 
896 
897  return status;
898 }
899 
900 
901 bool CNTV2KonaFlashProgram::CreateSRecord(bool bChangeEndian)
902 {
903  uint32_t baseAddress = 0;
904  // char sRecord[100];
905  uint32_t partitionOffset = 0;
906 
907  cout << "S0030000FC" << endl;
908 
909  for ( uint32_t count = 0; count < _flashSize; count+=32)
910  {
911  ostringstream sRec;
912  if (ROMHasBankSelect() && count % _bankSize == 0)
913  {
914  baseAddress = 0;
915  partitionOffset = count;
916  switch (partitionOffset)
917  {
918  default:
919  case 0x00000000: SetBankSelect(BANK_0); break;
920  case 0x01000000: SetBankSelect(BANK_1); break;
921  case 0x02000000: SetBankSelect(BANK_2); break;
922  case 0x03000000: SetBankSelect(BANK_3); break;
923  }
924  }
925 
926  uint32_t recordSize = 32;
927  if((_flashSize - count) < recordSize)
928  recordSize = _flashSize - count;
929 
930 
931  UByte checksum = 0;
932 
933  sRec << "S3"; // sRecord[0] = 'S'; sRecord[1] = '3';
934 
935  uint32_t cc (recordSize + 5);
936  sRec << Hex0N(cc,2); //sprintf(&sRecord[2], "%02x", cc);
937  checksum += cc;
938 
939  uint32_t addr = baseAddress+partitionOffset;
940  UWord aa = ((addr >> 24) &0xff);
941  sRec << Hex0N(aa,2); // sprintf(&sRecord[4], "%02x", aa);
942  checksum += aa;
943 
944  aa = ((addr >> 16) & 0xff);
945  sRec << Hex0N(aa,2); // sprintf (&sRecord[6],"%02x", aa);
946  checksum += aa;
947 
948  aa = ((addr >> 8) & 0xff);
949  sRec << Hex0N(aa,2); // sprintf (&sRecord[8],"%02x", aa);
950  checksum += aa;
951 
952  aa = (addr & 0xff);
953  sRec << Hex0N(aa,2); // sprintf (&sRecord[10],"%02x", aa);
954  checksum += aa;
955 
956  uint32_t i = 0;
957  int32_t index = 12;
958  while(i < recordSize)
959  {
963  uint32_t flashValue;
964  ReadRegister(kRegXenaxFlashDOUT, flashValue);
965  if(bChangeEndian)
966  flashValue = NTV2EndianSwap32(flashValue);
967 
968  UWord dd = (flashValue & 0xff);
969  sRec << Hex0N(dd,2); // sprintf(&sRecord[index], "%02x", dd);
970  checksum += dd;
971 
972  dd = ((flashValue >> 8) & 0xff);
973  sRec << Hex0N(dd,2); // sprintf(&sRecord[index+2], "%02x", dd);
974  checksum += dd;
975 
976  dd = ((flashValue >> 16) & 0xff);
977  sRec << Hex0N(dd,2); // sprintf(&sRecord[index+4], "%02x", dd);
978  checksum += dd;
979 
980  dd = ((flashValue >> 24) & 0xff);
981  sRec << Hex0N(dd,2); // sprintf(&sRecord[index+6], "%02x", dd);
982  checksum += dd;
983 
984  i += 4;
985  index += 8;
986  baseAddress += 4;
987  }
988  checksum = ~checksum;
989  sRec << Hex0N(UWord(checksum),2); // sprintf(&sRecord[index], "%02x", checksum);
990 
991  cout << sRec.str() << endl; // sRecord);
992  } // for loop
993 
995 
996  cout << "S705FFF001000A" << endl;
997 
998  return true;
999 }
1000 
1002 {
1003  uint32_t baseAddress = 0;
1004  ostringstream sRec; // char sRecord[100];
1005  uint32_t partitionOffset = 0;
1006 
1007  cout << "S0030000FC" << endl;
1008 
1009  for (uint32_t count = 0; count < _bankSize; count += 32)
1010  {
1011  if (ROMHasBankSelect())
1012  {
1013  SetBankSelect(bankID);
1014  }
1015 
1016  uint32_t recordSize = 32;
1017  if ((_flashSize - count) < recordSize)
1018  recordSize = _flashSize - count;
1019 
1020  UByte checksum = 0;
1021 
1022  sRec << "S3"; // sRecord[0] = 'S'; sRecord[1] = '3';
1023 
1024  UWord cc (UWord(recordSize) + 5);
1025  sRec << Hex0N(cc,2); // sprintf(&sRecord[2], "%02x", cc);
1026  checksum += cc;
1027 
1028  uint32_t addr = baseAddress + partitionOffset;
1029  UWord aa = ((addr >> 24) & 0xff);
1030  sRec << Hex0N(aa,2); // sprintf(&sRecord[4], "%02x", aa);
1031  checksum += aa;
1032 
1033  aa = ((addr >> 16) & 0xff);
1034  sRec << Hex0N(aa,2); // sprintf(&sRecord[6], "%02x", aa);
1035  checksum += aa;
1036 
1037  aa = ((addr >> 8) & 0xff);
1038  sRec << Hex0N(aa,2); // sprintf(&sRecord[8], "%02x", aa);
1039  checksum += aa;
1040 
1041  aa = (addr & 0xff);
1042  sRec << Hex0N(aa,2); // sprintf(&sRecord[10], "%02x", aa);
1043  checksum += aa;
1044 
1045  uint32_t i = 0;
1046  int32_t index = 12;
1047  while (i < recordSize)
1048  {
1049  WriteRegister(kRegXenaxFlashAddress, baseAddress);
1052  uint32_t flashValue;
1053  ReadRegister(kRegXenaxFlashDOUT, flashValue);
1054  //flashValue = NTV2EndianSwap32(flashValue);
1055 
1056  UWord dd = (flashValue & 0xff);
1057  sRec << Hex0N(dd,2); // sprintf(&sRecord[index], "%02x", dd);
1058  checksum += dd;
1059 
1060  dd = ((flashValue >> 8) & 0xff);
1061  sRec << Hex0N(dd,2); // sprintf(&sRecord[index + 2], "%02x", dd);
1062  checksum += dd;
1063 
1064  dd = ((flashValue >> 16) & 0xff);
1065  sRec << Hex0N(dd,2); // sprintf(&sRecord[index + 4], "%02x", dd);
1066  checksum += dd;
1067 
1068  dd = ((flashValue >> 24) & 0xff);
1069  sRec << Hex0N(dd,2); // sprintf(&sRecord[index + 6], "%02x", dd);
1070  checksum += dd;
1071 
1072  i += 4;
1073  index += 8;
1074  baseAddress += 4;
1075  }
1076  checksum = ~checksum;
1077  sRec << Hex0N(UWord(checksum),2); // sprintf(&sRecord[index], "%02x", checksum);
1078 
1079  cout << sRec.str() << endl; // sRecord);
1080  } // for loop
1081 
1083 
1084  cout << "S705FFF001000A" << endl;
1085 
1086  return true;
1087 }
1088 
1090 {
1091  ostringstream iRec; // char iRecord[100];
1092  int32_t recordSize = 16;
1093  UWord baseAddress = 0x0000;
1094  UByte checksum = 0;
1095  UByte recordType = 0x00;
1096  UByte byteCount = 0x10;
1097 
1098  uint32_t i2cVal = 0x02000050;
1099 
1100  for(int32_t x = 0; x < 16; x++)
1101  {
1102  int32_t i= 0;
1103  int32_t index = 0;
1104  checksum = 0;
1105 
1106  iRec << ":"; // iRecord[0] = ':';
1107 
1108  iRec << Hex0N(UWord(byteCount),2); // sprintf(&iRecord[1], "%02x", byteCount);
1109  checksum += byteCount;
1110 
1111  UWord addr = baseAddress;
1112  UByte aa = ((addr >> 8) & 0xff);
1113  iRec << Hex0N(UWord(aa),2); // sprintf(&iRecord[3], "%02x", aa);
1114  checksum += aa;
1115 
1116  aa = ((addr) & 0xff);
1117  iRec << Hex0N(UWord(aa),2); // sprintf(&iRecord[5], "%02x", aa);
1118  checksum += aa;
1119 
1120  iRec << Hex0N(UWord(recordType),2); // sprintf (&iRecord[7], "%02x", recordType);
1121 
1122  index = 9;
1123 
1124  while(i<recordSize)
1125  {
1127 
1128  AJATime::Sleep(100);
1129 
1130  uint32_t flashValue;
1131  ReadRegister(kRegFS1I2C1Data, flashValue);
1132 
1133  UByte dd = ((flashValue >> 8) & 0xff);
1134  iRec << Hex0N(UWord(dd),2); // sprintf(&iRecord[index], "%02x", dd);
1135  checksum += dd;
1136 
1137  i++;
1138  index+=2;
1139  i2cVal += 0x00000100;
1140  }
1141 
1142  baseAddress += 0x0010;
1143  checksum = (checksum ^ 0xFF)+1;
1144  iRec << Hex0N(UWord(checksum),2); // sprintf(&iRecord[index], "%02x", checksum);
1145 
1146  cout << iRec.str() << endl; // iRecord);
1147  } // for loop
1148 
1149  cout << ":00000001FF" << endl;
1150 
1151  return true;
1152 
1153 }
1154 
1156 {
1157  if(!IsIPDevice())
1158  return false;
1159 
1160  if (!mac1 || !mac2)
1161  return false;
1162 
1163  if (_spiFlash)
1164  {
1165  vector<uint8_t> macData;
1166  macData.push_back(mac1->mac[3]);
1167  macData.push_back(mac1->mac[2]);
1168  macData.push_back(mac1->mac[1]);
1169  macData.push_back(mac1->mac[0]);
1170  macData.push_back(0);
1171  macData.push_back(0);
1172  macData.push_back(mac1->mac[5]);
1173  macData.push_back(mac1->mac[4]);
1174 
1175  macData.push_back(mac2->mac[3]);
1176  macData.push_back(mac2->mac[2]);
1177  macData.push_back(mac2->mac[1]);
1178  macData.push_back(mac2->mac[0]);
1179  macData.push_back(0);
1180  macData.push_back(0);
1181  macData.push_back(mac2->mac[5]);
1182  macData.push_back(mac2->mac[4]);
1183 
1184  bool oldVerboseMode = _spiFlash->GetVerbosity();
1185  _spiFlash->SetVerbosity(false);
1186  uint32_t offset = _spiFlash->Offset(SPI_FLASH_SECTION_MAC);
1187  _spiFlash->Erase(offset, uint32_t(macData.size()));
1188  if (_spiFlash->Write(offset, macData, uint32_t(macData.size())))
1189  {
1190  _spiFlash->SetVerbosity(oldVerboseMode);
1191  return true;
1192  }
1193  else
1194  {
1195  _spiFlash->SetVerbosity(oldVerboseMode);
1196  return false;
1197  }
1198  }
1199  else
1200  {
1201  uint32_t baseAddress = _macOffset;
1202 
1204 
1206 
1207 
1208  uint32_t lo = 0;
1209  lo |= uint32_t((mac1->mac[0]) << 24) & 0xff000000;
1210  lo |= uint32_t((mac1->mac[1]) << 16) & 0x00ff0000;
1211  lo |= uint32_t((mac1->mac[2]) << 8) & 0x0000ff00;
1212  lo |= uint32_t(mac1->mac[3]) & 0x000000ff;
1213 
1214  uint32_t hi = 0;
1215  hi |= uint32_t((mac1->mac[4]) << 24) & 0xff000000;
1216  hi |= uint32_t((mac1->mac[5]) << 16) & 0x00ff0000;
1217 
1218  uint32_t lo2 = 0;
1219  lo2 |= uint32_t((mac2->mac[0]) << 24) & 0xff000000;
1220  lo2 |= uint32_t((mac2->mac[1]) << 16) & 0x00ff0000;
1221  lo2 |= uint32_t((mac2->mac[2]) << 8) & 0x0000ff00;
1222  lo2 |= uint32_t(mac2->mac[3]) & 0x000000ff;
1223 
1224  uint32_t hi2 = 0;
1225  hi2 |= uint32_t((mac2->mac[4]) << 24) & 0xff000000;
1226  hi2 |= uint32_t((mac2->mac[5]) << 16) & 0x00ff0000;
1227 
1228 
1229  ProgramFlashValue(baseAddress, lo);
1230  baseAddress += 4;
1231  ProgramFlashValue(baseAddress, hi);
1232  baseAddress += 4;
1233  ProgramFlashValue(baseAddress, lo2);
1234  baseAddress += 4;
1235  ProgramFlashValue(baseAddress, hi2);
1236 
1242 
1244 
1245  return true;
1246  }
1247 }
1248 
1250 {
1251  uint32_t lo;
1252  uint32_t hi;
1253  uint32_t lo2;
1254  uint32_t hi2;
1255 
1256  if(!IsIPDevice())
1257  return false;
1258 
1259  if (_spiFlash)
1260  {
1261  vector<uint8_t> macData;
1262  bool oldVerboseMode = _spiFlash->GetVerbosity();
1263  _spiFlash->SetVerbosity(false);
1264  uint32_t offset = _spiFlash->Offset(SPI_FLASH_SECTION_MAC);
1265  if (_spiFlash->Read(offset, macData, 16))
1266  {
1267  _spiFlash->SetVerbosity(oldVerboseMode);
1268  if (macData.size() < 16)
1269  return false;
1270 
1271  mac1.mac[0] = macData.at(3);
1272  mac1.mac[1] = macData.at(2);
1273  mac1.mac[2] = macData.at(1);
1274  mac1.mac[3] = macData.at(0);
1275  mac1.mac[4] = macData.at(7);
1276  mac1.mac[5] = macData.at(6);
1277 
1278  mac2.mac[0] = macData.at(8+3);
1279  mac2.mac[1] = macData.at(8+2);
1280  mac2.mac[2] = macData.at(8+1);
1281  mac2.mac[3] = macData.at(8+0);
1282  mac2.mac[4] = macData.at(8+7);
1283  mac2.mac[5] = macData.at(8+6);
1284  return true;
1285  }
1286  else
1287  {
1288  _spiFlash->SetVerbosity(oldVerboseMode);
1289  return false;
1290  }
1291  }
1292  else
1293  {
1294  uint32_t baseAddress = GetBaseAddressForProgramming(MAC_FLASHBLOCK);
1296 
1297  WriteRegister(kRegXenaxFlashAddress, baseAddress);
1301  baseAddress += 4;
1302 
1303  WriteRegister(kRegXenaxFlashAddress, baseAddress);
1307  baseAddress += 4;
1308 
1309  WriteRegister(kRegXenaxFlashAddress, baseAddress);
1313  baseAddress += 4;
1314 
1315  WriteRegister(kRegXenaxFlashAddress, baseAddress);
1319 
1321 
1322  //if (lo == 0xffffffff && hi == 0xffffffff && lo2 == 0xffffffff && hi2 == 0xffffffff)
1323  //return false;
1324 
1325  mac1.mac[0] = (lo & 0xff000000) >> 24;
1326  mac1.mac[1] = (lo & 0x00ff0000) >> 16;
1327  mac1.mac[2] = (lo & 0x0000ff00) >> 8;
1328  mac1.mac[3] = lo & 0x000000ff;
1329  mac1.mac[4] = (hi & 0xff000000) >> 24;
1330  mac1.mac[5] = (hi & 0x00ff0000) >> 16;
1331 
1332  mac2.mac[0] = (lo2 & 0xff000000) >> 24;
1333  mac2.mac[1] = (lo2 & 0x00ff0000) >> 16;
1334  mac2.mac[2] = (lo2 & 0x0000ff00) >> 8;
1335  mac2.mac[3] = lo2 & 0x000000ff;
1336  mac2.mac[4] = (hi2 & 0xff000000) >> 24;
1337  mac2.mac[5] = (hi2 & 0x00ff0000) >> 16;
1338  }
1339 
1340  return true;
1341 }
1342 
1343 bool CNTV2KonaFlashProgram::ProgramLicenseInfo (const string & licenseString)
1344 {
1345  if(!IsIPDevice())
1346  return false;
1347 
1348  if (_spiFlash)
1349  {
1350  vector<uint8_t> licenseData;
1351  for (string::const_iterator it(licenseString.begin()); it != licenseString.end(); ++it)
1352  licenseData.push_back(uint8_t(*it));
1353  licenseData.push_back(0);
1354 
1355  bool oldVerboseMode = _spiFlash->GetVerbosity();
1356  _spiFlash->SetVerbosity(false);
1357  uint32_t offset = _spiFlash->Offset(SPI_FLASH_SECTION_LICENSE);
1358  _spiFlash->Erase(offset, uint32_t(licenseData.size()));
1359  if (_spiFlash->Write(offset, licenseData, uint32_t(licenseData.size())))
1360  _spiFlash->SetVerbosity(oldVerboseMode);
1361  else
1362  {
1363  _spiFlash->SetVerbosity(oldVerboseMode);
1364  return false;
1365  }
1366  }
1367  else
1368  {
1369 
1371 
1373 
1375 
1376  size_t len (licenseString.size());
1377  size_t words ((len/4) + 2);
1378  NTV2Buffer data8(words*4);
1379  ULWord * data32 = data8;
1380  data8.Fill(0x0000);
1381  strcat(data8,licenseString.c_str());
1382 
1384 
1385  for (size_t i(0); i < words; i++)
1386  {
1387  ProgramFlashValue(sectorAddress, data32[i]);
1388  sectorAddress += 4;
1389  }
1390 
1391  // Protect Device
1403  }
1404  return true;
1405 }
1406 
1407 bool CNTV2KonaFlashProgram::ReadLicenseInfo(string& serialString)
1408 {
1409  const uint32_t maxSize = 100;
1410 
1411  if(!IsIPDevice())
1412  return false;
1413 
1414  if (_spiFlash)
1415  {
1416  vector<uint8_t> licenseData;
1417  bool oldVerboseMode = _spiFlash->GetVerbosity();
1418  uint32_t offset = _spiFlash->Offset(SPI_FLASH_SECTION_LICENSE);
1419  _spiFlash->SetVerbosity(false);
1420  if (_spiFlash->Read(offset, licenseData, maxSize))
1421  {
1422  _spiFlash->SetVerbosity(oldVerboseMode);
1423  serialString = "";
1424  if (licenseData.size() < 4)
1425  return false;
1426  else if (licenseData[0] == 0xff && licenseData[1] == 0xff && licenseData[2] == 0xff && licenseData[3] == 0xff)
1427  return false;
1428  else
1429  {
1430  serialString.assign(licenseData.begin(), licenseData.end());
1431 
1432  // remove any trailing nulls
1433  size_t found = serialString.find('\0');
1434  if (found != string::npos)
1435  serialString.resize(found);
1436  }
1437  }
1438  else
1439  {
1440  _spiFlash->SetVerbosity(oldVerboseMode);
1441  return false;
1442  }
1443  }
1444  else
1445  {
1446  ULWord license[maxSize];
1447  memset (license,0x0,sizeof(license));
1448 
1449  uint32_t baseAddress = GetBaseAddressForProgramming(LICENSE_BLOCK);
1451 
1452  bool terminated = false;
1453  bool good = false;
1454  for(uint32_t i = 0; i < maxSize; i++)
1455  {
1456  WriteRegister(kRegXenaxFlashAddress,baseAddress);
1459  ReadRegister(kRegXenaxFlashDOUT, license[i]);
1460  if (license[i] == 0xffffffff)
1461  {
1462  good = true; // uninitialized memory
1463  break;
1464  }
1465  if (license[i] == 0)
1466  {
1467  good = true;
1468  terminated = true;
1469  break;
1470  }
1471  baseAddress += 4;
1472  }
1473 
1474  std::string res;
1475  if (terminated)
1476  res = reinterpret_cast<char*>(license);
1477 
1478  serialString = res;
1479  return good;
1480  }
1481  return true;
1482 }
1483 
1485 {
1486  if (ROMHasBankSelect())
1487  {
1488  if (int(bankNumber) > int(BANK_3))
1489  return false; // illegal value
1492  WriteRegister(kRegXenaxFlashAddress, uint32_t(bankNumber));
1493 
1496  KFPDBUG ("selected bank: " << ReadBankSelect());
1497  }
1498  return true;
1499 }
1500 
1502 {
1503  uint32_t bankNumber = 0;
1504  if (ROMHasBankSelect())
1505  {
1508  ReadRegister(kRegXenaxFlashDOUT, bankNumber);
1509  }
1510  return bankNumber&0xf;
1511 }
1512 
1513 bool CNTV2KonaFlashProgram::SetMCSFile (const string & inMCSFileName)
1514 {
1515  if (!_bQuiet)
1516  cout << "Parsing MCS File" << endl;
1517  return _mcsFile.Open(inMCSFileName.c_str());
1518 }
1519 
1521 {
1522  if (!_mcsFile.isReady())
1523  {cerr << "MCS bitfile not open" << endl; return false;}
1524  if (!IsOpen())
1525  {cerr << "Device not open" << endl; return false;}
1526 
1527  if (_spiFlash)
1528  {
1529  if (!_mcsFile.isReady())
1530  {cerr << "MCS file not ready" << endl; return false;}
1531 
1532  // now the main FPGA part
1534 
1535  vector<uint8_t> fpgaData;
1536  uint16_t fpgaPartitionOffset = 0;
1537 
1538  _mcsFile.GetPartition(fpgaData, 0x0000, fpgaPartitionOffset, false);
1539  _bitFileSize = uint32_t(fpgaData.size());
1540  // +_256 for fastFlash Programming
1542  _bitFileBuffer.Fill(0xFFFFFFFF);
1543  ::memcpy(_bitFileBuffer, &fpgaData[0], _bitFileSize);
1544 
1545  // Parse header to make sure this is a xilinx bitfile.
1546  ostringstream msgs;
1547  if (!_parser.ParseHeader(_bitFileBuffer, msgs))
1548  {cerr << "Can't parse header" << endl << msgs.str() << endl; return false;}
1549 
1550  // handle the fpga part
1551  string msg = Program(verify);
1552  // handle the SOC part
1553  return ProgramSOC(verify);
1554  }
1555 
1556  bool hasErasedSOCs = false;
1557  uint16_t linearOffsetToBankOffset = 0x0000;
1558  uint16_t basePartitionAddress = linearOffsetToBankOffset;
1559  bool bPartitionValid = true;
1560  uint32_t partitionCount = 0;
1561  while (bPartitionValid)
1562  {
1566 
1567  uint16_t partitionOffset = 0;
1568  FlashBlockID blockID = MAIN_FLASHBLOCK;
1569  ParsePartitionFromFileLines(basePartitionAddress, partitionOffset);
1570  if (basePartitionAddress < 0x0100)
1571  {
1572  blockID = MAIN_FLASHBLOCK;
1573  linearOffsetToBankOffset = 0x0000;
1574  //Program Main
1575  if (!_bQuiet)
1576  cout << "Erase Main Bitfile Bank" << endl;
1580  }
1581  else if (basePartitionAddress >= 0x0100 && basePartitionAddress < 0x0200)
1582  {
1583  blockID = MCS_INFO_BLOCK;
1584  linearOffsetToBankOffset = 0x0100;
1585  //Program Comment
1586  if (!_bQuiet)
1587  cout << "Erase Package Info Block" << endl;
1591  }
1592  else if (basePartitionAddress >= 0x0200 && basePartitionAddress < 0x0400)
1593  {
1594  if (!hasErasedSOCs)
1595  {
1596  if (!_bQuiet)
1597  cout << "Erase SOC Bank 1" << endl;
1600  if (!_bQuiet)
1601  cout << "Erase SOC Bank 2" << endl;
1604  hasErasedSOCs = true;
1605  }
1606  if (basePartitionAddress >= 0x0200 && basePartitionAddress < 0x0300)
1607  {
1608  blockID = SOC1_FLASHBLOCK;
1609  linearOffsetToBankOffset = 0x0200;
1611  }
1612  else
1613  {
1614  blockID = SOC2_FLASHBLOCK;
1615  linearOffsetToBankOffset = 0x0300;
1617  }
1618  }
1619  else
1620  {
1621  break;
1622  }
1623 
1624  uint16_t baseOffset = basePartitionAddress - linearOffsetToBankOffset;
1625  uint32_t programOffset = uint32_t(baseOffset) << 16 | partitionOffset;
1626 
1627  if (_bankSize == 0)
1628  {
1629  bPartitionValid = false;
1630  break;
1631  }
1632 
1633  SetFlashBlockIDBank(blockID);
1634 
1635  uint32_t baseAddress = GetBaseAddressForProgramming(blockID) + programOffset;
1636  if (blockID == MCS_INFO_BLOCK)
1637  baseAddress = _mcsInfoOffset;
1638  uint32_t bufferIndex = 0;
1639  uint32_t blockSize = 512;
1640  uint32_t dwordsPerBlock = blockSize / 4;
1641  uint32_t totalBlockCount ((uint32_t(_partitionBuffer.size()) + blockSize) / blockSize);
1642  uint32_t percentComplete = 0;
1643 
1644  WriteRegister(kVRegFlashSize, totalBlockCount);
1645  for (uint32_t blockCount = 0; blockCount < totalBlockCount; blockCount++)
1646  {
1647  WriteRegister(kVRegFlashStatus,blockCount);
1648  if (baseAddress == 0x01000000 && blockCount > 0 && blockID == SOC1_FLASHBLOCK)
1649  {
1650  blockID = SOC2_FLASHBLOCK;
1651  SetFlashBlockIDBank(blockID);
1652  baseAddress = GetBaseAddressForProgramming(blockID);
1654  }
1655  uint32_t remainderBytes = static_cast<uint32_t>(_partitionBuffer.size() - bufferIndex);
1658 
1659  for (uint32_t dwordCount = 0; dwordCount < dwordsPerBlock; dwordCount++)
1660  {
1661  uint32_t partitionValue = 0xFFFFFFFF;
1662  if (remainderBytes >= 4)
1663  {
1664  partitionValue = uint32_t(_partitionBuffer[bufferIndex + 0]) << 24 |
1665  uint32_t(_partitionBuffer[bufferIndex + 1]) << 16 |
1666  uint32_t(_partitionBuffer[bufferIndex + 2]) << 8 |
1667  uint32_t(_partitionBuffer[bufferIndex + 3]);
1668  bufferIndex += 4;
1669  remainderBytes -= 4;
1670  }
1671  else
1672  {
1673  switch (remainderBytes)
1674  {
1675  case 3:
1676  partitionValue = 0xff;
1677  partitionValue |= uint32_t(_partitionBuffer[bufferIndex + 0]) << 24;
1678  partitionValue |= uint32_t(_partitionBuffer[bufferIndex + 1]) << 16;
1679  partitionValue |= uint32_t(_partitionBuffer[bufferIndex + 2]) << 8;
1680  break;
1681  case 2:
1682  partitionValue = 0xffff;
1683  partitionValue |= uint32_t(_partitionBuffer[bufferIndex + 0]) << 24;
1684  partitionValue |= uint32_t(_partitionBuffer[bufferIndex + 1]) << 16;
1685  break;
1686  case 1:
1687  partitionValue = 0xffffff;
1688  partitionValue |= uint32_t(_partitionBuffer[bufferIndex + 0]) << 24;
1689  break;
1690  default:
1691  break;
1692  }
1693  remainderBytes = 0;
1694  }
1695  partitionValue = NTV2EndianSwap32(partitionValue);
1696  WriteRegister(kRegXenaxFlashDIN, partitionValue);
1697  }
1698  WriteRegister(kRegXenaxFlashAddress, baseAddress);
1700 
1702 
1703  baseAddress += blockSize;
1704 
1705  percentComplete = (blockCount * 100) / totalBlockCount;
1706  if (!_bQuiet)
1707  cout << "Partition " << DEC(partitionCount) << " program status: " << DEC(percentComplete) << "%\r" << flush;
1708  }
1709  if (!_bQuiet)
1710  cout << "Partition " << DEC(partitionCount) << " program status: 100% " << endl;
1711 
1712  if (verify)
1713  {
1714  switch (blockID)
1715  {
1716  default:
1717  case MAIN_FLASHBLOCK:
1719  break;
1720  case SOC1_FLASHBLOCK:
1722  break;
1723  case SOC2_FLASHBLOCK:
1725  break;
1726  case MCS_INFO_BLOCK:
1728  break;
1729  }
1730 
1731  if (!VerifySOCPartition(blockID, programOffset))
1732  {
1734  cerr << "Verify Error" << endl;
1735  return false;
1736  }
1737  }
1738  partitionCount++;
1739 
1740  IntelRecordInfo recordInfo;
1741  _mcsFile.GetCurrentParsedRecord(recordInfo);
1742  if (recordInfo.recordType != IRT_ELAR)
1743  bPartitionValid = false;
1744  else
1745  basePartitionAddress = recordInfo.linearAddress;
1746 
1747  }
1748 
1749  //Protect Device
1755 
1762 
1764  return true;
1765 }
1766 
1767 bool CNTV2KonaFlashProgram::ProgramSOC (const bool verify)
1768 {
1769  if (!_mcsFile.isReady())
1770  {cerr << "MCS bitfile not open" << endl; return false;}
1771 
1772  if (_spiFlash)
1773  {
1774  if (!IsOpen())
1775  {cerr << "Device not open" << endl; return false;}
1776  if (!_mcsFile.isReady())
1777  {cerr << "MCS bitfile not ready" << endl; return false;}
1778 
1779  vector<uint8_t> ubootData;
1780  vector<uint8_t> imageData;
1781  vector<uint8_t> mcsInfoData;
1782  uint16_t ubootPartitionOffset = 0;
1783  uint16_t imagePartitionOffset = 0;
1784  uint16_t mcsInfoPartitionOffset = 0;
1785  _mcsFile.GetPartition(ubootData, 0x0400, ubootPartitionOffset, false);
1786  if (ubootData.empty())
1787  {cerr << "Could not find uboot data in MCS file" << endl; return false;}
1788 
1789  _mcsFile.GetPartition(imageData, 0x0410, imagePartitionOffset, false);
1790  if (imageData.empty())
1791  {cerr << "Could not find kernel data in MCS file" << endl; return false;}
1792 
1793  _mcsFile.GetPartition(mcsInfoData, 0x05F4, mcsInfoPartitionOffset, false);
1794  if (mcsInfoData.empty())
1795  {cerr << "Could not find mcs info in MCS file" << endl; return false;}
1796 
1797  uint32_t ubootFlashOffset = _spiFlash->Offset(SPI_FLASH_SECTION_UBOOT);
1798  uint32_t imageFlashOffset = _spiFlash->Offset(SPI_FLASH_SECTION_KERNEL);
1799  uint32_t mcsFlashOffset = _spiFlash->Offset(SPI_FLASH_SECTION_MCSINFO);
1800 
1801  uint32_t ubootSize = uint32_t(ubootData.size());
1802  uint32_t imageSize = uint32_t(imageData.size());
1803  uint32_t mcsInfoSize = uint32_t(mcsInfoData.size());
1804 
1805  // erase uboot
1806  _spiFlash->Erase(ubootFlashOffset, ubootSize);
1807 
1808  // write uboot
1809  _spiFlash->Write(ubootFlashOffset, ubootData, ubootSize);
1810 
1811  // verify uboot
1812  if (verify)
1813  _spiFlash->Verify(ubootFlashOffset, ubootData);
1814 
1815  // erase image
1816  _spiFlash->Erase(imageFlashOffset, imageSize);
1817 
1818  // write image
1819  _spiFlash->Write(imageFlashOffset, imageData, imageSize);
1820 
1821  // verify image
1822  if (verify)
1823  _spiFlash->Verify(imageFlashOffset, imageData);
1824 
1825  // erase mcs info
1826  _spiFlash->Erase(mcsFlashOffset, mcsInfoSize);
1827 
1828  // write mcs info
1829  _spiFlash->Write(mcsFlashOffset, mcsInfoData, mcsInfoSize);
1830 
1831  // verify mcs info
1832  if (verify)
1833  _spiFlash->Verify(mcsFlashOffset, mcsInfoData);
1834  return true;
1835  } // if _spiFlash
1836 
1837  // Not _spiFlash:
1838  if (!IsOpen())
1839  {cerr << "Device not open" << endl; return false;}
1840  if (!_bQuiet)
1841  cout << "Erase SOC Bank 1" << endl;
1843  if (!_bQuiet)
1844  cout << "Erase SOC Bank 2" << endl;
1846 
1847  //1st partition is assumed to be at 32M mark
1848  //the 32bit address is 0x02000000
1849  //the ELAR address is 0x0200
1850  uint16_t partition32M = 0x0200;
1851  uint16_t basePartitionAddress = partition32M;
1852  bool bPartitionValid = true;
1853  uint32_t partitionCount = 0;
1854  while (bPartitionValid)
1855  {
1856  uint16_t partitionOffset = 0;
1857  ParsePartitionFromFileLines(basePartitionAddress, partitionOffset);
1858  uint16_t baseOffset = basePartitionAddress - partition32M;
1859  uint32_t programOffset = uint32_t(baseOffset) << 16 | partitionOffset;
1860 
1861  FlashBlockID blockID = SOC1_FLASHBLOCK;
1862  if (programOffset >= 0x01000000)
1863  blockID = SOC2_FLASHBLOCK;
1864 
1865  if (_bankSize == 0)
1866  return true;
1867 
1868  SetFlashBlockIDBank(blockID);
1869  uint32_t baseAddress = GetBaseAddressForProgramming(blockID) + programOffset;
1870  uint32_t bufferIndex = 0;
1871  uint32_t blockSize = 512;
1872  uint32_t dwordsPerBlock = blockSize / 4;
1873  uint32_t totalBlockCount = static_cast<uint32_t>((_partitionBuffer.size() + blockSize) / blockSize);
1874  uint32_t percentComplete = 0;
1875  for (uint32_t blockCount = 0; blockCount < totalBlockCount; blockCount++)
1876  {
1877  if (baseAddress == 0x01000000 && blockCount > 0)
1878  {
1880  baseAddress = GetBaseAddressForProgramming(blockID);
1881  }
1882  uint32_t remainderBytes = static_cast<uint32_t>(_partitionBuffer.size() - bufferIndex);
1885 
1886  for (uint32_t dwordCount = 0; dwordCount < dwordsPerBlock; dwordCount++)
1887  {
1888  uint32_t partitionValue = 0xFFFFFFFF;
1889  if (remainderBytes >= 4)
1890  {
1891  partitionValue = uint32_t(_partitionBuffer[bufferIndex + 0]) << 24 |
1892  uint32_t(_partitionBuffer[bufferIndex + 1]) << 16 |
1893  uint32_t(_partitionBuffer[bufferIndex + 2]) << 8 |
1894  uint32_t(_partitionBuffer[bufferIndex + 3]);
1895  bufferIndex += 4;
1896  remainderBytes -= 4;
1897  }
1898  else
1899  {
1900  switch (remainderBytes)
1901  {
1902  case 3:
1903  partitionValue = 0xff;
1904  partitionValue |= uint32_t(_partitionBuffer[bufferIndex + 0]) << 24;
1905  partitionValue |= uint32_t(_partitionBuffer[bufferIndex + 1]) << 16;
1906  partitionValue |= uint32_t(_partitionBuffer[bufferIndex + 2]) << 8;
1907  break;
1908  case 2:
1909  partitionValue = 0xffff;
1910  partitionValue |= uint32_t(_partitionBuffer[bufferIndex + 0]) << 24;
1911  partitionValue |= uint32_t(_partitionBuffer[bufferIndex + 1]) << 16;
1912  break;
1913  case 1:
1914  partitionValue = 0xffffff;
1915  partitionValue |= uint32_t(_partitionBuffer[bufferIndex + 0]) << 24;
1916  break;
1917  default:
1918  break;
1919  }
1920  remainderBytes = 0;
1921  }
1922  partitionValue = NTV2EndianSwap32(partitionValue);
1923  WriteRegister(kRegXenaxFlashDIN, partitionValue);
1924  } // for dwordCount
1925  WriteRegister(kRegXenaxFlashAddress, baseAddress);
1927 
1929 
1930  baseAddress += blockSize;
1931 
1932  percentComplete = (blockCount * 100) / totalBlockCount;
1933  if (!_bQuiet)
1934  cout << "Partition " << DEC(partitionCount+2) << " program status: " << DEC(percentComplete) << "%\r" << flush;
1935  } // for blockCount
1936  if (!_bQuiet)
1937  cout << "Partition " << DEC(partitionCount+2) << " program status: 100% " << endl;
1938 
1939  if (verify && !VerifySOCPartition(blockID, programOffset))
1940  {
1942  cerr << "Verify failed" << endl;
1943  return false;
1944  }
1945 
1946  partitionCount++;
1947  IntelRecordInfo recordInfo;
1948  _mcsFile.GetCurrentParsedRecord(recordInfo);
1949  if (recordInfo.recordType != IRT_ELAR)
1950  bPartitionValid = false;
1951  else
1952  basePartitionAddress = recordInfo.linearAddress;
1953  } // while bPartitionValid
1954 
1955  //Protect Device
1961 
1968  return true;
1969 }
1970 
1971 static bool getFileSize (const string & fileName, size_t & outSizeBytes)
1972 {
1973  outSizeBytes = 0;
1974  ifstream ifs(fileName.c_str(), ios::binary | ios::in);
1975  if (ifs.fail())
1976  return false; // open failed
1977  if (!ifs.seekg (0, ios::end))
1978  return false; // seek failed
1979  ifstream::pos_type curOffset(ifs.tellg());
1980  if (int(curOffset) == -1)
1981  return false;
1982  outSizeBytes = size_t(curOffset);
1983  return true;
1984 }
1985 
1986 bool CNTV2KonaFlashProgram::ProgramCustom (const string &sCustomFileName, const uint32_t addr, ostream & outMsgs)
1987 {
1988  if (!IsOpen())
1989  {outMsgs << "Device not open" << endl; return false;}
1990 
1991  if (_spiFlash)
1992  {
1993  vector<uint8_t> writeData;
1994  size_t sz(0), maxFlashSize(_spiFlash->Size());
1995  // open file and read data
1996  if (!getFileSize(sCustomFileName, sz))
1997  {outMsgs << "getFileSize failed for '" << sCustomFileName << "'" << endl; return false;}
1998  if (sz > maxFlashSize)
1999  {outMsgs << "File size " << DEC(sz) << " exceeds max flash size " << DEC(maxFlashSize) << endl; return false;}
2000 
2001  ifstream ifs(sCustomFileName.c_str(), ios::binary | ios::in);
2002  if (ifs.fail())
2003  {outMsgs << "Unable to open file '" << sCustomFileName << "'" << endl; return false;}
2004 
2005  writeData.resize(sz);
2006  ifs.read(reinterpret_cast<char*>(&writeData[0]), streamsize(sz));
2007  if (!ifs.good())
2008  {outMsgs << "Error reading data from file '" << sCustomFileName << "'" << endl; return false;}
2009 
2010  // erase flash
2011  uint32_t writeSize = uint32_t(writeData.size());
2012  bool eraseGood = _spiFlash->Erase(addr, writeSize);
2013  if (!eraseGood)
2014  {outMsgs << "Error erasing sectors, addr=" << xHEX0N(addr,8) << " length=" << DEC(writeSize) << endl; return false;}
2015 
2016  // write flash
2017  _spiFlash->Write(addr, writeData, writeSize);
2018 
2019  bool result = true, verify = true;
2020  if (verify)
2021  {
2022  result = _spiFlash->Verify(addr, writeData);
2023  }
2024  return result;
2025  } // if _spiFlash
2026  else
2027  {
2028  static const size_t MAX_CUSTOM_FILE_SIZE (8<<20); // 1M
2029  NTV2Buffer customFileBuffer(MAX_CUSTOM_FILE_SIZE);
2030  size_t customSize(0), sz(0);
2031 
2032  uint32_t bank(addr / _bankSize), offset(addr % _bankSize);
2033  if (offset + customSize > _bankSize)
2034  {outMsgs << "Custom write spans banks -- unsupported"; return false;}
2035  if (offset % _sectorSize)
2036  {outMsgs << "Write not on sector boundary -- unsupported"; return false;}
2037  if (!getFileSize(sCustomFileName, sz))
2038  {outMsgs << "Error getting file size for '" << sCustomFileName << "'"; return false;}
2039  if (sz > MAX_CUSTOM_FILE_SIZE)
2040  {outMsgs << "File size " << DEC(sz) << " exceeds max supported size " << DEC(MAX_CUSTOM_FILE_SIZE); return false;}
2041 
2042  ifstream ifs(sCustomFileName.c_str(), ios::binary | ios::in);
2043  if (!ifs.fail())
2044  {outMsgs << "Unable to open file '" << sCustomFileName << "'" << endl; return false;}
2045 
2046  customSize = size_t(ifs.readsome(customFileBuffer, streamsize(customFileBuffer.GetByteCount())));
2047  if (!customSize)
2048  {outMsgs << "No data read from custom file '" << sCustomFileName << "'" << endl; return false;}
2049 
2050  static const BankSelect BankIdxToBankSelect[] = {BANK_0, BANK_1, BANK_2, BANK_3};
2051 
2052  SetBankSelect(BankIdxToBankSelect[bank]);
2058 
2059  const uint32_t customSectors ((uint32_t(customSize) + _sectorSize - 1) / (_sectorSize));
2060  for (uint32_t i(0); i < customSectors; i++)
2061  {
2062  if (!_bQuiet)
2063  cout << "Erasing sectors - " << DECN(i,3) << " of " << DECN(customSectors,3) << "\r" << flush;
2064  EraseSector(offset + (i * _sectorSize));
2065  }
2066 
2069 
2070  uint32_t blockSize (512);
2071  uint32_t dwordsPerBlock (blockSize / 4);
2072  uint32_t totalBlockCount ((uint32_t(customSize) + blockSize - 1) / blockSize);
2073  uint32_t percentComplete (0);
2074  uint32_t baseAddress (offset);
2075  size_t remainderBytes (customSize);
2076  uint32_t bufferIndex (0);
2077  for (uint32_t blockCount(0); blockCount < totalBlockCount; blockCount++)
2078  {
2081 
2082  for (uint32_t dwordCount(0); dwordCount < dwordsPerBlock; dwordCount++)
2083  {
2084  uint32_t partitionValue = 0xFFFFFFFF;
2085  if (remainderBytes >= 4)
2086  {
2087  partitionValue = uint32_t(_customFileBuffer[bufferIndex + 0]) << 24
2088  | uint32_t(_customFileBuffer[bufferIndex + 1]) << 16
2089  | uint32_t(_customFileBuffer[bufferIndex + 2]) << 8
2090  | uint32_t(_customFileBuffer[bufferIndex + 3]);
2091  bufferIndex += 4;
2092  remainderBytes -= 4;
2093  }
2094  else switch (remainderBytes)
2095  {
2096  case 3:
2097  partitionValue = 0xff;
2098  partitionValue |= uint32_t(_customFileBuffer[bufferIndex + 0]) << 24;
2099  partitionValue |= uint32_t(_customFileBuffer[bufferIndex + 1]) << 16;
2100  partitionValue |= uint32_t(_customFileBuffer[bufferIndex + 2]) << 8;
2101  remainderBytes = 0;
2102  break;
2103  case 2:
2104  partitionValue = 0xffff;
2105  partitionValue |= uint32_t(_customFileBuffer[bufferIndex + 0]) << 24;
2106  partitionValue |= uint32_t(_customFileBuffer[bufferIndex + 1]) << 16;
2107  remainderBytes = 0;
2108  break;
2109  case 1:
2110  partitionValue = 0xffffff;
2111  partitionValue |= uint32_t(_customFileBuffer[bufferIndex + 0]) << 24;
2112  remainderBytes = 0;
2113  break;
2114  default:
2115  break;
2116  }
2117  partitionValue = NTV2EndianSwap32(partitionValue);
2118  WriteRegister(kRegXenaxFlashDIN, partitionValue);
2119  } // for each dword
2120  WriteRegister(kRegXenaxFlashAddress, baseAddress);
2123 
2124  baseAddress += blockSize;
2125 
2126  percentComplete = (blockCount * 100) / totalBlockCount;
2127  if (!_bQuiet)
2128  cout << "Program status: " << DEC(percentComplete) << "% (" << DECN(blockCount,4) << " of " << DECN(totalBlockCount,4) << " blocks)\r" << flush;
2129  } // for each block
2130 
2131  //Protect Device
2137 
2144  } // else !_spiFlash
2145  return true;
2146 }
2147 
2148 bool CNTV2KonaFlashProgram::ProgramKonaxMB (const string &sCustomFileName, const uint32_t addr, ostream & outMsgs)
2149 {
2151  {
2152  _spiFlash = new CNTV2AxiSpiFlash(GetIndexNumber(), !_bQuiet);
2153  }
2154  else
2155  return false;
2156 
2157  return ProgramCustom(sCustomFileName, addr, outMsgs);
2158 }
2159 
2161 {
2162  BankSelect bankID = BANK_0;
2163  switch (blockID)
2164  {
2165  case MAIN_FLASHBLOCK:
2166  bankID = BANK_0;
2167  break;
2168  case FAILSAFE_FLASHBLOCK:
2170  break;
2171  case MCS_INFO_BLOCK:
2172  case MAC_FLASHBLOCK:
2173  case LICENSE_BLOCK:
2174  bankID = BANK_1;
2175  break;
2176  case SOC1_FLASHBLOCK:
2177  bankID = BANK_2;
2178  break;
2179  case SOC2_FLASHBLOCK:
2180  bankID = BANK_3;
2181  break;
2182  default:
2183  return false;
2184  }
2185  return SetBankSelect(bankID);
2186 }
2187 
2189 {
2191 }
2192 
2193 void CNTV2KonaFlashProgram::ParsePartitionFromFileLines(uint32_t address, uint16_t & partitionOffset)
2194 {
2195  _partitionBuffer.clear();
2196  _partitionBuffer.resize(0);
2197  bool getnext = false;
2198  if (address != 0x0000 && address != 0x0200)
2199  getnext = true;
2200  _mcsFile.GetPartition(_partitionBuffer, uint16_t(address), partitionOffset, getnext);
2201  _bankSize = uint32_t(_partitionBuffer.size());
2202  return;
2203 }
2204 
2205 bool CNTV2KonaFlashProgram::VerifySOCPartition(FlashBlockID flashID, uint32_t flashBlockOffset)
2206 {
2207  SetFlashBlockIDBank(flashID);
2208 
2209  uint32_t errorCount = 0;
2210  uint32_t baseAddress = flashBlockOffset;
2211 
2212  uint32_t dwordsPerPartition = _bankSize / 4;
2213  uint32_t percentComplete = 0;
2214  uint32_t bufferIndex = 0;
2215  WriteRegister(kVRegFlashSize,dwordsPerPartition);
2216  for (uint32_t dwordCount = 0; dwordCount < dwordsPerPartition; dwordCount += 100)//dwordCount++)
2217  {
2218  WriteRegister(kVRegFlashStatus,dwordCount);
2219  WriteRegister(kRegXenaxFlashAddress, baseAddress);
2222  uint32_t flashValue;
2223  ReadRegister(kRegXenaxFlashDOUT, flashValue);
2224  uint32_t partitionValue = uint32_t(_partitionBuffer[bufferIndex + 0]) << 24
2225  | uint32_t(_partitionBuffer[bufferIndex + 1]) << 16
2226  | uint32_t(_partitionBuffer[bufferIndex + 2]) << 8
2227  | uint32_t(_partitionBuffer[bufferIndex + 3]);
2228  partitionValue = NTV2EndianSwap32(partitionValue);
2229  bufferIndex += 400;//4;
2230  baseAddress += 400;//4;
2231 
2232  if (flashValue != partitionValue)
2233  {
2234  cerr << "Error " << DEC(dwordCount) << " E(" << xHEX0N(partitionValue,8) << "),R(" << xHEX0N(flashValue,8) << ")" << endl;
2235  errorCount++;
2236  if (errorCount > 1)
2237  break;
2238  }
2239 
2240  percentComplete = (dwordCount * 100) / dwordsPerPartition;
2241  if (!_bQuiet)
2242  cout << "Program verify: " << DEC(percentComplete) << "%\r" << flush;
2243  }
2244 
2245  if (errorCount)
2246  {
2247  if (!_bQuiet)
2248  cerr << "Program verify failed: " << DEC(percentComplete) << "%" << endl;
2249  return false;
2250  }
2251  else if (!_bQuiet)
2252  cout << "Program verify: 100% " << endl;
2253  return true;
2254 }
2255 
2256 void CNTV2KonaFlashProgram::DisplayData (const uint32_t address, const uint32_t wordCount)
2257 {
2258  const uint32_t WORDS_PER_LINE(4);
2259  uint32_t addr(address), bank(999), offset(addr % _bankSize);
2260 // SetBankSelect(BankSelect(bank));
2261 
2262  uint32_t lineCount(0);
2263  for (uint32_t words(0); words < wordCount; words++, offset += 4, addr += 4)
2264  {
2265  uint32_t newBank(addr / _bankSize), newOffset(addr % _bankSize);
2266  if (newBank != bank)
2267  {
2268  if (!SetBankSelect(BankSelect(bank = newBank)))
2269  break;
2270  offset = newOffset;
2271  if (words)
2272  cout << endl;
2273  cout << Hex0N(bank * _bankSize + offset,8) << ": ";
2274  }
2278  uint32_t flashValue;
2279  ReadRegister(kRegXenaxFlashDOUT, flashValue);
2280  flashValue = NTV2EndianSwap32(flashValue);
2281  cout << Hex0N(flashValue,8) << " ";
2282  if (++lineCount == WORDS_PER_LINE)
2283  {
2284  cout << endl
2285  << Hex0N((bank * _bankSize + offset + 4),8) << ": ";
2286  lineCount = 0;
2287  }
2288  NTV2_ASSERT((bank * _bankSize + offset) == addr);
2289  } // for each word of requested wordCount
2290  if (lineCount)
2291  cout << endl;
2292 }
2293 
2294 bool CNTV2KonaFlashProgram::FullProgram (vector<uint8_t> & dataBuffer)
2295 {
2296  if (!IsOpen())
2297  return false;
2298  uint32_t baseAddress = 0;
2299  if (!_bQuiet)
2300  cout << "Erasing ROM" << endl;
2301  EraseChip();
2302  BankSelect currentBank = BANK_0;
2303  SetBankSelect(currentBank);
2304 
2305  uint32_t* bitFilePtr = reinterpret_cast<uint32_t*>(dataBuffer.data());
2306  uint32_t twoFixtysixBlockSizeCount = uint32_t((dataBuffer.size()+256)/256);
2307  uint32_t percentComplete = 0;
2309  WriteRegister(kVRegFlashSize, twoFixtysixBlockSizeCount);
2310  for ( uint32_t count = 0; count < twoFixtysixBlockSizeCount; count++, baseAddress += 256, bitFilePtr += 64 )
2311  {
2312  if (baseAddress == _bankSize)
2313  {
2314  baseAddress = 0;
2315  switch(currentBank)
2316  {
2317  case BANK_0: currentBank = BANK_1; break;
2318  case BANK_1: currentBank = BANK_2; break;
2319  case BANK_2: currentBank = BANK_3; break;
2320  case BANK_3: currentBank = BANK_0; break;
2321  }
2322  SetBankSelect(currentBank);
2323  }
2324  FastProgramFlash256(baseAddress, bitFilePtr);
2325  percentComplete = (count*100)/twoFixtysixBlockSizeCount;
2326 
2328  if(!_bQuiet && (count%100 == 0))
2329  cout << "Program status: " << DEC(percentComplete) << "%\r" << flush;
2330  }
2331  if(!_bQuiet)
2332  cout << "Program status: 100% " << endl;
2333 
2334  // Protect Device
2340 
2342 
2350  return true;
2351 }
2352 
2354 {
2355  MacAddr mac1, mac2;
2356  ReadMACAddresses(mac1, mac2);
2357  if(mac1.mac[1] != 0x0C || mac2.mac[1] != 0x0c)
2358  {
2359  if (!_bQuiet)
2360  cout << "Reprogramming the Mac Addresses!" << endl;
2361  string serialString;
2362  GetSerialNumberString(serialString);
2363  MakeMACsFromSerial(serialString.c_str(), &mac1, &mac2);
2364  return ProgramMACAddresses(&mac1, &mac2);
2365  }
2366  return true;
2367 }
2368 
2369 bool CNTV2KonaFlashProgram::MakeMACsFromSerial( const char *sSerialNumber, MacAddr *pMac1, MacAddr *pMac2)
2370 {
2371  // NOTE: We do both auto if either is auto
2372  // TODO: Check if this is an IP board, etc etc
2373  if (strstr(sSerialNumber, "demo") == sSerialNumber)
2374  { // If the serial number begins with demo
2375  int demoNum = 0;
2376  if (sscanf(sSerialNumber + 4, "%d", &demoNum) != 1)
2377  return false;
2378  if ((demoNum < 1) || (demoNum > 128))
2379  {cerr << "WARNING: Outside serial numbers demo0001 to demo0128" << endl; return false;}
2380  pMac2->mac[0] = pMac1->mac[0] = 0x0;
2381  pMac2->mac[1] = pMac1->mac[1] = 0x0c;
2382  pMac2->mac[2] = pMac1->mac[2] = 0x17;
2383  pMac2->mac[3] = pMac1->mac[3] = 0x88;
2384  pMac2->mac[4] = pMac1->mac[4] = 0x12;
2385  pMac1->mac[5] = uint8_t((demoNum - 1) * 2);
2386  pMac2->mac[5] = pMac1->mac[5] + 1;
2387  return true;
2388  }
2389  else if (strstr(sSerialNumber, "1IP") == sSerialNumber)
2390  { // If the serial number begins with 1IP
2391  // 00050 to 08241 (qty 8192) maps to A000 to DFFF (16384 addresses)
2392  // First 4 bytes are: 00:0c:17:42 and next 2 bytes are computed
2393  // as mac1=((serNo - 50)*2 + 0xA000) and
2394  // mac2 = mac1 + 1
2395  int serNum = 0;
2396  if (sscanf(sSerialNumber + 4, "%d", &serNum) != 1)
2397  return false;
2398  if ((serNum < 50) || (serNum > 8241))
2399  {cerr << "WARNING: Outside serial numbers 1IP00050 to 1IP08241" << endl; return false;}
2400 
2401  int mac16LSBs = (0xA000) + (serNum - 50) * 2;
2402 
2403  pMac2->mac[0] = pMac1->mac[0] = 0x0;
2404  pMac2->mac[1] = pMac1->mac[1] = 0x0c;
2405  pMac2->mac[2] = pMac1->mac[2] = 0x17;
2406  pMac2->mac[3] = pMac1->mac[3] = 0x42;
2407  pMac2->mac[4] = pMac1->mac[4] = uint8_t(mac16LSBs >> 8);
2408  pMac2->mac[5] = pMac1->mac[5] = mac16LSBs & 0x0ff;
2409  // The above byte will always be same for the second mac
2410  // based on above allocation
2411  pMac2->mac[5] = pMac1->mac[5] + 1;
2412  return true;
2413  }
2414  else if (strstr(sSerialNumber, "ENG") == sSerialNumber)
2415  { // ENG IoIp - if the serial starts with ENG
2416  // 0000 to 0127 (qty 128) maps to 1B00 to 1BFF (256 addresses)
2417  // First 4 bytes are: 00:0c:17:88 and next 2 bytes are computed
2418  // as mac1= (0x1B00) + (serNum * 2) and
2419  // mac2 = mac1 + 1
2420  int serNum = 0;
2421  if (sscanf(sSerialNumber + 5, "%d", &serNum) != 1)
2422  return false;
2423 
2424  if (serNum > 127)
2425  {cerr << "WARNING: Outside serial numbers ENG00000 to ENG00127" << endl; return false;}
2426 
2427  int mac16LSBs = (0x1B00) + (serNum * 2);
2428 
2429  pMac2->mac[0] = pMac1->mac[0] = 0x0;
2430  pMac2->mac[1] = pMac1->mac[1] = 0x0c;
2431  pMac2->mac[2] = pMac1->mac[2] = 0x17;
2432  pMac2->mac[3] = pMac1->mac[3] = 0x88;
2433  pMac2->mac[4] = pMac1->mac[4] = uint8_t(mac16LSBs >> 8);
2434  pMac2->mac[5] = pMac1->mac[5] = mac16LSBs & 0xff;
2435  // The above byte will always be same for the second mac
2436  // based on above allocation
2437  pMac2->mac[5] = pMac1->mac[5] + 1;
2438  return true;
2439  }
2440  else if (strstr(sSerialNumber, "6XT") == sSerialNumber)
2441  { // IoIP and DNxIP serial numbers
2442  // IoIP Gen 1 [6XT000250 - 6XT008441]
2443  // DNxIP Gen 1 [6XT200250 - 6XT208441]
2444  // IoIP Gen 2 [6XT100250 - 6XT108441]
2445  // DNxIP Gen 2 [6XT300250 - 6XT308441]
2446 
2447  int serNum = 0;
2448  if (sscanf(sSerialNumber + 4, "%d", &serNum) != 1)
2449  return false;
2450 
2451  if ((serNum < 250) || (serNum > 8441))
2452  {cerr << "WARNING: Outside serial numbers range 250 to 8441" << endl; return false;}
2453 
2454  // 0250 to 8441 (qty 8192) maps to 16384 addresses
2455  // First 3 bytes are: 00:0c:17 and next 3 bytes are computed
2456  int mac24LSBs = -1;
2457  if (strstr(sSerialNumber, "6XT0") == sSerialNumber)
2458  {
2459  mac24LSBs = (0x48A000) + ((serNum - 250) * 2);
2460  }
2461  else if (strstr(sSerialNumber, "6XT2") == sSerialNumber)
2462  {
2463  mac24LSBs = (0x48E000) + ((serNum - 250) * 2);
2464  }
2465  else if (strstr(sSerialNumber, "6XT1") == sSerialNumber)
2466  {
2467  mac24LSBs = (0x4B2000) + ((serNum - 250) * 2);
2468  }
2469  else if (strstr(sSerialNumber, "6XT3") == sSerialNumber)
2470  {
2471  mac24LSBs = (0x4B6000) + ((serNum - 250) * 2);
2472  }
2473  else
2474  {
2475  return false;
2476  }
2477 
2478  pMac2->mac[0] = pMac1->mac[0] = 0x0;
2479  pMac2->mac[1] = pMac1->mac[1] = 0x0c;
2480  pMac2->mac[2] = pMac1->mac[2] = 0x17;
2481  pMac2->mac[3] = pMac1->mac[3] = (mac24LSBs & 0xFF0000) >> 16;
2482  pMac2->mac[4] = pMac1->mac[4] = (mac24LSBs & 0x00FF00) >> 8;
2483  pMac2->mac[5] = pMac1->mac[5] = (mac24LSBs & 0x0000FF) >> 0;
2484  // The above byte will always be same for the second mac
2485  // based on above allocation
2486  pMac2->mac[5] = pMac1->mac[5] + 1;
2487  return true;
2488  }
2489  else
2490  cerr << "Unrecognized or unspecified serial number '" << sSerialNumber << "'" << endl;
2491  return false;
2492 }
2493 
2494 
2495 
2496 #ifdef MSWindows
2497 #pragma warning(default: 4800)
2498 #endif
CNTV2KonaFlashProgram::WriteCommand
bool WriteCommand(_FLASH_COMMAND inCommand)
Definition: ntv2konaflashprogram.cpp:131
CNTV2KonaFlashProgram::_numSectorsMain
uint32_t _numSectorsMain
Definition: ntv2konaflashprogram.h:168
nlohmann::json_abiNLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON_v3_11_NLOHMANN_JSON_VERSION_PATCH::detail2::end
end_tag end(T &&...)
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:1407
BANK_0
@ BANK_0
Definition: ntv2enums.h:4240
kProgramStateEraseBank4
@ kProgramStateEraseBank4
Definition: ntv2publicinterface.h:4871
DEVICE_ID_KONAIP_2110
@ DEVICE_ID_KONAIP_2110
See KONA IP.
Definition: ntv2enums.h:70
kRegBoardID
@ kRegBoardID
Definition: ntv2publicinterface.h:153
BANK_2
@ BANK_2
Definition: ntv2enums.h:4242
BANKSELECT_COMMAND
@ BANKSELECT_COMMAND
Definition: ntv2enums.h:4256
CNTV2Card::SetWarmBootFirmwareReload
virtual bool SetWarmBootFirmwareReload(bool enable)
Definition: ntv2register.cpp:4546
BANK_1
@ BANK_1
Definition: ntv2enums.h:4241
DEVICE_IS_IOIP
#define DEVICE_IS_IOIP(__d__)
Definition: ntv2enums.h:133
CNTV2KonaFlashProgram::ProgramMACAddresses
bool ProgramMACAddresses(MacAddr *mac1, MacAddr *mac2)
Definition: ntv2konaflashprogram.cpp:1155
CNTV2KonaFlashProgram::SetMBReset
bool SetMBReset()
Definition: ntv2konaflashprogram.cpp:140
kRegFS1I2C1Data
@ kRegFS1I2C1Data
Definition: ntv2publicinterface.h:198
FAILSAFE_FLASHBLOCK
@ FAILSAFE_FLASHBLOCK
Definition: ntv2enums.h:4229
READID_COMMAND
@ READID_COMMAND
Definition: ntv2enums.h:4247
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:389
CNTV2KonaFlashProgram::GetNumberOfSectors
uint32_t GetNumberOfSectors(FlashBlockID flashBlockNumber)
Definition: ntv2konaflashprogram.h:131
MCS_INFO_BLOCK
@ MCS_INFO_BLOCK
Definition: ntv2enums.h:4234
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:6022
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:155
NTV2Buffer::GetByteCount
ULWord GetByteCount(void) const
Definition: ntv2publicinterface.h:6096
NTV2_ASSERT
#define NTV2_ASSERT(_expr_)
Definition: ajatypes.h:508
CNTV2KonaFlashProgram::Program
std::string Program(bool fullVerify=(0))
Definition: ntv2konaflashprogram.cpp:538
_FLASH_COMMAND
_FLASH_COMMAND
Definition: ntv2enums.h:4246
EXTENDEDADDRESS_COMMAND
@ EXTENDEDADDRESS_COMMAND
Definition: ntv2enums.h:4258
SOC1_FLASHBLOCK
@ SOC1_FLASHBLOCK
Definition: ntv2enums.h:4231
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:161
kProgramStateEraseMainFlashBlock
@ kProgramStateEraseMainFlashBlock
Definition: ntv2publicinterface.h:4862
CNTV2KonaFlashProgram::EraseChip
bool EraseChip(UWord chip=0)
Definition: ntv2konaflashprogram.cpp:703
CNTV2KonaFlashProgram::_parser
NTV2BitfileHeaderParser _parser
Definition: ntv2konaflashprogram.h:154
systemtime.h
Declares the AJATime class.
getFileSize
static bool getFileSize(const string &fileName, size_t &outSizeBytes)
Definition: ntv2konaflashprogram.cpp:1971
CNTV2KonaFlashProgram::_partitionBuffer
std::vector< uint8_t > _partitionBuffer
Definition: ntv2konaflashprogram.h:178
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:1681
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:6552
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:158
READEXTENDEDADDRESS_COMMAND
@ READEXTENDEDADDRESS_COMMAND
Definition: ntv2enums.h:4259
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:2314
CNTV2KonaFlashProgram::ReadHeader
bool ReadHeader(FlashBlockID flashBlock)
Definition: ntv2konaflashprogram.cpp:474
CNTV2KonaFlashProgram::ProgramFlashValue
bool ProgramFlashValue(uint32_t address, uint32_t value)
Definition: ntv2konaflashprogram.cpp:607
CNTV2KonaFlashProgram::FullProgram
bool FullProgram(std::vector< uint8_t > &dataBuffer)
Definition: ntv2konaflashprogram.cpp:2294
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:1647
SECTORERASE_COMMAND
@ SECTORERASE_COMMAND
Definition: ntv2enums.h:4254
PAGEPROGRAM_COMMAND
@ PAGEPROGRAM_COMMAND
Definition: ntv2enums.h:4253
CNTV2KonaFlashProgram::CheckFlashErasedWithBlockID
bool CheckFlashErasedWithBlockID(FlashBlockID flashBlockNumber)
Definition: ntv2konaflashprogram.cpp:866
CNTV2KonaFlashProgram::ParsePartitionFromFileLines
void ParsePartitionFromFileLines(uint32_t address, uint16_t &partitionOffset)
Definition: ntv2konaflashprogram.cpp:2193
CNTV2KonaFlashProgram::EraseBlock
bool EraseBlock(FlashBlockID blockNumber)
Definition: ntv2konaflashprogram.cpp:646
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:4233
nlohmann::json_abiNLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON_v3_11_NLOHMANN_JSON_VERSION_PATCH::detail::void
j template void())
Definition: json.hpp:4893
CNTV2DriverInterface::_boardID
NTV2DeviceID _boardID
My cached device ID.
Definition: ntv2driverinterface.h:679
CNTV2KonaFlashProgram::_customFileBuffer
uint8_t * _customFileBuffer
Definition: ntv2konaflashprogram.h:152
CNTV2KonaFlashProgram::_numSectorsSOC2
uint32_t _numSectorsSOC2
Definition: ntv2konaflashprogram.h:170
DEVICE_IS_KONAX
#define DEVICE_IS_KONAX(__d__)
Definition: ntv2enums.h:138
CNTV2KonaFlashProgram::_soc2Offset
uint32_t _soc2Offset
Definition: ntv2konaflashprogram.h:167
CNTV2KonaFlashProgram::_bQuiet
bool _bQuiet
Definition: ntv2konaflashprogram.h:175
AUTO_FLASHBLOCK
@ AUTO_FLASHBLOCK
Definition: ntv2enums.h:4230
CNTV2KonaFlashProgram::_failSafeOffset
uint32_t _failSafeOffset
Definition: ntv2konaflashprogram.h:162
CNTV2KonaFlashProgram::FastProgramFlash256
bool FastProgramFlash256(uint32_t address, uint32_t *buffer)
Definition: ntv2konaflashprogram.cpp:619
kVRegFlashSize
@ kVRegFlashSize
Definition: ntv2virtualregisters.h:300
ntv2registersmb.h
Defines the KonaIP/IoIP registers.
BIT_16
#define BIT_16
Definition: ajatypes.h:588
CNTV2KonaFlashProgram::_numSectorsFailSafe
uint32_t _numSectorsFailSafe
Definition: ntv2konaflashprogram.h:171
kProgramStateProgramBank3
@ kProgramStateProgramBank3
Definition: ntv2publicinterface.h:4869
CNTV2KonaFlashProgram::ProgramSOC
bool ProgramSOC(bool verify=(!(0)))
Definition: ntv2konaflashprogram.cpp:1767
kProgramStateProgramFlash
@ kProgramStateProgramFlash
Definition: ntv2publicinterface.h:4865
CNTV2KonaFlashProgram::ProgramFromMCS
bool ProgramFromMCS(bool verify)
Definition: ntv2konaflashprogram.cpp:1520
CNTV2SpiFlash::Verify
virtual bool Verify(const uint32_t address, const std::vector< uint8_t > &dataWritten)=0
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:169
FlashBlockID
FlashBlockID
Definition: ntv2enums.h:4226
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:2148
MAIN_FLASHBLOCK
@ MAIN_FLASHBLOCK
Definition: ntv2enums.h:4228
CNTV2KonaFlashProgram::ProgramCustom
bool ProgramCustom(const std::string &sCustomFileName, const uint32_t addr, std::ostream &outMsgs)
Definition: ntv2konaflashprogram.cpp:1986
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:901
CNTV2KonaFlashProgram::CheckAndFixMACs
bool CheckAndFixMACs()
Definition: ntv2konaflashprogram.cpp:2353
CNTV2KonaFlashProgram::SetDeviceProperties
bool SetDeviceProperties()
Definition: ntv2konaflashprogram.cpp:223
CNTV2KonaFlashProgram::ReadBankSelect
uint32_t ReadBankSelect()
Definition: ntv2konaflashprogram.cpp:1501
CNTV2SpiFlash::Offset
virtual uint32_t Offset(SpiFlashSection sectionID=SPI_FLASH_SECTION_TOTAL)=0
ULWord
uint32_t ULWord
Definition: ajatypes.h:255
MCS_STEPS
#define MCS_STEPS
Definition: ntv2konaflashprogram.h:27
NTV2DeviceCanReportRunningFirmwareDate
bool NTV2DeviceCanReportRunningFirmwareDate(const NTV2DeviceID inDeviceID)
Definition: ntv2devicefeatures.hpp:6228
kRegXenaxFlashControlStatus
@ kRegXenaxFlashControlStatus
Definition: ntv2publicinterface.h:161
kProgramStateErasePackageInfo
@ kProgramStateErasePackageInfo
Definition: ntv2publicinterface.h:4874
CNTV2KonaFlashProgram::ReadFlash
bool ReadFlash(NTV2Buffer &outBuffer, const FlashBlockID flashID, CNTV2FlashProgress &inFlashProgress=CNTV2FlashProgress::nullUpdater)
Definition: ntv2konaflashprogram.cpp:776
CNTV2KonaFlashProgram::ReadMACAddresses
bool ReadMACAddresses(MacAddr &mac1, MacAddr &mac2)
Definition: ntv2konaflashprogram.cpp:1249
CNTV2KonaFlashProgram::FlashBlockIDToString
static std::string FlashBlockIDToString(const FlashBlockID inID, const bool inShortDisplay=(0))
Definition: ntv2konaflashprogram.cpp:44
CNTV2KonaFlashProgram::_bitFileBuffer
NTV2Buffer _bitFileBuffer
Definition: ntv2konaflashprogram.h:151
CNTV2KonaFlashProgram::MakeMACsFromSerial
bool MakeMACsFromSerial(const char *sSerialNumber, MacAddr *pMac1, MacAddr *pMac2)
Definition: ntv2konaflashprogram.cpp:2369
NTV2EndianSwap32
#define NTV2EndianSwap32(__val__)
Definition: ntv2endian.h:19
CNTV2KonaFlashProgram::_failSafePadding
uint32_t _failSafePadding
Definition: ntv2konaflashprogram.h:179
CNTV2KonaFlashProgram::_mcsFile
CNTV2MCSfile _mcsFile
Definition: ntv2konaflashprogram.h:177
CNTV2KonaFlashProgram::_mcsInfoOffset
uint32_t _mcsInfoOffset
Definition: ntv2konaflashprogram.h:164
NTV2Buffer::IsAllocatedBySDK
bool IsAllocatedBySDK(void) const
Definition: ntv2publicinterface.h:6102
kRegXenaxFlashDIN
@ kRegXenaxFlashDIN
Definition: ntv2publicinterface.h:163
kProgramStateEraseFailSafeFlashBlock
@ kProgramStateEraseFailSafeFlashBlock
Definition: ntv2publicinterface.h:4864
READFAST_COMMAND
@ READFAST_COMMAND
Definition: ntv2enums.h:4252
kRegSarekControl
#define kRegSarekControl
Definition: ntv2registersmb.h:73
CNTV2KonaFlashProgram::_flashID
FlashBlockID _flashID
Definition: ntv2konaflashprogram.h:173
CNTV2KonaFlashProgram::DetermineFlashTypeAndBlockNumberFromFileName
void DetermineFlashTypeAndBlockNumberFromFileName(const std::string &bitFileName)
Definition: ntv2konaflashprogram.cpp:467
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:214
CNTV2KonaFlashProgram::ReadDeviceID
uint32_t ReadDeviceID()
Definition: ntv2konaflashprogram.cpp:634
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:253
kProgramStateProgramPackageInfo
@ kProgramStateProgramPackageInfo
Definition: ntv2publicinterface.h:4875
kProgramStateVerifyFlash
@ kProgramStateVerifyFlash
Definition: ntv2publicinterface.h:4866
SOC2_FLASHBLOCK
@ SOC2_FLASHBLOCK
Definition: ntv2enums.h:4232
CNTV2KonaFlashProgram::_macOffset
uint32_t _macOffset
Definition: ntv2konaflashprogram.h:163
kRegXenaxFlashAddress
@ kRegXenaxFlashAddress
Definition: ntv2publicinterface.h:162
LICENSE_BLOCK
@ LICENSE_BLOCK
Definition: ntv2enums.h:4235
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:4876
NTV2_UNUSED
#define NTV2_UNUSED(__p__)
Definition: ajatypes.h:164
NTV2DeviceROMHasBankSelect
bool NTV2DeviceROMHasBankSelect(const NTV2DeviceID inDeviceID)
Definition: ntv2devicefeatures.cpp:1149
CNTV2Card
I interrogate and control an AJA video/audio capture/playout device.
Definition: ntv2card.h:28
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:164
CNTV2KonaFlashProgram::GetBaseAddressForProgramming
uint32_t GetBaseAddressForProgramming(FlashBlockID flashBlockNumber)
Definition: ntv2konaflashprogram.h:115
MAXBITFILE_HEADERSIZE
#define MAXBITFILE_HEADERSIZE
Definition: ntv2konaflashprogram.h:24
CNTV2KonaFlashProgram::CreateEDIDIntelRecord
bool CreateEDIDIntelRecord()
Definition: ntv2konaflashprogram.cpp:1089
SPI_FLASH_SECTION_MCSINFO
@ SPI_FLASH_SECTION_MCSINFO
Definition: ntv2spiinterface.h:17
kProgramStateVerifyBank3
@ kProgramStateVerifyBank3
Definition: ntv2publicinterface.h:4870
CNTV2KonaFlashProgram::CNTV2KonaFlashProgram
CNTV2KonaFlashProgram()
Definition: ntv2konaflashprogram.cpp:61
AJA_NULL
#define AJA_NULL
Definition: ajatypes.h:199
gNullUpdater
static CNTV2FlashProgress gNullUpdater
Definition: ntv2konaflashprogram.cpp:40
NTV2Buffer::GetHostPointer
void * GetHostPointer(void) const
Definition: ntv2publicinterface.h:6079
CNTV2KonaFlashProgram::ReadInfoString
bool ReadInfoString()
Definition: ntv2konaflashprogram.cpp:491
CNTV2KonaFlashProgram::_deviceID
uint32_t _deviceID
Definition: ntv2konaflashprogram.h:174
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:5606
false
#define false
Definition: ntv2devicefeatures.h:25
common.h
Private include file for all ajabase sources.
UByte
uint8_t UByte
Definition: ajatypes.h:250
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:165
HEX0N
#define HEX0N(__x__, __n__)
Definition: debug.cpp:1175
kRegFS1I2C1Address
@ kRegFS1I2C1Address
Definition: ntv2publicinterface.h:197
ntv2konaflashprogram.h
Declares the CNTV2KonaFlashProgram class.
WRITEENABLE_COMMAND
@ WRITEENABLE_COMMAND
Definition: ntv2enums.h:4248
BANK_3
@ BANK_3
Definition: ntv2enums.h:4243
CNTV2KonaFlashProgram::_spiFlash
CNTV2SpiFlash * _spiFlash
Definition: ntv2konaflashprogram.h:180
IRT_ELAR
@ IRT_ELAR
Definition: ntv2mcsfile.h:26
kProgramStateProgramBank4
@ kProgramStateProgramBank4
Definition: ntv2publicinterface.h:4872
CNTV2AxiSpiFlash
Definition: ntv2spiinterface.h:45
std
Definition: json.hpp:5362
SPI_FLASH_SECTION_MAC
@ SPI_FLASH_SECTION_MAC
Definition: ntv2spiinterface.h:18
CNTV2KonaFlashProgram::DisplayData
void DisplayData(const uint32_t address, const uint32_t len)
Definition: ntv2konaflashprogram.cpp:2256
CNTV2KonaFlashProgram::VerifySOCPartition
bool VerifySOCPartition(FlashBlockID flashID, uint32_t FlashBlockOffset)
Definition: ntv2konaflashprogram.cpp:2205
Hex0N
#define Hex0N(__x__, __n__)
Definition: ntv2publicinterface.h:5598
CNTV2KonaFlashProgram::_bitFileSize
uint32_t _bitFileSize
Definition: ntv2konaflashprogram.h:153
CNTV2KonaFlashProgram::NextMcsStep
int32_t NextMcsStep()
Definition: ntv2konaflashprogram.h:99
kProgramStateVerifyBank4
@ kProgramStateVerifyBank4
Definition: ntv2publicinterface.h:4873
CNTV2MCSfile::isReady
virtual bool isReady(void) const
Definition: ntv2mcsfile.cpp:51
CHIPERASE_COMMAND
@ CHIPERASE_COMMAND
Definition: ntv2enums.h:4255
CNTV2KonaFlashProgram::_flashSize
uint32_t _flashSize
Definition: ntv2konaflashprogram.h:158
CNTV2DriverInterface::GetDeviceID
virtual NTV2DeviceID GetDeviceID(void)
Definition: ntv2driverinterface.cpp:407
READBANKSELECT_COMMAND
@ READBANKSELECT_COMMAND
Definition: ntv2enums.h:4257
CNTV2KonaFlashProgram::_mcsInfo
std::string _mcsInfo
Definition: ntv2konaflashprogram.h:156
CNTV2KonaFlashProgram::SetMCSFile
bool SetMCSFile(const std::string &sMCSFileName)
Definition: ntv2konaflashprogram.cpp:1513
CNTV2KonaFlashProgram::SetBankSelect
bool SetBankSelect(BankSelect bankNumber)
Definition: ntv2konaflashprogram.cpp:1484
WRITESTATUS_COMMAND
@ WRITESTATUS_COMMAND
Definition: ntv2enums.h:4251
CNTV2KonaFlashProgram::EraseSector
bool EraseSector(uint32_t sectorAddress)
Definition: ntv2konaflashprogram.cpp:694
CNTV2KonaFlashProgram::SetFlashBlockIDBank
bool SetFlashBlockIDBank(FlashBlockID blockID)
Definition: ntv2konaflashprogram.cpp:2160
NTV2Buffer::Fill
bool Fill(const T &inValue)
Fills me with the given scalar value.
Definition: ntv2publicinterface.h:6248
CNTV2KonaFlashProgram::CreateBankRecord
bool CreateBankRecord(BankSelect bankID)
Definition: ntv2konaflashprogram.cpp:1001
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:181
BIT
#define BIT(_x_)
Definition: ajatypes.h:563
xHEX0N
#define xHEX0N(__x__, __n__)
Definition: ntv2publicinterface.h:5605
DEVICE_ID_IOIP_2110_RGB12
@ DEVICE_ID_IOIP_2110_RGB12
See Io IP.
Definition: ntv2enums.h:40
CNTV2KonaFlashProgram::SetBoard
virtual bool SetBoard(uint32_t index=0)
Definition: ntv2konaflashprogram.cpp:208
CNTV2KonaFlashProgram::SetBitFile
bool SetBitFile(const std::string &inBitfileName, std::ostream &outMsgs, const FlashBlockID blockNumber=AUTO_FLASHBLOCK)
Definition: ntv2konaflashprogram.cpp:428
CNTV2KonaFlashProgram::WaitForFlashNOTBusy
bool WaitForFlashNOTBusy()
Definition: ntv2konaflashprogram.cpp:842
CNTV2KonaFlashProgram::ROMHasBankSelect
bool ROMHasBankSelect()
Definition: ntv2konaflashprogram.cpp:2188
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:430
CNTV2KonaFlashProgram::_sectorSize
uint32_t _sectorSize
Definition: ntv2konaflashprogram.h:160
CNTV2KonaFlashProgram::SetQuietMode
void SetQuietMode()
Definition: ntv2konaflashprogram.cpp:124
CNTV2KonaFlashProgram::ProgramLicenseInfo
bool ProgramLicenseInfo(const std::string &licenseString)
Definition: ntv2konaflashprogram.cpp:1343
CNTV2KonaFlashProgram::_bankSize
uint32_t _bankSize
Definition: ntv2konaflashprogram.h:159
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:4238
CNTV2KonaFlashProgram::_soc1Offset
uint32_t _soc1Offset
Definition: ntv2konaflashprogram.h:166
kProgramStateCalculating
@ kProgramStateCalculating
Definition: ntv2publicinterface.h:4877
kProgramStateEraseBank3
@ kProgramStateEraseBank3
Definition: ntv2publicinterface.h:4868
CNTV2KonaFlashProgram::VerifyFlash
bool VerifyFlash(FlashBlockID flashBlockNumber, bool fullVerify=(0))
Definition: ntv2konaflashprogram.cpp:717
NTV2DeviceGetSPIFlashVersion
UWord NTV2DeviceGetSPIFlashVersion(const NTV2DeviceID inDeviceID)
Definition: ntv2devicefeatures.hpp:12473
DECN
#define DECN(__x__, __n__)
Definition: ntv2publicinterface.h:5607
kRegGlobalControl
@ kRegGlobalControl
Definition: ntv2publicinterface.h:102
SPI_FLASH_SECTION_KERNEL
@ SPI_FLASH_SECTION_KERNEL
Definition: ntv2spiinterface.h:15