// NativeExportsConsumerApp.cpp : Defines the entry point for the console application.
 
//
 
#include <utility.h>
 
#include <stdlib.h>
 
#include <stdio.h>
 
#include "AitMduManager.h"
 
#include "AitMduManager_DEF.h"
 
 
 
//Unhandled Exception: System.Runtime.InteropServices.MarshalDirectiveException: 
 
//Cannot marshal 'return value': Invalid managed/unmanaged type combination.
 
#ifdef _CVI_
 
#include <ansi_c.h>
 
 
 
#define AddMessageI(x) AddMessage("%s %d\n", #x, x);
 
#define AddMessageF(x) AddMessage("%s %f\n", #x, x);
 
#define AddMessageX(x) AddMessage("%s 0x%x\n", #x, x);
 
#define AddMessageS(x) AddMessage("%s %s\n", #x, x);   
 
 
 
int sprintf_s(const char *dest, int len, const char *format, ...) {
 
        va_list aptr;
 
        int ret;
 
 
 
 
 
        ret = vsnprintf(dest, len, format, aptr);
 
        return(ret);
 
}
 
 
 
 
 
#endif
 
 
 
typedef unsigned short ushort;
 
typedef unsigned int uint;
 
#ifdef __cplusplus
 
extern "C"
 
{
 
#endif
 
        __declspec(dllimport) void NE_Rainbow();
 
#ifdef __cplusplus
 
}
 
#endif
 
 
 
#ifndef _CVI_
 
 
 
#ifdef _DEBUG
 
#pragma comment(lib, "../NativeExports/bin/Debug/NativeExports.lib")
 
#else
 
#pragma comment(lib, "../NativeExports/bin/Release/NativeExports.lib")
 
#endif
 
 
 
#endif
 
 
 
                //private MduManager SD4;
 
                uint deviceId = 0;
 
        int deviceIndex = -1;
 
        int adcBufferLen;
 
        ushort *adcBuffer;
 
        int histograms[4][0xFFF];
 
        int histogramtotal[0xFFF * 4];
 
 
 
        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";
 
 
 
 
 
        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
 
 
 
 
 
 
 
        void Sleep(int musec) {
 
      Delay(musec/1000.);
 
        }
 
 
 
        /*
 
                void AddMessage( const char * message)
 
                {
 
                  printf("%s\n", message);
 
                }
 
                */
 
 
 
        int AddMessage(const char *format, ...) {
 
                va_list aptr;
 
                int ret;
 
 
 
                char strbuf[0xFF];
 
 
 
                //  SetCtrlVal(p1h,P1_STDIO,strbuf);
 
 
 
 
 
                return(ret);
 
        }
 
 
 
 
 
        //----------------------------------------
 
        // 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/2;
 
}
 
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 = 28.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();
 
 
 
 
 
                AddMessageF(lHvImon);
 
                AddMessageF(HvVmon);
 
                AddMessageF(HvVmax);
 
                AddMessageF(lDetPva);
 
                AddMessageF(lDetNva);
 
                AddMessageF(lPva);
 
                AddMessageF(lNva);
 
                AddMessageF(l12V);
 
                AddMessageF(l33V);
 
                AddMessageF(l50V);
 
                AddMessageF(Temperature);
 
                AddMessageF(lRampRate);
 
 
 
 
 
 
 
 
 
 
 
                // 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);
 
 
 
 
 
                AddMessageF(lOffset1);
 
                AddMessageF(lOffset2);
 
                AddMessageF(lOffset3);
 
                AddMessageF(lOffset4);
 
                AddMessageF(lSumOffset);
 
                AddMessageX(csrMain);
 
                AddMessageX(lNvaStatus);
 
                AddMessageX(lNvaStatus);
 
                AddMessageX(l12vStatus);
 
                AddMessageX(l33vStatus);
 
                AddMessageX(l5vStatus);
 
 
 
                AddMessageI(lBufferWords);
 
                AddMessageI(lItime);
 
 
 
                // 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);
 
                addTimeStamp = GetBit(csrEventId, BIT_EVENTID_TIME);
 
                addEventCount = GetBit(csrEventId, BIT_EVENTID_COUNT);
 
                addChannelNum = GetBit(csrEventId, BIT_EVENTID_CHNUM);
 
                //lTimeStamp.Text = addTimeStamp ? "+" : "";
 
                //lEventCount.Text = addEventCount ? "+" : "";
 
                //lChannelNum.Text = addChannelNum ? "+" : "";
 
                AddMessageS(lTriggerSource);
 
                AddMessageI(addTimeStamp);
 
                AddMessageI(addEventCount);
 
                AddMessageI(addEventCount); 
 
                        
 
                // 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();
 
 
 
 
 
                AddMessageI(lTriggerInterval);
 
                AddMessageI(lTrigCount);
 
                AddMessageI(lTriggers);
 
                AddMessageI(lTriggerRate);
 
                AddMessageI(lAdcConversions);
 
                AddMessageF(lThreshold);
 
                AddMessageF(lHvIlimit);
 
                AddMessageF(lHvVoltage);
 
 
 
 
 
 
 
                // 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);
 
    AddMessageI(lHvEnabled); 
 
    AddMessageI(lHvOn); 
 
    AddMessageI(lSumCoupling); 
 
    AddMessageI(lSumGain); 
 
    AddMessageI(lAdcCoupling); 
 
    AddMessageI(lAdcGain ); 
 
    AddMessageI(lAmpEnabled); 
 
    AddMessageI(lAmpLevel); 
 
    AddMessageI(lDetPvaStatus ); 
 
    AddMessageI(lDetNvaStatus); 
 
    AddMessageI(lTemperatureOn); 
 
   
 
        }
 
 
 
 
 
 
 
        //----------------------------------------
 
        // Message list
 
        //----------------------------------------
 
 
 
 
 
 
 
 
 
        //----------------------------------------
 
        // 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
 
        //----------------------------------------
 
 
 
        void GetDeviceId() {
 
                deviceIndex = 0;
 
                deviceId = 1;
 
                /*
 
                if (tscbDeviceList.SelectedIndex >= 0)
 
                {
 
                 deviceIndex = 0; // tscbDeviceList.SelectedIndex;
 
                 deviceId = 1;  //UInt32.Parse((string)tscbDeviceList.SelectedItem, System.Globalization.NumberStyles.HexNumber);
 
                }
 
                else
 
                {
 
                 deviceIndex = -1;
 
                 deviceId = 0;
 
                }
 
                */
 
        }
 
 
 
        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\t", 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\t", ndevices
);  
        //SD4.DeviceAttached += new EventHandler(AitDeviceAttached);
 
        //SD4.DeviceRemoved += new EventHandler(AitDeviceRemoved);
 
        //tscbDeviceList.SelectedIndexChanged += new EventHandler(tscbDeviceList_SelectedIndexChanged);
 
          printf("Updated devices %d\n", UpdateDeviceList
());  
  
 
  
 
                
 
 
 
                // Set above the maximum bias voltage to prevent accidental over-bias.
 
                        // For example for 30V bias, set to 32V. For 70V bias, set to 72V
 
                SetMaximumHvSetting(32.0);
 
 
 
                // Set TTL port to 0
 
                WriteSD4Register(ADDR_TTLPORT, 0);
 
 
 
                // Set HV ramp rate to 20 V/s
 
                SetRampRate(20);
 
 
 
                // 1 second register scan interval
 
                //SetupTimer(1.0);
 
 
 
        }
 
 
 
 
 
        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);
 
                        AddMessage("AdcData event %d channel:%d  data:%d\n", eventNumber, channel + 1, data);
 
                }
 
                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 BlockTransferTime() {
 
  return SD4_BlockTransferTime();
 
}  
 
        void InitInterface(int events) {
 
                adcBufferLen = GetAdcEventSize() * events;
 
                //adcBuffer = (ushort *)malloc(sizeof(ushort) * adcBufferLen);
 
    /*
 
                for (int i = 0; i < 0xFFF; i++) {
 
                        for (int j = 0; j < 4; j++) histograms[j][i] = 0;
 
                }
 
                for (int i = 0; i < 4 * 0xFFF; i++) {
 
                        histogramtotal[i] = 0;
 
                }
 
    */
 
                histogramTotalEvents = 0;
 
        }
 
 
 
        int Acquire(int events) {
 
                //InitializeConnection();
 
                // Acquire
 
                InitInterface(events);
 
                //int wordsAcquired = ReadAdcByteBuffer();    //  use only to test byte buffer read operation
 
                int wordsAcquired = ReadAdcBuffer();
 
                if (wordsAcquired != adcBufferLen) {
 
                        char msg[0xFF];
 
                        AddMessage("ERROR: Timeout with possible data loss (%d/%d words received; Block Error = %d)\n", wordsAcquired, adcBufferLen, SD4_BlockError());
 
      return 0;
 
                }
 
 
 
                
 
    
 
                /*
 
                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[CHANNELS];
 
                ushort min[CHANNELS];
 
                ushort average[CHANNELS];
 
                int  total[CHANNELS];
 
                for (int i = 0; i < CHANNELS; i++) {
 
                        min[i] = 0xFFFF;
 
                        max[i] = 0;
 
                        total[i] = 0;
 
                }
 
                for (int eventNum = 0; eventNum < events; eventNum++) {
 
 
 
                        int sum = 0;
 
                        for (int channel = 0; channel < CHANNELS; channel++) {
 
                                rawAdcData = ExtractAdcData(eventNum, channel);
 
                                if (addChannelNum == true) {
 
                                        channelReceived = (rawAdcData >> 12) & 0xF;
 
                                        channelExpected = (channel & 0xF);
 
                                        if (channelReceived != channelExpected) {
 
 
 
                                                AddMessage("ERROR in Event %d : Expected channel %d, received %d -ANALYSIS STOPPED", eventNum, channelExpected, channelReceived);
 
 
 
                                                //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;
 
 
 
                                sum += adcData;
 
                        }
 
                        histogramtotal[sum]++;
 
                        histogramTotalEvents++;
 
                }
 
                //tbAdcStatistics.Clear();
 
                for (int channel = 0; channel < CHANNELS; channel++) {
 
                        average[channel] = (ushort)(total[channel] / events);
 
 
 
                        AddMessage(" {channel:%d}  : {min:0x%d}  {max:0x%d}  {max-min:%d}  {average:%d}\n", channel + 1, min[channel], max[channel], max[channel] - min[channel], average[channel]);
 
                        //if (channel < (CHANNELS - 1))
 
                        //    tbAdcStatistics.AppendText(Environment.NewLine);
 
 
 
                }
 
                //SetTextboxToTop(tbAdcStatistics);
 
        }
 
 
 
        void SetupAcquisition(int neve) {
 
                //EnableRegisterScanTimer(false);
 
                //nudEventSelect.Minimum = 0;
 
                //nudEventSelect.Maximum = 0;
 
                int eventsAcquired = Acquire(neve);
 
                if (eventsAcquired < 1){
 
      printf("Acquired events %d\n", eventsAcquired
);  
                        return;
 
    }  
 
                GetStatistics(eventsAcquired);
 
                ShowEvent(1);
 
                //ShowHistograms();
 
                //nudEventSelect.Minimum = 1;
 
                //nudEventSelect.Maximum = eventsAcquired;
 
                //EnableRegisterScanTimer(true);
 
        }
 
 
 
 
 
 
 
 
 
 
 
        int _tmain(int argc, char **argv) {
 
 
 
 
 
                int events = 1000;
 
 
 
                InitInterface(events);
 
                SetupAcquisition(1);
 
 
 
                //NE_Rainbow();
 
                //NE_Call(9);
 
                int b = 9;
 
                int k = 0;//NE_Func(b);
 
                return 0;
 
        }