blob: 984ad576ec9e76791eb9895fc5bd3d8fd0a03be0 [file] [log] [blame]
Brian Silverman26e4e522015-12-17 01:56:40 -05001/*----------------------------------------------------------------------------*/
Brian Silverman1a675112016-02-20 20:42:49 -05002/* Copyright (c) FIRST 2008-2016. All Rights Reserved. */
Brian Silverman26e4e522015-12-17 01:56:40 -05003/* Open Source Software - may be modified and shared by FRC teams. The code */
Brian Silverman1a675112016-02-20 20:42:49 -05004/* must be accompanied by the FIRST BSD license file in the root directory of */
5/* the project. */
Brian Silverman26e4e522015-12-17 01:56:40 -05006/*----------------------------------------------------------------------------*/
7
8#include "SensorBase.h"
9
10#include "NetworkCommunication/LoadOut.h"
11#include "WPIErrors.h"
12#include "HAL/HAL.hpp"
13#include "HAL/Port.h"
14
15const uint32_t SensorBase::kDigitalChannels;
16const uint32_t SensorBase::kAnalogInputs;
17const uint32_t SensorBase::kSolenoidChannels;
18const uint32_t SensorBase::kSolenoidModules;
19const uint32_t SensorBase::kPwmChannels;
20const uint32_t SensorBase::kRelayChannels;
21const uint32_t SensorBase::kPDPChannels;
22const uint32_t SensorBase::kChassisSlots;
23SensorBase* SensorBase::m_singletonList = nullptr;
24
25static bool portsInitialized = false;
26void* SensorBase::m_digital_ports[kDigitalChannels];
27void* SensorBase::m_relay_ports[kRelayChannels];
28void* SensorBase::m_pwm_ports[kPwmChannels];
29
30/**
31 * Creates an instance of the sensor base and gets an FPGA handle
32 */
33SensorBase::SensorBase() {
34 if (!portsInitialized) {
35 for (uint32_t i = 0; i < kDigitalChannels; i++) {
36 void* port = getPort(i);
37 int32_t status = 0;
38 m_digital_ports[i] = initializeDigitalPort(port, &status);
39 wpi_setErrorWithContext(status, getHALErrorMessage(status));
40 freePort(port);
41 }
42
43 for (uint32_t i = 0; i < kRelayChannels; i++) {
44 void* port = getPort(i);
45 int32_t status = 0;
46 m_relay_ports[i] = initializeDigitalPort(port, &status);
47 wpi_setErrorWithContext(status, getHALErrorMessage(status));
48 freePort(port);
49 }
50
51 for (uint32_t i = 0; i < kPwmChannels; i++) {
52 void* port = getPort(i);
53 int32_t status = 0;
54 m_pwm_ports[i] = initializeDigitalPort(port, &status);
55 wpi_setErrorWithContext(status, getHALErrorMessage(status));
56 freePort(port);
57 }
58 }
59}
60
61/**
62 * Add sensor to the singleton list.
63 * Add this sensor to the list of singletons that need to be deleted when
64 * the robot program exits. Each of the sensors on this list are singletons,
65 * that is they aren't allocated directly with new, but instead are allocated
66 * by the static GetInstance method. As a result, they are never deleted when
67 * the program exits. Consequently these sensors may still be holding onto
68 * resources and need to have their destructors called at the end of the
69 * program.
70 */
71void SensorBase::AddToSingletonList() {
72 m_nextSingleton = m_singletonList;
73 m_singletonList = this;
74}
75
76/**
77 * Delete all the singleton classes on the list.
78 * All the classes that were allocated as singletons need to be deleted so
79 * their resources can be freed.
80 */
81void SensorBase::DeleteSingletons() {
82 for (SensorBase* next = m_singletonList; next != nullptr;) {
83 SensorBase* tmp = next;
84 next = next->m_nextSingleton;
85 delete tmp;
86 }
87 m_singletonList = nullptr;
88}
89
90/**
91 * Check that the solenoid module number is valid.
92 *
93 * @return Solenoid module is valid and present
94 */
95bool SensorBase::CheckSolenoidModule(uint8_t moduleNumber) {
96 if (moduleNumber < 64) return true;
97 return false;
98}
99
100/**
101 * Check that the digital channel number is valid.
102 * Verify that the channel number is one of the legal channel numbers. Channel
103 * numbers are
104 * 1-based.
105 *
106 * @return Digital channel is valid
107 */
108bool SensorBase::CheckDigitalChannel(uint32_t channel) {
109 if (channel < kDigitalChannels) return true;
110 return false;
111}
112
113/**
114 * Check that the digital channel number is valid.
115 * Verify that the channel number is one of the legal channel numbers. Channel
116 * numbers are
117 * 1-based.
118 *
119 * @return Relay channel is valid
120 */
121bool SensorBase::CheckRelayChannel(uint32_t channel) {
122 if (channel < kRelayChannels) return true;
123 return false;
124}
125
126/**
127 * Check that the digital channel number is valid.
128 * Verify that the channel number is one of the legal channel numbers. Channel
129 * numbers are
130 * 1-based.
131 *
132 * @return PWM channel is valid
133 */
134bool SensorBase::CheckPWMChannel(uint32_t channel) {
135 if (channel < kPwmChannels) return true;
136 return false;
137}
138
139/**
140 * Check that the analog input number is value.
141 * Verify that the analog input number is one of the legal channel numbers.
142 * Channel numbers
143 * are 0-based.
144 *
145 * @return Analog channel is valid
146 */
147bool SensorBase::CheckAnalogInput(uint32_t channel) {
148 if (channel < kAnalogInputs) return true;
149 return false;
150}
151
152/**
153 * Check that the analog output number is valid.
154 * Verify that the analog output number is one of the legal channel numbers.
155 * Channel numbers
156 * are 0-based.
157 *
158 * @return Analog channel is valid
159 */
160bool SensorBase::CheckAnalogOutput(uint32_t channel) {
161 if (channel < kAnalogOutputs) return true;
162 return false;
163}
164
165/**
166 * Verify that the solenoid channel number is within limits.
167 *
168 * @return Solenoid channel is valid
169 */
170bool SensorBase::CheckSolenoidChannel(uint32_t channel) {
171 if (channel < kSolenoidChannels) return true;
172 return false;
173}
174
175/**
176 * Verify that the power distribution channel number is within limits.
177 *
178 * @return PDP channel is valid
179 */
180bool SensorBase::CheckPDPChannel(uint32_t channel) {
181 if (channel < kPDPChannels) return true;
182 return false;
183}