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  @SuppressWarnings("this-escape")
031  public DigitalInput(int channel) {
032    SensorUtil.checkDigitalChannel(channel);
033    m_channel = channel;
034
035    m_handle = DIOJNI.initializeDIOPort(HAL.getPort((byte) channel), true);
036
037    HAL.report(tResourceType.kResourceType_DigitalInput, channel + 1);
038    SendableRegistry.addLW(this, "DigitalInput", channel);
039  }
040
041  @Override
042  public void close() {
043    super.close();
044    SendableRegistry.remove(this);
045    DIOJNI.freeDIOPort(m_handle);
046    m_handle = 0;
047  }
048
049  /**
050   * Get the value from a digital input channel. Retrieve the value of a single digital input
051   * channel from the FPGA.
052   *
053   * @return the status of the digital input
054   */
055  public boolean get() {
056    return DIOJNI.getDIO(m_handle);
057  }
058
059  /**
060   * Get the channel of the digital input.
061   *
062   * @return The GPIO channel number that this object represents.
063   */
064  @Override
065  public int getChannel() {
066    return m_channel;
067  }
068
069  /**
070   * Get the analog trigger type.
071   *
072   * @return false
073   */
074  @Override
075  public int getAnalogTriggerTypeForRouting() {
076    return 0;
077  }
078
079  /**
080   * Is this an analog trigger.
081   *
082   * @return true if this is an analog trigger
083   */
084  @Override
085  public boolean isAnalogTrigger() {
086    return false;
087  }
088
089  /**
090   * Get the HAL Port Handle.
091   *
092   * @return The HAL Handle to the specified source.
093   */
094  @Override
095  public int getPortHandleForRouting() {
096    return m_handle;
097  }
098
099  /**
100   * Indicates this input is used by a simulated device.
101   *
102   * @param device simulated device handle
103   */
104  public void setSimDevice(SimDevice device) {
105    DIOJNI.setDIOSimDevice(m_handle, device.getNativeHandle());
106  }
107
108  @Override
109  public void initSendable(SendableBuilder builder) {
110    builder.setSmartDashboardType("Digital Input");
111    builder.addBooleanProperty("Value", this::get, null);
112  }
113}