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;
006
007import edu.wpi.first.hal.DIOJNI;
008import edu.wpi.first.hal.FRCNetComm.tResourceType;
009import edu.wpi.first.hal.HAL;
010import edu.wpi.first.hal.SimDevice;
011import edu.wpi.first.util.sendable.Sendable;
012import edu.wpi.first.util.sendable.SendableBuilder;
013import edu.wpi.first.util.sendable.SendableRegistry;
014
015/**
016 * Class to read a digital input. This class will read digital inputs and return the current value
017 * on the channel. Other devices such as encoders, gear tooth sensors, etc. that are implemented
018 * elsewhere will automatically allocate digital inputs and outputs as required. This class is only
019 * for devices like switches etc. that aren't implemented anywhere else.
020 */
021public class DigitalInput extends DigitalSource implements Sendable {
022  private final int m_channel;
023  private int m_handle;
024
025  /**
026   * Create an instance of a Digital Input class. Creates a digital input given a channel.
027   *
028   * @param channel the DIO channel for the digital input 0-9 are on-board, 10-25 are on the MXP
029   */
030  public DigitalInput(int channel) {
031    SensorUtil.checkDigitalChannel(channel);
032    m_channel = channel;
033
034    m_handle = DIOJNI.initializeDIOPort(HAL.getPort((byte) channel), true);
035
036    HAL.report(tResourceType.kResourceType_DigitalInput, channel + 1);
037    SendableRegistry.addLW(this, "DigitalInput", channel);
038  }
039
040  @Override
041  public void close() {
042    super.close();
043    SendableRegistry.remove(this);
044    DIOJNI.freeDIOPort(m_handle);
045    m_handle = 0;
046  }
047
048  /**
049   * Get the value from a digital input channel. Retrieve the value of a single digital input
050   * channel from the FPGA.
051   *
052   * @return the status of the digital input
053   */
054  public boolean get() {
055    return DIOJNI.getDIO(m_handle);
056  }
057
058  /**
059   * Get the channel of the digital input.
060   *
061   * @return The GPIO channel number that this object represents.
062   */
063  @Override
064  public int getChannel() {
065    return m_channel;
066  }
067
068  /**
069   * Get the analog trigger type.
070   *
071   * @return false
072   */
073  @Override
074  public int getAnalogTriggerTypeForRouting() {
075    return 0;
076  }
077
078  /**
079   * Is this an analog trigger.
080   *
081   * @return true if this is an analog trigger
082   */
083  @Override
084  public boolean isAnalogTrigger() {
085    return false;
086  }
087
088  /**
089   * Get the HAL Port Handle.
090   *
091   * @return The HAL Handle to the specified source.
092   */
093  @Override
094  public int getPortHandleForRouting() {
095    return m_handle;
096  }
097
098  /**
099   * Indicates this input is used by a simulated device.
100   *
101   * @param device simulated device handle
102   */
103  public void setSimDevice(SimDevice device) {
104    DIOJNI.setDIOSimDevice(m_handle, device.getNativeHandle());
105  }
106
107  @Override
108  public void initSendable(SendableBuilder builder) {
109    builder.setSmartDashboardType("Digital Input");
110    builder.addBooleanProperty("Value", this::get, null);
111  }
112}