Example #1
0
        /// <summary>
        /// Read FPGA compiler options; for values, see ENG-0034.
        /// </summary>
        void load()
        {
            logger.debug("FPGAOptions.load: getting compilation options");

            // NOTE: ENG-0001 says this only returns 2 bytes, but empirical testing on ARM
            // suggests it actually returns more (yet we only use the first two)
            byte[] buf = spectrometer.getCmd2(Opcodes.GET_COMPILATION_OPTIONS, 2, fakeBufferLengthARM: 8);
            if (buf == null)
            {
                return;
            }

            ushort word = (ushort)(buf[0] | (buf[1] << 8));

            logger.debug("FPGA compiler options: 0x{0:x4}", word);

            // bits 0-2: 0000 0000 0000 0111 IntegrationTimeResolution
            // bit  3-5: 0000 0000 0011 1000 DataHeader
            // bit    6: 0000 0000 0100 0000 HasCFSelect
            // bit  7-8: 0000 0001 1000 0000 LaserType
            // bit 9-11: 0000 1110 0000 0000 LaserControl
            // bit   12: 0001 0000 0000 0000 HasAreaScan
            // bit   13: 0010 0000 0000 0000 HasActualIntegTime
            // bit   14: 0100 0000 0000 0000 HasHorizBinning

            try
            {
                integrationTimeResolution = parseResolution(word & 0x07);
                dataHeader         = parseDataHeader((word & 0x0038) >> 3);
                hasCFSelect        = (word & 0x0040) != 0;
                laserType          = parseLaserType((word & 0x0180) >> 7);
                laserControl       = parseLaserControl((word & 0x0e00) >> 9);
                hasAreaScan        = (word & 0x1000) != 0;
                hasActualIntegTime = (word & 0x2000) != 0;
                hasHorizBinning    = (word & 0x4000) != 0;
            }
            catch (Exception ex)
            {
                logger.error("failed to parse FPGA compilation options: {0}", ex.Message);
            }

            if (logger.debugEnabled())
            {
                logger.debug("  IntegrationTimeResolution = {0}", integrationTimeResolution);
                logger.debug("  DataHeader                = {0}", dataHeader);
                logger.debug("  HasCFSelect               = {0}", hasCFSelect);
                logger.debug("  LaserType                 = {0}", laserType);
                logger.debug("  LaserControl              = {0}", laserControl);
                logger.debug("  HasAreaScan               = {0}", hasAreaScan);
                logger.debug("  HasActualIntegTime        = {0}", hasActualIntegTime);
                logger.debug("  HasHorizBinning           = {0}", hasHorizBinning);
            }
        }
Example #2
0
        public bool read()
        {
            // read all pages into cache
            pages = new List <byte[]>();
            for (ushort page = 0; page < MAX_PAGES; page++)
            {
                byte[] buf = spectrometer.getCmd2(Opcodes.GET_MODEL_CONFIG, 64, wIndex: page, fakeBufferLengthARM: 8);
                if (buf == null)
                {
                    return(false);
                }
                pages.Add(buf);
                logger.hexdump(buf, String.Format("read page {0}: ", page));
            }

            format = pages[0][63];

            try
            {
                model        = ParseData.toString(pages[0], 0, 16);
                serialNumber = ParseData.toString(pages[0], 16, 16);
                baudRate     = ParseData.toUInt32(pages[0], 32);
                hasCooling   = ParseData.toBool(pages[0], 36);
                hasBattery   = ParseData.toBool(pages[0], 37);
                hasLaser     = ParseData.toBool(pages[0], 38);
                excitationNM = ParseData.toUInt16(pages[0], 39);
                slitSizeUM   = ParseData.toUInt16(pages[0], 41);

                startupIntegrationTimeMS       = ParseData.toUInt16(pages[0], 43);
                startupDetectorTemperatureDegC = ParseData.toInt16(pages[0], 45);
                startupTriggeringMode          = ParseData.toUInt8(pages[0], 47);
                detectorGain      = ParseData.toFloat(pages[0], 48);        // "even pixels" for InGaAs
                detectorOffset    = ParseData.toInt16(pages[0], 52);        // "even pixels" for InGaAs
                detectorGainOdd   = ParseData.toFloat(pages[0], 54);        // InGaAs-only
                detectorOffsetOdd = ParseData.toInt16(pages[0], 58);        // InGaAs-only

                wavecalCoeffs[0]           = ParseData.toFloat(pages[1], 0);
                wavecalCoeffs[1]           = ParseData.toFloat(pages[1], 4);
                wavecalCoeffs[2]           = ParseData.toFloat(pages[1], 8);
                wavecalCoeffs[3]           = ParseData.toFloat(pages[1], 12);
                degCToDACCoeffs[0]         = ParseData.toFloat(pages[1], 16);
                degCToDACCoeffs[1]         = ParseData.toFloat(pages[1], 20);
                degCToDACCoeffs[2]         = ParseData.toFloat(pages[1], 24);
                detectorTempMax            = ParseData.toInt16(pages[1], 28);
                detectorTempMin            = ParseData.toInt16(pages[1], 30);
                adcToDegCCoeffs[0]         = ParseData.toFloat(pages[1], 32);
                adcToDegCCoeffs[1]         = ParseData.toFloat(pages[1], 36);
                adcToDegCCoeffs[2]         = ParseData.toFloat(pages[1], 40);
                thermistorResistanceAt298K = ParseData.toInt16(pages[1], 44);
                thermistorBeta             = ParseData.toInt16(pages[1], 46);
                calibrationDate            = ParseData.toString(pages[1], 48, 12);
                calibrationBy = ParseData.toString(pages[1], 60, 3);

                detectorName          = ParseData.toString(pages[2], 0, 16);
                activePixelsHoriz     = ParseData.toUInt16(pages[2], 16);   // note: byte 18 unused
                activePixelsVert      = ParseData.toUInt16(pages[2], 19);
                minIntegrationTimeMS  = ParseData.toUInt16(pages[2], 21);   // will overwrite if
                maxIntegrationTimeMS  = ParseData.toUInt16(pages[2], 23);   //   format >= 5
                actualPixelsHoriz     = ParseData.toUInt16(pages[2], 25);
                ROIHorizStart         = ParseData.toUInt16(pages[2], 27);
                ROIHorizEnd           = ParseData.toUInt16(pages[2], 29);
                ROIVertRegionStart[0] = ParseData.toUInt16(pages[2], 31);
                ROIVertRegionEnd[0]   = ParseData.toUInt16(pages[2], 33);
                ROIVertRegionStart[1] = ParseData.toUInt16(pages[2], 35);
                ROIVertRegionEnd[1]   = ParseData.toUInt16(pages[2], 37);
                ROIVertRegionStart[2] = ParseData.toUInt16(pages[2], 39);
                ROIVertRegionEnd[2]   = ParseData.toUInt16(pages[2], 41);
                linearityCoeffs[0]    = ParseData.toFloat(pages[2], 43);
                linearityCoeffs[1]    = ParseData.toFloat(pages[2], 47);
                linearityCoeffs[2]    = ParseData.toFloat(pages[2], 51);
                linearityCoeffs[3]    = ParseData.toFloat(pages[2], 55);
                linearityCoeffs[4]    = ParseData.toFloat(pages[2], 59);

                // deviceLifetimeOperationMinutes = ParseData.toInt32(pages[3], 0);
                // laserLifetimeOperationMinutes = ParseData.toInt32(pages[3], 4);
                // laserTemperatureMax  = ParseData.toInt16(pages[3], 8);
                // laserTemperatureMin  = ParseData.toInt16(pages[3], 10);

                laserPowerCoeffs[0] = ParseData.toFloat(pages[3], 12);
                laserPowerCoeffs[1] = ParseData.toFloat(pages[3], 16);
                laserPowerCoeffs[2] = ParseData.toFloat(pages[3], 20);
                laserPowerCoeffs[3] = ParseData.toFloat(pages[3], 24);
                maxLaserPowerMW     = ParseData.toFloat(pages[3], 28);
                minLaserPowerMW     = ParseData.toFloat(pages[3], 32);
                laserExcitationWavelengthNMFloat = ParseData.toFloat(pages[3], 36);
                if (format >= 5)
                {
                    minIntegrationTimeMS = ParseData.toUInt32(pages[3], 40);
                    maxIntegrationTimeMS = ParseData.toUInt32(pages[3], 44);
                }

                userData = format < 4 ? new byte[63] : new byte[64];
                Array.Copy(pages[4], userData, userData.Length);

                badPixelSet = new SortedSet <short>();
                for (int i = 0; i < 15; i++)
                {
                    short pixel = ParseData.toInt16(pages[5], i * 2);
                    badPixels[i] = pixel;
                    if (pixel >= 0)
                    {
                        badPixelSet.Add(pixel); // does not throw
                    }
                }
                badPixelList = new List <short>(badPixelSet);

                if (format >= 5)
                {
                    productConfiguration = ParseData.toString(pages[5], 30, 16);
                }
            }
            catch (Exception ex)
            {
                logger.error("ModelConfig: caught exception: {0}", ex.Message);
                return(false);
            }

            if (logger.debugEnabled())
            {
                dump();
            }

            enforceReasonableDefaults();

            return(true);
        }