Switches Counters to Handles (#123)

This commit is contained in:
Thad House
2016-07-01 00:29:08 -07:00
committed by Peter Johnson
parent 47694ef810
commit 0f105a26f7
9 changed files with 323 additions and 216 deletions

View File

@@ -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);
}
}
}