001package com.ctre.phoenix.led;
002
003import java.util.HashMap;
004
005import com.ctre.phoenix.ErrorCode;
006import com.ctre.phoenix.ErrorCollection;
007import com.ctre.phoenix.ParamEnum;
008
009/**
010 * CTRE CANdle
011 *
012 * Device for controlling LEDs from the CAN bus.
013 *
014 * <pre>
015 * {@code
016 * // Example usage of a CANdle
017 * CANdle candle = new CANdle(0); // creates a new CANdle with ID 0
018 *
019 * CANdleConfiguration config = new CANdleConfiguration();
020 * config.stripType = LEDStripType.RGB; // set the strip type to RGB
021 * config.brightnessScalar = 0.5; // dim the LEDs to half brightness
022 * candle.configAllSettings(config);
023 *
024 * candle.setLEDs(255, 255, 255); // set the CANdle LEDs to white
025 *
026 * // create a rainbow animation:
027 * // - max brightness
028 * // - half speed
029 * // - 64 LEDs
030 * RainbowAnimation rainbowAnim = new RainbowAnimation(1, 0.5, 64);
031 * candle.animate(rainbowAnim);
032 *
033 * ErrorCode error = candle.getLastError(); // gets the last error generated by the CANdle
034 * CANdleFaults faults = new CANdleFaults();
035 * ErrorCode faultsError = candle.getFaults(faults); // fills faults with the current CANdle faults; returns the last error generated
036 * }
037 * </pre>
038 */
039public class CANdle {
040    private long _handle;
041
042    /**
043     * The various LED types that the CANdle can support
044     */
045    public enum LEDStripType {
046        /**
047         * LEDs that are controlled by Green-Red-Blue values
048         */
049        GRB(0),
050        /**
051         * LEDs that are controlled by Red-Green-Blue values
052         */
053        RGB(1),
054        /**
055         * LEDs that are controlled by Blue-Red-Green values
056         */
057        BRG(2),
058        /**
059         * LEDs that are controlled by Green-Red-Blue-White values
060         */
061        GRBW(6),
062        /**
063         * LEDs that are controlled by Red-Green-Blue-White values
064         */
065        RGBW(7),
066        /**
067         * LEDs that are controlled by Blue-Red-Green-White values
068         */
069        BRGW(8);
070
071        final public int value;
072
073        LEDStripType(int value) {
074            this.value = value;
075        }
076        /** Keep singleton map to quickly lookup enum via int */
077        private static HashMap<Integer, LEDStripType> _map = null;
078        /** static c'tor, prepare the map */
079        static {
080            _map = new HashMap<Integer, LEDStripType>();
081            for (LEDStripType type : LEDStripType.values()) {
082                _map.put(type.value, type);
083            }
084        }
085        /**
086         * Get LEDStripType of specified value
087         * @param value value of LEDStripType
088         * @return LEDStripType of specified value
089         */
090        public static LEDStripType valueOf(int value) {
091            LEDStripType retval = _map.get(value);
092            if (retval != null)
093                return retval;
094            return GRB;
095        }
096        /**
097         * Get LEDStripType of specified value
098         * @param value value of LEDStripType
099         * @return LEDStripType of specified value
100         */
101        public static LEDStripType valueOf(double value) {
102            return valueOf((int) value); 
103        }
104    }
105
106    /**
107     * The various methods of managing the VBat output behavior
108     */
109    public enum VBatOutputMode {
110        /**
111         * VBat output is on at full power, no modulation
112         */
113        On(0),
114        /**
115         * VBat output is off, no modulation
116         */
117        Off(1),
118        /**
119         * VBat output is on at the specified modulation
120         */
121        Modulated(2);
122
123        final public int value;
124
125        VBatOutputMode(int value) {
126            this.value = value;
127        }
128        /** Keep singleton map to quickly lookup enum via int */
129        private static HashMap<Integer, VBatOutputMode> _map = null;
130        /** static c'tor, prepare the map */
131        static {
132            _map = new HashMap<Integer, VBatOutputMode>();
133            for (VBatOutputMode type : VBatOutputMode.values()) {
134                _map.put(type.value, type);
135            }
136        }
137        /**
138         * Get VBatOutputMode of specified value
139         * @param value value of VBatOutputMode
140         * @return VBatOutputMode of specified value
141         */
142        public static VBatOutputMode valueOf(int value) {
143            VBatOutputMode retval = _map.get(value);
144            if (retval != null)
145                return retval;
146            return On;
147        }
148        /**
149         * Get VBatOutputMode of specified value
150         * @param value value of VBatOutputMode
151         * @return VBatOutputMode of specified value
152         */
153        public static VBatOutputMode valueOf(double value) {
154            return valueOf((int) value); 
155        }
156    }
157    
158    /**
159     * Constructor for a CANdle Device
160     * @param deviceId The Device ID of the CANdle
161     * @param canbus Name of the CANbus; can be a SocketCAN interface (on Linux),
162     *               or a CANivore device name or serial number
163     */
164    public CANdle(int deviceId, String canbus) {
165        _handle = CANdleJNI.Create(deviceId, canbus);
166    }
167    /**
168     * Constructor for a CANdle Device
169     * @param deviceId The Device ID of the CANdle
170     */
171    public CANdle(int deviceId) {
172        this(deviceId, "");
173    }
174    
175    public ErrorCode destroyObject() {
176        return ErrorCode.valueOf(0);
177    }
178
179    /**
180     * Gets the Voltage of VBat as measured by CANdle
181     * @return Voltage of VBat
182     */
183    public double getBusVoltage() {
184        return CANdleJNI.GetBusVoltage(_handle);
185    }
186    /**
187     * Gets the Voltage of the 5V line as measured by CANdle
188     * @return Voltage of the 5V line
189     */
190    public double get5VRailVoltage() {
191        return CANdleJNI.Get5VRailVoltage(_handle);
192    }
193    /**
194     * Gets the low-side current as measured by CANdle
195     * @return Current in Amps
196     */
197    public double getCurrent() {
198        return CANdleJNI.GetCurrent(_handle);
199    }
200    /**
201     * Gets the temperature of the CANdle in Celcius
202     * @return Temperature in Celcius
203     */
204    public double getTemperature() {
205        return CANdleJNI.GetTemperature(_handle);
206    }
207    /**
208     * Gets the applied vbat modulation in percent.
209     * If the CANdle is configured to always enable VBat, this returns 1
210     * If the CANdle is confgigured to always disable VBat, this returns 0
211     * Otherwise it returns the last set Modulation as a value [0, 1]
212     * @return VBat Output Modulation
213     */
214    public double getVBatModulation() {
215        return CANdleJNI.GetVbatModulation(_handle);
216    }
217
218    /**
219     * Animates the CANdle with the passed-in animation
220     * If the animation changes after calling this function, 
221     *  it must be passed into animate again for the changes to take effect
222     * @param animation The animation that CANdle will run
223     * @return ErrorCode generated by function. OK indicates no error.
224     */
225    public ErrorCode animate(Animation animation) {
226        if(animation == null) return ErrorCode.InvalidParamValue;
227
228        BaseStandardAnimation baseStandard = animation.getBaseStandardAnimation();
229        if(baseStandard != null) return animate(baseStandard);
230
231        BaseTwoSizeAnimation baseTwoSize = animation.getBaseTwoSizeAnimation();
232        if(baseTwoSize != null) return animate(baseTwoSize);
233
234        return ErrorCode.InvalidParamValue;
235    }
236
237    private ErrorCode animate(BaseStandardAnimation animation) {
238        return ErrorCode.valueOf(
239            CANdleJNI.SetStandardAnimation(_handle, 
240                animation.getAnimationIdx(), 
241                animation.getBrightness(), 
242                animation.getSpeed(), 
243                animation.getNumLed(),
244                animation.getParam4(),
245                animation.getParam5()));
246    }
247    private ErrorCode animate(BaseTwoSizeAnimation animation) {
248        return ErrorCode.valueOf(
249            CANdleJNI.SetTwoSizeAnimation(_handle, 
250                animation.getAnimationIdx(), 
251                animation.getR(), 
252                animation.getG(), 
253                animation.getB(),
254                animation.getW(),
255                animation.getSpeed(),
256                animation.getNumLed(),
257                animation.getDirection(),
258                animation.getSize()));
259    }
260
261    /**
262     * Sets a block of LEDs to the specified color
263     * @param r The amount of Red to set, range is [0, 255]
264     * @param g The amount of Green to set, range is [0, 255]
265     * @param b The amount of Blue to set, range is [0, 255]
266     * @param w The amount of White to set, range is [0, 255]. This only applies for LED strips with white in them.
267     * @param startIdx Where to start setting the LEDs 
268     * @param count The number of LEDs to apply this to
269     * @return ErrorCode generated by function. OK indicates no error.
270     */
271    public ErrorCode setLEDs(int r, int g, int b, int w, int startIdx, int count) {
272        return ErrorCode.valueOf(CANdleJNI.BlockSet(_handle, r, g, b, w, startIdx, count));
273    }
274    /**
275     * Sets a block of LEDs to the specified color. This will apply to the first 255 LEDs.
276     * @param r The amount of Red to set, range is [0, 255]
277     * @param g The amount of Green to set, range is [0, 255]
278     * @param b The amount of Blue to set, range is [0, 255]
279     * @return ErrorCode generated by function. OK indicates no error.
280     */
281    public ErrorCode setLEDs(int r, int g, int b) {
282        return setLEDs(r, g, b, 0, 0, 512);
283    }
284
285    /**
286     * Modulates the VBat output to the specified duty cycle percentage
287     * This function will only do something if the CANdle's VBatOutput is configured to Modulated
288     * @param dutyCyclePrcnt The duty cycle of the output modulation [0, 1]
289     * @return ErrorCode generated by function. OK indicates no error.
290     */
291    public ErrorCode modulateVBatOutput(double dutyCyclePrcnt) {
292        return ErrorCode.valueOf(CANdleJNI.ModulateVBatOutput(_handle, dutyCyclePrcnt));
293    }
294
295    /**
296     * Configures what the CANdle should do if it loses communications to the Controller
297     * @param disableWhenLOS Set to true to disable the LEDs on Loss of Signal.
298     * @param timeoutMs
299     *            Timeout value in ms. If nonzero, function will wait for
300     *            config success and report an error if it times out.
301     *            If zero, no blocking or checking is performed.
302     * @return ErrorCode generated by function. OK indicates no error.
303     */
304    public ErrorCode configLOSBehavior(boolean disableWhenLOS, int timeoutMs) {
305        return ErrorCode.valueOf(CANdleJNI.ConfigSetParameter(_handle, ParamEnum.eLossOfSignalBehavior.value, disableWhenLOS ? 1 : 0, 0, 0, timeoutMs));
306    }
307    /**
308     * Configures what the CANdle should do if it loses communications to the Controller
309     * @param disableWhenLOS Set to true to disable the LEDs on Loss of Signal.
310     * @return ErrorCode generated by function. OK indicates no error.
311     */
312    public ErrorCode configLOSBehavior(boolean disableWhenLOS) {
313        int timeoutMs = 0;
314        return configLOSBehavior(disableWhenLOS, timeoutMs);
315    }
316    /**
317     * Configures the type of LED the CANdle controls
318     * @param type The type of the LEDs the CANdle controls
319     * @param timeoutMs
320     *            Timeout value in ms. If nonzero, function will wait for
321     *            config success and report an error if it times out.
322     *            If zero, no blocking or checking is performed.
323     * @return ErrorCode generated by function. OK indicates no error.
324     */
325    public ErrorCode configLEDType(LEDStripType type, int timeoutMs) {
326        return ErrorCode.valueOf(CANdleJNI.ConfigSetParameter(_handle, ParamEnum.eLEDStripType.value, type.value, 0, 0, timeoutMs));
327    }
328    /**
329     * Configures the type of LED the CANdle controls
330     * @param type The type of the LEDs the CANdle controls
331     * @return ErrorCode generated by function. OK indicates no error.
332     */
333    public ErrorCode configLEDType(LEDStripType type) {
334        int timeoutMs = 0;
335        return configLEDType(type, timeoutMs);
336    }
337    /**
338     * Configures the brightness scalar to be applied to every LED output.
339     * This value is bounded to [0, 1].
340     * 
341     * Setting this to 1 will allow the LEDs to function at max brightness.
342     * Setting this to 0.5 will scale all values to half their applied value.
343     * Setting this to 0 will turn off the LEDs.
344     * 
345     * Forcing the LEDs off this way may be useful in certain testing circumstances 
346     * but is generally not necessary. Self-test (Tuner) may be used to verify what 
347     * the effective scalar is in case user forgot to restore the scalar to a 
348     * non-zero value.
349     * 
350     * @param brightness Value from [0, 1] that will scale the LED output.
351     * @param timeoutMs
352                    Timeout value in ms. If nonzero, function will wait for
353                    config success and report an error if it times out.
354                    If zero, no blocking or checking is performed.
355     * @return Error Code generated by function. 0 indicates no error.
356     */
357    public ErrorCode configBrightnessScalar(double brightness, int timeoutMs) {
358        return ErrorCode.valueOf(CANdleJNI.ConfigSetParameter(_handle, ParamEnum.eBrightnessCoefficient.value, brightness, 0, 0, timeoutMs));
359    }
360    /**
361     * Configures the brightness scalar to be applied to every LED output.
362     * This value is bounded to [0, 1].
363     * 
364     * Setting this to 1 will allow the LEDs to function at max brightness.
365     * Setting this to 0.5 will scale all values to half their applied value.
366     * Setting this to 0 will turn off the LEDs.
367     * 
368     * Forcing the LEDs off this way may be useful in certain testing circumstances 
369     * but is generally not necessary. Self-test (Tuner) may be used to verify what 
370     * the effective scalar is in case user forgot to restore the scalar to a 
371     * non-zero value.
372     * 
373     * @param brightness Value from [0, 1] that will scale the LED output.
374     * @return Error Code generated by function. 0 indicates no error.
375     */
376    public ErrorCode configBrightnessScalar(double brightness) {
377        int timeoutMs = 0;
378        return configBrightnessScalar(brightness, timeoutMs);
379    }
380
381    /**
382     * Configures how the status led will behave when the CANdle is actively controlling LEDs
383     * If the CANdle is LOS or not actively commanded a value, it will always turn on its status LED.
384     * @param disableWhenRunning Disables the status LED when the CANdle is running
385     * @param timeoutMs
386                    Timeout value in ms. If nonzero, function will wait for
387                    config success and report an error if it times out.
388                    If zero, no blocking or checking is performed.
389     * @return Error Code generated by function. 0 indicates no error.
390     */
391    public ErrorCode configStatusLedState(boolean disableWhenRunning, int timeoutMs) {
392        return ErrorCode.valueOf(CANdleJNI.ConfigSetParameter(_handle, ParamEnum.eStatusLedState.value, disableWhenRunning ? 1 : 0, 0, 0, timeoutMs));
393    }
394    /**
395     * Configures how the status led will behave when the CANdle is actively controlling LEDs
396     * If the CANdle is LOS or not actively commanded a value, it will always turn on its status LED.
397     * @param disableWhenRunning Disables the status LED when the CANdle is running
398     * @return Error Code generated by function. 0 indicates no error.
399     */
400    public ErrorCode configStatusLedState(boolean disableWhenRunning) {
401        int timeoutMs = 0;
402        return configStatusLedState(disableWhenRunning, timeoutMs);
403    }
404    /**
405     * Configures how the VBat Output will behave
406     * @param mode VBat Output Behavior
407     * @param timeoutMs
408                    Timeout value in ms. If nonzero, function will wait for
409                    config success and report an error if it times out.
410                    If zero, no blocking or checking is performed.
411     * @return Error Code generated by function. 0 indicates no error.
412     */
413    public ErrorCode configVBatOutput(VBatOutputMode mode, int timeoutMs) {
414        return ErrorCode.valueOf(CANdleJNI.ConfigSetParameter(_handle, ParamEnum.eVBatOutput.value, mode.value, 0, 0, timeoutMs));
415    }
416    /**
417     * Configures how the VBat Output will behave
418     * @param mode VBat Output Behavior
419     * @return Error Code generated by function. 0 indicates no error.
420     */
421    public ErrorCode configVBatOutput(VBatOutputMode mode) {
422        int timeoutMs = 0;
423        return configVBatOutput(mode, timeoutMs);
424    }
425
426    /**
427     * Gets a parameter. Generally this is not used.
428     * This can be utilized in
429     * - Using new features without updating API installation.
430     * - Errata workarounds to circumvent API implementation.
431     * - Allows for rapid testing / unit testing of firmware.
432     *
433     * @param param
434     *            Parameter enumeration.
435     * @param ordinal
436     *            Ordinal of parameter.
437     * @param timeoutMs
438     *            Timeout value in ms. If nonzero, function will wait for
439     *            config success and report an error if it times out.
440     *            If zero, no blocking or checking is performed.
441     * @return Value of parameter.
442     */
443    public double configGetParameter(ParamEnum param, int ordinal, int timeoutMs) {
444        return CANdleJNI.ConfigGetParameter(_handle, param.value, ordinal, timeoutMs);
445    }
446    /**
447     * Gets a parameter. Generally this is not used.
448     * This can be utilized in
449     * - Using new features without updating API installation.
450     * - Errata workarounds to circumvent API implementation.
451     * - Allows for rapid testing / unit testing of firmware.
452     *
453     * @param param
454     *            Parameter enumeration.
455     * @param ordinal
456     *            Ordinal of parameter.
457     * @return Value of parameter.
458     */
459    public double configGetParameter(ParamEnum param, int ordinal) {
460        int timeoutMs = 0;
461        return configGetParameter(param, ordinal, timeoutMs);
462    }
463    /**
464     * Sets a parameter. Generally this is not used.
465     * This can be utilized in
466     * - Using new features without updating API installation.
467     * - Errata workarounds to circumvent API implementation.
468     * - Allows for rapid testing / unit testing of firmware.
469     *
470     * @param param
471     *            Parameter enumeration.
472     * @param value
473     *            Value of parameter.
474     * @param subValue
475     *            Subvalue for parameter. Maximum value of 255.
476     * @param ordinal
477     *            Ordinal of parameter.
478     * @param timeoutMs
479     *            Timeout value in ms. If nonzero, function will wait for
480     *            config success and report an error if it times out.
481     *            If zero, no blocking or checking is performed.
482     * @return Error Code generated by function. 0 indicates no error.
483     */
484    public ErrorCode configSetParameter(ParamEnum param, double value, int subValue, int ordinal, int timeoutMs) {
485        return ErrorCode.valueOf(CANdleJNI.ConfigSetParameter(_handle, param.value, value, subValue, ordinal, timeoutMs));
486    }
487    /**
488     * Sets a parameter. Generally this is not used.
489     * This can be utilized in
490     * - Using new features without updating API installation.
491     * - Errata workarounds to circumvent API implementation.
492     * - Allows for rapid testing / unit testing of firmware.
493     *
494     * @param param
495     *            Parameter enumeration.
496     * @param value
497     *            Value of parameter.
498     * @param subValue
499     *            Subvalue for parameter. Maximum value of 255.
500     * @param ordinal
501     *            Ordinal of parameter.
502     * @return Error Code generated by function. 0 indicates no error.
503     */
504    public ErrorCode configSetParameter(ParamEnum param, double value, int subValue, int ordinal) {
505        int timeoutMs = 0;
506        return configSetParameter(param, value, subValue, ordinal, timeoutMs);
507    }
508    /**
509     * Gets the value of a custom parameter. This is for arbitrary use.
510     *
511     * Sometimes it is necessary to save calibration/duty cycle/output
512     * information in the device. Particularly if the
513     * device is part of a subsystem that can be replaced.
514     *
515     * @param paramIndex
516     *            Index of custom parameter. [0-1]
517     * @param timeoutMs
518     *            Timeout value in ms. If nonzero, function will wait for
519     *            config success and report an error if it times out.
520     *            If zero, no blocking or checking is performed.
521     * @return Value of the custom param.
522     */
523    public int configGetCustomParam(int paramIndex, int timeoutMs) {
524        return CANdleJNI.ConfigGetCustomParam(_handle, paramIndex, timeoutMs);
525    }
526    /**
527     * Gets the value of a custom parameter. This is for arbitrary use.
528     *
529     * Sometimes it is necessary to save calibration/duty cycle/output
530     * information in the device. Particularly if the
531     * device is part of a subsystem that can be replaced.
532     *
533     * @param paramIndex
534     *            Index of custom parameter. [0-1]
535     * @return Value of the custom param.
536     */
537    public int configGetCustomParam(int paramIndex) {
538        int timeoutMs = 0;
539        return configGetCustomParam(paramIndex, timeoutMs);
540    }
541    /**
542     * Sets the value of a custom parameter. This is for arbitrary use.
543     *
544     * Sometimes it is necessary to save calibration/duty cycle/output
545     * information in the device. Particularly if the
546     * device is part of a subsystem that can be replaced.
547     *
548     * @param paramIndex
549     *            Index of custom parameter. [0-1]
550     * @param value
551     *            Value for custom parameter.
552     * @param timeoutMs
553     *            Timeout value in ms. If nonzero, function will wait for
554     *            config success and report an error if it times out.
555     *            If zero, no blocking or checking is performed.
556     * @return Error Code generated by function. 0 indicates no error.
557     */
558    public ErrorCode configSetCustomParam(int paramIndex, int value, int timeoutMs) {
559        return ErrorCode.valueOf(CANdleJNI.ConfigSetCustomParam(_handle, value, paramIndex, timeoutMs));
560    }
561    /**
562     * Sets the value of a custom parameter. This is for arbitrary use.
563     *
564     * Sometimes it is necessary to save calibration/duty cycle/output
565     * information in the device. Particularly if the
566     * device is part of a subsystem that can be replaced.
567     *
568     * @param paramIndex
569     *            Index of custom parameter. [0-1]
570     * @param value
571     *            Value for custom parameter.
572     * @return Error Code generated by function. 0 indicates no error.
573     */
574    public ErrorCode configSetCustomParam(int paramIndex, int value) {
575        int timeoutMs = 0;
576        return configSetCustomParam(value, paramIndex, timeoutMs);
577    }
578    /**
579     * Configures all persistent settings to defaults.
580     *
581     * @param timeoutMs
582     *              Timeout value in ms. If nonzero, function will wait for
583     *              config success and report an error if it times out.
584     *              If zero, no blocking or checking is performed.
585     *
586     * @return Error Code generated by function. 0 indicates no error. 
587     */
588    public ErrorCode configFactoryDefault(int timeoutMs) {
589        return ErrorCode.valueOf(CANdleJNI.ConfigFactoryDefault(_handle, timeoutMs));
590    }
591    /**
592     * Configures all persistent settings to defaults.
593     *
594     * @return Error Code generated by function. 0 indicates no error. 
595     */
596    public ErrorCode configFactoryDefault() {
597        int timeoutMs = 50;
598        return configFactoryDefault(timeoutMs);
599    }
600    /**
601     * Gets the CANdle fault status
602     *
603     * @param toFill Container for fault statuses.
604     * @return Error Code generated by function. OK indicates no error.
605     */
606    public ErrorCode getFaults(CANdleFaults toFill) {
607        int faults = CANdleJNI.GetFaults(_handle);
608        toFill.update(faults);
609        return getLastError();
610    }
611    /**
612     * Gets the CANdle sticky fault status
613     *
614     * @param toFill Container for sticky fault statuses.
615     * @return Error Code generated by function. OK indicates no error.
616     */
617    public ErrorCode getStickyFaults(CANdleStickyFaults toFill) {
618        int faults = CANdleJNI.GetStickyFaults(_handle);
619        toFill.update(faults);
620        return getLastError();
621    }
622    /**
623     * Clears the sticky faults.
624     * 
625     * @param timeoutMs
626     *            Timeout value in ms. If nonzero, function will wait for
627     *            config success and report an error if it times out.
628     *            If zero, no blocking or checking is performed.
629     * @return Error Code generated by function. 0 indicates no error.
630     */
631    public ErrorCode clearStickyFaults(int timeoutMs) {
632        return ErrorCode.valueOf(CANdleJNI.ClearStickyFaults(_handle, timeoutMs));
633    }
634    /**
635     * Clears the sticky faults.
636     * 
637     * @return Error Code generated by function. 0 indicates no error.
638     */
639    public ErrorCode clearStickyFaults() {
640        int timeoutMs = 0;
641        return clearStickyFaults(timeoutMs);
642    }
643    /**
644     * Returns true if the device has reset since last call.
645     *
646     * @return Has a Device Reset Occurred?
647     */
648    public boolean hasResetOccurred() {
649        return CANdleJNI.HasResetOccurred(_handle);
650    }
651    /**
652     * Sets the period of the given status frame.
653     *
654     * @param frame
655     *            Frame whose period is to be changed.
656     * @param periodMs
657     *            Period in ms for the given frame.
658     * @param timeoutMs
659     *            Timeout value in ms. If nonzero, function will wait for
660     *            config success and report an error if it times out.
661     *            If zero, no blocking or checking is performed.
662     * @return Error Code generated by function. 0 indicates no error.
663     */
664    public ErrorCode setStatusFramePeriod(CANdleStatusFrame frame, int periodMs, int timeoutMs) {
665        return ErrorCode.valueOf(CANdleJNI.SetStatusFramePeriod(_handle, frame.value, periodMs, timeoutMs));
666    }
667    /**
668     * Sets the period of the given status frame.
669     *
670     * @param frame
671     *            Frame whose period is to be changed.
672     * @param periodMs
673     *            Period in ms for the given frame.
674     * @return Error Code generated by function. 0 indicates no error.
675     */
676    public ErrorCode setStatusFramePeriod(CANdleStatusFrame frame, int periodMs) {
677        int timeoutMs = 0;
678        return setStatusFramePeriod(frame, periodMs, timeoutMs);
679    }
680    /**
681     * Gets the period of the given status frame.
682     *
683     * @param frame
684     *            Frame to get the period of.
685     * @param timeoutMs
686     *            Timeout value in ms. If nonzero, function will wait for
687     *            config success and report an error if it times out.
688     *            If zero, no blocking or checking is performed.
689     * @return Period of the given status frame.
690     */
691    public int getStatusFramePeriod(CANdleStatusFrame frame, int timeoutMs) {
692        return CANdleJNI.GetStatusFramePeriod(_handle, frame.value, timeoutMs);
693    }
694    /**
695     * Gets the period of the given status frame.
696     *
697     * @param frame
698     *            Frame to get the period of.
699     * @return Period of the given status frame.
700     */
701    public int getStatusFramePeriod(CANdleStatusFrame frame) {
702        int timeoutMs = 0;
703        return getStatusFramePeriod(frame, timeoutMs);
704    }
705    /**
706     * Sets the period of the given control frame.
707     *
708     * @param frame
709     *            Frame whose period is to be changed.
710     * @param periodMs
711     *            Period in ms for the given frame.
712     * @return Error Code generated by function. 0 indicates no error.
713     */
714    public ErrorCode setControlFramePeriod(CANdleControlFrame frame, int periodMs) {
715        return ErrorCode.valueOf(CANdleJNI.SetControlFramePeriod(_handle, frame.value, periodMs));
716    }
717
718    /**
719     * Configures all persistent settings.
720     *
721     * @param allConfigs        Object with all of the persistant settings
722     * @param timeoutMs
723     *              Timeout value in ms. If nonzero, function will wait for
724     *              config success and report an error if it times out.
725     *              If zero, no blocking or checking is performed.
726     * @return Error Code generated by function. 0 indicates no error.
727     */
728    public ErrorCode configAllSettings(CANdleConfiguration allConfigs, int timeoutMs) {
729        ErrorCollection errorCollection = new ErrorCollection();
730        
731        errorCollection.NewError(configFactoryDefault(timeoutMs));
732        if(CANdleConfigUtil.stripTypeDifferent(allConfigs)) errorCollection.NewError(configLEDType(allConfigs.stripType, timeoutMs));
733        if(CANdleConfigUtil.brightnessScalarDifferent(allConfigs)) errorCollection.NewError(configBrightnessScalar(allConfigs.brightnessScalar, timeoutMs));
734        if(CANdleConfigUtil.disableWhenLOSDifferent(allConfigs)) errorCollection.NewError(configLOSBehavior(allConfigs.disableWhenLOS, timeoutMs));
735        if(CANdleConfigUtil.statusLedOffWhenActiveDifferent(allConfigs)) errorCollection.NewError(configStatusLedState(allConfigs.statusLedOffWhenActive, timeoutMs));
736        if(CANdleConfigUtil.vBatOutputModeDifferent(allConfigs)) errorCollection.NewError(configVBatOutput(allConfigs.vBatOutputMode, timeoutMs));
737
738        if(CANdleConfigUtil.customParam0Different(allConfigs)) errorCollection.NewError(configSetCustomParam(0, allConfigs.customParam0, timeoutMs));
739        if(CANdleConfigUtil.customParam1Different(allConfigs)) errorCollection.NewError(configSetCustomParam(1, allConfigs.customParam1, timeoutMs));
740
741        return errorCollection._worstError;   
742    }
743    /**
744     * Configures all persistent settings.
745     *
746     * @param allConfigs        Object with all of the persistant settings
747     * @return Error Code generated by function. 0 indicates no error.
748     */
749    public ErrorCode configAllSettings(CANdleConfiguration allConfigs) {
750        int timeoutMs = 50;
751        return configAllSettings(allConfigs, timeoutMs);
752    }
753
754    /**
755     * Gets all persistant settings.
756     *
757     * @param allConfigs        Object with all of the persistant settings
758     * @param timeoutMs
759     *              Timeout value in ms. If nonzero, function will wait for
760     *              config success and report an error if it times out.
761     *              If zero, no blocking or checking is performed.
762     */
763    public void getAllConfigs(CANdleConfiguration allConfigs, int timeoutMs) {
764        allConfigs.brightnessScalar = configGetParameter(ParamEnum.eBrightnessCoefficient, 0, timeoutMs);
765        allConfigs.disableWhenLOS = configGetParameter(ParamEnum.eLossOfSignalBehavior, 0, timeoutMs) != 0;
766        allConfigs.statusLedOffWhenActive = configGetParameter(ParamEnum.eStatusLedState, 0, timeoutMs) != 0;
767        allConfigs.stripType = LEDStripType.valueOf(configGetParameter(ParamEnum.eLEDStripType, 0, timeoutMs));
768        allConfigs.vBatOutputMode = VBatOutputMode.valueOf(configGetParameter(ParamEnum.eVBatOutput, 0, timeoutMs));
769
770        allConfigs.customParam0 = (int)configGetParameter(ParamEnum.eCustomParam, 0, timeoutMs);
771        allConfigs.customParam1 = (int)configGetParameter(ParamEnum.eCustomParam, 1, timeoutMs);
772    }
773    /**
774     * Gets all persistant settings.
775     *
776     * @param allConfigs        Object with all of the persistant settings
777     */
778    public void getAllConfigs(CANdleConfiguration allConfigs) {
779        int timeoutMs = 50;
780        getAllConfigs(allConfigs, timeoutMs);
781    }
782
783    /**
784     * Call GetLastError() generated by this object.
785     * Not all functions return an error code but can
786     * potentially report errors.
787     *
788     * This function can be used to retrieve those error codes.
789     *
790     * @return The last ErrorCode generated.
791     */
792    public ErrorCode getLastError() {
793        return ErrorCode.valueOf(CANdleJNI.GetLastError(_handle));
794    }
795}