Scope
FPGANoiseOutput.cpp
1 #include "stdafx.h"
2 #include "FPGANoiseOutput.h"
3 #include "parameters/IO.h"
4 #include "helpers/DaqChunk.h"
5 
6 namespace scope {
7 
9  assert(SCOPE_NAREAS <= 2);
10 
11  status = NiFpga_Initialize();
12 
13  char* const Bitfile = "devices\\fpga\\" NiFpga_NoiseOutput_PXIe7962R_Bitfile;
14 
15  // Load but do not run yet
16  status = NiFpga_Open(Bitfile, NiFpga_NoiseOutput_PXIe7962R_Signature, "RIO0", 0, &session);
17  DBOUT(L"FPGANoiseOutput: FPGA Session opened");
18 
19  // Reset the non-running FPGA to clear any bad stuff (e.g. after a program crash with open FPGA before)
20  status = NiFpga_Reset(session);
21 
22  // YOU HAVE TO WAIT THAT LONG!!!
23  // Otherwise you will occasionally (!!!) into strange problems (communication with fpga error -61046)
24  // This took me very very long to figure out...
25  std::this_thread::sleep_for(std::chrono::milliseconds(500));
26  // Run after reset
27  status = NiFpga_Run(session, 0);
28 
29  // Set the fifo constants
30  fifos[0] = NiFpga_NoiseOutput_PXIe7962R_TargetToHostFifoU16_ToHostA1Ch1FIFO;
31  fifos[1] = NiFpga_NoiseOutput_PXIe7962R_TargetToHostFifoU16_ToHostA1Ch2FIFO;
32  fifos[2] = NiFpga_NoiseOutput_PXIe7962R_TargetToHostFifoU16_ToHostA2Ch1FIFO;
33  fifos[3] = NiFpga_NoiseOutput_PXIe7962R_TargetToHostFifoU16_ToHostA2Ch2FIFO;
34  smplsperpixel[0] = NiFpga_NoiseOutput_PXIe7962R_ControlU32_SamplesperlineA1;
35  smplsperpixel[1] = NiFpga_NoiseOutput_PXIe7962R_ControlU32_SamplesperlineA2;
36  smplsperline[0] = NiFpga_NoiseOutput_PXIe7962R_ControlU32_SamplesperlineA1;
37  smplsperline[1] = NiFpga_NoiseOutput_PXIe7962R_ControlU32_SamplesperlineA2;
38  reqpixels[0] = NiFpga_NoiseOutput_PXIe7962R_ControlU32_RequestedpixelsA1;
39  reqpixels[1] = NiFpga_NoiseOutput_PXIe7962R_ControlU32_RequestedpixelsA2;
40 }
41 
43  status = NiFpga_Close(session, 0);
44  status = NiFpga_Finalize();
45  DBOUT(L"FPGANoiseOutput::~FPGANoiseOutput session closed");
46 }
47 
49  if ( !initialized ) {
50  parameters = dynamic_cast<parameters::InputsFPGANoiseOutput*>(_parameters);
51  FPGAInterface::Initialize(_parameters);
52  }
53 }
54 
55 double FPGANoiseOutput::SetPixeltime(const uint32_t& _area, const double& _pixeltime) {
56  // "sampling rate" is 40 MHz
57  uint16_t samplesperpixel = round2ui16(_pixeltime * 1E-6 * 40E6);
58  status = NiFpga_WriteU16(session, smplsperpixel[_area], samplesperpixel);
59 
60  DBOUT(L"FPGANoiseOutput::SetPixeltime samples per pixel" << samplesperpixel);
61 
62  return static_cast<double>(samplesperpixel*1E6/40E6);
63 }
64 
65 double FPGANoiseOutput::SetLinetime(const uint32_t& _area, const double& _linetime) {
66  // "sampling rate" is 40 MHz
67  uint16_t samplesperline = round2ui16(_linetime * 1E-6 * 40E6);
68  status = NiFpga_WriteU16(session, smplsperline[_area], samplesperline);
69 
70  DBOUT(L"FPGANoiseOutput::SetPixeltime samples per line" << samplesperline);
71 
72  return static_cast<double>(samplesperline*1E6/40E6);
73 }
74 
75 void FPGANoiseOutput::SetTriggering(const bool& _waitfortrigger) {
76  status = NiFpga_WriteBool(session, NiFpga_NoiseOutput_PXIe7962R_ControlBool_Waitfortrigger, _waitfortrigger);
77 }
78 
80  status = NiFpga_WriteBool(session, NiFpga_NoiseOutput_PXIe7962R_ControlBool_Acquirecontinuously, _cont);
81 }
82 
83 void FPGANoiseOutput::SetRequestedPixels(const uint32_t& _area, const uint32_t& _reqpixels) {
84  status = NiFpga_WriteU32(session, reqpixels[_area], _reqpixels);
85 }
86 
88  ClearFIFOs();
89  status = NiFpga_WriteBool(session, NiFpga_NoiseOutput_PXIe7962R_ControlBool_Acquire, true);
90 }
91 
92 int32_t FPGANoiseOutput::ReadPixels(DaqChunk& _chunk, const double& _timeout, bool& _timedout) {
93  size_t remaining = 0;
94 
95  // only two channels and two areas supported in FPGA vi
96  assert( (_chunk.NChannels() <= 2) && (_chunk.Area() <= 1) );
97 
98  NiFpga_Status stat = NiFpga_Status_Success;
99 
100  // Read each channels fifo
101  for ( uint32_t c = 0 ; c < _chunk.NChannels() ; c++ ) {
102  stat = NiFpga_ReadFifoU16(session
103  , fifos[_chunk.Area() * 2 + c] // select correct fifo
104  , &_chunk.data[c * _chunk.PerChannel()] // offset start in vector for second channel pixels
105  , _chunk.PerChannel()
106  , static_cast<uint32_t>(_timeout * 1000) // FPGA C API takes timeout in milliseconds, to be consistent with DAQmx we have _timeout in seconds
107  , &remaining);
108 
109  _timedout = (stat == NiFpga_Status_FifoTimeout);
110 
111  // avoid throwing exception on time out (since FpgaStatus status could throw on all errors)
112  // return immediately, makes no sense to also wait for the other channels, since anyway something went seriously wrong
113  if ( _timedout )
114  return -1;
115 
116  // this could throw on error (if we would use FPGAStatus instead of FPGAStatusSafe)
117  status = stat;
118  }
119 
120  if ( status.Success() )
121  return _chunk.PerChannel();
122 
123  return -1;
124 }
125 
127  status = NiFpga_WriteBool(session, NiFpga_NoiseOutput_PXIe7962R_ControlBool_Acquire, false);
128 }
129 
131  NiFpga_Bool b;
132  status = NiFpga_ReadBool(session, NiFpga_NoiseOutput_PXIe7962R_IndicatorBool_ToHostA1Ch1Overflow, &b);
133  parameters->diagnosis.ToHostOverflowA1Ch1 = (b!=0);
134  status = NiFpga_ReadBool(session, NiFpga_NoiseOutput_PXIe7962R_IndicatorBool_ToHostA1Ch2Overflow, &b);
135  parameters->diagnosis.ToHostOverflowA1Ch2 = (b!=0);
136  status = NiFpga_ReadBool(session, NiFpga_NoiseOutput_PXIe7962R_IndicatorBool_ToHostA2Ch1Overflow, &b);
137  parameters->diagnosis.ToHostOverflowA2Ch1 = (b!=0);
138  status = NiFpga_ReadBool(session, NiFpga_NoiseOutput_PXIe7962R_IndicatorBool_ToHostA2Ch2Overflow, &b);
139  parameters->diagnosis.ToHostOverflowA2Ch2 = (b!=0);
140  status = NiFpga_ReadBool(session, NiFpga_NoiseOutput_PXIe7962R_IndicatorBool_Acquiring, &b);
141  parameters->diagnosis.Acquiring = (b!=0);
142 }
143 
145  // Stop FIFOs (clears them)
146  for ( auto f : fifos )
147  status = NiFpga_StopFifo(session, f);
148  std::this_thread::sleep_for(std::chrono::milliseconds(50));
149 
150  // Restart FIFOs
151  for ( auto f : fifos )
152  status = NiFpga_StartFifo(session, f);
153  std::this_thread::sleep_for(std::chrono::milliseconds(50));
154 }
155 
156 
157 }
void StopAcquisition() override
Stops the acquisition on the FPGA.
void ClearFIFOs()
Clears the interloop and ToHost FIFOs.
int32_t ReadPixels(DaqChunk &_chunk, const double &_timeout, bool &_timedout) override
Read only pixels from the FPGA FIFO.
ScopeNumber< bool > Acquiring
and the Acquiring indicator
Definition: IO.h:157
void SetContinuousAcquisition(const bool &_cont) override
Sets if the FPGA should acquire data continuously or acquire the number of pixels per channel set wit...
void SetRequestedPixels(const uint32_t &_area, const uint32_t &_reqpixels) override
Sets the number of pixels per channel the FPGA should acquire, set to -1 for live scanning...
void SetTriggering(const bool &_waitfortrigger) override
Sets if the FPGA should wait for a trigger before starting acquisition.
void CheckFPGADiagnosis()
Checks the status of the FIFOs on the FPGA.
std::vector< uint16_t > data
The data vector.
Definition: DaqChunk.h:26
Parameters for the noise generating FPGA vi.
Definition: IO.h:137
void Initialize(parameters::InputsFPGA *_parameters) override
Set initial parameters.
double SetPixeltime(const uint32_t &_area, const double &_pixeltime) override
Sets the time per pixel/dwell time (in seconds)
A DaqChunk contains data from all channels sequentially.
Definition: DaqChunk.h:9
This is the include file for standard system include files, or project specific include files that ar...
bool initialized
true if already initialized
Definition: FPGAInterface.h:29
FPGANoiseOutput()
Load the FPGA bitfile, reset, set the IO module's onboard clock and initialize the acquisition...
FPGAStatusSafe status
current FPGA status.
Definition: FPGAInterface.h:23
std::array< NiFpga_NoiseOutput_PXIe7962R_ControlU32, 2 > reqpixels
requested pixels for both areas
#define DBOUT(s)
A debug output to the debug console.
Definition: helpers.h:153
bool Success() const
std::array< NiFpga_NoiseOutput_PXIe7962R_ControlU32, 2 > smplsperpixel
samples per pixel for both areas
void StartAcquisition() override
Starts the acquisition on the FPGA.
~FPGANoiseOutput()
Close FPGA session.
double SetLinetime(const uint32_t &_area, const double &_linetime) override
Sets the time per line (in seconds) for the generation of the line clock (if implemented) ...
std::array< NiFpga_NoiseOutput_PXIe7962R_ControlU32, 2 > smplsperline
samples per line for both areas
parameters::InputsFPGANoiseOutput * parameters
the parameter set
virtual void Initialize(parameters::InputsFPGA *_parameters)
Set initial parameters.
Definition: FPGAInterface.h:38
std::array< NiFpga_NoiseOutput_PXIe7962R_TargetToHostFifoU16, 4 > fifos
both fifos for both channels and areas
Diagnosis diagnosis
Keeps the LEDs/ScopeNumber for FPGA diagnosis together.
Definition: IO.h:169
Parameters for pixel acquisition with NI-FPGA.
Definition: IO.h:117
NiFpga_Session session
NI FPGA session handle.
Definition: FPGAInterface.h:26