blob: e0121ea979424ee50a5f3c7c1782467ef5bbfd91 [file] [log] [blame]
Parker Schuhd3b7a8872018-02-19 16:42:27 -08001/*----------------------------------------------------------------------------*/
2/* Copyright (c) FIRST 2008-2017. All Rights Reserved. */
3/* Open Source Software - may be modified and shared by FRC teams. The code */
4/* must be accompanied by the FIRST BSD license file in the root directory of */
5/* the project. */
6/*----------------------------------------------------------------------------*/
7
8#include "frc971/wpilib/ahal/DigitalInput.h"
9
10#include <limits>
11#include <sstream>
12
Austin Schuhf6b94632019-02-02 22:11:27 -080013#include "hal/DIO.h"
14#include "hal/HAL.h"
15#include "hal/Ports.h"
Parker Schuhd3b7a8872018-02-19 16:42:27 -080016#include "frc971/wpilib/ahal/WPIErrors.h"
17
18using namespace frc;
19
20/**
21 * Create an instance of a Digital Input class.
22 *
23 * Creates a digital input given a channel.
24 *
25 * @param channel The DIO channel 0-9 are on-board, 10-25 are on the MXP port
26 */
27DigitalInput::DigitalInput(int channel) {
28 std::stringstream buf;
29
30 if (!CheckDigitalChannel(channel)) {
31 buf << "Digital Channel " << channel;
32 wpi_setWPIErrorWithContext(ChannelIndexOutOfRange, buf.str());
33 m_channel = std::numeric_limits<int>::max();
34 return;
35 }
36 m_channel = channel;
37
38 int32_t status = 0;
39 m_handle = HAL_InitializeDIOPort(HAL_GetPort(channel), true, &status);
40 if (status != 0) {
41 wpi_setErrorWithContextRange(status, 0, HAL_GetNumDigitalChannels(),
42 channel, HAL_GetErrorMessage(status));
43 m_handle = HAL_kInvalidHandle;
44 m_channel = std::numeric_limits<int>::max();
45 return;
46 }
47
48 HAL_Report(HALUsageReporting::kResourceType_DigitalInput, channel);
49}
50
51/**
52 * Free resources associated with the Digital Input class.
53 */
54DigitalInput::~DigitalInput() {
55 if (StatusIsFatal()) return;
56 if (m_interrupt != HAL_kInvalidHandle) {
57 int32_t status = 0;
58 HAL_CleanInterrupts(m_interrupt, &status);
59 // ignore status, as an invalid handle just needs to be ignored.
60 m_interrupt = HAL_kInvalidHandle;
61 }
62
63 HAL_FreeDIOPort(m_handle);
64}
65
66/**
67 * Get the value from a digital input channel.
68 *
69 * Retrieve the value of a single digital input channel from the FPGA.
70 */
71bool DigitalInput::Get() const {
72 if (StatusIsFatal()) return false;
73 int32_t status = 0;
74 bool value = HAL_GetDIO(m_handle, &status);
75 wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
76 return value;
77}
78
79/**
80 * @return The GPIO channel number that this object represents.
81 */
82int DigitalInput::GetChannel() const { return m_channel; }
83
84/**
85 * @return The HAL Handle to the specified source.
86 */
87HAL_Handle DigitalInput::GetPortHandleForRouting() const { return m_handle; }
88
89/**
90 * Is source an AnalogTrigger
91 */
92bool DigitalInput::IsAnalogTrigger() const { return false; }
93
94/**
95 * @return The type of analog trigger output to be used. 0 for Digitals
96 */
97AnalogTriggerType DigitalInput::GetAnalogTriggerTypeForRouting() const {
98 return (AnalogTriggerType)0;
99}