// NativeExportsConsumerApp.cpp : Defines the entry point for the console application.
 
//
 
 
 
#include "stdafx.h"
 
#include <string.h>
 
#include <windows.h>
 
#include "AitMduManager.h"
 
#include "AitMduManager_DEF.h"
 
 
 
typedef unsigned short ushort;
 
typedef unsigned int uint;
 
 
 
extern "C"
 
{
 
        DLLIMPORT  void NE_Rainbow();
 
 
 
        DLLIMPORT  int  NE_Func(int a);
 
        DLLIMPORT  int  NE_Ptr2ByteArray(char *, int len);
 
        DLLIMPORT  char * NE_ByteArray2Ptr(char *, int *);
 
        DLLIMPORT  int  NE_Ptr2String(char *, int len);
 
        DLLIMPORT  int  NE_String2Ptr(char *);
 
        DLLIMPORT  char * NE_String();
 
        DLLIMPORT  unsigned int * NE_UInt(int *);
 
}
 
 
 
#ifdef _DEBUG
 
#pragma comment(lib, "../UnmanagedDllInterface/bin/Debug/AitSipmDAQDll.lib")
 
#else
 
#pragma comment(lib, "../UnmanagedDllInterface/bin/Release/AitSipmDAQDll.lib")
 
#endif
 
 
 
uint deviceId = 0;
 
int deviceIndex = -1;
 
int adcBufferLen;
 
ushort * adcBuffer;
 
int histograms[4][0xFFF];
 
int histogramTotalEvents = 0;
 
 
 
const double MONADC_SCALE = 65535.0;                    // 16-bit monitor ADC
 
const double DAC_SCALE = 65535.0;                       // 16-bit DAC
 
const double MONADC_VRANGE = 2.5;                       // 2.5V ADC voltage range
 
const double DISCR_OFFSETRANGE = 250.0;         // +/- 250mV discriminator offset range
 
const double DISCR_THRESHOLDRANGE = 1000.0;     // 0-1000mV discriminator threshold range
 
const double HV_IRANGE = 5.0;                           // 0-5.0mA HV current monitor range
 
const double HV_VRANGE = 80.0;                          // 0-80V HV voltage control range
 
const int INTEGRATOR_LSB = 10;                          // 10ns integrator time resolution
 
const double RAMPRATESCALE = 61036.0;           // Ramp rate register setting = (rate in V/s) / RAMPRATESCALE
 
const char statusNoDevice[0xFF] = "No Device Connected";
 
const char statusReconfig[0xFF] = "Reconfiguring Device ... ";
 
const char statusReset[0xFF] = "Resetting Device ... ";
 
const char statusReconnect[0xFF] = "Reconnecting Device ... ";
 
const char statusDone[0xFF] = "Done";
 
 
 
/*
 
void Sleep(int musec) {
 
 
 
}
 
*/
 
 
 
//----------------------------------------
 
// Utilities
 
//----------------------------------------
 
ushort SetBit(ushort data, int bitIndex, bool bitValue)
 
{
 
        if (bitValue == true)
 
                return (ushort)(data | (1 << bitIndex));
 
        else
 
                return (ushort)(data & ~(1 << bitIndex));
 
}
 
 
 
bool GetBit(int data, int bitIndex)
 
{
 
        return (data & (1 << bitIndex)) != 0;
 
}
 
 
 
ushort ReadSD4Register(int reg)
 
{
 
        return SD4_Read(deviceId, reg);
 
}
 
 
 
uint ReadSD4Register32(int addrHi, int addrLo)
 
{
 
        uint dataHi = (uint)SD4_Read(deviceId, addrHi);
 
        uint dataLo = (uint)SD4_Read(deviceId, addrLo);
 
        return (dataHi << 16) | dataLo;
 
}
 
 
 
void WriteSD4Register(int address, ushort data)
 
{
 
        SD4_Write(deviceId, address, data);
 
}
 
 
 
void WriteSD4Register32(int addrHi, int addrLo, uint data)
 
{
 
        WriteSD4Register(addrHi, (ushort)(data >> 16));
 
        WriteSD4Register(addrLo, (ushort)data);
 
}
 
 
 
 
 
void ReadModifyWrite(int reg, int bitIndex, bool bitValue)
 
{
 
        ushort regData = ReadSD4Register(reg);
 
        regData = SetBit(regData, bitIndex, bitValue);
 
        WriteSD4Register(reg, regData);
 
}
 
 
 
double LimitSetting(double value, double min, double max)
 
{
 
        double limited = value;
 
        if (limited > max) limited = max;
 
        if (limited < min) limited = min;
 
        return limited;
 
}
 
 
 
 
 
 
 
int ReadAdcBuffer()
 
{
 
        //if (adcBuffer == NULL)
 
        //      return -1;
 
        int bytes = 0;
 
        //printf("In\n%d\n%d\n%d\n", deviceId, ADDR_BUFFER, adcBufferLen);
 
        adcBuffer = SD4_ReadUShortArray(deviceId, ADDR_BUFFER, adcBufferLen, &bytes);
 
        return bytes;
 
}
 
// Equivalent to ReadAdcBuffer() except using byte buffer for acquisition
 
int ReadAdcByteBuffer()
 
{
 
        if (adcBuffer == NULL)
 
                return -1;
 
        int bytes = 0;
 
        char * byteBuffer = SD4_ReadByteArray(deviceId, ADDR_BUFFER, adcBufferLen * 2, &bytes);
 
        int byteIndex = 0;
 
        int words = bytes / 2;
 
        ushort dataword = 0;
 
        for (int i = 0; i < words; i++)
 
        {
 
                dataword = (ushort)(byteBuffer[byteIndex++] << 8);
 
                adcBuffer[i] = (ushort)(dataword | byteBuffer[byteIndex++]);
 
        }
 
        return words;
 
}
 
 
 
 
 
 
 
 
 
 
 
 
 
//----------------------------------------
 
// Monitor ADC
 
//----------------------------------------
 
 
 
double GetVoltage(int reg)
 
{
 
        return ReadSD4Register(reg) * MONADC_VRANGE / MONADC_SCALE;
 
}
 
 
 
double GetDetectorTemperature()
 
{
 
        // Temperature = 500mV + 1mV per degree C
 
        return (GetVoltage(ADDR_BASE_TEMPERATURE) - 0.5) / 0.01;
 
}
 
 
 
double GetHvVoltage(int reg)
 
{
 
        return GetVoltage(reg) / MONADC_VRANGE * HV_VRANGE;
 
}
 
 
 
double GetHvCurrentInUa()
 
{
 
        // 2.5V ADC input voltage = 5000 microamps
 
        return GetVoltage(ADDR_HV_IMON) * 2000.0;
 
}
 
 
 
double GetVoltage75(int reg)
 
{
 
        // 2.5V ADC input voltage = 7.5V monitor voltage
 
        return GetVoltage(reg) * 3.0;
 
}
 
 
 
 
 
 
 
//----------------------------------------
 
// Discriminator, Sum
 
//----------------------------------------
 
 
 
void SetSumGain(int gain)
 
{
 
        ushort csrDetector = ReadSD4Register(ADDR_CSR_DETECTOR);
 
        bool g1 = GetBit(gain, 0);
 
        bool g2 = GetBit(gain, 1);
 
        bool g3 = GetBit(gain, 2);
 
        bool g4 = GetBit(gain, 3);
 
        csrDetector = SetBit(csrDetector, BIT_CSR_DET_SUMGAIN1, g1);
 
        csrDetector = SetBit(csrDetector, BIT_CSR_DET_SUMGAIN2, g2);
 
        csrDetector = SetBit(csrDetector, BIT_CSR_DET_SUMGAIN3, g3);
 
        csrDetector = SetBit(csrDetector, BIT_CSR_DET_SUMGAIN4, g4);
 
        WriteSD4Register(ADDR_CSR_DETECTOR, (ushort)csrDetector);
 
}
 
 
 
void SetSumCoupling(bool acCoupling)
 
{
 
        ReadModifyWrite(ADDR_CSR_DETECTOR, BIT_CSR_DET_SUMCOUPLING, acCoupling);
 
}
 
 
 
void SetThreshold(double thresholdInMillivolts)
 
{
 
        thresholdInMillivolts = LimitSetting(thresholdInMillivolts, -DISCR_THRESHOLDRANGE, DISCR_THRESHOLDRANGE);
 
        WriteSD4Register(ADDR_DISCR_THRESHOLD, (ushort)(thresholdInMillivolts * DAC_SCALE / DISCR_THRESHOLDRANGE));
 
}
 
 
 
double GetThreshold()
 
{
 
        return ReadSD4Register(ADDR_DISCR_THRESHOLD) / DAC_SCALE * DISCR_THRESHOLDRANGE;
 
}
 
 
 
double GetSumOffsetInMv()
 
{
 
        // Sum offsets are with respect to the positive sum output polarity.
 
        return (ReadSD4Register(ADDR_DISCR_OFFSET) / DAC_SCALE * (DISCR_OFFSETRANGE * 2)) - DISCR_OFFSETRANGE;
 
}
 
 
 
void SetSumOffset(double milliVolts)
 
{
 
        // Sum offsets are with respect to the positive sum output polarity.
 
        // Actual output offset is multiplied by the selectable gain stage.
 
        WriteSD4Register(ADDR_DISCR_OFFSET, (ushort)((milliVolts + DISCR_OFFSETRANGE) * DAC_SCALE / (DISCR_OFFSETRANGE * 2)));
 
}
 
 
 
 
 
 
 
//----------------------------------------
 
// Trigger
 
//----------------------------------------
 
 
 
void SetTriggerInterval(int triggerInterval)
 
{
 
        WriteSD4Register32(ADDR_TG_INTERVALHI, ADDR_TG_INTERVALLO, (uint)(triggerInterval / INTEGRATOR_LSB));
 
}
 
 
 
void SetTriggerBurst(int triggerBurst)
 
{
 
        WriteSD4Register32(ADDR_TG_COUNTHI, ADDR_TG_COUNTLO, (uint)triggerBurst);
 
}
 
 
 
void EnableTrigger(int bitIndex)
 
{
 
        WriteSD4Register(ADDR_CSR_TRIGGER, SetBit(0, bitIndex, true));
 
}
 
 
 
void DisableTriggers()
 
{
 
        WriteSD4Register(ADDR_CSR_TRIGGER, 0);
 
}
 
 
 
void SetDeadTime(int deadTimeInNs)
 
{
 
        WriteSD4Register(ADDR_DEADTIME, (ushort)(deadTimeInNs / INTEGRATOR_LSB));
 
}
 
 
 
 
 
 
 
//----------------------------------------
 
// Integrators, ADCs
 
//----------------------------------------
 
 
 
void SetIntegrationTime(int integrationTime)
 
{
 
        WriteSD4Register(ADDR_ITIME, (ushort)(integrationTime / INTEGRATOR_LSB));
 
}
 
 
 
int GetIntegrationTime()
 
{
 
        return ReadSD4Register(ADDR_ITIME) * INTEGRATOR_LSB;
 
}
 
 
 
void SetAdcCoupling(bool acCoupling)
 
{
 
        ReadModifyWrite(ADDR_CSR_DETECTOR, BIT_CSR_DET_ADCCOUPLING, acCoupling);
 
}
 
 
 
void ResetAdc(bool reset)
 
{
 
        ushort cmd = 0;
 
        cmd = SetBit(cmd, BIT_CSR_MAIN_ADCRESET, reset);
 
        WriteSD4Register(ADDR_CSR_MAIN, cmd);
 
}
 
 
 
double GetAdcOffsetInMv(int reg)
 
{
 
        // ADC offset polarity is with respect to the positive ADC polarity (integrator output), not the main negative input signal polarity.
 
        // Actual output offset is multiplied by the selectable gain stage.
 
        return DISCR_OFFSETRANGE - (ReadSD4Register(reg) / DAC_SCALE * (DISCR_OFFSETRANGE * 2));
 
}
 
 
 
void SetAdcOffset(int reg, double milliVolts)
 
{
 
        // ADC offset polarity is with respect to the positive ADC polarity (integrator output), not the main negative input signal polarity.
 
        // Actual output offset is multiplied by the selectable gain stage.
 
        WriteSD4Register(reg, (ushort)((DISCR_OFFSETRANGE - milliVolts) * DAC_SCALE / (DISCR_OFFSETRANGE * 2)));
 
}
 
 
 
 
 
 
 
//----------------------------------------
 
// Event ID
 
//----------------------------------------
 
 
 
void AddEventCount(bool addEventCount)
 
{
 
        ReadModifyWrite(ADDR_EVENTID, BIT_EVENTID_COUNT, addEventCount);
 
}
 
 
 
void AddTimeStamp(bool addTimeStamp)
 
{
 
        ReadModifyWrite(ADDR_EVENTID, BIT_EVENTID_TIME, addTimeStamp);
 
}
 
 
 
void AddChannelNumber(bool addChannelNumber)
 
{
 
        ReadModifyWrite(ADDR_EVENTID, BIT_EVENTID_CHNUM, addChannelNumber);
 
}
 
 
 
 
 
 
 
//----------------------------------------
 
// Detector VA
 
//----------------------------------------
 
 
 
void SetDetectorVaOn(bool on)
 
{
 
        ReadModifyWrite(ADDR_CSR_DETECTOR, BIT_CSR_DET_VAENABLE, on);
 
}
 
 
 
void SetDetectorVaHiRange(bool range)
 
{
 
        ReadModifyWrite(ADDR_CSR_DETECTOR, BIT_CSR_DET_VAHIRNG, range);
 
}
 
 
 
 
 
 
 
//----------------------------------------
 
// High Voltage
 
//----------------------------------------
 
 
 
void SetHvCurrentLimit(double milliamps)
 
{
 
        milliamps = LimitSetting(milliamps, 0, HV_IRANGE);
 
        WriteSD4Register(ADDR_HV_ILIMIT, (ushort)(milliamps * DAC_SCALE / HV_IRANGE));
 
}
 
 
 
void SetHvVoltage(int reg, double volts)
 
{
 
        volts = LimitSetting(volts, 0, HV_VRANGE);
 
        WriteSD4Register(reg, (ushort)(volts * DAC_SCALE / HV_VRANGE));
 
}
 
 
 
double GetHvIlimitSetting()
 
{
 
        return ReadSD4Register(ADDR_HV_ILIMIT) / DAC_SCALE * HV_IRANGE;
 
}
 
 
 
double GetHvVoltageSetting()
 
{
 
        return ReadSD4Register(ADDR_HV_CTRL) / DAC_SCALE * HV_VRANGE;
 
}
 
 
 
void SetHvOn(bool hvOn)
 
{
 
        ReadModifyWrite(ADDR_CSR_DETECTOR, BIT_CSR_DET_HVENABLE, hvOn);
 
}
 
 
 
void SetMaximumHvSetting(double volts)
 
{
 
        SetHvVoltage(ADDR_HV_MAX, volts);
 
}
 
 
 
void CycleHvReset()
 
{
 
        // CAUTION: Holding HV in reset will force it to ignore the current limit
 
        ReadModifyWrite(ADDR_CSR_DETECTOR, BIT_CSR_DET_HVRESET, true);
 
        ReadModifyWrite(ADDR_CSR_DETECTOR, BIT_CSR_DET_HVRESET, false);
 
}
 
 
 
void SetRampRate(double voltsPerSecond)
 
{
 
        WriteSD4Register(ADDR_HV_RAMPRATE, (ushort)(RAMPRATESCALE / voltsPerSecond));
 
}
 
 
 
double GetRampRate()
 
{
 
        return RAMPRATESCALE / (ReadSD4Register(ADDR_HV_RAMPRATE) + 1);
 
}
 
 
 
void SetAdcGain(int gain)
 
{
 
        ushort csrDetector = ReadSD4Register(ADDR_CSR_DETECTOR);
 
        bool g1 = GetBit(gain, 0);
 
        bool g2 = GetBit(gain, 1);
 
        csrDetector = SetBit(csrDetector, BIT_CSR_DET_ADCGAIN1, g1);
 
        csrDetector = SetBit(csrDetector, BIT_CSR_DET_ADCGAIN2, g2);
 
        WriteSD4Register(ADDR_CSR_DETECTOR, (ushort)csrDetector);
 
}
 
 
 
void SetAdcOffsets(int offsetInMv)
 
{
 
        //nudOffset1.Value = offsetInMv;
 
        //nudOffset2.Value = offsetInMv;
 
        //nudOffset3.Value = offsetInMv;
 
        //nudOffset4.Value = offsetInMv;
 
        SetAdcOffset(ADDR_OFFSET1, offsetInMv);
 
        SetAdcOffset(ADDR_OFFSET2, offsetInMv);
 
        SetAdcOffset(ADDR_OFFSET3, offsetInMv);
 
        SetAdcOffset(ADDR_OFFSET4, offsetInMv);
 
}
 
 
 
void QuickSetupContinuous()
 
{
 
        // Set ADC reset
 
        ResetAdc(true);
 
 
 
        // Clear ADC reset
 
        ResetAdc(false);
 
 
 
        // Set trigger dead time to 200ns
 
        SetDeadTime(200);
 
 
 
        // Set event ID
 
        AddTimeStamp(true);
 
        AddEventCount(true);
 
        AddChannelNumber(true);
 
 
 
        // Enable detector amplifier voltage
 
        SetDetectorVaHiRange(false);
 
        SetDetectorVaOn(true);
 
 
 
        /*
 
        // Set HV current limit
 
        double iLimit = 2.5;
 
        nudHvIlimit.Value = (decimal)iLimit;
 
        SetHvCurrentLimit(iLimit);
 
 
 
        // Reset any HV faults
 
        CycleHvReset();
 
 
 
        // Enable bias voltage
 
        SetHvOn(false);
 
        SetHvOn(true);
 
 
 
        // Set bias voltage
 
        double hvVoltage = 30.0;
 
        nudHvVoltage.Value = (decimal)hvVoltage;
 
        SetHvVoltage(ADDR_HV_CTRL, hvVoltage);
 
        */
 
 
 
        // Set integration time
 
        int integrationTime = 350;
 
        //nudIntegrationTime.Value = integrationTime;
 
        SetIntegrationTime(integrationTime);
 
 
 
        // Set discriminator threshold
 
        int threshold = 50;
 
        //nudThreshold.Value = threshold;
 
        SetThreshold(threshold);
 
 
 
        // Set sum coupling
 
        SetSumCoupling(true);
 
 
 
        // Set sum gain
 
        int sumGain = 3;
 
        //nudSumGain.Value = sumGain;
 
        SetSumGain(sumGain);
 
 
 
        // Set sum offset
 
        int offset = 0;
 
        //nudSumOffset.Value = offset;
 
        SetSumOffset(offset);
 
 
 
        // Set ADC coupling
 
        SetAdcCoupling(false);
 
 
 
        // Set ADC gains
 
        int gain = 1;
 
        //nudAdcGain.Value = gain;
 
        SetAdcGain(gain);
 
 
 
        // Set all ADC offsets
 
        SetAdcOffsets(5);
 
 
 
        // Set internal trigger interval
 
        int triggerInterval = 1000;
 
        //nudTriggerInterval.Value = triggerInterval;
 
        SetTriggerInterval(triggerInterval);
 
 
 
        // Enable continuous trigger
 
        EnableTrigger(BIT_CSR_TRIG_CONTINUOUS);
 
 
 
        // Begin continuous acquisition
 
        //nudEventsPerAcquisition.Value = 50000;
 
        //cbAcquireContinuous.Checked = true;
 
 
 
        // Update histogram offsets
 
        //SetAllHistogramOffsets(0);
 
}
 
 
 
 
 
void QuickSetupDiscriminator()
 
{
 
        // Set ADC reset
 
        ResetAdc(true);
 
 
 
        // Clear ADC reset
 
        ResetAdc(false);
 
 
 
        // Set trigger dead time to 300ns
 
        SetDeadTime(500);
 
 
 
        // Set event ID
 
        AddTimeStamp(true);
 
        AddEventCount(true);
 
        AddChannelNumber(true);
 
 
 
        // Enable detector amplifier voltage
 
        SetDetectorVaHiRange(true);
 
        SetDetectorVaOn(true);
 
 
 
        // Set HV current limit
 
        double iLimit = 2.5;
 
        //nudHvIlimit.Value = (decimal)iLimit;
 
        SetHvCurrentLimit(iLimit);
 
 
 
        // Reset any HV faults
 
        CycleHvReset();
 
 
 
        // Enable bias voltage
 
        SetHvOn(false);
 
        SetHvOn(true);
 
 
 
        // Set bias voltage
 
        double hvVoltage = 30.0;
 
        //nudHvVoltage.Value = (decimal)hvVoltage;
 
        SetHvVoltage(ADDR_HV_CTRL, hvVoltage);
 
 
 
        // Set integration time
 
        int integrationTime = 350;
 
        //nudIntegrationTime.Value = integrationTime;
 
        SetIntegrationTime(integrationTime);
 
 
 
        // Set discriminator threshold
 
        int threshold = 50;
 
        //nudThreshold.Value = threshold;
 
        SetThreshold(threshold);
 
 
 
        // Set sum coupling
 
        SetSumCoupling(true);
 
 
 
        // Set sum gain
 
        int sumGain = 3;
 
        //nudSumGain.Value = sumGain;
 
        SetSumGain(sumGain);
 
 
 
        // Set sum offset
 
        int offset = 0;
 
        //nudSumOffset.Value = offset;
 
        SetSumOffset(offset);
 
 
 
        // Set ADC coupling
 
        SetAdcCoupling(false);
 
 
 
        // Set ADC gains
 
        int gain = 1;
 
        //nudAdcGain.Value = gain;
 
        SetAdcGain(gain);
 
 
 
        // Set all ADC offsets
 
        SetAdcOffsets(5);
 
 
 
        // Clear histograms
 
        //ClearHistograms();
 
 
 
        // Enable discriminator trigger
 
        EnableTrigger(BIT_CSR_TRIG_DISCR);
 
 
 
        // Begin continuous acquisition
 
        //nudEventsPerAcquisition.Value = 1000;
 
        //cbAcquireContinuous.Checked = true;
 
 
 
        // Update histogram offsets
 
        //SetAllHistogramOffsets(0);
 
}
 
 
 
void QuickSetupTriggerOff()
 
{
 
        //cbAcquireContinuous.Checked = false;
 
        DisableTriggers();
 
        SetHvOn(false);
 
        SetDetectorVaOn(false);
 
}
 
 
 
void ReadRegisters()
 
{
 
        if (deviceIndex < 0)
 
                return;
 
 
 
        // Voltages
 
        double lHvImon = GetHvCurrentInUa();
 
        double HvVmon = GetHvVoltage(ADDR_HV_VMON);
 
        double HvVmax = GetHvVoltage(ADDR_HV_MAX);
 
        double lDetPva = GetVoltage75(ADDR_BASE_PVA);
 
        double lDetNva = GetVoltage75(ADDR_BASE_NVA);
 
        double lPva = GetVoltage75(ADDR_MAIN_PVA);
 
        double lNva = GetVoltage75(ADDR_MAIN_NVA);
 
        double l12V = GetVoltage(ADDR_MAIN_P12);
 
        double l33V = GetVoltage75(ADDR_MAIN_P33);
 
        double l50V = GetVoltage75(ADDR_MAIN_P50);
 
        double Temperature = GetDetectorTemperature();
 
        double lRampRate = GetRampRate();
 
 
 
        // Integration time
 
        int lItime = GetIntegrationTime();
 
 
 
        // Buffer memory used
 
        int lBufferWords = ReadSD4Register(ADDR_BUFFERWORDS);
 
 
 
        // Offsets
 
        double  lOffset1 = GetAdcOffsetInMv(ADDR_OFFSET1);
 
        double  lOffset2 = GetAdcOffsetInMv(ADDR_OFFSET2);
 
        double  lOffset3 = GetAdcOffsetInMv(ADDR_OFFSET3);
 
        double  lOffset4 = GetAdcOffsetInMv(ADDR_OFFSET4);
 
        double  lSumOffset = GetSumOffsetInMv();
 
 
 
        // Main CSR
 
        int csrMain = ReadSD4Register(ADDR_CSR_MAIN);
 
        int lPvaStatus = GetBit(csrMain, BIT_CSR_MAIN_PVA);
 
        int lNvaStatus = GetBit(csrMain, BIT_CSR_MAIN_NVA);
 
        int l12vStatus = GetBit(csrMain, BIT_CSR_MAIN_P12);
 
        int l33vStatus = GetBit(csrMain, BIT_CSR_MAIN_P33);
 
        int l5vStatus = GetBit(csrMain, BIT_CSR_MAIN_P50);
 
 
 
        // Trigger CSR
 
        // Assumes only one trigger source is active
 
        char lTriggerSource[0xFF];
 
        int csrTrigger = ReadSD4Register(ADDR_CSR_TRIGGER);
 
        if (GetBit(csrTrigger, BIT_CSR_TRIG_CONTINUOUS))
 
                sprintf_s(lTriggerSource, 0xFF, "CONTINUOUS");
 
        else if (GetBit(csrTrigger, BIT_CSR_TRIG_BURST))
 
                sprintf_s(lTriggerSource, 0xFF, "BURST");
 
        else if (GetBit(csrTrigger, BIT_CSR_TRIG_DISCR))
 
                sprintf_s(lTriggerSource, 0xFF, "DISCRIMINATOR");
 
        else if (GetBit(csrTrigger, BIT_CSR_TRIG_EXTERNAL))
 
                sprintf_s(lTriggerSource, 0xFF, "EXTERNAL");
 
        else
 
                sprintf_s(lTriggerSource, 0xFF, "OFF");
 
 
 
        // Event ID CSR
 
        int csrEventId = ReadSD4Register(ADDR_EVENTID);
 
        int addTimeStamp = GetBit(csrEventId, BIT_EVENTID_TIME);
 
        int addEventCount = GetBit(csrEventId, BIT_EVENTID_COUNT);
 
        int addChannelNum = GetBit(csrEventId, BIT_EVENTID_CHNUM);
 
        //lTimeStamp.Text = addTimeStamp ? "+" : "";
 
        //lEventCount.Text = addEventCount ? "+" : "";
 
        //lChannelNum.Text = addChannelNum ? "+" : "";
 
 
 
        // Trigger generator
 
        int lTriggerInterval = ReadSD4Register32(ADDR_TG_INTERVALHI, ADDR_TG_INTERVALLO) * 10;
 
        int lTrigCount = ReadSD4Register32(ADDR_TG_COUNTHI, ADDR_TG_COUNTLO);
 
        ushort dum = 0;
 
        WriteSD4Register(ADDR_TC_COUNTLO, dum);         // latch counters by writing to any counter register
 
        int lTriggers = ReadSD4Register32(ADDR_TC_COUNTHI, ADDR_TC_COUNTLO);
 
        int lTriggerRate = ReadSD4Register32(ADDR_TC_RATEHI, ADDR_TC_RATELO);
 
        int lAdcConversions = ReadSD4Register32(ADDR_CONV_COUNTHI, ADDR_CONV_COUNTLO);
 
        double lThreshold = GetThreshold();
 
        double lHvIlimit = GetHvIlimitSetting();
 
        double lHvVoltage = GetHvVoltageSetting();
 
 
 
        // Detector CSR
 
        int csrDetector = ReadSD4Register(ADDR_CSR_DETECTOR);
 
        int lHvEnabled = GetBit(csrDetector, BIT_CSR_DET_HVENABLE);
 
        int lHvOn = GetBit(csrDetector, BIT_CSR_DET_HVGOOD);
 
        int lSumCoupling = GetBit(csrDetector, BIT_CSR_DET_SUMCOUPLING);
 
        int lSumGain =
 
                ((GetBit(csrDetector, BIT_CSR_DET_SUMGAIN4) ? 1 : 0) << 3) |
 
                ((GetBit(csrDetector, BIT_CSR_DET_SUMGAIN3) ? 1 : 0) << 2) |
 
                ((GetBit(csrDetector, BIT_CSR_DET_SUMGAIN2) ? 1 : 0) << 1) |
 
                ((GetBit(csrDetector, BIT_CSR_DET_SUMGAIN1) ? 1 : 0) << 0);
 
        int lAdcCoupling = GetBit(csrDetector, BIT_CSR_DET_ADCCOUPLING);
 
        int lAdcGain = ((GetBit(csrDetector, BIT_CSR_DET_ADCGAIN2) ? 1 : 0) << 1) |
 
                ((GetBit(csrDetector, BIT_CSR_DET_ADCGAIN1) ? 1 : 0) << 0);
 
        int lAmpEnabled = GetBit(csrDetector, BIT_CSR_DET_VAENABLE);
 
        int lAmpLevel = GetBit(csrDetector, BIT_CSR_DET_VAHIRNG);
 
        int lDetPvaStatus = GetBit(csrDetector, BIT_CSR_DET_PVAGOOD);
 
        int lDetNvaStatus = GetBit(csrDetector, BIT_CSR_DET_NVAGOOD);
 
        int lTemperatureOn = GetBit(csrDetector, BIT_CSR_DET_TEMPVALID);
 
}
 
 
 
 
 
 
 
//----------------------------------------
 
// Message list
 
//----------------------------------------
 
 
 
void AddMessage(const char * message)
 
{
 
        printf("%s\n", message);
 
}
 
 
 
 
 
 
 
 
 
 
 
//----------------------------------------
 
// MDU Events
 
//----------------------------------------
 
 /*
 
private void AitDeviceAttached(object sender, EventArgs e)
 
{
 
        MduManager.DeviceChangedEventArgs aitEventArgs = e as MduManager.DeviceChangedEventArgs;
 
        AddMessage(String.Format("Attached : Index={0}, ID={1:X8}", aitEventArgs.DeviceIndex, aitEventArgs.DeviceId));
 
        UpdateDeviceList();
 
}
 
 
 
private void AitDeviceRemoved(object sender, EventArgs e)
 
{
 
        MduManager.DeviceChangedEventArgs aitEventArgs = e as MduManager.DeviceChangedEventArgs;
 
        AddMessage(String.Format("Removed : Index={0}, ID={1:X8}", aitEventArgs.DeviceIndex, aitEventArgs.DeviceId));
 
        UpdateDeviceList();
 
}
 
 
 
*/
 
 
 
//----------------------------------------
 
// Device Control
 
//----------------------------------------
 
 
 
int UpdateDeviceList()
 
{
 
        
 
        deviceIndex = -1;
 
        deviceId = 0;
 
        int deviceCount = 0;
 
        uint * devIds = SD4_GetDeviceList(&deviceCount);
 
        for (int i = 0; i < deviceCount; i++) {
 
                printf("Device %d = 0x%8x\n", i, devIds[i]);
 
                deviceId = devIds[i];
 
                deviceIndex =     i;
 
        }
 
        return deviceCount;
 
}
 
 
 
void ResetDevice()
 
{
 
        if (deviceIndex >= 0)
 
        {
 
                AddMessage(statusReset);
 
                SD4_ResetFpga(deviceIndex);
 
                Sleep(500);
 
                UpdateDeviceList();
 
                AddMessage(statusReset);
 
                AddMessage(statusDone);
 
        }
 
        else
 
                AddMessage(statusNoDevice);
 
}
 
 
 
void ReconnectDevice()
 
{
 
        if (deviceIndex >= 0)
 
        {
 
                AddMessage(statusReconnect);
 
                SD4_Reconnect(deviceIndex);
 
                Sleep(500);
 
                AddMessage(statusReconnect);
 
                AddMessage(statusDone);
 
        }
 
        else
 
                AddMessage(statusNoDevice);
 
}
 
 
 
void ReconfigureDevice()
 
{
 
        if (deviceIndex >= 0)
 
        {
 
                AddMessage(statusReconfig);
 
                SD4_Reconfigure(deviceIndex);
 
                Sleep(500);
 
                SD4_ResetFpga(deviceIndex);
 
                UpdateDeviceList();
 
                AddMessage(statusReconfig);
 
                AddMessage(statusDone);
 
        }
 
        else
 
                AddMessage(statusNoDevice);
 
}
 
 
 
//----------------------------------------
 
// Initialize Device Connection
 
//----------------------------------------
 
 
 
void InitializeConnection()
 
{
 
        int ndevices = 0;
 
        unsigned int * devlist = SD4_FindDevices(&ndevices);
 
        printf("Found %d devices\n", ndevices);
 
        //SD4.DeviceAttached += new EventHandler(AitDeviceAttached);
 
        //SD4.DeviceRemoved += new EventHandler(AitDeviceRemoved);
 
        //tscbDeviceList.SelectedIndexChanged += new EventHandler(tscbDeviceList_SelectedIndexChanged);
 
        printf("Updated devices %d\n", UpdateDeviceList());
 
}
 
 
 
 
 
const int CHANNELS = 4;                 // 4-Channel DAQ
 
const int ADCMAX = 4096;                // 12-bit ADC
 
 
 
bool addTimeStamp = false;              // updated by ReadRegisters
 
bool addEventCount = false;             // updated by ReadRegisters
 
bool addChannelNum = false;             // updated by ReadRegisters
 
 
 
int TIMESTAMP_LSB = 10;                 // 10ns time stamp resolution
 
 
 
 
 
 
 
int GetAdcEventSize()
 
{
 
        int eventSize = CHANNELS;
 
        if (addTimeStamp == true)
 
                eventSize += 3;         // 3 16-bit words for time stamp
 
        if (addEventCount == true)
 
                eventSize += 2;         // 2 16-bit words for event count
 
        return eventSize;
 
}
 
 
 
int GetEventPosition(int eventNum)
 
{
 
        int adcBoardEventSize = GetAdcEventSize();
 
        return adcBoardEventSize * eventNum;
 
}
 
 
 
ushort ExtractAdcData(int eventNum, int channel)
 
{
 
        int index = GetEventPosition(eventNum) + channel;
 
        return adcBuffer[index];
 
}
 
 
 
long ExtractTimeStamp(int eventNum)
 
{
 
        int index = GetEventPosition(eventNum) + CHANNELS;
 
        long timestamp = 0;
 
        for (int i = 0; i < 3; i++)
 
                timestamp = (timestamp << 16) | adcBuffer[index++];
 
        return timestamp;
 
}
 
 
 
int ExtractEventCount(int eventNum)
 
{
 
        int offset = 0;
 
        if (addTimeStamp == true)
 
                offset += 3;
 
        int index = GetEventPosition(eventNum) + CHANNELS + offset;
 
        int eventCount = adcBuffer[index];
 
        eventCount = (eventCount << 16) | adcBuffer[index + 1];
 
        return eventCount;
 
}
 
 
 
void ShowEvent(int eventNumber)
 
{
 
        if (eventNumber < 1)
 
                return;
 
        eventNumber--;
 
        char lAdcTimeStamp[0xFF];
 
        char lAdcAbsTimeStamp[0xFF];
 
        char lAdcEventCount[0xFF];
 
        //tbAdcData.Clear();
 
        int eventPosition = GetEventPosition(eventNumber);
 
        for (int channel = 0; channel < CHANNELS; channel++)
 
        {
 
                int data = ExtractAdcData(eventNumber, channel);
 
                printf(" 0:%d  1:%d ", channel + 1, data);
 
                if (channel < (CHANNELS - 1))
 
                        printf("\n");
 
        }
 
        if (addTimeStamp == true)
 
        {
 
                long reference = ExtractTimeStamp(0);
 
                long timeStamp = ExtractTimeStamp(eventNumber);
 
                sprintf_s(lAdcTimeStamp, 0xFF, "%d", ((timeStamp - reference) * TIMESTAMP_LSB));
 
                sprintf_s(lAdcAbsTimeStamp, 0xFF, "%d", (timeStamp * TIMESTAMP_LSB));
 
        }
 
        else
 
        {
 
                sprintf_s(lAdcTimeStamp, 0xFF, "%s", "----");
 
                sprintf_s(lAdcAbsTimeStamp, 0xFF, "%s", "----");
 
        }
 
        if (addEventCount == true)
 
        {
 
                sprintf_s(lAdcEventCount, 0xFF, "%d", ExtractEventCount(eventNumber));
 
        }
 
        else
 
        {
 
                sprintf_s(lAdcEventCount, 0xFF, "%s", "----");
 
        }
 
        //SetTextboxToTop(tbAdcData);
 
}
 
 
 
int Acquire(int events)
 
{
 
        // Acquire
 
        adcBufferLen = GetAdcEventSize() * events;
 
        //adcBuffer = new ushort[adcBufferLen];
 
 
 
        //int wordsAcquired = ReadAdcByteBuffer();              //  use only to test byte buffer read operation
 
        int wordsAcquired = ReadAdcBuffer();
 
        if (wordsAcquired != adcBufferLen)
 
        {
 
                char msg[0xFF];
 
                sprintf_s(msg, "ERROR: Timeout with possible data loss (%d/%d words received; Block Error = %d)", wordsAcquired, adcBufferLen, SD4_BlockError());
 
                AddMessage(msg);
 
                /*
 
                if (cbAcquireContinuous.Checked == true)
 
                {
 
                        cbAcquireContinuous.Checked = false;
 
                        AddMessage("Acquisition disabled");
 
                }
 
                */
 
        }
 
 
 
        // Update UI
 
        double blocksize = adcBufferLen * 2.0;
 
        double microseconds = SD4_BlockTransferTime();
 
        double transferRate = blocksize / microseconds;
 
        /*
 
        lTransferRate.Text = String.Format("{0:f2}", transferRate);
 
        lAcquisitionSize.Text = String.Format("{0:f2}", blocksize / 1e6);               // block size in MB
 
        lAcquisitionTime.Text = String.Format("{0:f2}", microseconds / 1e6);
 
        */
 
        return events;
 
}
 
 
 
void GetStatistics(int events)
 
{
 
        ushort rawAdcData = 0;
 
        ushort adcData = 0;
 
        int channelReceived = 0;
 
        int channelExpected = 0;
 
        bool includeSaturated = 0; // cbIncludeSaturated.Checked;
 
        ushort * max = new ushort[CHANNELS];
 
        ushort * min = new ushort[CHANNELS];
 
        ushort * average = new ushort[CHANNELS];
 
        int*  total = new int[CHANNELS];
 
        for (int i = 0; i < CHANNELS; i++)
 
        {
 
                min[i] = 0xFFFF;
 
                max[i] = 0;
 
                total[i] = 0;
 
        }
 
        for (int eventNum = 0; eventNum < events; eventNum++)
 
        {
 
                for (int channel = 0; channel < CHANNELS; channel++)
 
                {
 
                        rawAdcData = ExtractAdcData(eventNum, channel);
 
                        if (addChannelNum == true)
 
                        {
 
                                channelReceived = (rawAdcData >> 12) & 0xF;
 
                                channelExpected = (channel & 0xF);
 
                                if (channelReceived != channelExpected)
 
                                {
 
                                        char msg[0xFF];
 
                                        sprintf_s(msg, "ERROR in Event %d : Expected channel %d, received %d -ANALYSIS STOPPED", eventNum, channelExpected, channelReceived);
 
                                        AddMessage(msg);
 
                                        //EnableRegisterScanTimer(true);
 
                                        return;
 
                                }
 
                        }
 
                        adcData = (ushort)(rawAdcData & 0x0FFF);                // remove channel number
 
                        if ((includeSaturated == true) || ((includeSaturated == false) && (adcData < (ADCMAX - 2))))
 
                                histograms[channel][adcData]++;
 
                        total[channel] = total[channel] + adcData;
 
                        if (adcData > max[channel])
 
                                max[channel] = adcData;
 
                        else if (adcData < min[channel])
 
                                min[channel] = adcData;
 
                }
 
                histogramTotalEvents++;
 
        }
 
        //tbAdcStatistics.Clear();
 
        for (int channel = 0; channel < CHANNELS; channel++)
 
        {
 
                average[channel] = (ushort)(total[channel] / events);
 
                char msg[0xFF];
 
                sprintf_s(msg, " {0:%d}  : {1:0x%04x}  {2:0x%04x}  {3:0x%04x}  {4:0x%04x}", channel + 1, min[channel], max[channel], max[channel] - min[channel], average[channel]);
 
                //if (channel < (CHANNELS - 1))
 
          //      tbAdcStatistics.AppendText(Environment.NewLine);
 
                AddMessage(msg);
 
        }
 
        //SetTextboxToTop(tbAdcStatistics);
 
}
 
 
 
void SetupAcquisition(int neve)
 
{
 
        //EnableRegisterScanTimer(false);
 
        //nudEventSelect.Minimum = 0;
 
        //nudEventSelect.Maximum = 0;
 
        int eventsAcquired = Acquire(neve);
 
        if (eventsAcquired < 1)
 
                return;
 
        GetStatistics(eventsAcquired);
 
        ShowEvent(1);
 
        //ShowHistograms();
 
        //nudEventSelect.Minimum = 1;
 
        //nudEventSelect.Maximum = eventsAcquired;
 
        //EnableRegisterScanTimer(true);
 
}
 
 
 
int main(int argc, _TCHAR* argv[])
 
//int _tmain(int argc, _TCHAR* argv[])
 
{
 
 
 
 
 
        NE_Rainbow();
 
        //-----------------------------------
 
        char bla[100] = "abcd";
 
        NE_Ptr2ByteArray(bla, strlen(bla));
 
        //-----------------------------------
 
        char data[1000] = { 1,0,0,1,0,0,0,0,1,1,1,1 };
 
        int len = 0;
 
        //char *data=NULL;
 
        int *retval = (int *)NE_ByteArray2Ptr(data, &len);
 
        int *idata = (int*)data;
 
        printf("***NE_ByteArray2Ptr %d\n", len);
 
        for (int i = 0; i < len; i++) printf("%d %d %d\n", i, idata[i], retval[i]);
 
        printf("\n");
 
        //-----------------------------------
 
        char data1[100] = "NE_Ptr2String";
 
        NE_Ptr2String(data1, strlen(data1));
 
        //-----------------------------------
 
        char data2[100] = "abcd";
 
        int nb = NE_String2Ptr(data2);
 
        //-----------------------------------
 
 
 
        printf("result = %d %s\n", nb, bla);
 
        printf("string = %s\n", NE_String());
 
 
 
        //-----------------------------------
 
        unsigned int *n = NE_UInt(&len);
 
        printf("NE_UInt size = %d\n", len);
 
        for (int i = 0; i < len; i++) printf("%d\t", n[i]);
 
        printf("\n");
 
        //-----------------------------------
 
 
 
        int events = 1000;
 
        adcBufferLen = GetAdcEventSize() * events;
 
        //adcBuffer = new ushort[GetAdcEventSize() * events];
 
        for (int i = 0; i < 0xFFF; i++) {
 
                for (int j = 0; j < 4; j++) histograms[j][i] = 0;
 
        }
 
        histogramTotalEvents = 0;
 
        InitializeConnection();
 
        QuickSetupContinuous();
 
        ReadRegisters();
 
        SetupAcquisition(1);
 
 
 
        return 0;
 
}