mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-19 00:41:43 +00:00
Removed AnalogModule, DigitalModule, and Module from C++
The HAL calls from Analog/DigitalModule are now directly in the classes that use them. Change-Id: I1cf879ab2979be903d03ab8282dfe5a5e7ae9443
This commit is contained in:
@@ -9,7 +9,6 @@
|
||||
#include "SensorBase.h"
|
||||
#include "PIDSource.h"
|
||||
#include "LiveWindow/LiveWindowSendable.h"
|
||||
#include "AnalogModule.h"
|
||||
|
||||
/**
|
||||
* Analog input class.
|
||||
@@ -31,8 +30,6 @@ public:
|
||||
explicit AnalogInput(uint32_t channel);
|
||||
virtual ~AnalogInput();
|
||||
|
||||
AnalogModule *GetModule() { return AnalogModule::GetInstance(1); }
|
||||
|
||||
int16_t GetValue();
|
||||
int32_t GetAverageValue();
|
||||
|
||||
@@ -59,6 +56,9 @@ public:
|
||||
uint32_t GetAccumulatorCount();
|
||||
void GetAccumulatorOutput(int64_t *value, uint32_t *count);
|
||||
|
||||
static void SetSampleRate(float samplesPerSecond);
|
||||
static float GetSampleRate();
|
||||
|
||||
double PIDGet();
|
||||
|
||||
void UpdateTable();
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) FIRST 2008. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
#pragma once
|
||||
|
||||
#include "HAL/HAL.hpp"
|
||||
#include "Module.h"
|
||||
|
||||
/**
|
||||
* Analog Module class.
|
||||
* Each module can independently sample its channels at a configurable rate.
|
||||
* There is a 64-bit hardware accumulator associated with channel 1 on each module.
|
||||
* The accumulator is attached to the output of the oversample and average engine so that the center
|
||||
* value can be specified in higher resolution resulting in less error.
|
||||
*/
|
||||
class AnalogModule : public Module
|
||||
{
|
||||
friend class Module;
|
||||
|
||||
public:
|
||||
static const long kTimebase = 40000000; ///< 40 MHz clock
|
||||
static const long kDefaultOversampleBits = 0;
|
||||
static const long kDefaultAverageBits = 7;
|
||||
static const uint32_t kAnalogInputs = 8;
|
||||
static constexpr float kDefaultSampleRate = 50000.0;
|
||||
|
||||
void SetSampleRate(float samplesPerSecond);
|
||||
float GetSampleRate();
|
||||
void SetAverageBits(uint32_t channel, uint32_t bits);
|
||||
uint32_t GetAverageBits(uint32_t channel);
|
||||
void SetOversampleBits(uint32_t channel, uint32_t bits);
|
||||
uint32_t GetOversampleBits(uint32_t channel);
|
||||
int16_t GetValue(uint32_t channel);
|
||||
int32_t GetAverageValue(uint32_t channel);
|
||||
float GetAverageVoltage(uint32_t channel);
|
||||
float GetVoltage(uint32_t channel);
|
||||
uint32_t GetLSBWeight(uint32_t channel);
|
||||
int32_t GetOffset(uint32_t channel);
|
||||
int32_t VoltsToValue(int32_t channel, float voltage);
|
||||
|
||||
static AnalogModule* GetInstance(uint8_t moduleNumber);
|
||||
|
||||
protected:
|
||||
explicit AnalogModule(uint8_t moduleNumber);
|
||||
virtual ~AnalogModule();
|
||||
|
||||
private:
|
||||
uint8_t m_moduleNumber;
|
||||
void* m_ports[kAnalogInputs];
|
||||
};
|
||||
@@ -10,7 +10,6 @@
|
||||
#include "SensorBase.h"
|
||||
|
||||
class AnalogInput;
|
||||
class AnalogModule;
|
||||
|
||||
class AnalogTrigger : public SensorBase
|
||||
{
|
||||
|
||||
@@ -5,8 +5,6 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
#pragma once
|
||||
|
||||
class DigitalModule;
|
||||
|
||||
#include "DigitalSource.h"
|
||||
#include "LiveWindow/LiveWindowSendable.h"
|
||||
|
||||
@@ -45,7 +43,6 @@ public:
|
||||
private:
|
||||
void InitDigitalInput(uint32_t channel);
|
||||
uint32_t m_channel;
|
||||
DigitalModule *m_module;
|
||||
bool m_lastValue;
|
||||
|
||||
ITable *m_table;
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) FIRST 2008. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
#pragma once
|
||||
|
||||
#include "HAL/HAL.hpp"
|
||||
#include "Module.h"
|
||||
|
||||
class I2C;
|
||||
|
||||
const uint32_t kExpectedLoopTiming = 260;
|
||||
|
||||
class DigitalModule : public Module
|
||||
{
|
||||
friend class I2C;
|
||||
friend class Module;
|
||||
|
||||
protected:
|
||||
explicit DigitalModule(uint8_t moduleNumber);
|
||||
virtual ~DigitalModule();
|
||||
|
||||
public:
|
||||
void SetPWM(uint32_t channel, unsigned short value);
|
||||
unsigned short GetPWM(uint32_t channel);
|
||||
void SetPWMPeriodScale(uint32_t channel, uint32_t squelchMask);
|
||||
void SetRelayForward(uint32_t channel, bool on);
|
||||
void SetRelayReverse(uint32_t channel, bool on);
|
||||
bool GetRelayForward(uint32_t channel);
|
||||
uint8_t GetRelayForward();
|
||||
bool GetRelayReverse(uint32_t channel);
|
||||
uint8_t GetRelayReverse();
|
||||
bool AllocateDIO(uint32_t channel, bool input);
|
||||
void FreeDIO(uint32_t channel);
|
||||
void SetDIO(uint32_t channel, short value);
|
||||
bool GetDIO(uint32_t channel);
|
||||
uint16_t GetDIO();
|
||||
bool GetDIODirection(uint32_t channel);
|
||||
uint16_t GetDIODirection();
|
||||
void Pulse(uint32_t channel, float pulseLength);
|
||||
bool IsPulsing(uint32_t channel);
|
||||
bool IsPulsing();
|
||||
uint32_t AllocateDO_PWM();
|
||||
void FreeDO_PWM(uint32_t pwmGenerator);
|
||||
void SetDO_PWMRate(float rate);
|
||||
void SetDO_PWMDutyCycle(uint32_t pwmGenerator, float dutyCycle);
|
||||
void SetDO_PWMOutputChannel(uint32_t pwmGenerator, uint32_t channel);
|
||||
uint16_t GetLoopTiming();
|
||||
|
||||
static DigitalModule* GetInstance(uint8_t moduleNumber);
|
||||
static uint8_t RemapDigitalChannel(uint32_t channel)
|
||||
{
|
||||
return 15 - channel;
|
||||
} // TODO: Need channel validation
|
||||
static uint8_t UnmapDigitalChannel(uint32_t channel)
|
||||
{
|
||||
return 15 - channel;
|
||||
} // TODO: Need channel validation
|
||||
|
||||
private:
|
||||
uint8_t m_module;
|
||||
void* m_digital_ports[kDigitalChannels];
|
||||
void* m_relay_ports[kRelayChannels];
|
||||
void* m_pwm_ports[kPwmChannels];
|
||||
};
|
||||
@@ -9,8 +9,6 @@
|
||||
#include "LiveWindow/LiveWindowSendable.h"
|
||||
#include "tables/ITableListener.h"
|
||||
|
||||
class DigitalModule;
|
||||
|
||||
/**
|
||||
* Class to write to digital outputs.
|
||||
* Write values to the digital output channels. Other devices implemented elsewhere will allocate
|
||||
@@ -51,8 +49,7 @@ private:
|
||||
void InitDigitalOutput(uint32_t channel);
|
||||
|
||||
uint32_t m_channel;
|
||||
uint32_t m_pwmGenerator;
|
||||
DigitalModule *m_module;
|
||||
void *m_pwmGenerator;
|
||||
|
||||
ITable *m_table;
|
||||
};
|
||||
|
||||
@@ -7,14 +7,12 @@
|
||||
|
||||
#include "SensorBase.h"
|
||||
|
||||
class DigitalModule;
|
||||
|
||||
/**
|
||||
* I2C bus interface class.
|
||||
*
|
||||
*
|
||||
* This class is intended to be used by sensor (and other I2C device) drivers.
|
||||
* It probably should not be used directly.
|
||||
*
|
||||
*
|
||||
*/
|
||||
class I2C : SensorBase
|
||||
{
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) FIRST 2008. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
#pragma once
|
||||
|
||||
#include "SensorBase.h"
|
||||
#include "NetworkCommunication/LoadOut.h"
|
||||
|
||||
#define kMaxModules (nLoadOut::kModuleType_Solenoid * kMaxModuleNumber + (kMaxModuleNumber - 1))
|
||||
|
||||
class Module : public SensorBase
|
||||
{
|
||||
public:
|
||||
nLoadOut::tModuleType GetType()
|
||||
{
|
||||
return m_moduleType;
|
||||
}
|
||||
uint8_t GetNumber()
|
||||
{
|
||||
return m_moduleNumber;
|
||||
}
|
||||
static Module *GetModule(nLoadOut::tModuleType type, uint8_t number);
|
||||
|
||||
protected:
|
||||
explicit Module(nLoadOut::tModuleType type, uint8_t number);
|
||||
virtual ~Module();
|
||||
|
||||
nLoadOut::tModuleType m_moduleType; ///< The type of module represented.
|
||||
uint8_t m_moduleNumber; ///< The module index within the module type.
|
||||
|
||||
private:
|
||||
static uint8_t ToIndex(nLoadOut::tModuleType type, uint8_t number);
|
||||
static Module* m_modules[kMaxModules];
|
||||
};
|
||||
@@ -9,8 +9,6 @@
|
||||
#include "LiveWindow/LiveWindowSendable.h"
|
||||
#include "tables/ITableListener.h"
|
||||
|
||||
class DigitalModule;
|
||||
|
||||
/**
|
||||
* Class implements the PWM generation in the FPGA.
|
||||
*
|
||||
@@ -29,7 +27,6 @@ class DigitalModule;
|
||||
*/
|
||||
class PWM : public SensorBase, public ITableListener, public LiveWindowSendable
|
||||
{
|
||||
friend class DigitalModule;
|
||||
public:
|
||||
enum PeriodMultiplier
|
||||
{
|
||||
@@ -105,7 +102,6 @@ protected:
|
||||
private:
|
||||
void InitPWM(uint32_t channel);
|
||||
uint32_t m_channel;
|
||||
DigitalModule *m_module;
|
||||
int32_t GetMaxPositivePwm()
|
||||
{
|
||||
return m_maxPwm;
|
||||
|
||||
@@ -10,8 +10,6 @@
|
||||
#include "LiveWindow/LiveWindowSendable.h"
|
||||
#include "tables/ITable.h"
|
||||
|
||||
class DigitalModule;
|
||||
|
||||
/**
|
||||
* Class for Spike style relay outputs.
|
||||
* Relays are intended to be connected to spikes or similar relays. The relay channels controls
|
||||
@@ -59,5 +57,4 @@ private:
|
||||
|
||||
uint32_t m_channel;
|
||||
Direction m_direction;
|
||||
DigitalModule *m_module;
|
||||
};
|
||||
|
||||
@@ -21,7 +21,7 @@ public:
|
||||
virtual ~SensorBase();
|
||||
static void DeleteSingletons();
|
||||
|
||||
static uint32_t GetDefaultSolenoidModule()
|
||||
static uint32_t GetDefaultSolenoidModule()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -44,9 +44,14 @@ public:
|
||||
static const uint32_t kRelayChannels = 8;
|
||||
static const uint32_t kPDPChannels = 16;
|
||||
static const uint32_t kChassisSlots = 8;
|
||||
|
||||
protected:
|
||||
void AddToSingletonList();
|
||||
|
||||
static void* m_digital_ports[kDigitalChannels];
|
||||
static void* m_relay_ports[kRelayChannels];
|
||||
static void* m_pwm_ports[kPwmChannels];
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(SensorBase);
|
||||
static SensorBase *m_singletonList;
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
#include "AnalogInput.h"
|
||||
#include "AnalogOutput.h"
|
||||
#include "AnalogPotentiometer.h"
|
||||
#include "AnalogModule.h"
|
||||
#include "AnalogTrigger.h"
|
||||
#include "AnalogTriggerOutput.h"
|
||||
#include "BuiltInAccelerometer.h"
|
||||
@@ -41,7 +40,6 @@
|
||||
#include "Counter.h"
|
||||
#include "Dashboard.h"
|
||||
#include "DigitalInput.h"
|
||||
#include "DigitalModule.h"
|
||||
#include "DigitalOutput.h"
|
||||
#include "DigitalSource.h"
|
||||
#include "DoubleSolenoid.h"
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#include "ADXL345_I2C.h"
|
||||
#include "DigitalModule.h"
|
||||
//#include "NetworkCommunication/UsageReporting.h"
|
||||
#include "I2C.h"
|
||||
|
||||
|
||||
@@ -367,6 +367,29 @@ void AnalogInput::GetAccumulatorOutput(int64_t *value, uint32_t *count)
|
||||
*value += m_accumulatorOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the sample rate for all analog channels.
|
||||
*
|
||||
* @param samplesPerSecond The number of samples per second.
|
||||
*/
|
||||
void AnalogInput::SetSampleRate(float samplesPerSecond)
|
||||
{
|
||||
int32_t status = 0;
|
||||
setAnalogSampleRate(samplesPerSecond, &status);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current sample rate for all channels
|
||||
*
|
||||
* @return Sample rate.
|
||||
*/
|
||||
float AnalogInput::GetSampleRate()
|
||||
{
|
||||
int32_t status = 0;
|
||||
float sampleRate = getAnalogSampleRate(&status);
|
||||
return sampleRate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Average value for the PID Source base object.
|
||||
*
|
||||
|
||||
@@ -1,299 +0,0 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) FIRST 2008. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#include "AnalogModule.h"
|
||||
#include "Timer.h"
|
||||
#include "WPIErrors.h"
|
||||
|
||||
const long AnalogModule::kTimebase; ///< 40 MHz clock
|
||||
const long AnalogModule::kDefaultOversampleBits;
|
||||
const long AnalogModule::kDefaultAverageBits;
|
||||
constexpr float AnalogModule::kDefaultSampleRate;
|
||||
|
||||
/**
|
||||
* Get an instance of an Analog Module.
|
||||
*
|
||||
* Singleton analog module creation where a module is allocated on the first use
|
||||
* and the same module is returned on subsequent uses.
|
||||
*
|
||||
* @param moduleNumber The analog module to get (1 or 2).
|
||||
* @return A pointer to the AnalogModule.
|
||||
*/
|
||||
AnalogModule* AnalogModule::GetInstance(uint8_t moduleNumber)
|
||||
{
|
||||
if (checkAnalogModule(moduleNumber))
|
||||
{
|
||||
return (AnalogModule*)GetModule(nLoadOut::kModuleType_Analog, moduleNumber);
|
||||
}
|
||||
|
||||
// If this wasn't caught before now, make sure we say what's wrong before we crash
|
||||
char buf[64];
|
||||
snprintf(buf, 64, "Analog Module %d", moduleNumber);
|
||||
wpi_setGlobalWPIErrorWithContext(ModuleIndexOutOfRange, buf);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance of an analog module.
|
||||
*
|
||||
* Create an instance of the analog module object. Initialize all the parameters
|
||||
* to reasonable values on start.
|
||||
* Setting a global value on an analog module can be done only once unless subsequent
|
||||
* values are set the previously set value.
|
||||
* Analog modules are a singleton, so the constructor is never called outside of this class.
|
||||
*
|
||||
* @param moduleNumber The analog module to create (1 or 2).
|
||||
*/
|
||||
AnalogModule::AnalogModule(uint8_t moduleNumber)
|
||||
: Module(nLoadOut::kModuleType_Analog, moduleNumber)
|
||||
, m_moduleNumber(moduleNumber)
|
||||
, m_ports()
|
||||
{
|
||||
for (uint32_t i = 0; i < kAnalogInputs; i++)
|
||||
{
|
||||
void* port = getPortWithModule(moduleNumber, i);
|
||||
int32_t status = 0;
|
||||
m_ports[i] = initializeAnalogInputPort(port, &status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
}
|
||||
|
||||
AddToSingletonList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor for AnalogModule.
|
||||
*/
|
||||
AnalogModule::~AnalogModule()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the sample rate on the module.
|
||||
*
|
||||
* This is a global setting for the module and effects all channels.
|
||||
*
|
||||
* @param samplesPerSecond The number of samples per channel per second.
|
||||
*/
|
||||
void AnalogModule::SetSampleRate(float samplesPerSecond)
|
||||
{
|
||||
int32_t status = 0;
|
||||
setAnalogSampleRateWithModule(m_moduleNumber, samplesPerSecond, &status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current sample rate on the module.
|
||||
*
|
||||
* This assumes one entry in the scan list.
|
||||
* This is a global setting for the module and effects all channels.
|
||||
*
|
||||
* @return Sample rate.
|
||||
*/
|
||||
float AnalogModule::GetSampleRate()
|
||||
{
|
||||
int32_t status = 0;
|
||||
float sampleRate = getAnalogSampleRateWithModule(m_moduleNumber, &status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
return sampleRate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the number of averaging bits.
|
||||
*
|
||||
* This sets the number of averaging bits. The actual number of averaged samples is 2**bits.
|
||||
* Use averaging to improve the stability of your measurement at the expense of sampling rate.
|
||||
* The averaging is done automatically in the FPGA.
|
||||
*
|
||||
* @param channel Analog channel to configure.
|
||||
* @param bits Number of bits to average.
|
||||
*/
|
||||
void AnalogModule::SetAverageBits(uint32_t channel, uint32_t bits)
|
||||
{
|
||||
int32_t status = 0;
|
||||
setAnalogAverageBits(m_ports[channel-1], bits, &status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of averaging bits.
|
||||
*
|
||||
* This gets the number of averaging bits from the FPGA. The actual number of averaged samples is 2**bits.
|
||||
* The averaging is done automatically in the FPGA.
|
||||
*
|
||||
* @param channel Channel to address.
|
||||
* @return Bits to average.
|
||||
*/
|
||||
uint32_t AnalogModule::GetAverageBits(uint32_t channel)
|
||||
{
|
||||
int32_t status = 0;
|
||||
int32_t averageBits = getAnalogAverageBits(m_ports[channel-1], &status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
return averageBits;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the number of oversample bits.
|
||||
*
|
||||
* This sets the number of oversample bits. The actual number of oversampled values is 2**bits.
|
||||
* Use oversampling to improve the resolution of your measurements at the expense of sampling rate.
|
||||
* The oversampling is done automatically in the FPGA.
|
||||
*
|
||||
* @param channel Analog channel to configure.
|
||||
* @param bits Number of bits to oversample.
|
||||
*/
|
||||
void AnalogModule::SetOversampleBits(uint32_t channel, uint32_t bits)
|
||||
{
|
||||
int32_t status = 0;
|
||||
setAnalogOversampleBits(m_ports[channel-1], bits, &status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of oversample bits.
|
||||
*
|
||||
* This gets the number of oversample bits from the FPGA. The actual number of oversampled values is
|
||||
* 2**bits. The oversampling is done automatically in the FPGA.
|
||||
*
|
||||
* @param channel Channel to address.
|
||||
* @return Bits to oversample.
|
||||
*/
|
||||
uint32_t AnalogModule::GetOversampleBits(uint32_t channel)
|
||||
{
|
||||
int32_t status = 0;
|
||||
int32_t oversampleBits = getAnalogOversampleBits(m_ports[channel-1], &status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
return oversampleBits;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a sample straight from the channel on this module.
|
||||
*
|
||||
* The sample is a 12-bit value representing the -10V to 10V range of the A/D converter in the module.
|
||||
* The units are in A/D converter codes. Use GetVoltage() to get the analog value in calibrated units.
|
||||
*
|
||||
* @return A sample straight from the channel on this module.
|
||||
*/
|
||||
int16_t AnalogModule::GetValue(uint32_t channel)
|
||||
{
|
||||
int32_t status = 0;
|
||||
int16_t value = getAnalogValue(m_ports[channel-1], &status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a sample from the output of the oversample and average engine for the channel.
|
||||
*
|
||||
* The sample is 12-bit + the value configured in SetOversampleBits().
|
||||
* The value configured in SetAverageBits() will cause this value to be averaged 2**bits number of samples.
|
||||
* This is not a sliding window. The sample will not change until 2**(OversamplBits + AverageBits) samples
|
||||
* have been acquired from the module on this channel.
|
||||
* Use GetAverageVoltage() to get the analog value in calibrated units.
|
||||
*
|
||||
* @param channel Channel number to read.
|
||||
* @return A sample from the oversample and average engine for the channel.
|
||||
*/
|
||||
int32_t AnalogModule::GetAverageValue(uint32_t channel)
|
||||
{
|
||||
int32_t status = 0;
|
||||
int32_t value = getAnalogAverageValue(m_ports[channel-1], &status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a voltage to a raw value for a specified channel.
|
||||
*
|
||||
* This process depends on the calibration of each channel, so the channel
|
||||
* must be specified.
|
||||
*
|
||||
* @todo This assumes raw values. Oversampling not supported as is.
|
||||
*
|
||||
* @param channel The channel to convert for.
|
||||
* @param voltage The voltage to convert.
|
||||
* @return The raw value for the channel.
|
||||
*/
|
||||
int32_t AnalogModule::VoltsToValue(int32_t channel, float voltage)
|
||||
{
|
||||
int32_t status = 0;
|
||||
int32_t value = getAnalogVoltsToValue(m_ports[channel-1], voltage, &status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a scaled sample straight from the channel on this module.
|
||||
*
|
||||
* The value is scaled to units of Volts using the calibrated scaling data from GetLSBWeight() and GetOffset().
|
||||
*
|
||||
* @param channel The channel to read.
|
||||
* @return A scaled sample straight from the channel on this module.
|
||||
*/
|
||||
float AnalogModule::GetVoltage(uint32_t channel)
|
||||
{
|
||||
int32_t status = 0;
|
||||
float voltage = getAnalogVoltage(m_ports[channel-1], &status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
return voltage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a scaled sample from the output of the oversample and average engine for the channel.
|
||||
*
|
||||
* The value is scaled to units of Volts using the calibrated scaling data from GetLSBWeight() and GetOffset().
|
||||
* Using oversampling will cause this value to be higher resolution, but it will update more slowly.
|
||||
* Using averaging will cause this value to be more stable, but it will update more slowly.
|
||||
*
|
||||
* @param channel The channel to read.
|
||||
* @return A scaled sample from the output of the oversample and average engine for the channel.
|
||||
*/
|
||||
float AnalogModule::GetAverageVoltage(uint32_t channel)
|
||||
{
|
||||
int32_t status = 0;
|
||||
float voltage = getAnalogAverageVoltage(m_ports[channel-1], &status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
return voltage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the factory scaling least significant bit weight constant.
|
||||
* The least significant bit weight constant for the channel that was calibrated in
|
||||
* manufacturing and stored in an eeprom in the module.
|
||||
*
|
||||
* Volts = ((LSB_Weight * 1e-9) * raw) - (Offset * 1e-9)
|
||||
*
|
||||
* @param channel The channel to get calibration data for.
|
||||
* @return Least significant bit weight.
|
||||
*/
|
||||
uint32_t AnalogModule::GetLSBWeight(uint32_t channel)
|
||||
{
|
||||
int32_t status = 0;
|
||||
int32_t lsbWeight = getAnalogLSBWeight(m_ports[channel-1], &status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
return lsbWeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the factory scaling offset constant.
|
||||
* The offset constant for the channel that was calibrated in manufacturing and stored
|
||||
* in an eeprom in the module.
|
||||
*
|
||||
* Volts = ((LSB_Weight * 1e-9) * raw) - (Offset * 1e-9)
|
||||
*
|
||||
* @param channel The channel to get calibration data for.
|
||||
* @return Offset constant.
|
||||
*/
|
||||
int32_t AnalogModule::GetOffset(uint32_t channel)
|
||||
{
|
||||
int32_t status = 0;
|
||||
int32_t offset = getAnalogOffset(m_ports[channel-1], &status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
return offset;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
#include "AnalogTrigger.h"
|
||||
|
||||
#include "AnalogInput.h"
|
||||
#include "AnalogModule.h"
|
||||
//#include "NetworkCommunication/UsageReporting.h"
|
||||
#include "Resource.h"
|
||||
#include "WPIErrors.h"
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#include "DigitalInput.h"
|
||||
#include "DigitalModule.h"
|
||||
//#include "NetworkCommunication/UsageReporting.h"
|
||||
#include "Resource.h"
|
||||
#include "WPIErrors.h"
|
||||
@@ -31,8 +30,10 @@ void DigitalInput::InitDigitalInput(uint32_t channel)
|
||||
return;
|
||||
}
|
||||
m_channel = channel;
|
||||
m_module = DigitalModule::GetInstance(1);
|
||||
m_module->AllocateDIO(channel, true);
|
||||
|
||||
int32_t status = 0;
|
||||
bool allocated = allocateDIO(m_digital_ports[channel], true, &status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
|
||||
HALReport(HALUsageReporting::kResourceType_DigitalInput, channel);
|
||||
}
|
||||
@@ -62,7 +63,10 @@ DigitalInput::~DigitalInput()
|
||||
m_interrupt = NULL;
|
||||
interruptsResource->Free(m_interruptIndex);
|
||||
}
|
||||
m_module->FreeDIO(m_channel);
|
||||
|
||||
int32_t status = 0;
|
||||
freeDIO(m_digital_ports[m_channel], &status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -71,8 +75,10 @@ DigitalInput::~DigitalInput()
|
||||
*/
|
||||
uint32_t DigitalInput::Get()
|
||||
{
|
||||
if (StatusIsFatal()) return 0;
|
||||
return m_module->GetDIO(m_channel);
|
||||
int32_t status = 0;
|
||||
bool value = getDIO(m_digital_ports[m_channel], &status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -96,8 +102,7 @@ uint32_t DigitalInput::GetChannelForRouting()
|
||||
*/
|
||||
uint32_t DigitalInput::GetModuleForRouting()
|
||||
{
|
||||
if (StatusIsFatal()) return 0;
|
||||
return m_module->GetNumber() - 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,413 +0,0 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) FIRST 2008. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#include "DigitalModule.h"
|
||||
#include "I2C.h"
|
||||
#include "PWM.h"
|
||||
#include "HAL/cpp/Synchronized.hpp"
|
||||
#include "WPIErrors.h"
|
||||
#include <math.h>
|
||||
|
||||
/**
|
||||
* Get an instance of an Digital Module.
|
||||
* Singleton digital module creation where a module is allocated on the first use
|
||||
* and the same module is returned on subsequent uses.
|
||||
*
|
||||
* @param moduleNumber The digital module to get (1 or 2).
|
||||
*/
|
||||
DigitalModule* DigitalModule::GetInstance(uint8_t moduleNumber)
|
||||
{
|
||||
if (checkDigitalModule(moduleNumber))
|
||||
{
|
||||
return (DigitalModule *)GetModule(nLoadOut::kModuleType_Digital, moduleNumber);
|
||||
}
|
||||
|
||||
// If this wasn't caught before now, make sure we say what's wrong before we crash
|
||||
char buf[64];
|
||||
snprintf(buf, 64, "Digital Module %d", moduleNumber);
|
||||
wpi_setGlobalWPIErrorWithContext(ModuleIndexOutOfRange, buf);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance of an digital module.
|
||||
* Create an instance of the digital module object. Initialize all the parameters
|
||||
* to reasonable values on start.
|
||||
* Setting a global value on an digital module can be done only once unless subsequent
|
||||
* values are set the previously set value.
|
||||
* Digital modules are a singleton, so the constructor is never called outside of this class.
|
||||
*
|
||||
* @param moduleNumber The digital module to create (1 or 2).
|
||||
*/
|
||||
DigitalModule::DigitalModule(uint8_t moduleNumber)
|
||||
: Module(nLoadOut::kModuleType_Digital, moduleNumber)
|
||||
{
|
||||
// TODO: Refactor out common logic
|
||||
m_module = moduleNumber;
|
||||
for (uint32_t i = 0; i < kDigitalChannels; i++)
|
||||
{
|
||||
void* port = getPortWithModule(moduleNumber, i);
|
||||
int32_t status = 0;
|
||||
m_digital_ports[i] = initializeDigitalPort(port, &status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
}
|
||||
for (uint32_t i = 0; i < kRelayChannels; i++)
|
||||
{
|
||||
void* port = getPortWithModule(moduleNumber, i);
|
||||
int32_t status = 0;
|
||||
m_relay_ports[i] = initializeDigitalPort(port, &status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
}
|
||||
for (uint32_t i = 0; i < kPwmChannels; i++)
|
||||
{
|
||||
void* port = getPortWithModule(moduleNumber, i);
|
||||
int32_t status = 0;
|
||||
m_pwm_ports[i] = initializeDigitalPort(port, &status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
}
|
||||
AddToSingletonList();
|
||||
}
|
||||
|
||||
DigitalModule::~DigitalModule()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a PWM channel to the desired value. The values range from 0 to 255 and the period is controlled
|
||||
* by the PWM Period and MinHigh registers.
|
||||
*
|
||||
* @param channel The PWM channel to set.
|
||||
* @param value The PWM value to set.
|
||||
*/
|
||||
void DigitalModule::SetPWM(uint32_t channel, unsigned short value)
|
||||
{
|
||||
int32_t status = 0;
|
||||
setPWM(m_pwm_ports[channel], value, &status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a value from a PWM channel.
|
||||
*
|
||||
* @param channel The PWM channel to read from.
|
||||
* @return The raw PWM value.
|
||||
*/
|
||||
unsigned short DigitalModule::GetPWM(uint32_t channel)
|
||||
{
|
||||
int32_t status = 0;
|
||||
uint16_t value = getPWM(m_pwm_ports[channel], &status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set how how often the PWM signal is squelched, thus scaling the period.
|
||||
*
|
||||
* @param channel The PWM channel to configure.
|
||||
* @param squelchMask The 2-bit mask of outputs to squelch.
|
||||
*/
|
||||
void DigitalModule::SetPWMPeriodScale(uint32_t channel, uint32_t squelchMask)
|
||||
{
|
||||
int32_t status = 0;
|
||||
setPWMPeriodScale(m_pwm_ports[channel], squelchMask, &status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the state of a relay.
|
||||
* Set the state of a relay output to be forward. Relays have two outputs and each is
|
||||
* independently set to 0v or 12v.
|
||||
*/
|
||||
void DigitalModule::SetRelayForward(uint32_t channel, bool on)
|
||||
{
|
||||
int32_t status = 0;
|
||||
setRelayForward(m_relay_ports[channel], on, &status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the state of a relay.
|
||||
* Set the state of a relay output to be reverse. Relays have two outputs and each is
|
||||
* independently set to 0v or 12v.
|
||||
*/
|
||||
void DigitalModule::SetRelayReverse(uint32_t channel, bool on)
|
||||
{
|
||||
int32_t status = 0;
|
||||
setRelayReverse(m_relay_ports[channel], on, &status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current state of the forward relay channel
|
||||
*/
|
||||
bool DigitalModule::GetRelayForward(uint32_t channel)
|
||||
{
|
||||
int32_t status = 0;
|
||||
bool on = getRelayForward(m_relay_ports[channel], &status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
return on;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current state of all of the forward relay channels on this module.
|
||||
*/
|
||||
uint8_t DigitalModule::GetRelayForward()
|
||||
{
|
||||
uint8_t value = 0;
|
||||
for (unsigned int i = 0; i < kRelayChannels; i++) {
|
||||
value |= GetRelayForward(i) << i;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current state of the reverse relay channel
|
||||
*/
|
||||
bool DigitalModule::GetRelayReverse(uint32_t channel)
|
||||
{
|
||||
int32_t status = 0;
|
||||
bool on = getRelayReverse(m_relay_ports[channel], &status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
return on;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current state of all of the reverse relay channels on this module.
|
||||
*/
|
||||
uint8_t DigitalModule::GetRelayReverse()
|
||||
{
|
||||
uint8_t value = 0;
|
||||
for (unsigned int i = 0; i < kRelayChannels; i++) {
|
||||
value |= GetRelayReverse(i) << i;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Allocate Digital I/O channels.
|
||||
* Allocate channels so that they are not accidently reused. Also the direction is set at the
|
||||
* time of the allocation.
|
||||
*
|
||||
* @param channel The Digital I/O channel
|
||||
* @param input If true open as input; if false open as output
|
||||
* @return Was successfully allocated
|
||||
*/
|
||||
bool DigitalModule::AllocateDIO(uint32_t channel, bool input)
|
||||
{
|
||||
int32_t status = 0;
|
||||
bool allocated = allocateDIO(m_digital_ports[channel], input, &status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
return allocated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Free the resource associated with a digital I/O channel.
|
||||
*
|
||||
* @param channel The Digital I/O channel to free
|
||||
*/
|
||||
void DigitalModule::FreeDIO(uint32_t channel)
|
||||
{
|
||||
int32_t status = 0;
|
||||
freeDIO(m_digital_ports[channel], &status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a digital I/O bit to the FPGA.
|
||||
* Set a single value on a digital I/O channel.
|
||||
*
|
||||
* @param channel The Digital I/O channel
|
||||
* @param value The state to set the digital channel (if it is configured as an output)
|
||||
*/
|
||||
void DigitalModule::SetDIO(uint32_t channel, short value)
|
||||
{
|
||||
int32_t status = 0;
|
||||
setDIO(m_digital_ports[channel], value, &status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a digital I/O bit from the FPGA.
|
||||
* Get a single value from a digital I/O channel.
|
||||
*
|
||||
* @param channel The digital I/O channel
|
||||
* @return The state of the specified channel
|
||||
*/
|
||||
bool DigitalModule::GetDIO(uint32_t channel)
|
||||
{
|
||||
int32_t status = 0;
|
||||
bool value = getDIO(m_digital_ports[channel], &status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the state of all the Digital I/O lines from the FPGA
|
||||
* These are not remapped to logical order. They are still in hardware order.
|
||||
*/
|
||||
uint16_t DigitalModule::GetDIO()
|
||||
{
|
||||
uint16_t value = 0;
|
||||
for (unsigned int i = 0; i < kDigitalChannels; i++) {
|
||||
value |= GetDIO(i) << i;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the direction of a the Digital I/O lines
|
||||
* A 1 bit means output and a 0 bit means input.
|
||||
*
|
||||
* @param channel The digital I/O channel
|
||||
* @return The direction of the specified channel
|
||||
*/
|
||||
bool DigitalModule::GetDIODirection(uint32_t channel)
|
||||
{
|
||||
int32_t status = 0;
|
||||
bool value = getDIODirection(m_digital_ports[channel], &status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the direction of all the Digital I/O lines from the FPGA
|
||||
* A 1 bit means output and a 0 bit means input.
|
||||
* These are not remapped to logical order. They are still in hardware order.
|
||||
*/
|
||||
uint16_t DigitalModule::GetDIODirection()
|
||||
{
|
||||
uint16_t value = 0;
|
||||
for (unsigned int i = 0; i < kDigitalChannels; i++) {
|
||||
value |= GetDIODirection(i) << i;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a single pulse.
|
||||
* Write a pulse to the specified digital output channel. There can only be a single pulse going at any time.
|
||||
*
|
||||
* @param channel The Digital Output channel that the pulse should be output on
|
||||
* @param pulseLength The active length of the pulse (in seconds)
|
||||
*/
|
||||
void DigitalModule::Pulse(uint32_t channel, float pulseLength)
|
||||
{
|
||||
int32_t status = 0;
|
||||
pulse(m_digital_ports[channel], pulseLength, &status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check a DIO line to see if it is currently generating a pulse.
|
||||
*
|
||||
* @return A pulse is in progress
|
||||
*/
|
||||
bool DigitalModule::IsPulsing(uint32_t channel)
|
||||
{
|
||||
int32_t status = 0;
|
||||
bool value = isPulsing(m_digital_ports[channel], &status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if any DIO line is currently generating a pulse.
|
||||
*
|
||||
* @return A pulse on some line is in progress
|
||||
*/
|
||||
bool DigitalModule::IsPulsing()
|
||||
{
|
||||
int32_t status = 0;
|
||||
bool value = isAnyPulsing(&status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate a DO PWM Generator.
|
||||
* Allocate PWM generators so that they are not accidently reused.
|
||||
*
|
||||
* @return PWM Generator refnum
|
||||
*/
|
||||
uint32_t DigitalModule::AllocateDO_PWM()
|
||||
{
|
||||
int32_t status = 0;
|
||||
uint32_t value = *((uint32_t*) allocatePWMWithModule(m_module, &status)); // TODO: Hacky
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Free the resource associated with a DO PWM generator.
|
||||
*
|
||||
* @param pwmGenerator The pwmGen to free that was allocated with AllocateDO_PWM()
|
||||
*/
|
||||
void DigitalModule::FreeDO_PWM(uint32_t pwmGenerator) // Note: should become void*
|
||||
{
|
||||
int32_t status = 0;
|
||||
void* generator = &pwmGenerator;
|
||||
freePWMWithModule(m_module, generator, &status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the frequency of the DO PWM generator.
|
||||
*
|
||||
* The valid range is from 0.6 Hz to 19 kHz. The frequency resolution is logarithmic.
|
||||
*
|
||||
* @param rate The frequency to output all digital output PWM signals on this module.
|
||||
*/
|
||||
void DigitalModule::SetDO_PWMRate(float rate)
|
||||
{
|
||||
int32_t status = 0;
|
||||
setPWMRateWithModule(m_module, rate, &status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure which DO channel the PWM siganl is output on
|
||||
*
|
||||
* @param pwmGenerator The generator index reserved by AllocateDO_PWM()
|
||||
* @param channel The Digital Output channel to output on
|
||||
*/
|
||||
void DigitalModule::SetDO_PWMOutputChannel(uint32_t pwmGenerator, uint32_t channel) // pwmGenerator should become void*
|
||||
{
|
||||
int32_t status = 0;
|
||||
void* generator = &pwmGenerator;
|
||||
setPWMOutputChannelWithModule(m_module, generator, channel, &status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the duty-cycle of the PWM generator
|
||||
*
|
||||
* @param pwmGenerator The generator index reserved by AllocateDO_PWM()
|
||||
* @param dutyCycle The percent duty cycle to output [0..1].
|
||||
*/
|
||||
void DigitalModule::SetDO_PWMDutyCycle(uint32_t pwmGenerator, float dutyCycle)
|
||||
{
|
||||
int32_t status = 0;
|
||||
void* generator = &pwmGenerator;
|
||||
setPWMDutyCycleWithModule(m_module, generator, dutyCycle, &status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the loop timing of the Digital Module
|
||||
*
|
||||
* @return The loop time
|
||||
*/
|
||||
uint16_t DigitalModule::GetLoopTiming()
|
||||
{
|
||||
int32_t status = 0;
|
||||
uint16_t timing = getLoopTimingWithModule(m_module, &status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
return timing;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#include "DigitalOutput.h"
|
||||
#include "DigitalModule.h"
|
||||
//#include "NetworkCommunication/UsageReporting.h"
|
||||
#include "Resource.h"
|
||||
#include "WPIErrors.h"
|
||||
@@ -29,9 +28,11 @@ void DigitalOutput::InitDigitalOutput(uint32_t channel)
|
||||
return;
|
||||
}
|
||||
m_channel = channel;
|
||||
m_pwmGenerator = ~0ul;
|
||||
m_module = DigitalModule::GetInstance(1);
|
||||
m_module->AllocateDIO(m_channel, false);
|
||||
m_pwmGenerator = (void *)~0ul;
|
||||
|
||||
int32_t status = 0;
|
||||
allocateDIO(m_digital_ports[channel], false, &status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
|
||||
HALReport(HALUsageReporting::kResourceType_DigitalOutput, channel);
|
||||
}
|
||||
@@ -55,7 +56,10 @@ DigitalOutput::~DigitalOutput()
|
||||
if (StatusIsFatal()) return;
|
||||
// Disable the PWM in case it was running.
|
||||
DisablePWM();
|
||||
m_module->FreeDIO(m_channel);
|
||||
|
||||
int32_t status = 0;
|
||||
freeDIO(m_digital_ports[m_channel], &status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -65,7 +69,10 @@ DigitalOutput::~DigitalOutput()
|
||||
void DigitalOutput::Set(uint32_t value)
|
||||
{
|
||||
if (StatusIsFatal()) return;
|
||||
m_module->SetDIO(m_channel, value);
|
||||
|
||||
int32_t status = 0;
|
||||
setDIO(m_digital_ports[m_channel], value, &status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -85,7 +92,10 @@ uint32_t DigitalOutput::GetChannel()
|
||||
void DigitalOutput::Pulse(float length)
|
||||
{
|
||||
if (StatusIsFatal()) return;
|
||||
m_module->Pulse(m_channel, length);
|
||||
|
||||
int32_t status = 0;
|
||||
pulse(m_digital_ports[m_channel], length, &status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -95,7 +105,11 @@ void DigitalOutput::Pulse(float length)
|
||||
bool DigitalOutput::IsPulsing()
|
||||
{
|
||||
if (StatusIsFatal()) return false;
|
||||
return m_module->IsPulsing(m_channel);
|
||||
|
||||
int32_t status = 0;
|
||||
bool value = isPulsing(m_digital_ports[m_channel], &status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -103,14 +117,17 @@ bool DigitalOutput::IsPulsing()
|
||||
*
|
||||
* The valid range is from 0.6 Hz to 19 kHz. The frequency resolution is logarithmic.
|
||||
*
|
||||
* There is only one PWM frequency per digital module.
|
||||
* There is only one PWM frequency for all digital channels.
|
||||
*
|
||||
* @param rate The frequency to output all digital output PWM signals on this module.
|
||||
* @param rate The frequency to output all digital output PWM signals.
|
||||
*/
|
||||
void DigitalOutput::SetPWMRate(float rate)
|
||||
{
|
||||
if (StatusIsFatal()) return;
|
||||
m_module->SetDO_PWMRate(rate);
|
||||
|
||||
int32_t status = 0;
|
||||
setPWMRate(rate, &status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -127,11 +144,21 @@ void DigitalOutput::SetPWMRate(float rate)
|
||||
*/
|
||||
void DigitalOutput::EnablePWM(float initialDutyCycle)
|
||||
{
|
||||
if (StatusIsFatal()) return;
|
||||
if (m_pwmGenerator != ~0ul) return;
|
||||
m_pwmGenerator = m_module->AllocateDO_PWM();
|
||||
m_module->SetDO_PWMDutyCycle(m_pwmGenerator, initialDutyCycle);
|
||||
m_module->SetDO_PWMOutputChannel(m_pwmGenerator, m_channel);
|
||||
if(m_pwmGenerator != (void *)~0ul) return;
|
||||
|
||||
int32_t status = 0;
|
||||
|
||||
if(StatusIsFatal()) return;
|
||||
m_pwmGenerator = allocatePWM(&status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
|
||||
if(StatusIsFatal()) return;
|
||||
setPWMDutyCycle(m_pwmGenerator, initialDutyCycle, &status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
|
||||
if(StatusIsFatal()) return;
|
||||
setPWMOutputChannel(m_pwmGenerator, m_channel, &status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -142,10 +169,18 @@ void DigitalOutput::EnablePWM(float initialDutyCycle)
|
||||
void DigitalOutput::DisablePWM()
|
||||
{
|
||||
if (StatusIsFatal()) return;
|
||||
if(m_pwmGenerator == (void *)~0ul) return;
|
||||
|
||||
int32_t status = 0;
|
||||
|
||||
// Disable the output by routing to a dead bit.
|
||||
m_module->SetDO_PWMOutputChannel(m_pwmGenerator, kDigitalChannels);
|
||||
m_module->FreeDO_PWM(m_pwmGenerator);
|
||||
m_pwmGenerator = ~0ul;
|
||||
setPWMOutputChannel(m_pwmGenerator, kDigitalChannels, &status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
|
||||
freePWM(m_pwmGenerator, &status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
|
||||
m_pwmGenerator = (void *)~0ul;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -159,7 +194,10 @@ void DigitalOutput::DisablePWM()
|
||||
void DigitalOutput::UpdateDutyCycle(float dutyCycle)
|
||||
{
|
||||
if (StatusIsFatal()) return;
|
||||
m_module->SetDO_PWMDutyCycle(m_pwmGenerator, dutyCycle);
|
||||
|
||||
int32_t status = 0;
|
||||
setPWMDutyCycle(m_pwmGenerator, dutyCycle, &status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -167,7 +205,7 @@ void DigitalOutput::UpdateDutyCycle(float dutyCycle)
|
||||
*/
|
||||
uint32_t DigitalOutput::GetChannelForRouting()
|
||||
{
|
||||
return DigitalModule::RemapDigitalChannel(GetChannel() - 1);
|
||||
return GetChannel();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -175,8 +213,7 @@ uint32_t DigitalOutput::GetChannelForRouting()
|
||||
*/
|
||||
uint32_t DigitalOutput::GetModuleForRouting()
|
||||
{
|
||||
if (StatusIsFatal()) return 0;
|
||||
return m_module->GetNumber() - 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
|
||||
#include "Gyro.h"
|
||||
#include "AnalogInput.h"
|
||||
#include "AnalogModule.h"
|
||||
//#include "NetworkCommunication/UsageReporting.h"
|
||||
#include "Timer.h"
|
||||
#include "WPIErrors.h"
|
||||
@@ -46,7 +45,7 @@ void Gyro::InitGyro()
|
||||
m_analog->SetOversampleBits(kOversampleBits);
|
||||
float sampleRate = kSamplesPerSecond *
|
||||
(1 << (kAverageBits + kOversampleBits));
|
||||
m_analog->GetModule()->SetSampleRate(sampleRate);
|
||||
m_analog->SetSampleRate(sampleRate);
|
||||
Wait(1.0);
|
||||
|
||||
m_analog->InitAccumulator();
|
||||
@@ -148,7 +147,7 @@ float Gyro::GetAngle( void )
|
||||
int64_t value = rawValue - (int64_t)((float)count * m_offset);
|
||||
|
||||
double scaledValue = value * 1e-9 * (double)m_analog->GetLSBWeight() * (double)(1 << m_analog->GetAverageBits()) /
|
||||
(m_analog->GetModule()->GetSampleRate() * m_voltsPerDegreePerSecond);
|
||||
(m_analog->GetSampleRate() * m_voltsPerDegreePerSecond);
|
||||
|
||||
return (float)scaledValue;
|
||||
}
|
||||
|
||||
@@ -5,14 +5,13 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#include "I2C.h"
|
||||
#include "DigitalModule.h"
|
||||
//#include "NetworkCommunication/UsageReporting.h"
|
||||
#include "HAL/Digital.hpp"
|
||||
#include "WPIErrors.h"
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
*
|
||||
* @param Port The I2C port to which the device is connected.
|
||||
* @param deviceAddress The address of the device on the I2C bus.
|
||||
*/
|
||||
@@ -37,9 +36,9 @@ I2C::~I2C()
|
||||
|
||||
/**
|
||||
* Generic transaction.
|
||||
*
|
||||
*
|
||||
* This is a lower-level interface to the I2C hardware giving you more control over each transaction.
|
||||
*
|
||||
*
|
||||
* @param dataToSend Buffer of data to send as part of the transaction.
|
||||
* @param sendSize Number of bytes to send as part of the transaction. [0..6]
|
||||
* @param dataReceived Buffer to read data into.
|
||||
@@ -68,10 +67,10 @@ bool I2C::Transaction(uint8_t *dataToSend, uint8_t sendSize, uint8_t *dataReceiv
|
||||
|
||||
/**
|
||||
* Attempt to address a device on the I2C bus.
|
||||
*
|
||||
*
|
||||
* This allows you to figure out if there is a device on the I2C bus that
|
||||
* responds to the address specified in the constructor.
|
||||
*
|
||||
*
|
||||
* @return Transfer Aborted... false for success, true for aborted.
|
||||
*/
|
||||
bool I2C::AddressOnly()
|
||||
@@ -83,10 +82,10 @@ bool I2C::AddressOnly()
|
||||
|
||||
/**
|
||||
* Execute a write transaction with the device.
|
||||
*
|
||||
*
|
||||
* Write a single byte to a register on a device and wait until the
|
||||
* transaction is complete.
|
||||
*
|
||||
*
|
||||
* @param registerAddress The address of the register on the device to be written.
|
||||
* @param data The byte to write to the register on the device.
|
||||
* @return Transfer Aborted... false for success, true for aborted.
|
||||
@@ -120,12 +119,12 @@ bool I2C::WriteBulk(uint8_t* data, uint8_t count)
|
||||
|
||||
/**
|
||||
* Execute a read transaction with the device.
|
||||
*
|
||||
*
|
||||
* Read 1 to 7 bytes from a device.
|
||||
* Most I2C devices will auto-increment the register pointer internally
|
||||
* allowing you to read up to 7 consecutive registers on a device in a
|
||||
* single transaction.
|
||||
*
|
||||
*
|
||||
* @param registerAddress The register to read first in the transaction.
|
||||
* @param count The number of bytes to read in the transaction. [1..7]
|
||||
* @param buffer A pointer to the array of bytes to store the data read from the device.
|
||||
@@ -180,9 +179,9 @@ bool I2C::ReadOnly(uint8_t count, uint8_t *buffer)
|
||||
|
||||
/**
|
||||
* Send a broadcast write to all devices on the I2C bus.
|
||||
*
|
||||
*
|
||||
* This is not currently implemented!
|
||||
*
|
||||
*
|
||||
* @param registerAddress The register to write on all devices on the bus.
|
||||
* @param data The value to write to the devices.
|
||||
*/
|
||||
@@ -192,13 +191,13 @@ void I2C::Broadcast(uint8_t registerAddress, uint8_t data)
|
||||
|
||||
/**
|
||||
* Verify that a device's registers contain expected values.
|
||||
*
|
||||
*
|
||||
* Most devices will have a set of registers that contain a known value that
|
||||
* can be used to identify them. This allows an I2C device driver to easily
|
||||
* verify that the device contains the expected value.
|
||||
*
|
||||
*
|
||||
* @pre The device must support and be configured to use register auto-increment.
|
||||
*
|
||||
*
|
||||
* @param registerAddress The base register to start reading from the device.
|
||||
* @param count The size of the field to be verified.
|
||||
* @param expected A buffer containing the values expected from the device.
|
||||
@@ -220,4 +219,3 @@ bool I2C::VerifySensor(uint8_t registerAddress, uint8_t count, const uint8_t *ex
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) FIRST 2008. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#include "Module.h"
|
||||
#include "AnalogModule.h"
|
||||
#include "DigitalModule.h"
|
||||
//#include "SolenoidModule.h"
|
||||
|
||||
Module* Module::m_modules[kMaxModules] = {NULL};
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param type The type of module represented.
|
||||
* @param number The module index within the module type.
|
||||
*/
|
||||
Module::Module(nLoadOut::tModuleType type, uint8_t number)
|
||||
: m_moduleType (type)
|
||||
, m_moduleNumber (number)
|
||||
{
|
||||
m_modules[ToIndex(type, number)] = this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
Module::~Module()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Static module singleton factory.
|
||||
*
|
||||
* @param type The type of module represented.
|
||||
* @param number The module index within the module type.
|
||||
*/
|
||||
Module* Module::GetModule(nLoadOut::tModuleType type, uint8_t number)
|
||||
{
|
||||
if (m_modules[ToIndex(type, number)] == NULL)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case nLoadOut::kModuleType_Analog:
|
||||
new AnalogModule(number);
|
||||
break;
|
||||
case nLoadOut::kModuleType_Digital:
|
||||
new DigitalModule(number);
|
||||
break;
|
||||
/*
|
||||
case nLoadOut::kModuleType_Solenoid:
|
||||
new SolenoidModule(number);
|
||||
break;
|
||||
*/
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return m_modules[ToIndex(type, number)];
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an index into the m_modules array based on type and number
|
||||
*
|
||||
* @param type The type of module represented.
|
||||
* @param number The module index within the module type.
|
||||
* @return The index into m_modules.
|
||||
*/
|
||||
uint8_t Module::ToIndex(nLoadOut::tModuleType type, uint8_t number)
|
||||
{
|
||||
if (number == 0 || number > kMaxModuleNumber) return 0;
|
||||
if (type < nLoadOut::kModuleType_Analog || type > nLoadOut::kModuleType_Solenoid) return 0;
|
||||
return (type * kMaxModuleNumber) + (number - 1);
|
||||
}
|
||||
@@ -6,7 +6,6 @@
|
||||
|
||||
#include "PWM.h"
|
||||
|
||||
#include "DigitalModule.h"
|
||||
//#include "NetworkCommunication/UsageReporting.h"
|
||||
#include "Resource.h"
|
||||
#include "Utility.h"
|
||||
@@ -44,9 +43,13 @@ void PWM::InitPWM(uint32_t channel)
|
||||
CloneError(allocated);
|
||||
return;
|
||||
}
|
||||
|
||||
m_channel = channel;
|
||||
m_module = DigitalModule::GetInstance(1);
|
||||
m_module->SetPWM(m_channel, kPwmDisabled);
|
||||
|
||||
int32_t status = 0;
|
||||
setPWM(m_pwm_ports[m_channel], kPwmDisabled, &status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
|
||||
m_eliminateDeadband = false;
|
||||
|
||||
HALReport(HALUsageReporting::kResourceType_PWM, channel);
|
||||
@@ -58,7 +61,6 @@ void PWM::InitPWM(uint32_t channel)
|
||||
* @param channel The PWM channel.
|
||||
*/
|
||||
PWM::PWM(uint32_t channel)
|
||||
: m_module(NULL)
|
||||
{
|
||||
InitPWM(channel);
|
||||
}
|
||||
@@ -70,11 +72,11 @@ PWM::PWM(uint32_t channel)
|
||||
*/
|
||||
PWM::~PWM()
|
||||
{
|
||||
if (m_module)
|
||||
{
|
||||
m_module->SetPWM(m_channel, kPwmDisabled);
|
||||
allocated->Free(m_channel);
|
||||
}
|
||||
int32_t status = 0;
|
||||
setPWM(m_pwm_ports[m_channel], kPwmDisabled, &status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
|
||||
allocated->Free(m_channel);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -123,15 +125,17 @@ void PWM::SetBounds(int32_t max, int32_t deadbandMax, int32_t center, int32_t de
|
||||
void PWM::SetBounds(double max, double deadbandMax, double center, double deadbandMin, double min)
|
||||
{
|
||||
// calculate the loop time in milliseconds
|
||||
double loopTime = m_module->GetLoopTiming()/(kSystemClockTicksPerMicrosecond*1e3);
|
||||
int32_t status = 0;
|
||||
double loopTime = getLoopTiming(&status)/(kSystemClockTicksPerMicrosecond*1e3);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
|
||||
if (StatusIsFatal()) return;
|
||||
|
||||
m_maxPwm = (int32_t)((max-kDefaultPwmCenter)/loopTime+kDefaultPwmStepsDown-1);
|
||||
m_deadbandMaxPwm = (int32_t)((deadbandMax-kDefaultPwmCenter)/loopTime+kDefaultPwmStepsDown-1);
|
||||
m_centerPwm = (int32_t)((center-kDefaultPwmCenter)/loopTime+kDefaultPwmStepsDown-1);
|
||||
m_deadbandMinPwm = (int32_t)((deadbandMin-kDefaultPwmCenter)/loopTime+kDefaultPwmStepsDown-1);
|
||||
m_minPwm = (int32_t)((min-kDefaultPwmCenter)/loopTime+kDefaultPwmStepsDown-1);
|
||||
// printf("Calculated m_minPwm: %d min: %lf loopTime: %lf defaultStepsDown: %d\n", m_minPwm, min, loopTime, kDefaultPwmStepsDown);
|
||||
m_maxPwm = (int32_t)((max-kDefaultPwmCenter)/loopTime+kDefaultPwmStepsDown-1);
|
||||
m_deadbandMaxPwm = (int32_t)((deadbandMax-kDefaultPwmCenter)/loopTime+kDefaultPwmStepsDown-1);
|
||||
m_centerPwm = (int32_t)((center-kDefaultPwmCenter)/loopTime+kDefaultPwmStepsDown-1);
|
||||
m_deadbandMinPwm = (int32_t)((deadbandMin-kDefaultPwmCenter)/loopTime+kDefaultPwmStepsDown-1);
|
||||
m_minPwm = (int32_t)((min-kDefaultPwmCenter)/loopTime+kDefaultPwmStepsDown-1);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -298,7 +302,10 @@ float PWM::GetSpeed()
|
||||
void PWM::SetRaw(unsigned short value)
|
||||
{
|
||||
if (StatusIsFatal()) return;
|
||||
m_module->SetPWM(m_channel, value);
|
||||
|
||||
int32_t status = 0;
|
||||
setPWM(m_pwm_ports[m_channel], value, &status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -311,7 +318,12 @@ void PWM::SetRaw(unsigned short value)
|
||||
unsigned short PWM::GetRaw()
|
||||
{
|
||||
if (StatusIsFatal()) return 0;
|
||||
return m_module->GetPWM(m_channel);
|
||||
|
||||
int32_t status = 0;
|
||||
unsigned short value = getPWM(m_pwm_ports[m_channel], &status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -322,20 +334,25 @@ unsigned short PWM::GetRaw()
|
||||
void PWM::SetPeriodMultiplier(PeriodMultiplier mult)
|
||||
{
|
||||
if (StatusIsFatal()) return;
|
||||
|
||||
int32_t status = 0;
|
||||
|
||||
switch(mult)
|
||||
{
|
||||
case kPeriodMultiplier_4X:
|
||||
m_module->SetPWMPeriodScale(m_channel, 3); // Squelch 3 out of 4 outputs
|
||||
setPWMPeriodScale(m_pwm_ports[m_channel], 3, &status); // Squelch 3 out of 4 outputs
|
||||
break;
|
||||
case kPeriodMultiplier_2X:
|
||||
m_module->SetPWMPeriodScale(m_channel, 1); // Squelch 1 out of 2 outputs
|
||||
setPWMPeriodScale(m_pwm_ports[m_channel], 1, &status); // Squelch 1 out of 2 outputs
|
||||
break;
|
||||
case kPeriodMultiplier_1X:
|
||||
m_module->SetPWMPeriodScale(m_channel, 0); // Don't squelch any outputs
|
||||
setPWMPeriodScale(m_pwm_ports[m_channel], 0, &status); // Don't squelch any outputs
|
||||
break;
|
||||
default:
|
||||
wpi_assert(false);
|
||||
}
|
||||
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) FIRST 2008. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#include "Relay.h"
|
||||
|
||||
#include "DigitalModule.h"
|
||||
//#include "NetworkCommunication/UsageReporting.h"
|
||||
#include "Resource.h"
|
||||
#include "WPIErrors.h"
|
||||
@@ -54,9 +53,12 @@ void Relay::InitRelay()
|
||||
|
||||
HALReport(HALUsageReporting::kResourceType_Relay, m_channel + 128);
|
||||
}
|
||||
m_module = DigitalModule::GetInstance(1);
|
||||
m_module->SetRelayForward(m_channel, false);
|
||||
m_module->SetRelayReverse(m_channel, false);
|
||||
|
||||
int32_t status = 0;
|
||||
setRelayForward(m_relay_ports[m_channel], false, &status);
|
||||
setRelayReverse(m_relay_ports[m_channel], false, &status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
|
||||
LiveWindow::GetInstance()->AddActuator("Relay", 1, m_channel, this);
|
||||
}
|
||||
|
||||
@@ -78,8 +80,11 @@ Relay::Relay(uint32_t channel, Relay::Direction direction)
|
||||
*/
|
||||
Relay::~Relay()
|
||||
{
|
||||
m_module->SetRelayForward(m_channel, false);
|
||||
m_module->SetRelayReverse(m_channel, false);
|
||||
|
||||
int32_t status = 0;
|
||||
setRelayForward(m_relay_ports[m_channel], false, &status);
|
||||
setRelayReverse(m_relay_ports[m_channel], false, &status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
|
||||
if (m_direction == kBothDirections || m_direction == kForwardOnly)
|
||||
{
|
||||
@@ -97,37 +102,40 @@ Relay::~Relay()
|
||||
* Valid values depend on which directions of the relay are controlled by the object.
|
||||
*
|
||||
* When set to kBothDirections, the relay can be any of the four states:
|
||||
* 0v-0v, 0v-12v, 12v-0v, 12v-12v
|
||||
* 0v-0v, 0v-12v, 12v-0v, 12v-12v
|
||||
*
|
||||
* When set to kForwardOnly or kReverseOnly, you can specify the constant for the
|
||||
* direction or you can simply specify kOff and kOn. Using only kOff and kOn is
|
||||
* recommended.
|
||||
* direction or you can simply specify kOff and kOn. Using only kOff and kOn is
|
||||
* recommended.
|
||||
*
|
||||
* @param value The state to set the relay.
|
||||
*/
|
||||
void Relay::Set(Relay::Value value)
|
||||
{
|
||||
if (StatusIsFatal()) return;
|
||||
|
||||
int32_t status = 0;
|
||||
|
||||
switch (value)
|
||||
{
|
||||
case kOff:
|
||||
if (m_direction == kBothDirections || m_direction == kForwardOnly)
|
||||
{
|
||||
m_module->SetRelayForward(m_channel, false);
|
||||
setRelayForward(m_relay_ports[m_channel], false, &status);
|
||||
}
|
||||
if (m_direction == kBothDirections || m_direction == kReverseOnly)
|
||||
{
|
||||
m_module->SetRelayReverse(m_channel, false);
|
||||
setRelayReverse(m_relay_ports[m_channel], false, &status);
|
||||
}
|
||||
break;
|
||||
case kOn:
|
||||
if (m_direction == kBothDirections || m_direction == kForwardOnly)
|
||||
{
|
||||
m_module->SetRelayForward(m_channel, true);
|
||||
setRelayForward(m_relay_ports[m_channel], true, &status);
|
||||
}
|
||||
if (m_direction == kBothDirections || m_direction == kReverseOnly)
|
||||
{
|
||||
m_module->SetRelayReverse(m_channel, true);
|
||||
setRelayReverse(m_relay_ports[m_channel], true, &status);
|
||||
}
|
||||
break;
|
||||
case kForward:
|
||||
@@ -138,11 +146,11 @@ void Relay::Set(Relay::Value value)
|
||||
}
|
||||
if (m_direction == kBothDirections || m_direction == kForwardOnly)
|
||||
{
|
||||
m_module->SetRelayForward(m_channel, true);
|
||||
setRelayForward(m_relay_ports[m_channel], true, &status);
|
||||
}
|
||||
if (m_direction == kBothDirections)
|
||||
{
|
||||
m_module->SetRelayReverse(m_channel, false);
|
||||
setRelayReverse(m_relay_ports[m_channel], false, &status);
|
||||
}
|
||||
break;
|
||||
case kReverse:
|
||||
@@ -153,14 +161,16 @@ void Relay::Set(Relay::Value value)
|
||||
}
|
||||
if (m_direction == kBothDirections)
|
||||
{
|
||||
m_module->SetRelayForward(m_channel, false);
|
||||
setRelayForward(m_relay_ports[m_channel], false, &status);
|
||||
}
|
||||
if (m_direction == kBothDirections || m_direction == kReverseOnly)
|
||||
{
|
||||
m_module->SetRelayReverse(m_channel, true);
|
||||
setRelayReverse(m_relay_ports[m_channel], true, &status);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -174,27 +184,31 @@ void Relay::Set(Relay::Value value)
|
||||
* @return The current state of the relay as a Relay::Value
|
||||
*/
|
||||
Relay::Value Relay::Get() {
|
||||
if(m_module->GetRelayForward(m_channel)) {
|
||||
if(m_module->GetRelayReverse(m_channel)) {
|
||||
return kOn;
|
||||
} else {
|
||||
if(m_direction == kForwardOnly) {
|
||||
return kOn;
|
||||
} else {
|
||||
return kForward;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(m_module->GetRelayReverse(m_channel)) {
|
||||
if(m_direction == kReverseOnly) {
|
||||
return kOn;
|
||||
} else {
|
||||
return kReverse;
|
||||
}
|
||||
} else {
|
||||
return kOff;
|
||||
}
|
||||
}
|
||||
int32_t status;
|
||||
|
||||
if(getRelayForward(m_relay_ports[m_channel], &status)) {
|
||||
if(getRelayReverse(m_relay_ports[m_channel], &status)) {
|
||||
return kOn;
|
||||
} else {
|
||||
if(m_direction == kForwardOnly) {
|
||||
return kOn;
|
||||
} else {
|
||||
return kForward;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(getRelayReverse(m_relay_ports[m_channel], &status)) {
|
||||
if(m_direction == kReverseOnly) {
|
||||
return kOn;
|
||||
} else {
|
||||
return kReverse;
|
||||
}
|
||||
} else {
|
||||
return kOff;
|
||||
}
|
||||
}
|
||||
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
}
|
||||
|
||||
void Relay::ValueChanged(ITable* source, const std::string& key, EntryValue value, bool isNew) {
|
||||
|
||||
@@ -19,11 +19,41 @@ const uint32_t SensorBase::kPDPChannels;
|
||||
const uint32_t SensorBase::kChassisSlots;
|
||||
SensorBase *SensorBase::m_singletonList = NULL;
|
||||
|
||||
static bool portsInitialized = false;
|
||||
void* SensorBase::m_digital_ports[kDigitalChannels];
|
||||
void* SensorBase::m_relay_ports[kRelayChannels];
|
||||
void* SensorBase::m_pwm_ports[kPwmChannels];
|
||||
|
||||
/**
|
||||
* Creates an instance of the sensor base and gets an FPGA handle
|
||||
*/
|
||||
SensorBase::SensorBase()
|
||||
{
|
||||
if(!portsInitialized) {
|
||||
for (uint32_t i = 0; i < kDigitalChannels; i++)
|
||||
{
|
||||
void* port = getPort(i);
|
||||
int32_t status = 0;
|
||||
m_digital_ports[i] = initializeDigitalPort(port, &status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < kRelayChannels; i++)
|
||||
{
|
||||
void* port = getPort(i);
|
||||
int32_t status = 0;
|
||||
m_relay_ports[i] = initializeDigitalPort(port, &status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < kPwmChannels; i++)
|
||||
{
|
||||
void* port = getPort(i);
|
||||
int32_t status = 0;
|
||||
m_pwm_ports[i] = initializeDigitalPort(port, &status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -141,9 +171,9 @@ bool SensorBase::CheckAnalogInput(uint32_t channel)
|
||||
*/
|
||||
bool SensorBase::CheckAnalogOutput(uint32_t channel)
|
||||
{
|
||||
if (channel < kAnalogOutputs)
|
||||
return true;
|
||||
return false;
|
||||
if (channel < kAnalogOutputs)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user