blob: f46d2da6d5940f65999ac59d997cb8350c80d51a [file] [log] [blame]
Austin Schuh812d0d12021-11-04 20:16:48 -07001// Copyright (c) FIRST and other WPILib contributors.
2// Open Source Software; you can modify and/or share it under the terms of
3// the WPILib BSD license file in the root directory of this project.
Brian Silverman8fce7482020-01-05 13:18:21 -08004
5#include "hal/DutyCycle.h"
6
7#include "HALInitializer.h"
8#include "PortsInternal.h"
9#include "hal/Errors.h"
10#include "hal/handles/HandlesInternal.h"
11#include "hal/handles/LimitedHandleResource.h"
12#include "mockdata/DutyCycleDataInternal.h"
13
14using namespace hal;
15
16namespace {
17struct DutyCycle {
18 uint8_t index;
19};
20struct Empty {};
21} // namespace
22
23static LimitedHandleResource<HAL_DutyCycleHandle, DutyCycle, kNumDutyCycles,
24 HAL_HandleEnum::DutyCycle>* dutyCycleHandles;
25
Austin Schuh812d0d12021-11-04 20:16:48 -070026namespace hal::init {
Brian Silverman8fce7482020-01-05 13:18:21 -080027void InitializeDutyCycle() {
28 static LimitedHandleResource<HAL_DutyCycleHandle, DutyCycle, kNumDutyCycles,
29 HAL_HandleEnum::DutyCycle>
30 dcH;
31 dutyCycleHandles = &dcH;
32}
Austin Schuh812d0d12021-11-04 20:16:48 -070033} // namespace hal::init
Brian Silverman8fce7482020-01-05 13:18:21 -080034
35extern "C" {
36HAL_DutyCycleHandle HAL_InitializeDutyCycle(HAL_Handle digitalSourceHandle,
37 HAL_AnalogTriggerType triggerType,
38 int32_t* status) {
39 hal::init::CheckInit();
40
41 HAL_DutyCycleHandle handle = dutyCycleHandles->Allocate();
42 if (handle == HAL_kInvalidHandle) {
43 *status = NO_AVAILABLE_RESOURCES;
44 return HAL_kInvalidHandle;
45 }
46
47 auto dutyCycle = dutyCycleHandles->Get(handle);
48 if (dutyCycle == nullptr) { // would only occur on thread issue
49 *status = HAL_HANDLE_ERROR;
50 return HAL_kInvalidHandle;
51 }
52
53 int16_t index = getHandleIndex(handle);
54 SimDutyCycleData[index].digitalChannel = getHandleIndex(digitalSourceHandle);
55 SimDutyCycleData[index].initialized = true;
56 SimDutyCycleData[index].simDevice = 0;
57 dutyCycle->index = index;
58 return handle;
59}
60void HAL_FreeDutyCycle(HAL_DutyCycleHandle dutyCycleHandle) {
61 auto dutyCycle = dutyCycleHandles->Get(dutyCycleHandle);
62 dutyCycleHandles->Free(dutyCycleHandle);
Austin Schuh812d0d12021-11-04 20:16:48 -070063 if (dutyCycle == nullptr) {
64 return;
65 }
Brian Silverman8fce7482020-01-05 13:18:21 -080066 SimDutyCycleData[dutyCycle->index].initialized = false;
67}
68
69void HAL_SetDutyCycleSimDevice(HAL_EncoderHandle handle,
70 HAL_SimDeviceHandle device) {
71 auto dutyCycle = dutyCycleHandles->Get(handle);
Austin Schuh812d0d12021-11-04 20:16:48 -070072 if (dutyCycle == nullptr) {
73 return;
74 }
Brian Silverman8fce7482020-01-05 13:18:21 -080075 SimDutyCycleData[dutyCycle->index].simDevice = device;
76}
77
78int32_t HAL_GetDutyCycleFrequency(HAL_DutyCycleHandle dutyCycleHandle,
79 int32_t* status) {
80 auto dutyCycle = dutyCycleHandles->Get(dutyCycleHandle);
81 if (dutyCycle == nullptr) {
82 *status = HAL_HANDLE_ERROR;
83 return 0;
84 }
85 return SimDutyCycleData[dutyCycle->index].frequency;
86}
James Kuszmaulcf324122023-01-14 14:07:17 -080087
Brian Silverman8fce7482020-01-05 13:18:21 -080088double HAL_GetDutyCycleOutput(HAL_DutyCycleHandle dutyCycleHandle,
89 int32_t* status) {
90 auto dutyCycle = dutyCycleHandles->Get(dutyCycleHandle);
91 if (dutyCycle == nullptr) {
92 *status = HAL_HANDLE_ERROR;
93 return 0;
94 }
95 return SimDutyCycleData[dutyCycle->index].output;
96}
James Kuszmaulcf324122023-01-14 14:07:17 -080097
98int32_t HAL_GetDutyCycleHighTime(HAL_DutyCycleHandle dutyCycleHandle,
99 int32_t* status) {
Brian Silverman8fce7482020-01-05 13:18:21 -0800100 auto dutyCycle = dutyCycleHandles->Get(dutyCycleHandle);
101 if (dutyCycle == nullptr) {
102 *status = HAL_HANDLE_ERROR;
103 return 0;
104 }
James Kuszmaulcf324122023-01-14 14:07:17 -0800105
106 if (SimDutyCycleData[dutyCycle->index].frequency == 0) {
107 return 0;
108 }
109
110 double periodSeconds = 1.0 / SimDutyCycleData[dutyCycle->index].frequency;
111 double periodNanoSeconds = periodSeconds * 1e9;
112 return periodNanoSeconds * SimDutyCycleData[dutyCycle->index].output;
Brian Silverman8fce7482020-01-05 13:18:21 -0800113}
James Kuszmaulcf324122023-01-14 14:07:17 -0800114
Brian Silverman8fce7482020-01-05 13:18:21 -0800115int32_t HAL_GetDutyCycleOutputScaleFactor(HAL_DutyCycleHandle dutyCycleHandle,
116 int32_t* status) {
117 return 4e7 - 1;
118}
James Kuszmaulcf324122023-01-14 14:07:17 -0800119
Brian Silverman8fce7482020-01-05 13:18:21 -0800120int32_t HAL_GetDutyCycleFPGAIndex(HAL_DutyCycleHandle dutyCycleHandle,
121 int32_t* status) {
122 auto dutyCycle = dutyCycleHandles->Get(dutyCycleHandle);
123 if (dutyCycle == nullptr) {
124 *status = HAL_HANDLE_ERROR;
125 return -1;
126 }
127 return dutyCycle->index;
128}
129} // extern "C"