def ConfigureBoard(board, fft_module, recordLength_samples): # TODO: Select clock parameters as required to generate this # sample rate # # For example: if samplesPerSec is 100e6 (100 MS/s), then you can # either: # - select clock source INTERNAL_CLOCK and sample rate # SAMPLE_RATE_100MSPS # - or select clock source FAST_EXTERNAL_CLOCK, sample rate # SAMPLE_RATE_USER_DEF, and connect a 100MHz signal to the # EXT CLK BNC connector samplesPerSec = 500000000.0 board.setCaptureClock(ats.INTERNAL_CLOCK, ats.SAMPLE_RATE_500MSPS, ats.CLOCK_EDGE_RISING, 0) # TODO: Select channel A input parameters as required. board.inputControlEx(ats.CHANNEL_A, ats.AC_COUPLING, ats.INPUT_RANGE_PM_400_MV, ats.IMPEDANCE_50_OHM) # TODO: Select channel A bandwidth limit as required. board.setBWLimit(ats.CHANNEL_A, 0) # TODO: Select channel B input parameters as required. board.inputControlEx(ats.CHANNEL_B, ats.AC_COUPLING, ats.INPUT_RANGE_PM_400_MV, ats.IMPEDANCE_50_OHM) # TODO: Select channel B bandwidth limit as required. board.setBWLimit(ats.CHANNEL_B, 0) # TODO: Select trigger inputs and levels as required. board.setTriggerOperation(ats.TRIG_ENGINE_OP_J, ats.TRIG_ENGINE_J, ats.TRIG_CHAN_A, ats.TRIGGER_SLOPE_POSITIVE, 150, ats.TRIG_ENGINE_K, ats.TRIG_DISABLE, ats.TRIGGER_SLOPE_POSITIVE, 128) # TODO: Select external trigger parameters as required. board.setExternalTrigger(ats.DC_COUPLING, ats.ETR_5V) # TODO: Set trigger delay as required. triggerDelay_sec = 0 triggerDelay_samples = int(triggerDelay_sec * samplesPerSec + 0.5) board.setTriggerDelay(triggerDelay_samples) # TODO: Set trigger timeout as required. # # NOTE: The board will wait for a for this amount of time for a # trigger event. If a trigger event does not arrive, then the # board will automatically trigger. Set the trigger timeout value # to 0 to force the board to wait forever for a trigger event. # # IMPORTANT: The trigger timeout value should be set to zero after # appropriate trigger parameters have been determined, otherwise # the board may trigger if the timeout interval expires before a # hardware trigger event arrives. triggerTimeout_sec = 0 triggerTimeout_clocks = int(triggerTimeout_sec / 10e-6 + 0.5) board.setTriggerTimeOut(triggerTimeout_clocks) # Configure AUX I/O connector as required board.configureAuxIO(ats.AUX_OUT_TRIGGER, 0) # FFT Configuration # TODO: Select the window function type windowType = ats.DSP_WINDOW_HANNING id, major, minor, maxLength = fft_module.dspGetInfo() if id != ats.DSP_MODULE_FFT: print("Error: DSP module is not FFT") return fftLength_samples = 1 while fftLength_samples < recordLength_samples: fftLength_samples *= 2 # Create and fill the window function window = ats.dspGenerateWindowFunction( windowType, recordLength_samples, fftLength_samples - recordLength_samples) # Set the window function fft_module.fftSetWindowFunction(fftLength_samples, window.ctypes.data_as(POINTER(c_float)), None) # TODO: Select the background subtraction record backgroundSubtractionRecord = np.zeros((recordLength_samples), dtype=np.int16) # Background subtraction fft_module.fftBackgroundSubtractionSetRecordS16( backgroundSubtractionRecord.ctypes.data_as(POINTER(c_int16)), recordLength_samples) fft_module.fftBackgroundSubtractionSetEnabled(True)
def prepare_acquisition(self, board, parameters): """ Prepare the DMA buffers for the board. Return a list of buffers """ samplesPerSec = parameters['samplerate'] * 1e6 # No pre-trigger samples in NPT mode preTriggerSamples = 0 postTriggerSamples = parameters['samplesPerRecord'] # Select the number of records per DMA buffer. recordsPerBuffer = parameters['records_per_buffer'] # Select the number of buffers per acquisition. buffersPerAcquisition = parameters['buffers_per_acquisition'] # get the info about the FFT module if parameters['mode'] == 'FFT': dsp_array = board.dspGetModules() fft_module = dsp_array[0] dsp_info = fft_module.dspGetInfo() # define the channel mask according to the working mode of the digitizer if parameters['mode'] == 'FFT': # Only channel A is used when on-FPGA FFT is active channels = ats.CHANNEL_A channelCount = 1 elif parameters['mode'] == 'CHANNEL_AB': # For two active channels channels = ats.CHANNEL_A | ats.CHANNEL_B channelCount = 2 elif parameters['mode'] == 'CHANNEL_A': # If channel A only is active channels = ats.CHANNEL_A channelCount = 1 elif parameters['mode'] == 'CHANNEL_B': # If channel B only is active channels = ats.CHANNEL_B channelCount = 1 else: raise ValueError('mode of the digitizer must be "CHANNEL_AB" or \ "CHANNEL_A" or "CHANNEL_B" or "FFT"') # Compute the number of samples per record samplesPerRecord = preTriggerSamples + postTriggerSamples #Configure the FFT module if parameters['mode'] == 'FFT': fftLength_samples = 1 while fftLength_samples < samplesPerRecord: fftLength_samples *= 2 # Sets the real part of the FFT windowing fft_window_real = ats.dspGenerateWindowFunction( windowType, samplesPerRecord, fftLength_samples - samplesPerRecord) # According to the documentation, the imaginary part of the FFT windowing should be filled with zeros fft_window_imag = ats.dspGenerateWindowFunction( windowType, 0, fftLength_samples - samplesPerRecord) # Configures the FFT window fft_module.fftSetWindowFunction( samplesPerRecord, ctypes.c_void_p(fft_window_real.ctypes.data), ctypes.c_void_p(fft_window_imag.ctypes.data)) # Compute the number of bytes per record and per buffer # For now the output of the output of the on-FPGA FFT is set to 'FFT_OUTPUT_FORMAT_U16_AMP2', # thus the number of bytes per sample is 2 bytesPerSample = 2 # Computes the number of bytes per record according to the settings of the on-FPGA FFT bytesPerRecord = fft_module.fftSetup( channels, samplesPerRecord, fftLength_samples, ats.FFT_OUTPUT_FORMAT_U16_AMP2, ats.FFT_FOOTER_NONE, 0) bytesPerBuffer = bytesPerRecord * recordsPerBuffer # change made by Remy the 2018/06/21 parameters['samplesPerRecord'] = int(bytesPerRecord / bytesPerSample) # before it was: # parameters['samplesPerRecord'] = bytesPerRecord/bytesPerSample else: # Compute the number of bytes per record and per buffer memorySize_samples, bitsPerSample = board.getChannelInfo() bytesPerSample = (bitsPerSample.value + 7) // 8 bytesPerRecord = bytesPerSample * samplesPerRecord bytesPerBuffer = bytesPerRecord * recordsPerBuffer * channelCount # change made by Remy the 2018/06/21 parameters['samplesPerRecord'] = int(bytesPerRecord / bytesPerSample) # before it was: # parameters['samplesPerRecord'] = bytesPerRecord/bytesPerSample # Select number of DMA buffers to allocate bufferCount = parameters['nb_buffer_allocated'] # Modified per Etienne. # Alazar gave bytesPerSample > 8 but this condition seemed strange to # me considering the previous code bytesPerSample = (bitsPerSample.value + 7) // 8 # Allocate DMA buffers sample_type = ctypes.c_uint8 if bytesPerSample > 1: sample_type = ctypes.c_uint16 buffers = [] for i in range(bufferCount): buffers.append(ats.DMABuffer(sample_type, bytesPerBuffer)) board.setRecordSize(preTriggerSamples, postTriggerSamples) # Prepate the board to work in the asynchroneous mode of acquisition recordsPerAcquisition = recordsPerBuffer * buffersPerAcquisition if parameters['mode'] == 'FFT': admaFlags = ats.ADMA_EXTERNAL_STARTCAPTURE | ats.ADMA_NPT | ats.ADMA_DSP board.beforeAsyncRead(channels, 0, bytesPerRecord, recordsPerBuffer, 0x7FFFFFFF, admaFlags) elif parameters['mode'] == 'CHANNEL_AB': board.beforeAsyncRead(channels, -preTriggerSamples, samplesPerRecord, recordsPerBuffer, recordsPerAcquisition, ats.ADMA_EXTERNAL_STARTCAPTURE \ | ats.ADMA_NPT | ats.ADMA_FIFO_ONLY_STREAMING) elif parameters['mode'] == 'CHANNEL_A': board.beforeAsyncRead(channels, -preTriggerSamples, samplesPerRecord, recordsPerBuffer, recordsPerAcquisition, ats.ADMA_EXTERNAL_STARTCAPTURE \ | ats.ADMA_NPT | ats.ADMA_FIFO_ONLY_STREAMING) elif parameters['mode'] == 'CHANNEL_B': board.beforeAsyncRead(channels, -preTriggerSamples, samplesPerRecord, recordsPerBuffer, recordsPerAcquisition, ats.ADMA_EXTERNAL_STARTCAPTURE \ | ats.ADMA_NPT | ats.ADMA_FIFO_ONLY_STREAMING) # Put the buffers previously created in the list of available buffers for buff in buffers: board.postAsyncBuffer(buff.addr, buff.size_bytes) return buffers
def prepare_acquisition(self, board, parameters): """ Prepare the DMA buffers for the board. Return a list of buffers """ samplesPerSec = parameters['samplerate']*1e6 # No pre-trigger samples in NPT mode preTriggerSamples = 0 postTriggerSamples = parameters['samplesPerRecord'] # Select the number of records per DMA buffer. recordsPerBuffer = parameters['records_per_buffer'] # Select the number of buffers per acquisition. buffersPerAcquisition = parameters['buffers_per_acquisition'] # get the info about the FFT module if parameters['mode'] == 'FFT': dsp_array=board.dspGetModules() fft_module=dsp_array[0] dsp_info=fft_module.dspGetInfo() # define the channel mask according to the working mode of the digitizer if parameters['mode']== 'FFT': # Only channel A is used when on-FPGA FFT is active channels = ats.CHANNEL_A channelCount = 1 elif parameters['mode']== 'CHANNEL_AB': # For two active channels channels = ats.CHANNEL_A | ats.CHANNEL_B channelCount = 2 elif parameters['mode']== 'CHANNEL_A': # If channel A only is active channels = ats.CHANNEL_A channelCount = 1 elif parameters['mode']== 'CHANNEL_B': # If channel B only is active channels = ats.CHANNEL_B channelCount = 1 else: raise ValueError('mode of the digitizer must be "CHANNEL_AB" or \ "CHANNEL_A" or "CHANNEL_B" or "FFT"') # Compute the number of samples per record samplesPerRecord = preTriggerSamples + postTriggerSamples #Configure the FFT module if parameters['mode'] == 'FFT': fftLength_samples = 1 while fftLength_samples < samplesPerRecord : fftLength_samples *= 2 # Sets the real part of the FFT windowing fft_window_real=ats.dspGenerateWindowFunction(windowType, samplesPerRecord, fftLength_samples - samplesPerRecord) # According to the documentation, the imaginary part of the FFT windowing should be filled with zeros fft_window_imag=ats.dspGenerateWindowFunction(windowType, 0, fftLength_samples - samplesPerRecord) # Configures the FFT window fft_module.fftSetWindowFunction(samplesPerRecord,ctypes.c_void_p(fft_window_real.ctypes.data),ctypes.c_void_p(fft_window_imag.ctypes.data)) # Compute the number of bytes per record and per buffer # For now the output of the output of the on-FPGA FFT is set to 'FFT_OUTPUT_FORMAT_U16_AMP2', # thus the number of bytes per sample is 2 bytesPerSample = 2 # Computes the number of bytes per record according to the settings of the on-FPGA FFT bytesPerRecord=fft_module.fftSetup(channels, samplesPerRecord, fftLength_samples, ats.FFT_OUTPUT_FORMAT_U16_AMP2, ats.FFT_FOOTER_NONE,0) bytesPerBuffer = bytesPerRecord * recordsPerBuffer parameters['samplesPerRecord'] = bytesPerRecord/bytesPerSample else: # Compute the number of bytes per record and per buffer memorySize_samples, bitsPerSample = board.getChannelInfo() bytesPerSample = (bitsPerSample.value + 7) // 8 bytesPerRecord = bytesPerSample * samplesPerRecord bytesPerBuffer = bytesPerRecord * recordsPerBuffer * channelCount parameters['samplesPerRecord'] = bytesPerRecord/bytesPerSample # Select number of DMA buffers to allocate bufferCount = parameters['nb_buffer_allocated'] # Modified per Etienne. # Alazar gave bytesPerSample > 8 but this condition seemed strange to # me considering the previous code bytesPerSample = (bitsPerSample.value + 7) // 8 # Allocate DMA buffers sample_type = ctypes.c_uint8 if bytesPerSample > 1: sample_type = ctypes.c_uint16 buffers = [] for i in range(bufferCount): buffers.append(ats.DMABuffer(sample_type, bytesPerBuffer)) board.setRecordSize(preTriggerSamples, postTriggerSamples) # Prepate the board to work in the asynchroneous mode of acquisition recordsPerAcquisition = recordsPerBuffer * buffersPerAcquisition if parameters['mode'] == 'FFT': admaFlags = ats.ADMA_EXTERNAL_STARTCAPTURE| ats.ADMA_NPT | ats.ADMA_DSP board.beforeAsyncRead(channels, 0, bytesPerRecord, recordsPerBuffer, 0x7FFFFFFF, admaFlags) elif parameters['mode'] == 'CHANNEL_AB': board.beforeAsyncRead(channels, -preTriggerSamples, samplesPerRecord, recordsPerBuffer, recordsPerAcquisition, ats.ADMA_EXTERNAL_STARTCAPTURE \ | ats.ADMA_NPT | ats.ADMA_FIFO_ONLY_STREAMING) elif parameters['mode'] == 'CHANNEL_A': board.beforeAsyncRead(channels, -preTriggerSamples, samplesPerRecord, recordsPerBuffer, recordsPerAcquisition, ats.ADMA_EXTERNAL_STARTCAPTURE \ | ats.ADMA_NPT | ats.ADMA_FIFO_ONLY_STREAMING) elif parameters['mode'] == 'CHANNEL_B': board.beforeAsyncRead(channels, -preTriggerSamples, samplesPerRecord, recordsPerBuffer, recordsPerAcquisition, ats.ADMA_EXTERNAL_STARTCAPTURE \ | ats.ADMA_NPT | ats.ADMA_FIFO_ONLY_STREAMING) # Put the buffers previously created in the list of available buffers for buff in buffers: board.postAsyncBuffer(buff.addr, buff.size_bytes) return buffers