blob: 1c1a678cb82fe8bdf08431b692b184dcb4c2bcd5 [file] [log] [blame]
Brian Silverman8fce7482020-01-05 13:18:21 -08001/*----------------------------------------------------------------------------*/
2/* Copyright (c) 2019 FIRST. All Rights Reserved. */
3/* Open Source Software - may be modified and shared by FRC teams. The code */
4/* must be accompanied by the FIRST BSD license file in the root directory of */
5/* the project. */
6/*----------------------------------------------------------------------------*/
7
8#include "hal/DutyCycle.h"
9
10#include <memory>
11
12#include "DigitalInternal.h"
13#include "DutyCycleInternal.h"
14#include "HALInitializer.h"
15#include "PortsInternal.h"
16#include "hal/ChipObject.h"
17#include "hal/Errors.h"
18#include "hal/handles/HandlesInternal.h"
19#include "hal/handles/LimitedHandleResource.h"
20
21using namespace hal;
22
23namespace hal {
24LimitedHandleResource<HAL_DutyCycleHandle, DutyCycle, kNumDutyCycles,
25 HAL_HandleEnum::DutyCycle>* dutyCycleHandles;
26namespace init {
27void InitializeDutyCycle() {
28 static LimitedHandleResource<HAL_DutyCycleHandle, DutyCycle, kNumDutyCycles,
29 HAL_HandleEnum::DutyCycle>
30 dcH;
31 dutyCycleHandles = &dcH;
32}
33} // namespace init
34} // namespace hal
35
36static constexpr int32_t kScaleFactor = 4e7 - 1;
37
38extern "C" {
39HAL_DutyCycleHandle HAL_InitializeDutyCycle(HAL_Handle digitalSourceHandle,
40 HAL_AnalogTriggerType triggerType,
41 int32_t* status) {
42 hal::init::CheckInit();
43
44 bool routingAnalogTrigger = false;
45 uint8_t routingChannel = 0;
46 uint8_t routingModule = 0;
47 bool success =
48 remapDigitalSource(digitalSourceHandle, triggerType, routingChannel,
49 routingModule, routingAnalogTrigger);
50
51 if (!success) {
52 *status = HAL_HANDLE_ERROR;
53 return HAL_kInvalidHandle;
54 }
55
56 HAL_DutyCycleHandle handle = dutyCycleHandles->Allocate();
57 if (handle == HAL_kInvalidHandle) {
58 *status = NO_AVAILABLE_RESOURCES;
59 return HAL_kInvalidHandle;
60 }
61
62 auto dutyCycle = dutyCycleHandles->Get(handle);
63 uint32_t index = static_cast<uint32_t>(getHandleIndex(handle));
64 dutyCycle->dutyCycle.reset(tDutyCycle::create(index, status));
65
66 dutyCycle->dutyCycle->writeSource_AnalogTrigger(routingAnalogTrigger, status);
67 dutyCycle->dutyCycle->writeSource_Channel(routingChannel, status);
68 dutyCycle->dutyCycle->writeSource_Module(routingModule, status);
69 dutyCycle->index = index;
70
71 return handle;
72}
73void HAL_FreeDutyCycle(HAL_DutyCycleHandle dutyCycleHandle) {
74 // Just free it, the unique ptr will take care of everything else
75 dutyCycleHandles->Free(dutyCycleHandle);
76}
77
78int32_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"