AJA NTV2 SDK  18.1.0.2439
NTV2 SDK 18.1.0.2439
ntv2dynamicdevice.cpp
Go to the documentation of this file.
1 /* SPDX-License-Identifier: MIT */
8 #include "ntv2card.h"
9 #include "ntv2devicefeatures.h"
10 #include "ntv2utils.h"
11 #include "ntv2bitfile.h"
12 #include "ntv2bitfilemanager.h"
13 #include "ajabase/system/debug.h"
14 
15 using namespace std;
16 
17 #define DDFAIL(__x__) AJA_sERROR (AJA_DebugUnit_Firmware, AJAFUNC << ": " << __x__)
18 #define DDWARN(__x__) AJA_sWARNING(AJA_DebugUnit_Firmware, AJAFUNC << ": " << __x__)
19 #define DDNOTE(__x__) AJA_sNOTICE (AJA_DebugUnit_Firmware, AJAFUNC << ": " << __x__)
20 #define DDINFO(__x__) AJA_sINFO (AJA_DebugUnit_Firmware, AJAFUNC << ": " << __x__)
21 #define DDDBG(__x__) AJA_sDEBUG (AJA_DebugUnit_Firmware, AJAFUNC << ": " << __x__)
22 
23 
25 
26 
28 {
29  NTV2ULWordVector reg;
30  if (!IsOpen())
31  return false; // device not open
32  if (!IsSupported(kDeviceCanDoFastBitfileSwitching))
33  return false; // doesn't support MCAP
34  if (!BitstreamStatus(reg))
35  return false; // can't get bitstream status
36  if (!reg[BITSTREAM_VERSION])
37  return false; // Bitstream version is zero
38  return true;
39 }
40 
42 {
43  if (!IsDynamicDevice())
44  return false;
45 
46  ULWord counts(0);
47  ReadRegister(kVRegDynFirmwareUpdateCounts, counts);
48  const ULWord successes(counts & 0x0000FFFF);
49  if (!successes)
50  return false;
51  // At least 1 successful dynamic firmware load/update done
52  return true;
53 }
54 
56 {
57  if (!IsDynamicDevice())
58  return DEVICE_ID_INVALID;
59 
60  ULWord value(0);
61  if (!ReadRegister(kVRegBaseFirmwareDeviceID, value))
62  return DEVICE_ID_INVALID;
63  return NTV2DeviceID(value);
64 }
65 
67 {
68  NTV2DeviceIDList result;
69  if (!IsSupported(kDeviceCanDoFastBitfileSwitching))
70  return result;
71  const NTV2DeviceIDSet devs(GetDynamicDeviceIDs());
72  for (NTV2DeviceIDSetConstIter it(devs.begin()); it != devs.end(); ++it)
73  result.push_back(*it);
74  return result;
75 }
76 
78 {
79  NTV2DeviceIDSet result;
80  if (!IsOpen())
81  return result;
82  if (!IsSupported(kDeviceCanDoFastBitfileSwitching))
83  return result;
84 
85  const NTV2DeviceID currentDeviceID (GetDeviceID());
86  if (currentDeviceID == 0)
87  return result;
88 
89  // Get current design ID and version...
90  NTV2ULWordVector reg;
91  if (!BitstreamStatus(reg))
92  return result;
93 
94  if (reg[BITSTREAM_VERSION] == 0)
95  return result;
96 
97  ULWord currentUserID(0), currentDesignID(0), currentDesignVersion(0), currentBitfileID(0), currentBitfileVersion(0);
98 
99  if (GetRunningFirmwareUserID(currentUserID) && currentUserID)
100  { // The new way
101  currentDesignID = NTV2BitfileHeaderParser::GetDesignID(currentUserID);
102  currentDesignVersion = NTV2BitfileHeaderParser::GetDesignVersion(currentUserID);
103  currentBitfileID = NTV2BitfileHeaderParser::GetBitfileID(currentUserID);
104  currentBitfileVersion = NTV2BitfileHeaderParser::GetBitfileVersion(currentUserID);
105  }
106  else
107  { // The old way
110  currentBitfileID = CNTV2Bitfile::ConvertToBitfileID(currentDeviceID);
111  currentBitfileVersion = 0xff; // ignores bitfile version
112  }
113 
114  if (!currentDesignID)
115  return result;
116 
117  // Get the clear file matching current bitfile...
118  NTV2Buffer clearStream;
119  if (!s_BitfileManager.GetBitStream (clearStream,
120  currentDesignID,
121  currentDesignVersion,
122  currentBitfileID,
123  currentBitfileVersion,
124  NTV2_BITFILE_FLAG_CLEAR) || !clearStream)
125  return result;
126 
127  // Build the deviceID set...
129  for (NTV2BitfileInfoListConstIter it(infoList.begin()); it != infoList.end(); ++it)
130  if (it->designID == currentDesignID)
131  if (it->designVersion == currentDesignVersion)
132  if (it->bitfileFlags & NTV2_BITFILE_FLAG_PARTIAL)
133  {
134  const NTV2DeviceID devID (CNTV2Bitfile::ConvertToDeviceID(it->designID, it->bitfileID));
135  if (result.find(devID) == result.end())
136  result.insert(devID);
137  }
138  return result;
139 }
140 
142 {
143  if (!IsSupported(kDeviceCanDoFastBitfileSwitching))
144  return false;
145  const NTV2DeviceIDSet devices(GetDynamicDeviceIDs());
146  return devices.find(inDeviceID) != devices.end();
147 }
148 
150 {
151  if (!IsOpen())
152  {DDFAIL("Device not open"); return false;}
153  if (!IsSupported(kDeviceCanDoFastBitfileSwitching))
154  {DDFAIL("Fast bitfile switching unsupported"); return false;}
155 
156  const NTV2DeviceID currentDeviceID (GetDeviceID());
157  if (!currentDeviceID)
158  {DDFAIL("Current device ID is zero"); return false;}
159 
160  const string oldDevName (GetDisplayName());
161 
162  // Get current design ID and version...
163  NTV2ULWordVector regs;
164  if (!BitstreamStatus(regs))
165  {DDFAIL("Unable to read current bitstream status for " << oldDevName); return false;}
166 
167  if (!regs[BITSTREAM_VERSION])
168  {DDFAIL("Bitstream version is zero for " << oldDevName); return false;}
169 
170  ULWord currentUserID(0), currentDesignID(0), currentDesignVersion(0), currentBitfileID(0), currentBitfileVersion(0);
171 
172  if (GetRunningFirmwareUserID(currentUserID) && currentUserID)
173  { // the new way:
174  currentDesignID = NTV2BitfileHeaderParser::GetDesignID(currentUserID);
175  currentDesignVersion = NTV2BitfileHeaderParser::GetDesignVersion(currentUserID);
176  currentBitfileID = NTV2BitfileHeaderParser::GetBitfileID(currentUserID);
177  currentBitfileVersion = NTV2BitfileHeaderParser::GetBitfileVersion(currentUserID);
178  }
179  else
180  { // the old way:
182  currentDesignVersion = NTV2BitfileHeaderParser::GetDesignVersion(regs[BITSTREAM_VERSION]);
183  currentBitfileID = CNTV2Bitfile::ConvertToBitfileID(currentDeviceID);
184  currentBitfileVersion = 0xff; // ignores bitfile version
185  }
186 
187  if (!currentDesignID)
188  {DDFAIL("Current design ID is zero for " << oldDevName); return false;}
189 
190  // Get the clear file matching current bitfile...
191  NTV2Buffer clearStream;
192  if (!s_BitfileManager.GetBitStream (clearStream,
193  currentDesignID,
194  currentDesignVersion,
195  currentBitfileID,
196  currentBitfileVersion,
197  NTV2_BITFILE_FLAG_CLEAR) || !clearStream)
198  {DDFAIL("GetBitStream 'clear' failed for " << oldDevName); return false;}
199 
200  // Get the partial file matching the inDeviceID...
201  NTV2Buffer partialStream;
202  if (!s_BitfileManager.GetBitStream (partialStream,
203  currentDesignID,
204  currentDesignVersion,
206  0xff,
207  NTV2_BITFILE_FLAG_PARTIAL) || !partialStream)
208  {DDFAIL("GetBitStream 'partial' failed for " << oldDevName); return false;}
209 
210  // Load the clear bitstream...
211  if (!BitstreamWrite (clearStream, true, true))
212  {DDFAIL("BitstreamWrite failed writing 'clear' bitstream for " << oldDevName); return false;}
213  // Load the partial bitstream...
214  if (!BitstreamWrite (partialStream, false, true))
215  {DDFAIL("BitstreamWrite failed writing 'partial' bitstream for " << oldDevName); return false;}
216 
217  DDNOTE(oldDevName << " dynamically changed to '" << ::NTV2DeviceIDToString(inDeviceID) << "' (" << xHEX0N(inDeviceID,8) << ")");
218  return true;
219 } // LoadDynamicDevice
220 
221 bool CNTV2Card::AddDynamicBitfile (const string & inBitfilePath)
222 {
223  if (!IsSupported(kDeviceCanDoFastBitfileSwitching))
224  return false;
225  return s_BitfileManager.AddFile(inBitfilePath);
226 }
227 
228 bool CNTV2Card::AddDynamicDirectory (const string & inDirectory)
229 {
230  if (!IsSupported(kDeviceCanDoFastBitfileSwitching))
231  return false;
232  return s_BitfileManager.AddDirectory(inDirectory);
233 }
#define DDNOTE(__x__)
static ULWord ConvertToBitfileID(const NTV2DeviceID inDeviceID)
std::vector< NTV2BitfileInfo > NTV2BitfileInfoList
#define DDFAIL(__x__)
virtual bool LoadDynamicDevice(const NTV2DeviceID inDeviceID)
Quickly, dynamically loads the given device ID firmware.
Declares the AJADebug class.
True if device supports fast bitfile switching. (New in SDK 18.1)
Definition: json.hpp:5362
static NTV2DeviceID ConvertToDeviceID(const ULWord inDesignID, const ULWord inBitfileID)
virtual bool IsDynamicDevice(void)
uint32_t ULWord
Definition: ajatypes.h:236
static ULWord GetDesignVersion(const ULWord userID)
Definition: ntv2bitfile.h:55
virtual NTV2DeviceID GetBaseDeviceID()
static ULWord GetBitfileID(const ULWord userID)
Definition: ntv2bitfile.h:56
#define BITSTREAM_VERSION
Bitstream version register.
NTV2DeviceID
Identifies a specific AJA NTV2 device model number. The NTV2DeviceID is actually the PROM part number...
Definition: ntv2enums.h:20
virtual NTV2DeviceIDList GetDynamicDeviceList(void)
NTV2DeviceIDSet::const_iterator NTV2DeviceIDSetConstIter
A convenient const iterator for NTV2DeviceIDSet.
Definition: ntv2utils.h:1100
std::vector< ULWord > NTV2ULWordVector
An ordered sequence of ULWords.
virtual NTV2DeviceIDSet GetDynamicDeviceIDs(void)
virtual bool AddDynamicDirectory(const std::string &inDirectory)
Adds all bitfiles found in the given host file directory to the list of available dynamic bitfiles...
virtual bool CanLoadDynamicDevice(const NTV2DeviceID inDeviceID)
virtual bool AddDirectory(const std::string &inDirectory)
Add the bitfile(s) at the given path to the list of bitfiles.
static ULWord GetBitfileVersion(const ULWord userID)
Definition: ntv2bitfile.h:57
static CNTV2BitfileManager s_BitfileManager
Describes a user-space buffer on the host computer. I have an address and a length, plus some optional attributes (allocated by SDK?, page-aligned? etc.).
Declares the CNTV2BitfileManager class that manages Xilinx bitfiles.
std::string NTV2DeviceIDToString(const NTV2DeviceID inValue, const bool inForRetailDisplay=false)
Definition: ntv2utils.cpp:4608
virtual bool IsDynamicFirmwareLoaded(void)
Declares numerous NTV2 utility functions.
virtual const NTV2BitfileInfoList & GetBitfileInfoList(void) const
Returns an NTV2BitfileInfoList standard C++ vector.
Declares the CNTV2Bitfile class.
#define NTV2_BITFILE_FLAG_CLEAR
This is a clear bitfile.
#define xHEX0N(__x__, __n__)
Declares the CNTV2Card class.
virtual bool AddDynamicBitfile(const std::string &inBitfilePath)
Adds the given bitfile to the list of available dynamic bitfiles.
std::set< NTV2DeviceID > NTV2DeviceIDSet
A set of NTV2DeviceIDs.
Definition: ntv2utils.h:1098
NTV2BitfileInfoList::const_iterator NTV2BitfileInfoListConstIter
I manage and cache any number of bitfiles for any number of NTV2 devices/designs. ...
static ULWord GetDesignID(const ULWord userID)
Definition: ntv2bitfile.h:54
std::vector< NTV2DeviceID > NTV2DeviceIDList
An ordered list of NTV2DeviceIDs.
Definition: ntv2utils.h:1091
Declares device capability functions.
#define NTV2_BITFILE_FLAG_PARTIAL
This is a partial bitfile.
virtual bool GetBitStream(NTV2Buffer &outBitstream, const ULWord inDesignID, const ULWord inDesignVersion, const ULWord inBitfileID, const ULWord inBitfileVersion, const ULWord inBitfileFlags)
Retrieves the bitstream specified by design ID & version, and bitfile ID & version. It loads it into host memory, and updates/reallocates the given NTV2Buffer to access it.
virtual bool AddFile(const std::string &inBitfilePath)
Add the bitfile at the given path to the list of bitfiles.