blob: 0e14eeb3dd6d676841bf1ab5ad87b9c8fd2be569 [file] [log] [blame]
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2019 FIRST. 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 the root directory of */
/* the 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 {
namespace init {
void InitializeDutyCycle() {
static LimitedHandleResource<HAL_DutyCycleHandle, DutyCycle, kNumDutyCycles,
HAL_HandleEnum::DutyCycle>
dcH;
dutyCycleHandles = &dcH;
}
} // namespace init
} // namespace hal
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_GetDutyCycleOutputRaw(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 *
HAL_GetDutyCycleOutputScaleFactor(dutyCycleHandle, status);
}
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"