[hal, wpilib] Add initial systemcore counter implementation (#7723)

This commit is contained in:
Thad House
2025-01-28 08:58:34 -08:00
committed by GitHub
parent b799b285b3
commit 48ce2dcc8d
47 changed files with 201 additions and 4357 deletions

View File

@@ -6,23 +6,13 @@
#include <cassert>
#include <wpi/jni_util.h>
#include "HALUtil.h"
#include "edu_wpi_first_hal_CounterJNI.h"
#include "hal/Counter.h"
#include "hal/Errors.h"
static_assert(HAL_Counter_Mode::HAL_Counter_kTwoPulse ==
edu_wpi_first_hal_CounterJNI_TWO_PULSE);
static_assert(HAL_Counter_Mode::HAL_Counter_kSemiperiod ==
edu_wpi_first_hal_CounterJNI_SEMI_PERIOD);
static_assert(HAL_Counter_Mode::HAL_Counter_kPulseLength ==
edu_wpi_first_hal_CounterJNI_PULSE_LENGTH);
static_assert(HAL_Counter_Mode::HAL_Counter_kExternalDirection ==
edu_wpi_first_hal_CounterJNI_EXTERNAL_DIRECTION);
using namespace hal;
extern "C" {
@@ -30,16 +20,16 @@ extern "C" {
/*
* Class: edu_wpi_first_hal_CounterJNI
* Method: initializeCounter
* Signature: (ILjava/lang/Object;)I
* Signature: (IZ)I
*/
JNIEXPORT jint JNICALL
Java_edu_wpi_first_hal_CounterJNI_initializeCounter
(JNIEnv* env, jclass, jint mode, jobject index)
(JNIEnv* env, jclass, jint channel, jboolean risingEdge)
{
jint* indexPtr = reinterpret_cast<jint*>(env->GetDirectBufferAddress(index));
int32_t status = 0;
auto counter = HAL_InitializeCounter(
(HAL_Counter_Mode)mode, reinterpret_cast<int32_t*>(indexPtr), &status);
auto stack = wpi::java::GetJavaStackTrace(env, "edu.wpi.first");
auto counter =
HAL_InitializeCounter(channel, risingEdge, stack.c_str(), &status);
CheckStatusForceThrow(env, status);
return (jint)counter;
}
@@ -60,192 +50,15 @@ Java_edu_wpi_first_hal_CounterJNI_freeCounter
/*
* Class: edu_wpi_first_hal_CounterJNI
* Method: setCounterAverageSize
* Signature: (II)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_CounterJNI_setCounterAverageSize
(JNIEnv* env, jclass, jint id, jint value)
{
int32_t status = 0;
HAL_SetCounterAverageSize((HAL_CounterHandle)id, value, &status);
CheckStatus(env, status);
}
/*
* Class: edu_wpi_first_hal_CounterJNI
* Method: setCounterUpSource
* Signature: (III)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_CounterJNI_setCounterUpSource
(JNIEnv* env, jclass, jint id, jint digitalSourceHandle,
jint analogTriggerType)
{
int32_t status = 0;
HAL_SetCounterUpSource((HAL_CounterHandle)id, (HAL_Handle)digitalSourceHandle,
(HAL_AnalogTriggerType)analogTriggerType, &status);
CheckStatus(env, status);
}
/*
* Class: edu_wpi_first_hal_CounterJNI
* Method: setCounterUpSourceEdge
* Signature: (IZZ)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_CounterJNI_setCounterUpSourceEdge
(JNIEnv* env, jclass, jint id, jboolean valueRise, jboolean valueFall)
{
int32_t status = 0;
HAL_SetCounterUpSourceEdge((HAL_CounterHandle)id, valueRise, valueFall,
&status);
CheckStatus(env, status);
}
/*
* Class: edu_wpi_first_hal_CounterJNI
* Method: clearCounterUpSource
* Signature: (I)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_CounterJNI_clearCounterUpSource
(JNIEnv* env, jclass, jint id)
{
int32_t status = 0;
HAL_ClearCounterUpSource((HAL_CounterHandle)id, &status);
CheckStatus(env, status);
}
/*
* Class: edu_wpi_first_hal_CounterJNI
* Method: setCounterDownSource
* Signature: (III)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_CounterJNI_setCounterDownSource
(JNIEnv* env, jclass, jint id, jint digitalSourceHandle,
jint analogTriggerType)
{
int32_t status = 0;
HAL_SetCounterDownSource((HAL_CounterHandle)id,
(HAL_Handle)digitalSourceHandle,
(HAL_AnalogTriggerType)analogTriggerType, &status);
CheckStatus(env, status);
}
/*
* Class: edu_wpi_first_hal_CounterJNI
* Method: setCounterDownSourceEdge
* Signature: (IZZ)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_CounterJNI_setCounterDownSourceEdge
(JNIEnv* env, jclass, jint id, jboolean valueRise, jboolean valueFall)
{
int32_t status = 0;
HAL_SetCounterDownSourceEdge((HAL_CounterHandle)id, valueRise, valueFall,
&status);
CheckStatus(env, status);
}
/*
* Class: edu_wpi_first_hal_CounterJNI
* Method: clearCounterDownSource
* Signature: (I)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_CounterJNI_clearCounterDownSource
(JNIEnv* env, jclass, jint id)
{
int32_t status = 0;
HAL_ClearCounterDownSource((HAL_CounterHandle)id, &status);
CheckStatus(env, status);
}
/*
* Class: edu_wpi_first_hal_CounterJNI
* Method: setCounterUpDownMode
* Signature: (I)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_CounterJNI_setCounterUpDownMode
(JNIEnv* env, jclass, jint id)
{
int32_t status = 0;
HAL_SetCounterUpDownMode((HAL_CounterHandle)id, &status);
CheckStatus(env, status);
}
/*
* Class: edu_wpi_first_hal_CounterJNI
* Method: setCounterExternalDirectionMode
* Signature: (I)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_CounterJNI_setCounterExternalDirectionMode
(JNIEnv* env, jclass, jint id)
{
int32_t status = 0;
HAL_SetCounterExternalDirectionMode((HAL_CounterHandle)id, &status);
CheckStatus(env, status);
}
/*
* Class: edu_wpi_first_hal_CounterJNI
* Method: setCounterSemiPeriodMode
* Method: setCounterEdgeConfiguration
* Signature: (IZ)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_CounterJNI_setCounterSemiPeriodMode
(JNIEnv* env, jclass, jint id, jboolean value)
Java_edu_wpi_first_hal_CounterJNI_setCounterEdgeConfiguration
(JNIEnv* env, jclass, jint id, jboolean valueRise)
{
int32_t status = 0;
HAL_SetCounterSemiPeriodMode((HAL_CounterHandle)id, value, &status);
CheckStatus(env, status);
}
/*
* Class: edu_wpi_first_hal_CounterJNI
* Method: setCounterPulseLengthMode
* Signature: (ID)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_CounterJNI_setCounterPulseLengthMode
(JNIEnv* env, jclass, jint id, jdouble value)
{
int32_t status = 0;
HAL_SetCounterPulseLengthMode((HAL_CounterHandle)id, value, &status);
CheckStatus(env, status);
}
/*
* Class: edu_wpi_first_hal_CounterJNI
* Method: getCounterSamplesToAverage
* Signature: (I)I
*/
JNIEXPORT jint JNICALL
Java_edu_wpi_first_hal_CounterJNI_getCounterSamplesToAverage
(JNIEnv* env, jclass, jint id)
{
int32_t status = 0;
jint returnValue =
HAL_GetCounterSamplesToAverage((HAL_CounterHandle)id, &status);
CheckStatus(env, status);
return returnValue;
}
/*
* Class: edu_wpi_first_hal_CounterJNI
* Method: setCounterSamplesToAverage
* Signature: (II)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_CounterJNI_setCounterSamplesToAverage
(JNIEnv* env, jclass, jint id, jint value)
{
int32_t status = 0;
HAL_SetCounterSamplesToAverage((HAL_CounterHandle)id, value, &status);
HAL_SetCounterEdgeConfiguration((HAL_CounterHandle)id, valueRise, &status);
CheckStatus(env, status);
}
@@ -307,20 +120,6 @@ Java_edu_wpi_first_hal_CounterJNI_setCounterMaxPeriod
CheckStatus(env, status);
}
/*
* Class: edu_wpi_first_hal_CounterJNI
* Method: setCounterUpdateWhenEmpty
* Signature: (IZ)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_CounterJNI_setCounterUpdateWhenEmpty
(JNIEnv* env, jclass, jint id, jboolean value)
{
int32_t status = 0;
HAL_SetCounterUpdateWhenEmpty((HAL_CounterHandle)id, value, &status);
CheckStatus(env, status);
}
/*
* Class: edu_wpi_first_hal_CounterJNI
* Method: getCounterStopped
@@ -336,34 +135,4 @@ Java_edu_wpi_first_hal_CounterJNI_getCounterStopped
return returnValue;
}
/*
* Class: edu_wpi_first_hal_CounterJNI
* Method: getCounterDirection
* Signature: (I)Z
*/
JNIEXPORT jboolean JNICALL
Java_edu_wpi_first_hal_CounterJNI_getCounterDirection
(JNIEnv* env, jclass, jint id)
{
int32_t status = 0;
jboolean returnValue =
HAL_GetCounterDirection((HAL_CounterHandle)id, &status);
CheckStatus(env, status);
return returnValue;
}
/*
* Class: edu_wpi_first_hal_CounterJNI
* Method: setCounterReverseDirection
* Signature: (IZ)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_CounterJNI_setCounterReverseDirection
(JNIEnv* env, jclass, jint id, jboolean value)
{
int32_t status = 0;
HAL_SetCounterReverseDirection((HAL_CounterHandle)id, value, &status);
CheckStatus(env, status);
}
} // extern "C"

View File

@@ -15,20 +15,6 @@
* @{
*/
/**
* The counter mode.
*/
HAL_ENUM(HAL_Counter_Mode) {
/** Two pulse mode. */
HAL_Counter_kTwoPulse = 0,
/** Semi-period mode. */
HAL_Counter_kSemiperiod = 1,
/** Pulse length mode. */
HAL_Counter_kPulseLength = 2,
/** External direction mode. */
HAL_Counter_kExternalDirection = 3
};
#ifdef __cplusplus
extern "C" {
#endif
@@ -36,12 +22,16 @@ extern "C" {
/**
* Initializes a counter.
*
* @param[in] mode the counter mode
* @param[in] index the compressor index (output)
* @param[out] status Error status variable. 0 on success.
* @param[in] channel the dio channel
* @param[in] risingEdge true to count on rising edge, false for
* falling
* @param[in] allocationLocation the location where the allocation is
* occurring (can be null)
* @param[out] status Error status variable. 0 on success.
* @return the created handle
*/
HAL_CounterHandle HAL_InitializeCounter(HAL_Counter_Mode mode, int32_t* index,
HAL_CounterHandle HAL_InitializeCounter(int channel, HAL_Bool risingEdge,
const char* allocationLocation,
int32_t* status);
/**
@@ -51,32 +41,6 @@ HAL_CounterHandle HAL_InitializeCounter(HAL_Counter_Mode mode, int32_t* index,
*/
void HAL_FreeCounter(HAL_CounterHandle counterHandle);
/**
* Sets the average sample size of a counter.
*
* @param[in] counterHandle the counter handle
* @param[in] size the size of samples to average
* @param[out] status Error status variable. 0 on success.
*/
void HAL_SetCounterAverageSize(HAL_CounterHandle counterHandle, int32_t size,
int32_t* status);
/**
* Sets the source object that causes the counter to count up.
*
* @param[in] counterHandle the counter handle
* @param[in] digitalSourceHandle the digital source handle (either a
* HAL_AnalogTriggerHandle or a
* HAL_DigitalHandle)
* @param[in] analogTriggerType the analog trigger type if the source is an
* analog trigger
* @param[out] status Error status variable. 0 on success.
*/
void HAL_SetCounterUpSource(HAL_CounterHandle counterHandle,
HAL_Handle digitalSourceHandle,
HAL_AnalogTriggerType analogTriggerType,
int32_t* status);
/**
* Sets the up source to either detect rising edges or falling edges.
*
@@ -84,132 +48,10 @@ void HAL_SetCounterUpSource(HAL_CounterHandle counterHandle,
*
* @param[in] counterHandle the counter handle
* @param[in] risingEdge true to trigger on rising
* @param[in] fallingEdge true to trigger on falling
* @param[out] status Error status variable. 0 on success.
*/
void HAL_SetCounterUpSourceEdge(HAL_CounterHandle counterHandle,
HAL_Bool risingEdge, HAL_Bool fallingEdge,
int32_t* status);
/**
* Disables the up counting source to the counter.
*
* @param[in] counterHandle the counter handle
* @param[out] status Error status variable. 0 on success.
*/
void HAL_ClearCounterUpSource(HAL_CounterHandle counterHandle, int32_t* status);
/**
* Sets the source object that causes the counter to count down.
*
* @param[in] counterHandle the counter handle
* @param[in] digitalSourceHandle the digital source handle (either a
* HAL_AnalogTriggerHandle or a
* HAL_DigitalHandle)
* @param[in] analogTriggerType the analog trigger type if the source is an
* analog trigger
* @param[out] status Error status variable. 0 on success.
*/
void HAL_SetCounterDownSource(HAL_CounterHandle counterHandle,
HAL_Handle digitalSourceHandle,
HAL_AnalogTriggerType analogTriggerType,
int32_t* status);
/**
* Sets the down source to either detect rising edges or falling edges.
* Note that both are allowed to be set true at the same time without issues.
*
* @param[in] counterHandle the counter handle
* @param[in] risingEdge true to trigger on rising
* @param[in] fallingEdge true to trigger on falling
* @param[out] status Error status variable. 0 on success.
*/
void HAL_SetCounterDownSourceEdge(HAL_CounterHandle counterHandle,
HAL_Bool risingEdge, HAL_Bool fallingEdge,
int32_t* status);
/**
* Disables the down counting source to the counter.
*
* @param[in] counterHandle the counter handle
* @param[out] status Error status variable. 0 on success.
*/
void HAL_ClearCounterDownSource(HAL_CounterHandle counterHandle,
int32_t* status);
/**
* Sets standard up / down counting mode on this counter.
*
* Up and down counts are sourced independently from two inputs.
*
* @param[in] counterHandle the counter handle
* @param[out] status Error status variable. 0 on success.
*/
void HAL_SetCounterUpDownMode(HAL_CounterHandle counterHandle, int32_t* status);
/**
* Sets directional counting mode on this counter.
*
* The direction is determined by the B input, with counting happening with the
* A input.
*
* @param[in] counterHandle the counter handle
* @param[out] status Error status variable. 0 on success.
*/
void HAL_SetCounterExternalDirectionMode(HAL_CounterHandle counterHandle,
int32_t* status);
/**
* Sets Semi-period mode on this counter.
*
* The counter counts up based on the time the input is triggered. High or Low
* depends on the highSemiPeriod parameter.
*
* @param[in] counterHandle the counter handle
* @param[in] highSemiPeriod true for counting when the input is high, false for
* low
* @param[out] status Error status variable. 0 on success.
*/
void HAL_SetCounterSemiPeriodMode(HAL_CounterHandle counterHandle,
HAL_Bool highSemiPeriod, int32_t* status);
/**
* Configures the counter to count in up or down based on the length of the
* input pulse.
*
* This mode is most useful for direction sensitive gear tooth sensors.
*
* @param[in] counterHandle the counter handle
* @param[in] threshold The pulse length beyond which the counter counts the
* opposite direction (seconds)
* @param[out] status Error status variable. 0 on success.
*/
void HAL_SetCounterPulseLengthMode(HAL_CounterHandle counterHandle,
double threshold, int32_t* status);
/**
* Gets the Samples to Average which specifies the number of samples of the
* timer to average when calculating the period. Perform averaging to account
* for mechanical imperfections or as oversampling to increase resolution.
*
* @param[in] counterHandle the counter handle
* @param[out] status Error status variable. 0 on success.
* @return SamplesToAverage The number of samples being averaged (from 1 to 127)
*/
int32_t HAL_GetCounterSamplesToAverage(HAL_CounterHandle counterHandle,
int32_t* status);
/**
* Sets the Samples to Average which specifies the number of samples of the
* timer to average when calculating the period. Perform averaging to account
* for mechanical imperfections or as oversampling to increase resolution.
*
* @param[in] counterHandle the counter handle
* @param[in] samplesToAverage The number of samples to average from 1 to 127
* @param[out] status Error status variable. 0 on success.
*/
void HAL_SetCounterSamplesToAverage(HAL_CounterHandle counterHandle,
int32_t samplesToAverage, int32_t* status);
void HAL_SetCounterEdgeConfiguration(HAL_CounterHandle counterHandle,
HAL_Bool risingEdge, int32_t* status);
/**
* Resets the Counter to zero.
@@ -261,33 +103,6 @@ double HAL_GetCounterPeriod(HAL_CounterHandle counterHandle, int32_t* status);
void HAL_SetCounterMaxPeriod(HAL_CounterHandle counterHandle, double maxPeriod,
int32_t* status);
/**
* Selects whether you want to continue updating the event timer output when
* there are no samples captured.
*
* The output of the event timer has a buffer of periods that are averaged and
* posted to a register on the FPGA. When the timer detects that the event
* source has stopped (based on the MaxPeriod) the buffer of samples to be
* averaged is emptied.
*
* If you enable the update when empty, you will be
* notified of the stopped source and the event time will report 0 samples.
*
* If you disable update when empty, the most recent average will remain on the
* output until a new sample is acquired.
*
* You will never see 0 samples output (except when there have been no events
* since an FPGA reset) 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).
*
* @param[in] counterHandle the counter handle
* @param[in] enabled true to enable counter updating with no samples
* @param[out] status Error status variable. 0 on success.
*/
void HAL_SetCounterUpdateWhenEmpty(HAL_CounterHandle counterHandle,
HAL_Bool enabled, int32_t* status);
/**
* Determines if the clock is stopped.
*
@@ -302,29 +117,6 @@ void HAL_SetCounterUpdateWhenEmpty(HAL_CounterHandle counterHandle,
*/
HAL_Bool HAL_GetCounterStopped(HAL_CounterHandle counterHandle,
int32_t* status);
/**
* Gets the last direction the counter value changed.
*
* @param[in] counterHandle the counter handle
* @param[out] status Error status variable. 0 on success.
* @return the last direction the counter value changed
*/
HAL_Bool HAL_GetCounterDirection(HAL_CounterHandle counterHandle,
int32_t* status);
/**
* Sets the Counter to return reversed sensing on the direction.
*
* This allows counters to change the direction they are counting in the case of
* 1X and 2X quadrature encoding only. Any other counter mode isn't supported.
*
* @param[in] counterHandle the counter handle
* @param[in] reverseDirection true if the value counted should be negated.
* @param[out] status Error status variable. 0 on success.
*/
void HAL_SetCounterReverseDirection(HAL_CounterHandle counterHandle,
HAL_Bool reverseDirection, int32_t* status);
#ifdef __cplusplus
} // extern "C"
#endif

View File

@@ -26,47 +26,15 @@ void InitializeCounter() {
} // namespace hal::init
extern "C" {
HAL_CounterHandle HAL_InitializeCounter(HAL_Counter_Mode mode, int32_t* index,
HAL_CounterHandle HAL_InitializeCounter(int channel, HAL_Bool risingEdge,
const char* allocationLocation,
int32_t* status) {
hal::init::CheckInit();
return 0;
}
void HAL_FreeCounter(HAL_CounterHandle counterHandle) {}
void HAL_SetCounterAverageSize(HAL_CounterHandle counterHandle, int32_t size,
int32_t* status) {}
void HAL_SetCounterUpSource(HAL_CounterHandle counterHandle,
HAL_Handle digitalSourceHandle,
HAL_AnalogTriggerType analogTriggerType,
int32_t* status) {}
void HAL_SetCounterUpSourceEdge(HAL_CounterHandle counterHandle,
HAL_Bool risingEdge, HAL_Bool fallingEdge,
int32_t* status) {}
void HAL_ClearCounterUpSource(HAL_CounterHandle counterHandle,
int32_t* status) {}
void HAL_SetCounterDownSource(HAL_CounterHandle counterHandle,
HAL_Handle digitalSourceHandle,
HAL_AnalogTriggerType analogTriggerType,
int32_t* status) {}
void HAL_SetCounterDownSourceEdge(HAL_CounterHandle counterHandle,
HAL_Bool risingEdge, HAL_Bool fallingEdge,
int32_t* status) {}
void HAL_ClearCounterDownSource(HAL_CounterHandle counterHandle,
int32_t* status) {}
void HAL_SetCounterUpDownMode(HAL_CounterHandle counterHandle,
int32_t* status) {}
void HAL_SetCounterExternalDirectionMode(HAL_CounterHandle counterHandle,
int32_t* status) {}
void HAL_SetCounterSemiPeriodMode(HAL_CounterHandle counterHandle,
HAL_Bool highSemiPeriod, int32_t* status) {}
void HAL_SetCounterPulseLengthMode(HAL_CounterHandle counterHandle,
double threshold, int32_t* status) {}
int32_t HAL_GetCounterSamplesToAverage(HAL_CounterHandle counterHandle,
int32_t* status) {
return 0;
}
void HAL_SetCounterSamplesToAverage(HAL_CounterHandle counterHandle,
int32_t samplesToAverage, int32_t* status) {
}
void HAL_SetCounterEdgeConfiguration(HAL_CounterHandle counterHandle,
HAL_Bool risingEdge, int32_t* status) {}
void HAL_ResetCounter(HAL_CounterHandle counterHandle, int32_t* status) {}
int32_t HAL_GetCounter(HAL_CounterHandle counterHandle, int32_t* status) {
return 0;
@@ -76,17 +44,8 @@ double HAL_GetCounterPeriod(HAL_CounterHandle counterHandle, int32_t* status) {
}
void HAL_SetCounterMaxPeriod(HAL_CounterHandle counterHandle, double maxPeriod,
int32_t* status) {}
void HAL_SetCounterUpdateWhenEmpty(HAL_CounterHandle counterHandle,
HAL_Bool enabled, int32_t* status) {}
HAL_Bool HAL_GetCounterStopped(HAL_CounterHandle counterHandle,
int32_t* status) {
return false;
}
HAL_Bool HAL_GetCounterDirection(HAL_CounterHandle counterHandle,
int32_t* status) {
return false;
}
void HAL_SetCounterReverseDirection(HAL_CounterHandle counterHandle,
HAL_Bool reverseDirection,
int32_t* status) {}
} // extern "C"

View File

@@ -4,15 +4,19 @@
#include "hal/Counter.h"
#include <cstdio>
#include <limits>
#include <memory>
#include <thread>
#include <fmt/format.h>
#include "HALInitializer.h"
#include "HALInternal.h"
#include "PortsInternal.h"
#include "SmartIo.h"
#include "hal/HAL.h"
#include "hal/cpp/fpga_clock.h"
#include "hal/handles/LimitedHandleResource.h"
using namespace hal;
@@ -23,106 +27,90 @@ void InitializeCounter() {}
extern "C" {
HAL_CounterHandle HAL_InitializeCounter(HAL_Counter_Mode mode, int32_t* index,
HAL_CounterHandle HAL_InitializeCounter(int channel, HAL_Bool risingEdge,
const char* allocationLocation,
int32_t* status) {
hal::init::CheckInit();
*status = HAL_HANDLE_ERROR;
return HAL_kInvalidHandle;
if (channel == InvalidHandleIndex || channel >= kNumSmartIo) {
*status = RESOURCE_OUT_OF_RANGE;
hal::SetLastErrorIndexOutOfRange(status, "Invalid Index for Counter", 0,
kNumSmartIo, channel);
return HAL_kInvalidHandle;
}
HAL_CounterHandle handle;
auto port = smartIoHandles->Allocate(channel, HAL_HandleEnum::Counter,
&handle, status);
if (*status != 0) {
if (port) {
hal::SetLastErrorPreviouslyAllocated(status, "SmartIo", channel,
port->previousAllocation);
} else {
hal::SetLastErrorIndexOutOfRange(status, "Invalid Index for Counter", 0,
kNumSmartIo, channel);
}
return HAL_kInvalidHandle; // failed to allocate. Pass error back.
}
port->channel = channel;
*status =
port->InitializeMode(risingEdge ? SmartIoMode::SingleCounterRising
: SmartIoMode::SingleCounterFalling);
if (*status != 0) {
smartIoHandles->Free(handle, HAL_HandleEnum::Counter);
return HAL_kInvalidHandle;
}
port->previousAllocation = allocationLocation ? allocationLocation : "";
return handle;
}
void HAL_FreeCounter(HAL_CounterHandle counterHandle) {}
void HAL_FreeCounter(HAL_CounterHandle counterHandle) {
auto port = smartIoHandles->Get(counterHandle, HAL_HandleEnum::Counter);
if (port == nullptr) {
return;
}
void HAL_SetCounterAverageSize(HAL_CounterHandle counterHandle, int32_t size,
int32_t* status) {
*status = HAL_HANDLE_ERROR;
return;
smartIoHandles->Free(counterHandle, HAL_HandleEnum::Counter);
// Wait for no other object to hold this handle.
auto start = hal::fpga_clock::now();
while (port.use_count() != 1) {
auto current = hal::fpga_clock::now();
if (start + std::chrono::seconds(1) < current) {
std::puts("DIO handle free timeout");
std::fflush(stdout);
break;
}
std::this_thread::yield();
}
}
void HAL_SetCounterUpSource(HAL_CounterHandle counterHandle,
HAL_Handle digitalSourceHandle,
HAL_AnalogTriggerType analogTriggerType,
int32_t* status) {
*status = HAL_HANDLE_ERROR;
return;
}
void HAL_SetCounterUpSourceEdge(HAL_CounterHandle counterHandle,
HAL_Bool risingEdge, HAL_Bool fallingEdge,
int32_t* status) {
*status = HAL_HANDLE_ERROR;
return;
}
void HAL_ClearCounterUpSource(HAL_CounterHandle counterHandle,
int32_t* status) {
*status = HAL_HANDLE_ERROR;
return;
}
void HAL_SetCounterDownSource(HAL_CounterHandle counterHandle,
HAL_Handle digitalSourceHandle,
HAL_AnalogTriggerType analogTriggerType,
int32_t* status) {
*status = HAL_HANDLE_ERROR;
return;
}
void HAL_SetCounterDownSourceEdge(HAL_CounterHandle counterHandle,
HAL_Bool risingEdge, HAL_Bool fallingEdge,
int32_t* status) {
*status = HAL_HANDLE_ERROR;
return;
}
void HAL_ClearCounterDownSource(HAL_CounterHandle counterHandle,
int32_t* status) {
*status = HAL_HANDLE_ERROR;
return;
}
void HAL_SetCounterUpDownMode(HAL_CounterHandle counterHandle,
int32_t* status) {
*status = HAL_HANDLE_ERROR;
return;
}
void HAL_SetCounterExternalDirectionMode(HAL_CounterHandle counterHandle,
int32_t* status) {
*status = HAL_HANDLE_ERROR;
return;
}
void HAL_SetCounterSemiPeriodMode(HAL_CounterHandle counterHandle,
HAL_Bool highSemiPeriod, int32_t* status) {
*status = HAL_HANDLE_ERROR;
return;
}
void HAL_SetCounterPulseLengthMode(HAL_CounterHandle counterHandle,
double threshold, int32_t* status) {
*status = HAL_HANDLE_ERROR;
return;
}
int32_t HAL_GetCounterSamplesToAverage(HAL_CounterHandle counterHandle,
int32_t* status) {
*status = HAL_HANDLE_ERROR;
return 0;
}
void HAL_SetCounterSamplesToAverage(HAL_CounterHandle counterHandle,
int32_t samplesToAverage, int32_t* status) {
void HAL_SetCounterEdgeConfiguration(HAL_CounterHandle counterHandle,
HAL_Bool risingEdge, int32_t* status) {
*status = HAL_HANDLE_ERROR;
return;
}
void HAL_ResetCounter(HAL_CounterHandle counterHandle, int32_t* status) {
*status = HAL_HANDLE_ERROR;
// TODO
return;
}
int32_t HAL_GetCounter(HAL_CounterHandle counterHandle, int32_t* status) {
*status = HAL_HANDLE_ERROR;
auto port = smartIoHandles->Get(counterHandle, HAL_HandleEnum::Counter);
if (port == nullptr) {
*status = HAL_HANDLE_ERROR;
return false;
}
int32_t ret = 0;
*status = port->GetCounter(&ret);
return ret;
return 0;
}
@@ -137,12 +125,6 @@ void HAL_SetCounterMaxPeriod(HAL_CounterHandle counterHandle, double maxPeriod,
return;
}
void HAL_SetCounterUpdateWhenEmpty(HAL_CounterHandle counterHandle,
HAL_Bool enabled, int32_t* status) {
*status = HAL_HANDLE_ERROR;
return;
}
HAL_Bool HAL_GetCounterStopped(HAL_CounterHandle counterHandle,
int32_t* status) {
*status = HAL_HANDLE_ERROR;
@@ -155,9 +137,8 @@ HAL_Bool HAL_GetCounterDirection(HAL_CounterHandle counterHandle,
return false;
}
void HAL_SetCounterReverseDirection(HAL_CounterHandle counterHandle,
HAL_Bool reverseDirection,
int32_t* status) {
void HAL_SetCounterDirection(HAL_CounterHandle counterHandle, HAL_Bool countUp,
int32_t* status) {
*status = HAL_HANDLE_ERROR;
return;
}

View File

@@ -164,4 +164,17 @@ int32_t SmartIo::GetAnalogInput(uint16_t* value) {
return 0;
}
int32_t SmartIo::GetCounter(int32_t* value) {
if (currentMode != SmartIoMode::SingleCounterFalling &&
currentMode != SmartIoMode::SingleCounterRising) {
return INCOMPATIBLE_STATE;
}
int32_t val = getSubscriber.Get();
*value = val;
return 0;
}
} // namespace hal

View File

@@ -66,6 +66,8 @@ struct SmartIo {
int32_t GetPwmMicroseconds(uint16_t* microseconds);
int32_t GetAnalogInput(uint16_t* value);
int32_t GetCounter(int32_t* count);
};
extern DigitalHandleResource<HAL_DigitalHandle, SmartIo, kNumSmartIo>*