001// Copyright (c) FIRST and other WPILib contributors. 002// Open Source Software; you can modify and/or share it under the terms of 003// the WPILib BSD license file in the root directory of this project. 004 005package edu.wpi.first.wpilibj.simulation; 006 007import edu.wpi.first.hal.simulation.DigitalPWMDataJNI; 008import edu.wpi.first.hal.simulation.NotifyCallback; 009import edu.wpi.first.wpilibj.DigitalOutput; 010import java.util.NoSuchElementException; 011 012/** 013 * Class to control a simulated digital PWM output. 014 * 015 * <p>This is for duty cycle PWM outputs on a DigitalOutput, not for the servo style PWM outputs on 016 * a PWM channel. 017 */ 018public class DigitalPWMSim { 019 private final int m_index; 020 021 /** 022 * Constructs from a DigitalOutput object. 023 * 024 * @param digitalOutput DigitalOutput to simulate 025 */ 026 public DigitalPWMSim(DigitalOutput digitalOutput) { 027 m_index = digitalOutput.getChannel(); 028 } 029 030 private DigitalPWMSim(int index) { 031 m_index = index; 032 } 033 034 /** 035 * Creates an DigitalPWMSim for a digital I/O channel. 036 * 037 * @param channel DIO channel 038 * @return Simulated object 039 * @throws NoSuchElementException if no Digital PWM is configured for that channel 040 */ 041 public static DigitalPWMSim createForChannel(int channel) { 042 int index = DigitalPWMDataJNI.findForChannel(channel); 043 if (index < 0) { 044 throw new NoSuchElementException("no digital PWM found for channel " + channel); 045 } 046 return new DigitalPWMSim(index); 047 } 048 049 /** 050 * Creates an DigitalPWMSim for a simulated index. The index is incremented for each simulated 051 * DigitalPWM. 052 * 053 * @param index simulator index 054 * @return Simulated object 055 */ 056 public static DigitalPWMSim createForIndex(int index) { 057 return new DigitalPWMSim(index); 058 } 059 060 /** 061 * Register a callback to be run when this PWM output is initialized. 062 * 063 * @param callback the callback 064 * @param initialNotify whether to run the callback with the initial state 065 * @return the {@link CallbackStore} object associated with this callback. Save a reference to 066 * this object so GC doesn't cancel the callback. 067 */ 068 public CallbackStore registerInitializedCallback(NotifyCallback callback, boolean initialNotify) { 069 int uid = DigitalPWMDataJNI.registerInitializedCallback(m_index, callback, initialNotify); 070 return new CallbackStore(m_index, uid, DigitalPWMDataJNI::cancelInitializedCallback); 071 } 072 073 /** 074 * Check whether this PWM output has been initialized. 075 * 076 * @return true if initialized 077 */ 078 public boolean getInitialized() { 079 return DigitalPWMDataJNI.getInitialized(m_index); 080 } 081 082 /** 083 * Define whether this PWM output has been initialized. 084 * 085 * @param initialized whether this object is initialized 086 */ 087 public void setInitialized(boolean initialized) { 088 DigitalPWMDataJNI.setInitialized(m_index, initialized); 089 } 090 091 /** 092 * Register a callback to be run whenever the duty cycle value changes. 093 * 094 * @param callback the callback 095 * @param initialNotify whether to call the callback with the initial state 096 * @return the {@link CallbackStore} object associated with this callback. Save a reference to 097 * this object so GC doesn't cancel the callback. 098 */ 099 public CallbackStore registerDutyCycleCallback(NotifyCallback callback, boolean initialNotify) { 100 int uid = DigitalPWMDataJNI.registerDutyCycleCallback(m_index, callback, initialNotify); 101 return new CallbackStore(m_index, uid, DigitalPWMDataJNI::cancelDutyCycleCallback); 102 } 103 104 /** 105 * Read the duty cycle value. 106 * 107 * @return the duty cycle value of this PWM output 108 */ 109 public double getDutyCycle() { 110 return DigitalPWMDataJNI.getDutyCycle(m_index); 111 } 112 113 /** 114 * Set the duty cycle value of this PWM output. 115 * 116 * @param dutyCycle the new value 117 */ 118 public void setDutyCycle(double dutyCycle) { 119 DigitalPWMDataJNI.setDutyCycle(m_index, dutyCycle); 120 } 121 122 /** 123 * Register a callback to be run whenever the pin changes. 124 * 125 * @param callback the callback 126 * @param initialNotify whether to call the callback with the initial state 127 * @return the {@link CallbackStore} object associated with this callback. Save a reference to 128 * this object so GC doesn't cancel the callback. 129 */ 130 public CallbackStore registerPinCallback(NotifyCallback callback, boolean initialNotify) { 131 int uid = DigitalPWMDataJNI.registerPinCallback(m_index, callback, initialNotify); 132 return new CallbackStore(m_index, uid, DigitalPWMDataJNI::cancelPinCallback); 133 } 134 135 /** 136 * Check the pin number. 137 * 138 * @return the pin number 139 */ 140 public int getPin() { 141 return DigitalPWMDataJNI.getPin(m_index); 142 } 143 144 /** 145 * Change the pin number. 146 * 147 * @param pin the new pin number 148 */ 149 public void setPin(int pin) { 150 DigitalPWMDataJNI.setPin(m_index, pin); 151 } 152 153 /** Reset all simulation data. */ 154 public void resetData() { 155 DigitalPWMDataJNI.resetData(m_index); 156 } 157}