AJA NTV2 SDK  18.1.0.2262
NTV2 SDK 18.1.0.2262
ntv2metale2e.cpp
Go to the documentation of this file.
1 /* SPDX-License-Identifier: MIT */
9 // Includes
10 #include "ntv2metale2e.h"
11 
12 void hex_to_bytes(char *hex, uint8_t *output, uint32_t array_length)
13 {
14  uint32_t i;
15  uint32_t j;
16 
17  for (i = 0, j = 0; i < array_length; i++, j+=2)
18  {
19  uint8_t bottom = hex[j+1] - (hex[j+1] > '9' ? 'A' - 10 : '0');
20  uint8_t top = hex[j] - (hex[j] > '9' ? 'A' - 10 : '0');
21  output[i] = (top * 16) + bottom;
22  }
23 }
24 
26 {
27 } // constructor
28 
29 
31 {
32 } // destructor
33 
34 
36 {
37  mDevice.Open(0);
38  NTV2DeviceID mDeviceID = mDevice.GetDeviceID(); // Keep this ID handy -- it's used frequently
39 
40  //if (mDeviceID != DEVICE_ID_KONAX)
41  //return AJA_STATUS_FAIL;
42 
43  // Set up the Genlock circuit
44  AJAStatus status (SetUpGenlock());
45  if (AJA_FAILURE(status))
46  return status;
47 
48  // Set up the desired video configuration...
49  status = SetUpVideo();
50  if (AJA_FAILURE(status))
51  return status;
52 
53  // Set up the E2E routing
55 
56  return AJA_STATUS_SUCCESS;
57 
58 } // Init
59 
61 {
62  // Port driver genlock
63 
65  uint32_t count = 0, errorCount = 0, totalBytes = 0;
66  uint32_t value;
67  uint32_t mask;
68  uint8_t writeBytes[256];
69  uint32_t outFreq1 = 0, outFreq2 = 0, outFreq3 = 0, outFreq4 = 0, outFreq5 = 0;
70  uint8_t dpll0Status[1] = { 0 };
71  uint32_t gpioValue;
72  bool check = false;
73 
74  SPIReset();
75 
76  while ((gdat->size != 0))
77  {
78  hex_to_bytes(gdat->data+2, writeBytes, gdat->size);
79  if (!SPIGenlock2Write(gdat->size, gdat->addr, writeBytes, true))
80  {
81  return AJA_STATUS_FAIL;
82  }
83  totalBytes += gdat->size;
84 
85  if (check)
86  {
87  uint8_t readBytes[256];
88  uint16_t i;
89  if (SPIGenlock2Read(gdat->addr, readBytes, gdat->size))
90  {
91  for (i = 0; i < gdat->size; i++)
92  {
93  SPIGenlock2Read(gdat->addr+i, readBytes+i, 1);
94  if (readBytes[i] != writeBytes[i])
95  {
96  errorCount++;
97  ntv2Message("Set: %d, Offset: %04X, size: %d, data: %s\n", count, gdat->addr, gdat->size, gdat->data);
98  ntv2Message("Bytes did not match i : %d read : %02X write : %02X\n", i, readBytes[i], writeBytes[i]);
99  }
100  else
101  {
102  //ntv2Message("Bytes matched\n");
103  }
104  }
105  }
106  }
107  else
108  {
109  //ntv2Message("Set: %d, Offset: %04X No check\n", count, gdat->addr);
110  }
111  count++;
112  gdat++;
113  }
114 
115  // Wait for initial lock
116  count = 0;
117  outFreq1 = RegRead(ntv2_reg_out_freq1);
118  outFreq2 = RegRead(ntv2_reg_out_freq2);
119  outFreq3 = RegRead(ntv2_reg_out_freq3);
120  outFreq4 = RegRead(ntv2_reg_out_freq4);
121  outFreq5 = RegRead(ntv2_reg_out_freq5);
122  while( (outFreq1 & 0xffffff00) != 0x08D9EE00 &&
123  (outFreq2 & 0xffffff00) != 0x08D7AA00 &&
124  (outFreq3 & 0xffffff00) != 0x019BFC00 &&
125  (outFreq4 & 0xffffff00) != 0x00BB8000 &&
126  (outFreq5 & 0xffffff00) != 0x08D9EE00 &&
127  count < 10000)
128  {
129  WaitGenlock2(1000);
130  outFreq1 = RegRead(ntv2_reg_out_freq1);
131  outFreq2 = RegRead(ntv2_reg_out_freq2);
132  outFreq3 = RegRead(ntv2_reg_out_freq3);
133  outFreq4 = RegRead(ntv2_reg_out_freq4);
134  outFreq5 = RegRead(ntv2_reg_out_freq5);
135  count++;
136  }
137 
138  if (count >= 10000){
139  // genlock2 initial lock check timeout
140  return AJA_STATUS_FAIL;
141  }
142 
143  // Reset Genlock
146 
147  return AJA_STATUS_SUCCESS;
148 
149 }
150 
152 {
154  mDevice.EnableChannel(NTV2_CHANNEL1);
155  mDevice.EnableChannel(NTV2_CHANNEL2);
156 
158  mDevice.SetVideoFormat (videoFormat, false, false, NTV2_CHANNEL1);
159  mDevice.SetVideoFormat (videoFormat, false, false, NTV2_CHANNEL2);
160 
161  NTV2Standard videoStandard = GetNTV2StandardFromVideoFormat(videoFormat);
162  mDevice.SetSDIOutputStandard(NTV2_CHANNEL2, videoStandard);
163 
164  bool isValidVPID (mDevice.GetVPIDValidA(NTV2_CHANNEL1));
165  if (isValidVPID)
166  {
167  CNTV2VPID inputVPID;
168  ULWord vpidDS1(0), vpidDS2(0);
169  mDevice.ReadSDIInVPID(NTV2_CHANNEL1, vpidDS1, vpidDS2);
170  inputVPID.SetVPID(vpidDS1);
171  isValidVPID = inputVPID.IsValid();
172  mDevice.SetSDIOutVPID(vpidDS1, vpidDS2, NTV2_CHANNEL2);
173  }
174 
175  bool is3G (false), is6G (false), is12G (false);
176  mDevice.GetSDIInput3GPresent(is3G, NTV2_CHANNEL1);
177  mDevice.GetSDIInput6GPresent(is6G, NTV2_CHANNEL1);
178  mDevice.GetSDIInput12GPresent(is12G, NTV2_CHANNEL1);
179 
180  mDevice.SetSDIOut3GEnable(NTV2_CHANNEL2, is3G);
181  mDevice.SetSDIOut6GEnable(NTV2_CHANNEL2, is6G);
182  mDevice.SetSDIOut12GEnable(NTV2_CHANNEL2, is12G);
183 
184  return AJA_STATUS_SUCCESS;
185 
186 } // SetUpVideo
187 
189 {
190  mDevice.SetSDITransmitEnable (NTV2_CHANNEL1, false);
191  mDevice.SetSDITransmitEnable (NTV2_CHANNEL2, true);
192  mDevice.ClearRouting();
194 
195 } // RouteOutputSignal
196 
197 bool NTV2MetalE2E::SPIWaitWriteEmpty (void)
198 {
199  uint32_t dtrStatus = 0;
200  uint32_t count = 0;
201 
202 
203  dtrStatus = RegRead(ntv2_reg_spi_ip_status);
204  count = 0;
205  while ((dtrStatus & DTR_EMPTY) == 0)
206  {
207  if (count++ > c_spi_timeout) return false;
208  dtrStatus = RegRead(ntv2_reg_spi_ip_status);
209  }
210 
211  return true;
212 }
213 
214 bool NTV2MetalE2E::SPIWaitReadNotEmpty (void)
215 {
216  uint32_t status = 0;
217  uint32_t count = 0;
218 
219  status = RegRead(ntv2_reg_spi_status);
220  while ((status & GENL_SPI_READ_FIFO_EMPTY) != 0)
221  {
222  if (count++ > c_spi_timeout) return false;
223  status = RegRead(ntv2_reg_spi_status);
224  }
225  return true;
226 }
227 
228 bool NTV2MetalE2E::ResetDTRStatus (void)
229 {
230  uint32_t dtrStatus = RegRead(ntv2_reg_spi_ip_status);
231  if ((dtrStatus & DTR_EMPTY) != 0)
232  {
233  mDevice.WriteRegister(ntv2_reg_spi_ip_status, 1, BIT(2), 2);
234  return true;
235  }
236  return false;
237 }
238 
239 bool NTV2MetalE2E::SPIGenlock2Write (uint32_t size, uint16_t addr, uint8_t* data, bool triggerWait)
240 {
241  uint32_t controlVal;
242  uint8_t page_select_buffer[10];
243  uint32_t i;
244 
245 
246  // Step 1 reset FIFOs
247  SPIResetFIFOs();
248 
249  if (addr != 0x7C)
250  {
251  // set page
252  page_select_buffer[0] = addr & 0x80;
253  page_select_buffer[1] = addr >> 8;
254  page_select_buffer[2] = 0x10;
255  page_select_buffer[3] = 0x20;
256 
257  SPIGenlock2Write(4, 0x7C, page_select_buffer, true);
258  }
259 
260  // Step 2 load data
261  mDevice.WriteRegister(ntv2_reg_spi_write, addr & 0x7f);
262 
263  for (i = 0; i < size; i++)
264  {
266  }
267 
268  // Reset DRT Shift bit
269  ResetDTRStatus();
270 
271  // Step 3 chip select low
272  mDevice.WriteRegister(ntv2_reg_spi_slave, 0x0);
273 
274  // Step 4 enable master transactions
275  controlVal = RegRead(ntv2_reg_spi_control);
276  controlVal &= ~0x100;
277  mDevice.WriteRegister(ntv2_reg_spi_control, controlVal);
278 
279  SPIWaitWriteEmpty();
280 
281  // Step 5 deassert chip select
282  mDevice.WriteRegister(ntv2_reg_spi_slave, 0x01);
283 
284  // Step 6 disable master transactions
285  controlVal = RegRead(ntv2_reg_spi_control);
286  controlVal |= 0x100;
287  mDevice.WriteRegister(ntv2_reg_spi_control, controlVal);
288 
289  if (triggerWait)
290  WaitGenlock2(200);
291 
292  return true;
293 }
294 
295 bool NTV2MetalE2E::SPIGenlock2Read (uint16_t addr, uint8_t* data, uint32_t numBytes)
296 {
297  uint32_t val, status;
298  uint8_t tx_buffer[10];
299  uint32_t i;
300 
301  // Step 1 reset FIFOs
302  SPIResetFIFOs();
303 
304  if (addr != 0x7c)
305  {
306  // set page
307  tx_buffer[0] = addr & 0x80;
308  tx_buffer[1] = addr >> 8;
309  tx_buffer[2] = 0x10;
310  tx_buffer[3] = 0x20;
311 
312  SPIGenlock2Write(4, 0x7C, tx_buffer, true);
313  }
314 
315  mDevice.WriteRegister(ntv2_reg_spi_control, 0xfe);
316  WaitGenlock2(1000);
317  mDevice.WriteRegister(ntv2_reg_spi_slave, 0x00);
318  WaitGenlock2(1000);
319 
320  mDevice.WriteRegister(ntv2_reg_spi_write, 0x80 | (addr & 0x7f));
321  WaitGenlock2(1000);
322 
323  for (i = 0; i < numBytes; i++)
324  mDevice.WriteRegister(ntv2_reg_spi_write, 0);
325 
326  if (!SPIWaitWriteEmpty())
327  return false;
328 
329  mDevice.WriteRegister(ntv2_reg_spi_slave, 0x01);
330  WaitGenlock2(10000);
331 
332  if(!SPIWaitReadNotEmpty())
333  return false;
334 
335 
336  val = RegRead(ntv2_reg_spi_read); // dummy read for address sent
337 
338  for (i = 0; i < numBytes; i++)
339  {
340  status = RegRead(ntv2_reg_spi_status);
341  if(!SPIWaitReadNotEmpty())
342  return false;
343  val = RegRead(ntv2_reg_spi_read);
344  data[i] = (uint8_t)val;
345  }
346 
347  mDevice.WriteRegister(ntv2_reg_spi_control, 0xfe);
348 
349  return true;
350 }
351 
352 bool NTV2MetalE2E::WaitGenlock2 (uint32_t numMicrosSeconds)
353 {
354  uint32_t usTicks = 0;
355  uint32_t timeoutCount = 0;
356 
357  mDevice.WriteRegister(0x3606, 0);
358  while (usTicks < numMicrosSeconds)
359  {
360  usTicks = RegRead(0x3606);
361  }
362  return true;
363 }
364 
365 void NTV2MetalE2E::SPIReset (void)
366 {
367  // reset spi hardware
368  mDevice.WriteRegister(ntv2_reg_spi_reset, 0x0a);
369 
370  // configure spi & reset fifos
371  mDevice.WriteRegister(ntv2_reg_spi_slave, 0x1);
372  mDevice.WriteRegister(ntv2_reg_spi_control, 0x1fe);
373 }
374 
375 void NTV2MetalE2E::SPIResetFIFOs (void)
376 {
377  mDevice.WriteRegister(ntv2_reg_spi_control, 0x1fe);
378 }
379 
380 uint32_t NTV2MetalE2E::RegRead (uint32_t reg)
381 {
382  uint32_t outVal(0);
383  mDevice.ReadRegister(reg, outVal);
384  return outVal;
385 }
386 
387 
388 
void RouteE2ESignal(void)
Sets up board routing for E2E.
const uint32_t ntv2_reg_out_freq2
Definition: ntv2metale2e.h:422
virtual bool SetReference(const NTV2ReferenceSource inRefSource, const bool inKeepFramePulseSelect=(0))
Sets the device&#39;s clock reference source. See Video Output Clocking & Synchronization for more inform...
virtual bool GetSDIInput3GPresent(bool &outValue, const NTV2Channel channel)
#define BIT(_x_)
Definition: ajatypes.h:596
virtual bool SetVideoFormat(const NTV2VideoFormat inVideoFormat, const bool inIsAJARetail=(!(0)), const bool inKeepVancSettings=(0), const NTV2Channel inChannel=NTV2_CHANNEL1)
Configures the AJA device to handle a specific video format.
virtual bool SetSDIOut6GEnable(const NTV2Channel inChannel, const bool inEnable)
#define ntv2Message(string,...)
Definition: ntv2metale2e.h:408
AJAStatus
Definition: types.h:380
enum _NTV2VideoFormat NTV2VideoFormat
Identifies a particular video format.
#define AJA_FAILURE(_status_)
Definition: types.h:373
const uint32_t ntv2_reg_genlock_reset
Definition: ntv2metale2e.h:427
virtual bool ReadSDIInVPID(const NTV2Channel inSDIInput, ULWord &outValueA, ULWord &outValueB)
Definition: ntv2regvpid.cpp:85
virtual bool SetSDIOutVPID(const ULWord inValueA, const ULWord inValueB, const UWord inOutputSpigot=NTV2_CHANNEL1)
virtual bool GetVPIDValidA(const NTV2Channel inChannel)
Definition: ntv2regvpid.cpp:67
virtual bool Open(const UWord inDeviceIndex)
Opens a local/physical AJA device so it can be monitored/controlled.
void hex_to_bytes(char *hex, uint8_t *output, uint32_t array_length)
static struct ntv2_genlock2_data s_rc32012a_broadcast_1485[]
Definition: ntv2metale2e.h:21
const uint32_t ntv2_genlock_reset_mask
Definition: ntv2metale2e.h:429
uint32_t ULWord
Definition: ajatypes.h:236
const uint32_t ntv2_reg_spi_read
Definition: ntv2metale2e.h:418
virtual bool GetSDIInput12GPresent(bool &outValue, const NTV2Channel channel)
const uint32_t ntv2_reg_spi_slave
Definition: ntv2metale2e.h:419
virtual bool ClearRouting(void)
Removes all existing signal path connections between any and all widgets on the AJA device...
AJAStatus SetUpVideo(void)
Setup video formats and outputs.
virtual bool SetSDIOut3GEnable(const NTV2Channel inChannel, const bool inEnable)
NTV2Standard
Identifies a particular video standard.
Definition: ntv2enums.h:167
NTV2DeviceID
Identifies a specific AJA NTV2 device model number. The NTV2DeviceID is actually the PROM part number...
Definition: ntv2enums.h:20
const uint32_t ntv2_reg_out_freq5
Definition: ntv2metale2e.h:425
virtual bool SetSDITransmitEnable(const NTV2Channel inChannel, const bool inEnable)
Sets the specified bidirectional SDI connector to act as an input or an output.
virtual NTV2VideoFormat GetInputVideoFormat(const NTV2InputSource inVideoSource=NTV2_INPUTSOURCE_SDI1, const bool inIsProgressive=(0))
Returns the video format of the signal that is present on the given input source. ...
const uint32_t ntv2_reg_out_freq1
Definition: ntv2metale2e.h:421
const uint32_t ntv2_reg_out_freq4
Definition: ntv2metale2e.h:424
const uint32_t ntv2_reg_spi_reset
Definition: ntv2metale2e.h:414
Specifies channel or FrameStore 2 (or the 2nd item).
Definition: ntv2enums.h:1362
virtual NTV2DeviceID GetDeviceID(void)
Specifies the SDI In 1 connector.
Definition: ntv2enums.h:1460
const uint32_t ntv2_genlock_reset_shift
Definition: ntv2metale2e.h:428
virtual bool GetSDIInput6GPresent(bool &outValue, const NTV2Channel channel)
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...
virtual bool Connect(const NTV2InputCrosspointID inInputXpt, const NTV2OutputCrosspointID inOutputXpt, const bool inValidate=(0))
Connects the given widget signal input (sink) to the given widget signal output (source).
virtual CNTV2VPID & SetVPID(const ULWord inData)
Definition: ntv2vpid.h:71
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...
const uint32_t ntv2_reg_out_freq3
Definition: ntv2metale2e.h:423
Specifies channel or FrameStore 1 (or the first item).
Definition: ntv2enums.h:1361
NTV2MetalE2E(void)
Constructs me using the given configuration settings.
A convenience class that simplifies encoding or decoding the 4-byte VPID payload that can be read or ...
Definition: ntv2vpid.h:23
const uint32_t ntv2_reg_spi_control
Definition: ntv2metale2e.h:415
NTV2Standard GetNTV2StandardFromVideoFormat(const NTV2VideoFormat inVideoFormat)
Definition: ntv2utils.cpp:2375
const uint32_t ntv2_reg_spi_ip_status
Definition: ntv2metale2e.h:412
~NTV2MetalE2E(void)
const uint32_t ntv2_reg_spi_write
Definition: ntv2metale2e.h:417
AJAStatus SetUpGenlock(void)
Sets up the genlock circuit.
virtual bool SetSDIOutputStandard(const UWord inOutputSpigot, const NTV2Standard inValue)
Sets the SDI output spigot&#39;s video standard.
Identifies the 1st SDI video input.
Definition: ntv2enums.h:1271
#define DTR_EMPTY
Definition: ntv2metale2e.h:409
const uint32_t ntv2_reg_spi_status
Definition: ntv2metale2e.h:416
virtual bool SetSDIOut12GEnable(const NTV2Channel inChannel, const bool inEnable)
virtual bool IsValid(void) const
Definition: ntv2vpid.h:56
const int64_t c_spi_timeout
Definition: ntv2metale2e.h:431
#define GENL_SPI_READ_FIFO_EMPTY
Definition: ntv2metale2e.h:410
AJAStatus Run(void)
Do something from the KonaX Xilinx Baremetal system.
virtual bool EnableChannel(const NTV2Channel inChannel)
Enables the given FrameStore.