mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-26 01:51:41 +00:00
Switches Counters to Handles (#123)
This commit is contained in:
committed by
Peter Johnson
parent
47694ef810
commit
0f105a26f7
@@ -9,46 +9,62 @@
|
||||
|
||||
#include "DigitalInternal.h"
|
||||
#include "HAL/HAL.h"
|
||||
#include "handles/LimitedHandleResource.h"
|
||||
|
||||
static_assert(sizeof(uint32_t) <= sizeof(void*),
|
||||
"This file shoves uint32_ts into pointers.");
|
||||
|
||||
using namespace hal;
|
||||
|
||||
extern "C" {
|
||||
struct counter_t {
|
||||
namespace {
|
||||
struct Counter {
|
||||
tCounter* counter;
|
||||
uint32_t index;
|
||||
};
|
||||
typedef struct counter_t Counter;
|
||||
}
|
||||
|
||||
static hal::Resource* counters = nullptr;
|
||||
static LimitedHandleResource<HalCounterHandle, Counter, tCounter::kNumSystems,
|
||||
HalHandleEnum::Counter>
|
||||
counterHandles;
|
||||
|
||||
void* initializeCounter(Mode mode, uint32_t* index, int32_t* status) {
|
||||
hal::Resource::CreateResourceObject(&counters, tCounter::kNumSystems);
|
||||
*index = counters->Allocate("Counter");
|
||||
if (*index == ~0ul) {
|
||||
extern "C" {
|
||||
HalCounterHandle initializeCounter(Mode mode, uint32_t* index,
|
||||
int32_t* status) {
|
||||
auto handle = counterHandles.Allocate();
|
||||
if (handle == HAL_INVALID_HANDLE) { // out of resources
|
||||
*status = NO_AVAILABLE_RESOURCES;
|
||||
return nullptr;
|
||||
return HAL_INVALID_HANDLE;
|
||||
}
|
||||
Counter* counter = new Counter();
|
||||
auto counter = counterHandles.Get(handle);
|
||||
if (counter == nullptr) { // would only occur on thread issues
|
||||
*status = PARAMETER_OUT_OF_RANGE;
|
||||
return HAL_INVALID_HANDLE;
|
||||
}
|
||||
*index = static_cast<uint32_t>(getHandleIndex(handle));
|
||||
|
||||
counter->counter = tCounter::create(*index, status);
|
||||
counter->counter->writeConfig_Mode(mode, status);
|
||||
counter->counter->writeTimerConfig_AverageSize(1, status);
|
||||
counter->index = *index;
|
||||
return counter;
|
||||
return handle;
|
||||
}
|
||||
|
||||
void freeCounter(void* counter_pointer, int32_t* status) {
|
||||
Counter* counter = (Counter*)counter_pointer;
|
||||
if (!counter) return;
|
||||
void freeCounter(HalCounterHandle counter_handle, int32_t* status) {
|
||||
auto counter = counterHandles.Get(counter_handle);
|
||||
if (counter == nullptr) { // don't throw status as unneccesary
|
||||
return;
|
||||
}
|
||||
delete counter->counter;
|
||||
counters->Free(counter->index);
|
||||
counterHandles.Free(counter_handle);
|
||||
}
|
||||
|
||||
void setCounterAverageSize(void* counter_pointer, int32_t size,
|
||||
void setCounterAverageSize(HalCounterHandle counter_handle, int32_t size,
|
||||
int32_t* status) {
|
||||
Counter* counter = (Counter*)counter_pointer;
|
||||
auto counter = counterHandles.Get(counter_handle);
|
||||
if (counter == nullptr) {
|
||||
*status = PARAMETER_OUT_OF_RANGE;
|
||||
return;
|
||||
}
|
||||
counter->counter->writeTimerConfig_AverageSize(size, status);
|
||||
}
|
||||
|
||||
@@ -56,9 +72,13 @@ void setCounterAverageSize(void* counter_pointer, int32_t size,
|
||||
* Set the source object that causes the counter to count up.
|
||||
* Set the up counting DigitalSource.
|
||||
*/
|
||||
void setCounterUpSource(void* counter_pointer, uint32_t pin, bool analogTrigger,
|
||||
int32_t* status) {
|
||||
Counter* counter = (Counter*)counter_pointer;
|
||||
void setCounterUpSource(HalCounterHandle counter_handle, uint32_t pin,
|
||||
bool analogTrigger, int32_t* status) {
|
||||
auto counter = counterHandles.Get(counter_handle);
|
||||
if (counter == nullptr) {
|
||||
*status = PARAMETER_OUT_OF_RANGE;
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t module;
|
||||
|
||||
@@ -70,7 +90,7 @@ void setCounterUpSource(void* counter_pointer, uint32_t pin, bool analogTrigger,
|
||||
|
||||
if (counter->counter->readConfig_Mode(status) == kTwoPulse ||
|
||||
counter->counter->readConfig_Mode(status) == kExternalDirection) {
|
||||
setCounterUpSourceEdge(counter_pointer, true, false, status);
|
||||
setCounterUpSourceEdge(counter_handle, true, false, status);
|
||||
}
|
||||
counter->counter->strobeReset(status);
|
||||
}
|
||||
@@ -79,9 +99,13 @@ void setCounterUpSource(void* counter_pointer, uint32_t pin, bool analogTrigger,
|
||||
* Set the edge sensitivity on an up counting source.
|
||||
* Set the up source to either detect rising edges or falling edges.
|
||||
*/
|
||||
void setCounterUpSourceEdge(void* counter_pointer, bool risingEdge,
|
||||
void setCounterUpSourceEdge(HalCounterHandle counter_handle, bool risingEdge,
|
||||
bool fallingEdge, int32_t* status) {
|
||||
Counter* counter = (Counter*)counter_pointer;
|
||||
auto counter = counterHandles.Get(counter_handle);
|
||||
if (counter == nullptr) {
|
||||
*status = PARAMETER_OUT_OF_RANGE;
|
||||
return;
|
||||
}
|
||||
counter->counter->writeConfig_UpRisingEdge(risingEdge, status);
|
||||
counter->counter->writeConfig_UpFallingEdge(fallingEdge, status);
|
||||
}
|
||||
@@ -89,8 +113,12 @@ void setCounterUpSourceEdge(void* counter_pointer, bool risingEdge,
|
||||
/**
|
||||
* Disable the up counting source to the counter.
|
||||
*/
|
||||
void clearCounterUpSource(void* counter_pointer, int32_t* status) {
|
||||
Counter* counter = (Counter*)counter_pointer;
|
||||
void clearCounterUpSource(HalCounterHandle counter_handle, int32_t* status) {
|
||||
auto counter = counterHandles.Get(counter_handle);
|
||||
if (counter == nullptr) {
|
||||
*status = PARAMETER_OUT_OF_RANGE;
|
||||
return;
|
||||
}
|
||||
counter->counter->writeConfig_UpFallingEdge(false, status);
|
||||
counter->counter->writeConfig_UpRisingEdge(false, status);
|
||||
// Index 0 of digital is always 0.
|
||||
@@ -102,9 +130,13 @@ void clearCounterUpSource(void* counter_pointer, int32_t* status) {
|
||||
* Set the source object that causes the counter to count down.
|
||||
* Set the down counting DigitalSource.
|
||||
*/
|
||||
void setCounterDownSource(void* counter_pointer, uint32_t pin,
|
||||
void setCounterDownSource(HalCounterHandle counter_handle, uint32_t pin,
|
||||
bool analogTrigger, int32_t* status) {
|
||||
Counter* counter = (Counter*)counter_pointer;
|
||||
auto counter = counterHandles.Get(counter_handle);
|
||||
if (counter == nullptr) {
|
||||
*status = PARAMETER_OUT_OF_RANGE;
|
||||
return;
|
||||
}
|
||||
unsigned char mode = counter->counter->readConfig_Mode(status);
|
||||
if (mode != kTwoPulse && mode != kExternalDirection) {
|
||||
// TODO: wpi_setWPIErrorWithContext(ParameterOutOfRange, "Counter only
|
||||
@@ -121,7 +153,7 @@ void setCounterDownSource(void* counter_pointer, uint32_t pin,
|
||||
counter->counter->writeConfig_DownSource_Channel(pin, status);
|
||||
counter->counter->writeConfig_DownSource_AnalogTrigger(analogTrigger, status);
|
||||
|
||||
setCounterDownSourceEdge(counter_pointer, true, false, status);
|
||||
setCounterDownSourceEdge(counter_handle, true, false, status);
|
||||
counter->counter->strobeReset(status);
|
||||
}
|
||||
|
||||
@@ -129,9 +161,13 @@ void setCounterDownSource(void* counter_pointer, uint32_t pin,
|
||||
* Set the edge sensitivity on a down counting source.
|
||||
* Set the down source to either detect rising edges or falling edges.
|
||||
*/
|
||||
void setCounterDownSourceEdge(void* counter_pointer, bool risingEdge,
|
||||
void setCounterDownSourceEdge(HalCounterHandle counter_handle, bool risingEdge,
|
||||
bool fallingEdge, int32_t* status) {
|
||||
Counter* counter = (Counter*)counter_pointer;
|
||||
auto counter = counterHandles.Get(counter_handle);
|
||||
if (counter == nullptr) {
|
||||
*status = PARAMETER_OUT_OF_RANGE;
|
||||
return;
|
||||
}
|
||||
counter->counter->writeConfig_DownRisingEdge(risingEdge, status);
|
||||
counter->counter->writeConfig_DownFallingEdge(fallingEdge, status);
|
||||
}
|
||||
@@ -139,8 +175,12 @@ void setCounterDownSourceEdge(void* counter_pointer, bool risingEdge,
|
||||
/**
|
||||
* Disable the down counting source to the counter.
|
||||
*/
|
||||
void clearCounterDownSource(void* counter_pointer, int32_t* status) {
|
||||
Counter* counter = (Counter*)counter_pointer;
|
||||
void clearCounterDownSource(HalCounterHandle counter_handle, int32_t* status) {
|
||||
auto counter = counterHandles.Get(counter_handle);
|
||||
if (counter == nullptr) {
|
||||
*status = PARAMETER_OUT_OF_RANGE;
|
||||
return;
|
||||
}
|
||||
counter->counter->writeConfig_DownFallingEdge(false, status);
|
||||
counter->counter->writeConfig_DownRisingEdge(false, status);
|
||||
// Index 0 of digital is always 0.
|
||||
@@ -152,8 +192,12 @@ void clearCounterDownSource(void* counter_pointer, int32_t* status) {
|
||||
* Set standard up / down counting mode on this counter.
|
||||
* Up and down counts are sourced independently from two inputs.
|
||||
*/
|
||||
void setCounterUpDownMode(void* counter_pointer, int32_t* status) {
|
||||
Counter* counter = (Counter*)counter_pointer;
|
||||
void setCounterUpDownMode(HalCounterHandle counter_handle, int32_t* status) {
|
||||
auto counter = counterHandles.Get(counter_handle);
|
||||
if (counter == nullptr) {
|
||||
*status = PARAMETER_OUT_OF_RANGE;
|
||||
return;
|
||||
}
|
||||
counter->counter->writeConfig_Mode(kTwoPulse, status);
|
||||
}
|
||||
|
||||
@@ -162,8 +206,13 @@ void setCounterUpDownMode(void* counter_pointer, int32_t* status) {
|
||||
* Counts are sourced on the Up counter input.
|
||||
* The Down counter input represents the direction to count.
|
||||
*/
|
||||
void setCounterExternalDirectionMode(void* counter_pointer, int32_t* status) {
|
||||
Counter* counter = (Counter*)counter_pointer;
|
||||
void setCounterExternalDirectionMode(HalCounterHandle counter_handle,
|
||||
int32_t* status) {
|
||||
auto counter = counterHandles.Get(counter_handle);
|
||||
if (counter == nullptr) {
|
||||
*status = PARAMETER_OUT_OF_RANGE;
|
||||
return;
|
||||
}
|
||||
counter->counter->writeConfig_Mode(kExternalDirection, status);
|
||||
}
|
||||
|
||||
@@ -171,12 +220,16 @@ void setCounterExternalDirectionMode(void* counter_pointer, int32_t* status) {
|
||||
* Set Semi-period mode on this counter.
|
||||
* Counts up on both rising and falling edges.
|
||||
*/
|
||||
void setCounterSemiPeriodMode(void* counter_pointer, bool highSemiPeriod,
|
||||
int32_t* status) {
|
||||
Counter* counter = (Counter*)counter_pointer;
|
||||
void setCounterSemiPeriodMode(HalCounterHandle counter_handle,
|
||||
bool highSemiPeriod, int32_t* status) {
|
||||
auto counter = counterHandles.Get(counter_handle);
|
||||
if (counter == nullptr) {
|
||||
*status = PARAMETER_OUT_OF_RANGE;
|
||||
return;
|
||||
}
|
||||
counter->counter->writeConfig_Mode(kSemiperiod, status);
|
||||
counter->counter->writeConfig_UpRisingEdge(highSemiPeriod, status);
|
||||
setCounterUpdateWhenEmpty(counter_pointer, false, status);
|
||||
setCounterUpdateWhenEmpty(counter_handle, false, status);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -186,9 +239,13 @@ void setCounterSemiPeriodMode(void* counter_pointer, bool highSemiPeriod,
|
||||
* @param threshold The pulse length beyond which the counter counts the
|
||||
* opposite direction. Units are seconds.
|
||||
*/
|
||||
void setCounterPulseLengthMode(void* counter_pointer, double threshold,
|
||||
int32_t* status) {
|
||||
Counter* counter = (Counter*)counter_pointer;
|
||||
void setCounterPulseLengthMode(HalCounterHandle counter_handle,
|
||||
double threshold, int32_t* status) {
|
||||
auto counter = counterHandles.Get(counter_handle);
|
||||
if (counter == nullptr) {
|
||||
*status = PARAMETER_OUT_OF_RANGE;
|
||||
return;
|
||||
}
|
||||
counter->counter->writeConfig_Mode(kPulseLength, status);
|
||||
counter->counter->writeConfig_PulseLengthThreshold(
|
||||
(uint32_t)(threshold * 1.0e6) * kSystemClockTicksPerMicrosecond, status);
|
||||
@@ -201,8 +258,13 @@ void setCounterPulseLengthMode(void* counter_pointer, double threshold,
|
||||
* mechanical imperfections or as oversampling to increase resolution.
|
||||
* @return SamplesToAverage The number of samples being averaged (from 1 to 127)
|
||||
*/
|
||||
int32_t getCounterSamplesToAverage(void* counter_pointer, int32_t* status) {
|
||||
Counter* counter = (Counter*)counter_pointer;
|
||||
int32_t getCounterSamplesToAverage(HalCounterHandle counter_handle,
|
||||
int32_t* status) {
|
||||
auto counter = counterHandles.Get(counter_handle);
|
||||
if (counter == nullptr) {
|
||||
*status = PARAMETER_OUT_OF_RANGE;
|
||||
return 0;
|
||||
}
|
||||
return counter->counter->readTimerConfig_AverageSize(status);
|
||||
}
|
||||
|
||||
@@ -212,9 +274,13 @@ int32_t getCounterSamplesToAverage(void* counter_pointer, int32_t* status) {
|
||||
* mechanical imperfections or as oversampling to increase resolution.
|
||||
* @param samplesToAverage The number of samples to average from 1 to 127.
|
||||
*/
|
||||
void setCounterSamplesToAverage(void* counter_pointer, int samplesToAverage,
|
||||
int32_t* status) {
|
||||
Counter* counter = (Counter*)counter_pointer;
|
||||
void setCounterSamplesToAverage(HalCounterHandle counter_handle,
|
||||
int samplesToAverage, int32_t* status) {
|
||||
auto counter = counterHandles.Get(counter_handle);
|
||||
if (counter == nullptr) {
|
||||
*status = PARAMETER_OUT_OF_RANGE;
|
||||
return;
|
||||
}
|
||||
if (samplesToAverage < 1 || samplesToAverage > 127) {
|
||||
*status = PARAMETER_OUT_OF_RANGE;
|
||||
}
|
||||
@@ -226,8 +292,12 @@ void setCounterSamplesToAverage(void* counter_pointer, int samplesToAverage,
|
||||
* Set the counter value to zero. This doesn't effect the running state of the
|
||||
* counter, just sets the current value to zero.
|
||||
*/
|
||||
void resetCounter(void* counter_pointer, int32_t* status) {
|
||||
Counter* counter = (Counter*)counter_pointer;
|
||||
void resetCounter(HalCounterHandle counter_handle, int32_t* status) {
|
||||
auto counter = counterHandles.Get(counter_handle);
|
||||
if (counter == nullptr) {
|
||||
*status = PARAMETER_OUT_OF_RANGE;
|
||||
return;
|
||||
}
|
||||
counter->counter->strobeReset(status);
|
||||
}
|
||||
|
||||
@@ -236,8 +306,12 @@ void resetCounter(void* counter_pointer, int32_t* status) {
|
||||
* Read the value at this instant. It may still be running, so it reflects the
|
||||
* current value. Next time it is read, it might have a different value.
|
||||
*/
|
||||
int32_t getCounter(void* counter_pointer, int32_t* status) {
|
||||
Counter* counter = (Counter*)counter_pointer;
|
||||
int32_t getCounter(HalCounterHandle counter_handle, int32_t* status) {
|
||||
auto counter = counterHandles.Get(counter_handle);
|
||||
if (counter == nullptr) {
|
||||
*status = PARAMETER_OUT_OF_RANGE;
|
||||
return 0;
|
||||
}
|
||||
int32_t value = counter->counter->readOutput_Value(status);
|
||||
return value;
|
||||
}
|
||||
@@ -248,8 +322,12 @@ int32_t getCounter(void* counter_pointer, int32_t* status) {
|
||||
* velocity calculations to determine shaft speed.
|
||||
* @returns The period of the last two pulses in units of seconds.
|
||||
*/
|
||||
double getCounterPeriod(void* counter_pointer, int32_t* status) {
|
||||
Counter* counter = (Counter*)counter_pointer;
|
||||
double getCounterPeriod(HalCounterHandle counter_handle, int32_t* status) {
|
||||
auto counter = counterHandles.Get(counter_handle);
|
||||
if (counter == nullptr) {
|
||||
*status = PARAMETER_OUT_OF_RANGE;
|
||||
return 0.0;
|
||||
}
|
||||
tCounter::tTimerOutput output = counter->counter->readTimerOutput(status);
|
||||
double period;
|
||||
if (output.Stalled) {
|
||||
@@ -272,9 +350,13 @@ double getCounterPeriod(void* counter_pointer, int32_t* status) {
|
||||
* @param maxPeriod The maximum period where the counted device is considered
|
||||
* moving in seconds.
|
||||
*/
|
||||
void setCounterMaxPeriod(void* counter_pointer, double maxPeriod,
|
||||
void setCounterMaxPeriod(HalCounterHandle counter_handle, double maxPeriod,
|
||||
int32_t* status) {
|
||||
Counter* counter = (Counter*)counter_pointer;
|
||||
auto counter = counterHandles.Get(counter_handle);
|
||||
if (counter == nullptr) {
|
||||
*status = PARAMETER_OUT_OF_RANGE;
|
||||
return;
|
||||
}
|
||||
counter->counter->writeTimerConfig_StallPeriod((uint32_t)(maxPeriod * 4.0e8),
|
||||
status);
|
||||
}
|
||||
@@ -292,9 +374,13 @@ void setCounterMaxPeriod(void* counter_pointer, double maxPeriod,
|
||||
* and you will likely not see the stopped bit become true (since it is updated
|
||||
* at the end of an average and there are no samples to average).
|
||||
*/
|
||||
void setCounterUpdateWhenEmpty(void* counter_pointer, bool enabled,
|
||||
void setCounterUpdateWhenEmpty(HalCounterHandle counter_handle, bool enabled,
|
||||
int32_t* status) {
|
||||
Counter* counter = (Counter*)counter_pointer;
|
||||
auto counter = counterHandles.Get(counter_handle);
|
||||
if (counter == nullptr) {
|
||||
*status = PARAMETER_OUT_OF_RANGE;
|
||||
return;
|
||||
}
|
||||
counter->counter->writeTimerConfig_UpdateWhenEmpty(enabled, status);
|
||||
}
|
||||
|
||||
@@ -306,8 +392,12 @@ void setCounterUpdateWhenEmpty(void* counter_pointer, bool enabled,
|
||||
* @return Returns true if the most recent counter period exceeds the MaxPeriod
|
||||
* value set by SetMaxPeriod.
|
||||
*/
|
||||
bool getCounterStopped(void* counter_pointer, int32_t* status) {
|
||||
Counter* counter = (Counter*)counter_pointer;
|
||||
bool getCounterStopped(HalCounterHandle counter_handle, int32_t* status) {
|
||||
auto counter = counterHandles.Get(counter_handle);
|
||||
if (counter == nullptr) {
|
||||
*status = PARAMETER_OUT_OF_RANGE;
|
||||
return false;
|
||||
}
|
||||
return counter->counter->readTimerOutput_Stalled(status);
|
||||
}
|
||||
|
||||
@@ -315,8 +405,12 @@ bool getCounterStopped(void* counter_pointer, int32_t* status) {
|
||||
* The last direction the counter value changed.
|
||||
* @return The last direction the counter value changed.
|
||||
*/
|
||||
bool getCounterDirection(void* counter_pointer, int32_t* status) {
|
||||
Counter* counter = (Counter*)counter_pointer;
|
||||
bool getCounterDirection(HalCounterHandle counter_handle, int32_t* status) {
|
||||
auto counter = counterHandles.Get(counter_handle);
|
||||
if (counter == nullptr) {
|
||||
*status = PARAMETER_OUT_OF_RANGE;
|
||||
return false;
|
||||
}
|
||||
bool value = counter->counter->readOutput_Direction(status);
|
||||
return value;
|
||||
}
|
||||
@@ -327,14 +421,18 @@ bool getCounterDirection(void* counter_pointer, int32_t* status) {
|
||||
* 1X and 2X quadrature encoding only. Any other counter mode isn't supported.
|
||||
* @param reverseDirection true if the value counted should be negated.
|
||||
*/
|
||||
void setCounterReverseDirection(void* counter_pointer, bool reverseDirection,
|
||||
int32_t* status) {
|
||||
Counter* counter = (Counter*)counter_pointer;
|
||||
void setCounterReverseDirection(HalCounterHandle counter_handle,
|
||||
bool reverseDirection, int32_t* status) {
|
||||
auto counter = counterHandles.Get(counter_handle);
|
||||
if (counter == nullptr) {
|
||||
*status = PARAMETER_OUT_OF_RANGE;
|
||||
return;
|
||||
}
|
||||
if (counter->counter->readConfig_Mode(status) == kExternalDirection) {
|
||||
if (reverseDirection)
|
||||
setCounterDownSourceEdge(counter_pointer, true, true, status);
|
||||
setCounterDownSourceEdge(counter_handle, true, true, status);
|
||||
else
|
||||
setCounterDownSourceEdge(counter_pointer, false, true, status);
|
||||
setCounterDownSourceEdge(counter_handle, false, true, status);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user