blob: 6d70570d30f1db24f867c81af5da0183221b4141 [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 <memory>
8
9#include "DigitalInternal.h"
10#include "DutyCycleInternal.h"
11#include "HALInitializer.h"
12#include "PortsInternal.h"
13#include "hal/ChipObject.h"
14#include "hal/Errors.h"
15#include "hal/handles/HandlesInternal.h"
16#include "hal/handles/LimitedHandleResource.h"
17
18using namespace hal;
19
20namespace hal {
21LimitedHandleResource<HAL_DutyCycleHandle, DutyCycle, kNumDutyCycles,
22 HAL_HandleEnum::DutyCycle>* dutyCycleHandles;
23namespace init {
24void InitializeDutyCycle() {
25 static LimitedHandleResource<HAL_DutyCycleHandle, DutyCycle, kNumDutyCycles,
26 HAL_HandleEnum::DutyCycle>
27 dcH;
28 dutyCycleHandles = &dcH;
29}
30} // namespace init
31} // namespace hal
32
33static constexpr int32_t kScaleFactor = 4e7 - 1;
34
35extern "C" {
36HAL_DutyCycleHandle HAL_InitializeDutyCycle(HAL_Handle digitalSourceHandle,
37 HAL_AnalogTriggerType triggerType,
38 int32_t* status) {
39 hal::init::CheckInit();
40
41 bool routingAnalogTrigger = false;
42 uint8_t routingChannel = 0;
43 uint8_t routingModule = 0;
44 bool success =
45 remapDigitalSource(digitalSourceHandle, triggerType, routingChannel,
46 routingModule, routingAnalogTrigger);
47
48 if (!success) {
49 *status = HAL_HANDLE_ERROR;
50 return HAL_kInvalidHandle;
51 }
52
53 HAL_DutyCycleHandle handle = dutyCycleHandles->Allocate();
54 if (handle == HAL_kInvalidHandle) {
55 *status = NO_AVAILABLE_RESOURCES;
56 return HAL_kInvalidHandle;
57 }
58
59 auto dutyCycle = dutyCycleHandles->Get(handle);
60 uint32_t index = static_cast<uint32_t>(getHandleIndex(handle));
61 dutyCycle->dutyCycle.reset(tDutyCycle::create(index, status));
62
63 dutyCycle->dutyCycle->writeSource_AnalogTrigger(routingAnalogTrigger, status);
64 dutyCycle->dutyCycle->writeSource_Channel(routingChannel, status);
65 dutyCycle->dutyCycle->writeSource_Module(routingModule, status);
66 dutyCycle->index = index;
67
68 return handle;
69}
70void HAL_FreeDutyCycle(HAL_DutyCycleHandle dutyCycleHandle) {
71 // Just free it, the unique ptr will take care of everything else
72 dutyCycleHandles->Free(dutyCycleHandle);
73}
74
Austin Schuh1e69f942020-11-14 15:06:14 -080075void HAL_SetDutyCycleSimDevice(HAL_EncoderHandle handle,
76 HAL_SimDeviceHandle device) {}
77
Brian Silverman8fce7482020-01-05 13:18:21 -080078int32_t HAL_GetDutyCycleFrequency(HAL_DutyCycleHandle dutyCycleHandle,
79 int32_t* status) {
80 auto dutyCycle = dutyCycleHandles->Get(dutyCycleHandle);
81 if (!dutyCycle) {
82 *status = HAL_HANDLE_ERROR;
83 return 0;
84 }
85
86 // TODO Handle Overflow
87 unsigned char overflow = 0;
88 return dutyCycle->dutyCycle->readFrequency(&overflow, status);
89}
90
91double HAL_GetDutyCycleOutput(HAL_DutyCycleHandle dutyCycleHandle,
92 int32_t* status) {
93 return HAL_GetDutyCycleOutputRaw(dutyCycleHandle, status) /
94 static_cast<double>(kScaleFactor);
95}
96
97int32_t HAL_GetDutyCycleOutputRaw(HAL_DutyCycleHandle dutyCycleHandle,
98 int32_t* status) {
99 auto dutyCycle = dutyCycleHandles->Get(dutyCycleHandle);
100 if (!dutyCycle) {
101 *status = HAL_HANDLE_ERROR;
102 return 0;
103 }
104
105 // TODO Handle Overflow
106 unsigned char overflow = 0;
107 return dutyCycle->dutyCycle->readOutput(&overflow, status);
108}
109
110int32_t HAL_GetDutyCycleOutputScaleFactor(HAL_DutyCycleHandle dutyCycleHandle,
111 int32_t* status) {
112 return kScaleFactor;
113}
114
115int32_t HAL_GetDutyCycleFPGAIndex(HAL_DutyCycleHandle dutyCycleHandle,
116 int32_t* status) {
117 auto dutyCycle = dutyCycleHandles->Get(dutyCycleHandle);
118 if (!dutyCycle) {
119 *status = HAL_HANDLE_ERROR;
120 return -1;
121 }
122 return dutyCycle->index;
123}
124} // extern "C"