Example #1
0
        /////////////////////////////////////////////////////////////////////////
        // Pages 6-7 unallocated
        /////////////////////////////////////////////////////////////////////////

        /////////////////////////////////////////////////////////////////////////
        //
        // public methods
        //
        /////////////////////////////////////////////////////////////////////////

        /// <summary>
        /// Save updated EEPROM fields to the device.
        /// </summary>
        /// <remarks>
        /// Only a handful of fields are recommended to be changed by users:
        ///
        /// - excitationNM
        /// - wavecalCoeffs
        /// - calibrationDate
        /// - calibrationBy
        /// - ROI
        /// - linearityCoeffs (not currently used)
        /// - userData
        /// - badPixels
        ///
        /// Note that the EEPROM isn't an SSD...it's not terribly fast, and there
        /// are a finite number of lifetime writes, so use sparingly.
        ///
        /// Due to the high risk of bricking a unit through a failed / bad EEPROM
        /// write, all internal calls bail at the first error in hopes of salvaging
        /// the unit if at all possible.
        ///
        /// That said, if you do frag your EEPROM, Wasatch has a "Model Configuration"
        /// utility to let you manually write EEPROM fields; contact your sales rep
        /// for a copy.
        /// </remarks>
        /// <returns>true on success, false on failure</returns>
        public bool write()
        {
            if (pages == null || pages.Count != MAX_PAGES)
            {
                logger.error("ModelConfig.write: need to perform a read first");
                return(false);
            }

            if (!ParseData.writeString(model, pages[0], 0, 16))
            {
                return(false);
            }
            if (!ParseData.writeString(serialNumber, pages[0], 16, 16))
            {
                return(false);
            }
            if (!ParseData.writeUInt32(baudRate, pages[0], 32))
            {
                return(false);
            }
            if (!ParseData.writeBool(hasCooling, pages[0], 36))
            {
                return(false);
            }
            if (!ParseData.writeBool(hasBattery, pages[0], 37))
            {
                return(false);
            }
            if (!ParseData.writeBool(hasLaser, pages[0], 38))
            {
                return(false);
            }
            if (!ParseData.writeUInt16(excitationNM, pages[0], 39))
            {
                return(false);
            }
            if (!ParseData.writeUInt16(slitSizeUM, pages[0], 41))
            {
                return(false);
            }
            if (!ParseData.writeUInt16(startupIntegrationTimeMS, pages[0], 43))
            {
                return(false);
            }
            if (!ParseData.writeInt16(startupDetectorTemperatureDegC, pages[0], 45))
            {
                return(false);
            }
            if (!ParseData.writeByte(startupTriggeringMode, pages[0], 47))
            {
                return(false);
            }
            if (!ParseData.writeFloat(detectorGain, pages[0], 48))
            {
                return(false);
            }
            if (!ParseData.writeInt16(detectorOffset, pages[0], 52))
            {
                return(false);
            }
            if (!ParseData.writeFloat(detectorGainOdd, pages[0], 54))
            {
                return(false);
            }
            if (!ParseData.writeInt16(detectorOffsetOdd, pages[0], 58))
            {
                return(false);
            }

            if (!ParseData.writeFloat(wavecalCoeffs[0], pages[1], 0))
            {
                return(false);
            }
            if (!ParseData.writeFloat(wavecalCoeffs[1], pages[1], 4))
            {
                return(false);
            }
            if (!ParseData.writeFloat(wavecalCoeffs[2], pages[1], 8))
            {
                return(false);
            }
            if (!ParseData.writeFloat(wavecalCoeffs[3], pages[1], 12))
            {
                return(false);
            }
            if (!ParseData.writeFloat(degCToDACCoeffs[0], pages[1], 16))
            {
                return(false);
            }
            if (!ParseData.writeFloat(degCToDACCoeffs[1], pages[1], 20))
            {
                return(false);
            }
            if (!ParseData.writeFloat(degCToDACCoeffs[2], pages[1], 24))
            {
                return(false);
            }
            if (!ParseData.writeInt16(detectorTempMax, pages[1], 28))
            {
                return(false);
            }
            if (!ParseData.writeInt16(detectorTempMin, pages[1], 30))
            {
                return(false);
            }
            if (!ParseData.writeFloat(adcToDegCCoeffs[0], pages[1], 32))
            {
                return(false);
            }
            if (!ParseData.writeFloat(adcToDegCCoeffs[1], pages[1], 36))
            {
                return(false);
            }
            if (!ParseData.writeFloat(adcToDegCCoeffs[2], pages[1], 40))
            {
                return(false);
            }
            if (!ParseData.writeInt16(thermistorResistanceAt298K, pages[1], 44))
            {
                return(false);
            }
            if (!ParseData.writeInt16(thermistorBeta, pages[1], 46))
            {
                return(false);
            }
            if (!ParseData.writeString(calibrationDate, pages[1], 48, 12))
            {
                return(false);
            }
            if (!ParseData.writeString(calibrationBy, pages[1], 60, 3))
            {
                return(false);
            }

            if (!ParseData.writeString(detectorName, pages[2], 0, 16))
            {
                return(false);
            }
            if (!ParseData.writeUInt16(activePixelsHoriz, pages[2], 16))
            {
                return(false);
            }
            // skip 18
            if (!ParseData.writeUInt16(activePixelsVert, pages[2], 19))
            {
                return(false);
            }
            if (!ParseData.writeUInt16((ushort)minIntegrationTimeMS, pages[2], 21))
            {
                return(false);                                                                    // for now
            }
            if (!ParseData.writeUInt16((ushort)maxIntegrationTimeMS, pages[2], 23))
            {
                return(false);                                                                    // for now
            }
            if (!ParseData.writeUInt16(actualPixelsHoriz, pages[2], 25))
            {
                return(false);
            }
            if (!ParseData.writeUInt16(ROIHorizStart, pages[2], 27))
            {
                return(false);
            }
            if (!ParseData.writeUInt16(ROIHorizEnd, pages[2], 29))
            {
                return(false);
            }
            if (!ParseData.writeUInt16(ROIVertRegionStart[0], pages[2], 31))
            {
                return(false);
            }
            if (!ParseData.writeUInt16(ROIVertRegionEnd  [0], pages[2], 33))
            {
                return(false);
            }
            if (!ParseData.writeUInt16(ROIVertRegionStart[1], pages[2], 35))
            {
                return(false);
            }
            if (!ParseData.writeUInt16(ROIVertRegionEnd  [1], pages[2], 37))
            {
                return(false);
            }
            if (!ParseData.writeUInt16(ROIVertRegionStart[2], pages[2], 39))
            {
                return(false);
            }
            if (!ParseData.writeUInt16(ROIVertRegionEnd  [2], pages[2], 41))
            {
                return(false);
            }
            if (!ParseData.writeFloat(linearityCoeffs[0], pages[2], 43))
            {
                return(false);
            }
            if (!ParseData.writeFloat(linearityCoeffs[1], pages[2], 47))
            {
                return(false);
            }
            if (!ParseData.writeFloat(linearityCoeffs[2], pages[2], 51))
            {
                return(false);
            }
            if (!ParseData.writeFloat(linearityCoeffs[3], pages[2], 55))
            {
                return(false);
            }
            if (!ParseData.writeFloat(linearityCoeffs[4], pages[2], 59))
            {
                return(false);
            }

            if (!ParseData.writeFloat(laserPowerCoeffs[0], pages[3], 12))
            {
                return(false);
            }
            if (!ParseData.writeFloat(laserPowerCoeffs[1], pages[3], 16))
            {
                return(false);
            }
            if (!ParseData.writeFloat(laserPowerCoeffs[2], pages[3], 20))
            {
                return(false);
            }
            if (!ParseData.writeFloat(laserPowerCoeffs[3], pages[3], 24))
            {
                return(false);
            }
            if (!ParseData.writeFloat(maxLaserPowerMW, pages[3], 28))
            {
                return(false);
            }
            if (!ParseData.writeFloat(minLaserPowerMW, pages[3], 32))
            {
                return(false);
            }
            if (!ParseData.writeFloat(laserExcitationWavelengthNMFloat, pages[3], 36))
            {
                return(false);
            }
            if (!ParseData.writeUInt32(minIntegrationTimeMS, pages[3], 40))
            {
                return(false);
            }
            if (!ParseData.writeUInt32(maxIntegrationTimeMS, pages[3], 44))
            {
                return(false);
            }

            Array.Copy(userData, pages[4], userData.Length);

            // note that we write the positional, error-prone array (which is
            // user -writable), not the List or SortedSet caches
            for (int i = 0; i < badPixels.Length; i++)
            {
                if (!ParseData.writeInt16(badPixels[i], pages[5], i * 2))
                {
                    return(false);
                }
            }

            if (!ParseData.writeString(productConfiguration, pages[5], 30, 16))
            {
                return(false);
            }

            // regardless of what the "read" format was (this.format), we always WRITE the latest format version.
            pages[0][63] = FORMAT;

            for (short page = 0; page < pages.Count; page++)
            {
                bool ok = false;
                if (spectrometer.isARM)
                {
                    logger.hexdump(pages[page], String.Format("writing page {0} [ARM]: ", page));
                    ok = spectrometer.sendCmd(
                        opcode: Opcodes.SECOND_TIER_COMMAND,
                        wValue: (ushort)Opcodes.SET_MODEL_CONFIG_ARM,
                        wIndex: (ushort)page,
                        buf: pages[page]);
                }
                else
                {
                    const uint DATA_START = 0x3c00; // from Wasatch Stroker Console's EnhancedStroker.SetModelInformation()
                    ushort     pageOffset = (ushort)(DATA_START + page * 64);
                    logger.hexdump(pages[page], String.Format("writing page {0} to offset {1} [FX2]: ", page, pageOffset));
                    ok = spectrometer.sendCmd(
                        opcode: Opcodes.SET_MODEL_CONFIG_FX2,
                        wValue: pageOffset,
                        wIndex: 0,
                        buf: pages[page]);
                }
                if (!ok)
                {
                    logger.error("ModelConfig.write: failed to save page {0}", page);
                    return(false);
                }
                logger.debug("ModelConfig: wrote EEPROM page {0}", page);
            }
            return(true);
        }