mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-22 01:11:42 +00:00
The existing raw time has an issue where it jumps around, as in the FPGA if the frequency is not a multiple or divisor of 25 Mhz it jumps around by 1 every second. While waiting on an FPGA change, update the API to make raw output give nanoseconds rather then a scaled value. This does a longer read cycle to get the correct value, but in the future if a fast FPGA function is added this can be easily changed.
130 lines
3.9 KiB
C++
130 lines
3.9 KiB
C++
// Copyright (c) FIRST and other WPILib contributors.
|
|
// Open Source Software; you can modify and/or share it under the terms of
|
|
// the WPILib BSD license file in the root directory of this project.
|
|
|
|
#include "hal/DutyCycle.h"
|
|
|
|
#include "HALInitializer.h"
|
|
#include "PortsInternal.h"
|
|
#include "hal/Errors.h"
|
|
#include "hal/handles/HandlesInternal.h"
|
|
#include "hal/handles/LimitedHandleResource.h"
|
|
#include "mockdata/DutyCycleDataInternal.h"
|
|
|
|
using namespace hal;
|
|
|
|
namespace {
|
|
struct DutyCycle {
|
|
uint8_t index;
|
|
};
|
|
struct Empty {};
|
|
} // namespace
|
|
|
|
static LimitedHandleResource<HAL_DutyCycleHandle, DutyCycle, kNumDutyCycles,
|
|
HAL_HandleEnum::DutyCycle>* dutyCycleHandles;
|
|
|
|
namespace hal::init {
|
|
void InitializeDutyCycle() {
|
|
static LimitedHandleResource<HAL_DutyCycleHandle, DutyCycle, kNumDutyCycles,
|
|
HAL_HandleEnum::DutyCycle>
|
|
dcH;
|
|
dutyCycleHandles = &dcH;
|
|
}
|
|
} // namespace hal::init
|
|
|
|
extern "C" {
|
|
HAL_DutyCycleHandle HAL_InitializeDutyCycle(HAL_Handle digitalSourceHandle,
|
|
HAL_AnalogTriggerType triggerType,
|
|
int32_t* status) {
|
|
hal::init::CheckInit();
|
|
|
|
HAL_DutyCycleHandle handle = dutyCycleHandles->Allocate();
|
|
if (handle == HAL_kInvalidHandle) {
|
|
*status = NO_AVAILABLE_RESOURCES;
|
|
return HAL_kInvalidHandle;
|
|
}
|
|
|
|
auto dutyCycle = dutyCycleHandles->Get(handle);
|
|
if (dutyCycle == nullptr) { // would only occur on thread issue
|
|
*status = HAL_HANDLE_ERROR;
|
|
return HAL_kInvalidHandle;
|
|
}
|
|
|
|
int16_t index = getHandleIndex(handle);
|
|
SimDutyCycleData[index].digitalChannel = getHandleIndex(digitalSourceHandle);
|
|
SimDutyCycleData[index].initialized = true;
|
|
SimDutyCycleData[index].simDevice = 0;
|
|
dutyCycle->index = index;
|
|
return handle;
|
|
}
|
|
void HAL_FreeDutyCycle(HAL_DutyCycleHandle dutyCycleHandle) {
|
|
auto dutyCycle = dutyCycleHandles->Get(dutyCycleHandle);
|
|
dutyCycleHandles->Free(dutyCycleHandle);
|
|
if (dutyCycle == nullptr) {
|
|
return;
|
|
}
|
|
SimDutyCycleData[dutyCycle->index].initialized = false;
|
|
}
|
|
|
|
void HAL_SetDutyCycleSimDevice(HAL_EncoderHandle handle,
|
|
HAL_SimDeviceHandle device) {
|
|
auto dutyCycle = dutyCycleHandles->Get(handle);
|
|
if (dutyCycle == nullptr) {
|
|
return;
|
|
}
|
|
SimDutyCycleData[dutyCycle->index].simDevice = device;
|
|
}
|
|
|
|
int32_t HAL_GetDutyCycleFrequency(HAL_DutyCycleHandle dutyCycleHandle,
|
|
int32_t* status) {
|
|
auto dutyCycle = dutyCycleHandles->Get(dutyCycleHandle);
|
|
if (dutyCycle == nullptr) {
|
|
*status = HAL_HANDLE_ERROR;
|
|
return 0;
|
|
}
|
|
return SimDutyCycleData[dutyCycle->index].frequency;
|
|
}
|
|
|
|
double HAL_GetDutyCycleOutput(HAL_DutyCycleHandle dutyCycleHandle,
|
|
int32_t* status) {
|
|
auto dutyCycle = dutyCycleHandles->Get(dutyCycleHandle);
|
|
if (dutyCycle == nullptr) {
|
|
*status = HAL_HANDLE_ERROR;
|
|
return 0;
|
|
}
|
|
return SimDutyCycleData[dutyCycle->index].output;
|
|
}
|
|
|
|
int32_t HAL_GetDutyCycleHighTime(HAL_DutyCycleHandle dutyCycleHandle,
|
|
int32_t* status) {
|
|
auto dutyCycle = dutyCycleHandles->Get(dutyCycleHandle);
|
|
if (dutyCycle == nullptr) {
|
|
*status = HAL_HANDLE_ERROR;
|
|
return 0;
|
|
}
|
|
|
|
if (SimDutyCycleData[dutyCycle->index].frequency == 0) {
|
|
return 0;
|
|
}
|
|
|
|
double periodSeconds = 1.0 / SimDutyCycleData[dutyCycle->index].frequency;
|
|
double periodNanoSeconds = periodSeconds * 1e9;
|
|
return periodNanoSeconds * SimDutyCycleData[dutyCycle->index].output;
|
|
}
|
|
|
|
int32_t HAL_GetDutyCycleOutputScaleFactor(HAL_DutyCycleHandle dutyCycleHandle,
|
|
int32_t* status) {
|
|
return 4e7 - 1;
|
|
}
|
|
|
|
int32_t HAL_GetDutyCycleFPGAIndex(HAL_DutyCycleHandle dutyCycleHandle,
|
|
int32_t* status) {
|
|
auto dutyCycle = dutyCycleHandles->Get(dutyCycleHandle);
|
|
if (dutyCycle == nullptr) {
|
|
*status = HAL_HANDLE_ERROR;
|
|
return -1;
|
|
}
|
|
return dutyCycle->index;
|
|
}
|
|
} // extern "C"
|