mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-07-04 03:11:43 +00:00
Add DMA support to HAL and WPILibC (#2080)
This commit is contained in:
committed by
Peter Johnson
parent
8280b7e3af
commit
82b2170feb
@@ -201,6 +201,14 @@ double HAL_GetAnalogVoltage(HAL_AnalogInputHandle analogPortHandle,
|
||||
return voltage;
|
||||
}
|
||||
|
||||
double HAL_GetAnalogValueToVolts(HAL_AnalogInputHandle analogPortHandle,
|
||||
int32_t rawValue, int32_t* status) {
|
||||
int32_t LSBWeight = HAL_GetAnalogLSBWeight(analogPortHandle, status);
|
||||
int32_t offset = HAL_GetAnalogOffset(analogPortHandle, status);
|
||||
double voltage = LSBWeight * 1.0e-9 * rawValue - offset * 1.0e-9;
|
||||
return voltage;
|
||||
}
|
||||
|
||||
double HAL_GetAnalogAverageVoltage(HAL_AnalogInputHandle analogPortHandle,
|
||||
int32_t* status) {
|
||||
int32_t value = HAL_GetAnalogAverageValue(analogPortHandle, status);
|
||||
|
||||
1004
hal/src/main/native/athena/DMA.cpp
Normal file
1004
hal/src/main/native/athena/DMA.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@@ -238,6 +238,19 @@ void InitializeEncoder() {
|
||||
} // namespace init
|
||||
} // namespace hal
|
||||
|
||||
namespace hal {
|
||||
bool GetEncoderBaseHandle(HAL_EncoderHandle handle,
|
||||
HAL_FPGAEncoderHandle* fpgaHandle,
|
||||
HAL_CounterHandle* counterHandle) {
|
||||
auto encoder = encoderHandles->Get(handle);
|
||||
if (!handle) return false;
|
||||
|
||||
*fpgaHandle = encoder->m_encoder;
|
||||
*counterHandle = encoder->m_counter;
|
||||
return true;
|
||||
}
|
||||
} // namespace hal
|
||||
|
||||
extern "C" {
|
||||
HAL_EncoderHandle HAL_InitializeEncoder(
|
||||
HAL_Handle digitalSourceHandleA, HAL_AnalogTriggerType analogTriggerTypeA,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
|
||||
/* Copyright (c) 2016-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. */
|
||||
@@ -13,8 +13,16 @@
|
||||
|
||||
namespace hal {
|
||||
|
||||
bool GetEncoderBaseHandle(HAL_EncoderHandle handle,
|
||||
HAL_FPGAEncoderHandle* fpgaEncoderHandle,
|
||||
HAL_CounterHandle* counterHandle);
|
||||
|
||||
class Encoder {
|
||||
public:
|
||||
friend bool GetEncoderBaseHandle(HAL_EncoderHandle handle,
|
||||
HAL_FPGAEncoderHandle* fpgaEncoderHandle,
|
||||
HAL_CounterHandle* counterHandle);
|
||||
|
||||
Encoder(HAL_Handle digitalSourceHandleA,
|
||||
HAL_AnalogTriggerType analogTriggerTypeA,
|
||||
HAL_Handle digitalSourceHandleB,
|
||||
|
||||
@@ -56,6 +56,7 @@ void InitializeHAL() {
|
||||
InitializeCounter();
|
||||
InitializeDigitalInternal();
|
||||
InitializeDIO();
|
||||
InitializeDMA();
|
||||
InitializeDutyCycle();
|
||||
InitializeEncoder();
|
||||
InitializeFPGAEncoder();
|
||||
@@ -256,6 +257,28 @@ uint64_t HAL_GetFPGATime(int32_t* status) {
|
||||
return (upper2 << 32) + lower;
|
||||
}
|
||||
|
||||
uint64_t HAL_ExpandFPGATime(uint32_t unexpanded_lower, int32_t* status) {
|
||||
// Capture the current FPGA time. This will give us the upper half of the
|
||||
// clock.
|
||||
uint64_t fpga_time = HAL_GetFPGATime(status);
|
||||
if (*status != 0) return 0;
|
||||
|
||||
// Now, we need to detect the case where the lower bits rolled over after we
|
||||
// sampled. In that case, the upper bits will be 1 bigger than they should
|
||||
// be.
|
||||
|
||||
// Break it into lower and upper portions.
|
||||
uint32_t lower = fpga_time & 0xffffffffull;
|
||||
uint64_t upper = (fpga_time >> 32) & 0xffffffff;
|
||||
|
||||
// The time was sampled *before* the current time, so roll it back.
|
||||
if (lower < unexpanded_lower) {
|
||||
--upper;
|
||||
}
|
||||
|
||||
return (upper << 32) + static_cast<uint64_t>(unexpanded_lower);
|
||||
}
|
||||
|
||||
HAL_Bool HAL_GetFPGAButton(int32_t* status) {
|
||||
if (!global) {
|
||||
*status = NiFpga_Status_ResourceNotInitialized;
|
||||
|
||||
@@ -32,6 +32,7 @@ extern void InitializeConstants();
|
||||
extern void InitializeCounter();
|
||||
extern void InitializeDigitalInternal();
|
||||
extern void InitializeDIO();
|
||||
extern void InitializeDMA();
|
||||
extern void InitializeDutyCycle();
|
||||
extern void InitializeEncoder();
|
||||
extern void InitializeFPGAEncoder();
|
||||
|
||||
@@ -233,6 +233,16 @@ int32_t HAL_GetAnalogLSBWeight(HAL_AnalogInputHandle analogPortHandle,
|
||||
*/
|
||||
int32_t HAL_GetAnalogOffset(HAL_AnalogInputHandle analogPortHandle,
|
||||
int32_t* status);
|
||||
|
||||
/**
|
||||
* Get the analog voltage from a raw value.
|
||||
*
|
||||
* @param analogPortHandle Handle to the analog port the values were read from.
|
||||
* @param rawValue The raw analog value
|
||||
* @return The voltage relating to the value
|
||||
*/
|
||||
double HAL_GetAnalogValueToVolts(HAL_AnalogInputHandle analogPortHandle,
|
||||
int32_t rawValue, int32_t* status);
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
129
hal/src/main/native/include/hal/DMA.h
Normal file
129
hal/src/main/native/include/hal/DMA.h
Normal file
@@ -0,0 +1,129 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* 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. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "hal/AnalogTrigger.h"
|
||||
#include "hal/Types.h"
|
||||
|
||||
// clang-format off
|
||||
/**
|
||||
* The DMA Read Status.
|
||||
*/
|
||||
HAL_ENUM(HAL_DMAReadStatus ) {
|
||||
HAL_DMA_OK = 1,
|
||||
HAL_DMA_TIMEOUT = 2,
|
||||
HAL_DMA_ERROR = 3,
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
struct HAL_DMASample {
|
||||
uint32_t readBuffer[74];
|
||||
int32_t channelOffsets[22];
|
||||
uint64_t timeStamp;
|
||||
uint32_t captureSize;
|
||||
uint8_t triggerChannels;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
HAL_DMAHandle HAL_InitializeDMA(int32_t* status);
|
||||
void HAL_FreeDMA(HAL_DMAHandle handle);
|
||||
|
||||
void HAL_SetDMAPause(HAL_DMAHandle handle, HAL_Bool pause, int32_t* status);
|
||||
void HAL_SetDMARate(HAL_DMAHandle handle, int32_t cycles, int32_t* status);
|
||||
|
||||
void HAL_AddDMAEncoder(HAL_DMAHandle handle, HAL_EncoderHandle encoderHandle,
|
||||
int32_t* status);
|
||||
void HAL_AddDMAEncoderPeriod(HAL_DMAHandle handle,
|
||||
HAL_EncoderHandle encoderHandle, int32_t* status);
|
||||
void HAL_AddDMACounter(HAL_DMAHandle handle, HAL_CounterHandle counterHandle,
|
||||
int32_t* status);
|
||||
void HAL_AddDMACounterPeriod(HAL_DMAHandle handle,
|
||||
HAL_CounterHandle counterHandle, int32_t* status);
|
||||
void HAL_AddDMADigitalSource(HAL_DMAHandle handle,
|
||||
HAL_Handle digitalSourceHandle, int32_t* status);
|
||||
void HAL_AddDMAAnalogInput(HAL_DMAHandle handle,
|
||||
HAL_AnalogInputHandle aInHandle, int32_t* status);
|
||||
|
||||
void HAL_AddDMAAveragedAnalogInput(HAL_DMAHandle handle,
|
||||
HAL_AnalogInputHandle aInHandle,
|
||||
int32_t* status);
|
||||
|
||||
void HAL_AddDMAAnalogAccumulator(HAL_DMAHandle handle,
|
||||
HAL_AnalogInputHandle aInHandle,
|
||||
int32_t* status);
|
||||
|
||||
void HAL_AddDMADutyCycle(HAL_DMAHandle handle,
|
||||
HAL_DutyCycleHandle dutyCycleHandle, int32_t* status);
|
||||
|
||||
void HAL_SetDMAExternalTrigger(HAL_DMAHandle handle,
|
||||
HAL_Handle digitalSourceHandle,
|
||||
HAL_AnalogTriggerType analogTriggerType,
|
||||
HAL_Bool rising, HAL_Bool falling,
|
||||
int32_t* status);
|
||||
|
||||
void HAL_StartDMA(HAL_DMAHandle handle, int32_t queueDepth, int32_t* status);
|
||||
void HAL_StopDMA(HAL_DMAHandle handle, int32_t* status);
|
||||
|
||||
void* HAL_GetDMADirectPointer(HAL_DMAHandle handle);
|
||||
|
||||
enum HAL_DMAReadStatus HAL_ReadDMADirect(void* dmaPointer,
|
||||
HAL_DMASample* dmaSample,
|
||||
int32_t timeoutMs,
|
||||
int32_t* remainingOut,
|
||||
int32_t* status);
|
||||
|
||||
enum HAL_DMAReadStatus HAL_ReadDMA(HAL_DMAHandle handle,
|
||||
HAL_DMASample* dmaSample, int32_t timeoutMs,
|
||||
int32_t* remainingOut, int32_t* status);
|
||||
|
||||
// Sampling Code
|
||||
uint64_t HAL_GetDMASampleTime(const HAL_DMASample* dmaSample, int32_t* status);
|
||||
|
||||
int32_t HAL_GetDMASampleEncoderRaw(const HAL_DMASample* dmaSample,
|
||||
HAL_EncoderHandle encoderHandle,
|
||||
int32_t* status);
|
||||
|
||||
int32_t HAL_GetDMASampleCounter(const HAL_DMASample* dmaSample,
|
||||
HAL_CounterHandle counterHandle,
|
||||
int32_t* status);
|
||||
|
||||
int32_t HAL_GetDMASampleEncoderPeriodRaw(const HAL_DMASample* dmaSample,
|
||||
HAL_EncoderHandle encoderHandle,
|
||||
int32_t* status);
|
||||
|
||||
int32_t HAL_GetDMASampleCounterPeriod(const HAL_DMASample* dmaSample,
|
||||
HAL_CounterHandle counterHandle,
|
||||
int32_t* status);
|
||||
HAL_Bool HAL_GetDMASampleDigitalSource(const HAL_DMASample* dmaSample,
|
||||
HAL_Handle dSourceHandle,
|
||||
int32_t* status);
|
||||
int32_t HAL_GetDMASampleAnalogInputRaw(const HAL_DMASample* dmaSample,
|
||||
HAL_AnalogInputHandle aInHandle,
|
||||
int32_t* status);
|
||||
|
||||
int32_t HAL_GetDMASampleAveragedAnalogInputRaw(const HAL_DMASample* dmaSample,
|
||||
HAL_AnalogInputHandle aInHandle,
|
||||
int32_t* status);
|
||||
|
||||
void HAL_GetDMASampleAnalogAccumulator(const HAL_DMASample* dmaSample,
|
||||
HAL_AnalogInputHandle aInHandle,
|
||||
int64_t* count, int64_t* value,
|
||||
int32_t* status);
|
||||
|
||||
int32_t HAL_GetDMASampleDutyCycleOutputRaw(const HAL_DMASample* dmaSample,
|
||||
HAL_DutyCycleHandle dutyCycleHandle,
|
||||
int32_t* status);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
@@ -94,6 +94,10 @@
|
||||
#define HAL_HANDLE_ERROR_MESSAGE \
|
||||
"HAL: A handle parameter was passed incorrectly"
|
||||
|
||||
#define HAL_INVALID_DMA_ADDITION -1102
|
||||
#define HAL_INVALID_DMA_ADDITION_MESSAGE \
|
||||
"HAL_AddDMA() only works before HAL_StartDMA()"
|
||||
|
||||
#define HAL_SERIAL_PORT_NOT_FOUND -1123
|
||||
#define HAL_SERIAL_PORT_NOT_FOUND_MESSAGE \
|
||||
"HAL: The specified serial port device was not found"
|
||||
|
||||
@@ -109,6 +109,20 @@ HAL_PortHandle HAL_GetPortWithModule(int32_t module, int32_t channel);
|
||||
*/
|
||||
uint64_t HAL_GetFPGATime(int32_t* status);
|
||||
|
||||
/**
|
||||
* Given an 32 bit FPGA time, expand it to the nearest likely 64 bit FPGA time.
|
||||
*
|
||||
* Note: This is making the assumption that the timestamp being converted is
|
||||
* always in the past. If you call this with a future timestamp, it probably
|
||||
* will make it in the past. If you wait over 70 minutes between capturing the
|
||||
* bottom 32 bits of the timestamp and expanding it, you will be off by
|
||||
* multiples of 1<<32 microseconds.
|
||||
*
|
||||
* @return The current time in microseconds according to the FPGA (since FPGA
|
||||
* reset) as a 64 bit number.
|
||||
*/
|
||||
uint64_t HAL_ExpandFPGATime(uint32_t unexpanded_lower, int32_t* status);
|
||||
|
||||
/**
|
||||
* Call this to start up HAL. This is required for robot programs.
|
||||
*
|
||||
|
||||
@@ -57,6 +57,8 @@ typedef HAL_Handle HAL_SimDeviceHandle;
|
||||
|
||||
typedef HAL_Handle HAL_SimValueHandle;
|
||||
|
||||
typedef HAL_Handle HAL_DMAHandle;
|
||||
|
||||
typedef HAL_Handle HAL_DutyCycleHandle;
|
||||
|
||||
typedef HAL_CANHandle HAL_PDPHandle;
|
||||
|
||||
@@ -66,7 +66,8 @@ enum class HAL_HandleEnum {
|
||||
SimulationJni = 18,
|
||||
CAN = 19,
|
||||
SerialPort = 20,
|
||||
DutyCycle = 21
|
||||
DutyCycle = 21,
|
||||
DMA = 22,
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -165,6 +165,15 @@ double HAL_GetAnalogVoltage(HAL_AnalogInputHandle analogPortHandle,
|
||||
|
||||
return SimAnalogInData[port->channel].voltage;
|
||||
}
|
||||
|
||||
double HAL_GetAnalogValueToVolts(HAL_AnalogInputHandle analogPortHandle,
|
||||
int32_t rawValue, int32_t* status) {
|
||||
int32_t LSBWeight = HAL_GetAnalogLSBWeight(analogPortHandle, status);
|
||||
int32_t offset = HAL_GetAnalogOffset(analogPortHandle, status);
|
||||
double voltage = LSBWeight * 1.0e-9 * rawValue - offset * 1.0e-9;
|
||||
return voltage;
|
||||
}
|
||||
|
||||
double HAL_GetAnalogAverageVoltage(HAL_AnalogInputHandle analogPortHandle,
|
||||
int32_t* status) {
|
||||
auto port = analogInputHandles->Get(analogPortHandle);
|
||||
|
||||
124
hal/src/main/native/sim/DMA.cpp
Normal file
124
hal/src/main/native/sim/DMA.cpp
Normal file
@@ -0,0 +1,124 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* 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/DMA.h"
|
||||
|
||||
extern "C" {
|
||||
HAL_DMAHandle HAL_InitializeDMA(int32_t* status) { return HAL_kInvalidHandle; }
|
||||
void HAL_FreeDMA(HAL_DMAHandle handle) {}
|
||||
|
||||
void HAL_SetDMAPause(HAL_DMAHandle handle, HAL_Bool pause, int32_t* status) {}
|
||||
void HAL_SetDMARate(HAL_DMAHandle handle, int32_t cycles, int32_t* status) {}
|
||||
|
||||
void HAL_AddDMAEncoder(HAL_DMAHandle handle, HAL_EncoderHandle encoderHandle,
|
||||
int32_t* status) {}
|
||||
void HAL_AddDMAEncoderPeriod(HAL_DMAHandle handle,
|
||||
HAL_EncoderHandle encoderHandle, int32_t* status) {
|
||||
}
|
||||
void HAL_AddDMACounter(HAL_DMAHandle handle, HAL_CounterHandle counterHandle,
|
||||
int32_t* status) {}
|
||||
void HAL_AddDMACounterPeriod(HAL_DMAHandle handle,
|
||||
HAL_CounterHandle counterHandle, int32_t* status) {
|
||||
}
|
||||
void HAL_AddDMADigitalSource(HAL_DMAHandle handle,
|
||||
HAL_Handle digitalSourceHandle, int32_t* status) {}
|
||||
void HAL_AddDMAAnalogInput(HAL_DMAHandle handle,
|
||||
HAL_AnalogInputHandle aInHandle, int32_t* status) {}
|
||||
|
||||
void HAL_AddDMAAveragedAnalogInput(HAL_DMAHandle handle,
|
||||
HAL_AnalogInputHandle aInHandle,
|
||||
int32_t* status) {}
|
||||
|
||||
void HAL_AddDMAAnalogAccumulator(HAL_DMAHandle handle,
|
||||
HAL_AnalogInputHandle aInHandle,
|
||||
int32_t* status) {}
|
||||
|
||||
void HAL_AddDMADutyCycle(HAL_DMAHandle handle,
|
||||
HAL_DutyCycleHandle dutyCycleHandle, int32_t* status) {
|
||||
}
|
||||
|
||||
void HAL_SetDMAExternalTrigger(HAL_DMAHandle handle,
|
||||
HAL_Handle digitalSourceHandle,
|
||||
HAL_AnalogTriggerType analogTriggerType,
|
||||
HAL_Bool rising, HAL_Bool falling,
|
||||
int32_t* status) {}
|
||||
|
||||
void HAL_StartDMA(HAL_DMAHandle handle, int32_t queueDepth, int32_t* status) {}
|
||||
void HAL_StopDMA(HAL_DMAHandle handle, int32_t* status) {}
|
||||
|
||||
void* HAL_GetDMADirectPointer(HAL_DMAHandle handle) { return nullptr; }
|
||||
|
||||
enum HAL_DMAReadStatus HAL_ReadDMADirect(void* dmaPointer,
|
||||
HAL_DMASample* dmaSample,
|
||||
int32_t timeoutMs,
|
||||
int32_t* remainingOut,
|
||||
int32_t* status) {
|
||||
return HAL_DMA_ERROR;
|
||||
}
|
||||
|
||||
enum HAL_DMAReadStatus HAL_ReadDMA(HAL_DMAHandle handle,
|
||||
HAL_DMASample* dmaSample, int32_t timeoutMs,
|
||||
int32_t* remainingOut, int32_t* status) {
|
||||
return HAL_DMA_ERROR;
|
||||
}
|
||||
|
||||
// Sampling Code
|
||||
uint64_t HAL_GetDMASampleTime(const HAL_DMASample* dmaSample, int32_t* status) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t HAL_GetDMASampleEncoderRaw(const HAL_DMASample* dmaSample,
|
||||
HAL_EncoderHandle encoderHandle,
|
||||
int32_t* status) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t HAL_GetDMASampleCounter(const HAL_DMASample* dmaSample,
|
||||
HAL_CounterHandle counterHandle,
|
||||
int32_t* status) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t HAL_GetDMASampleEncoderPeriodRaw(const HAL_DMASample* dmaSample,
|
||||
HAL_EncoderHandle encoderHandle,
|
||||
int32_t* status) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t HAL_GetDMASampleCounterPeriod(const HAL_DMASample* dmaSample,
|
||||
HAL_CounterHandle counterHandle,
|
||||
int32_t* status) {
|
||||
return 0;
|
||||
}
|
||||
HAL_Bool HAL_GetDMASampleDigitalSource(const HAL_DMASample* dmaSample,
|
||||
HAL_Handle dSourceHandle,
|
||||
int32_t* status) {
|
||||
return 0;
|
||||
}
|
||||
int32_t HAL_GetDMASampleAnalogInputRaw(const HAL_DMASample* dmaSample,
|
||||
HAL_AnalogInputHandle aInHandle,
|
||||
int32_t* status) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t HAL_GetDMASampleAveragedAnalogInputRaw(const HAL_DMASample* dmaSample,
|
||||
HAL_AnalogInputHandle aInHandle,
|
||||
int32_t* status) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void HAL_GetDMASampleAnalogAccumulator(const HAL_DMASample* dmaSample,
|
||||
HAL_AnalogInputHandle aInHandle,
|
||||
int64_t* count, int64_t* value,
|
||||
int32_t* status) {}
|
||||
|
||||
int32_t HAL_GetDMASampleDutyCycleOutputRaw(const HAL_DMASample* dmaSample,
|
||||
HAL_DutyCycleHandle dutyCycleHandle,
|
||||
int32_t* status) {
|
||||
return 0;
|
||||
}
|
||||
} // extern "C"
|
||||
@@ -222,6 +222,28 @@ int64_t HAL_GetFPGARevision(int32_t* status) {
|
||||
|
||||
uint64_t HAL_GetFPGATime(int32_t* status) { return hal::GetFPGATime(); }
|
||||
|
||||
uint64_t HAL_ExpandFPGATime(uint32_t unexpanded_lower, int32_t* status) {
|
||||
// Capture the current FPGA time. This will give us the upper half of the
|
||||
// clock.
|
||||
uint64_t fpga_time = HAL_GetFPGATime(status);
|
||||
if (*status != 0) return 0;
|
||||
|
||||
// Now, we need to detect the case where the lower bits rolled over after we
|
||||
// sampled. In that case, the upper bits will be 1 bigger than they should
|
||||
// be.
|
||||
|
||||
// Break it into lower and upper portions.
|
||||
uint32_t lower = fpga_time & 0xffffffffull;
|
||||
uint64_t upper = (fpga_time >> 32) & 0xffffffff;
|
||||
|
||||
// The time was sampled *before* the current time, so roll it back.
|
||||
if (lower < unexpanded_lower) {
|
||||
--upper;
|
||||
}
|
||||
|
||||
return (upper << 32) + static_cast<uint64_t>(unexpanded_lower);
|
||||
}
|
||||
|
||||
HAL_Bool HAL_GetFPGAButton(int32_t* status) {
|
||||
return SimRoboRioData[0].fpgaButton;
|
||||
}
|
||||
|
||||
115
wpilibc/src/main/native/cpp/DMA.cpp
Normal file
115
wpilibc/src/main/native/cpp/DMA.cpp
Normal file
@@ -0,0 +1,115 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* 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 "frc/DMA.h"
|
||||
|
||||
#include <frc/AnalogInput.h>
|
||||
#include <frc/Counter.h>
|
||||
#include <frc/DigitalSource.h>
|
||||
#include <frc/DutyCycle.h>
|
||||
#include <frc/Encoder.h>
|
||||
|
||||
#include <hal/DMA.h>
|
||||
#include <hal/HALBase.h>
|
||||
|
||||
using namespace frc;
|
||||
|
||||
DMA::DMA() {
|
||||
int32_t status = 0;
|
||||
dmaHandle = HAL_InitializeDMA(&status);
|
||||
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
|
||||
}
|
||||
|
||||
DMA::~DMA() { HAL_FreeDMA(dmaHandle); }
|
||||
|
||||
void DMA::SetPause(bool pause) {
|
||||
int32_t status = 0;
|
||||
HAL_SetDMAPause(dmaHandle, pause, &status);
|
||||
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
|
||||
}
|
||||
|
||||
void DMA::SetRate(int cycles) {
|
||||
int32_t status = 0;
|
||||
HAL_SetDMARate(dmaHandle, cycles, &status);
|
||||
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
|
||||
}
|
||||
|
||||
void DMA::AddEncoder(const Encoder* encoder) {
|
||||
int32_t status = 0;
|
||||
HAL_AddDMAEncoder(dmaHandle, encoder->m_encoder, &status);
|
||||
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
|
||||
}
|
||||
|
||||
void DMA::AddEncoderPeriod(const Encoder* encoder) {
|
||||
int32_t status = 0;
|
||||
HAL_AddDMAEncoderPeriod(dmaHandle, encoder->m_encoder, &status);
|
||||
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
|
||||
}
|
||||
|
||||
void DMA::AddCounter(const Counter* counter) {
|
||||
int32_t status = 0;
|
||||
HAL_AddDMACounter(dmaHandle, counter->m_counter, &status);
|
||||
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
|
||||
}
|
||||
|
||||
void DMA::AddCounterPeriod(const Counter* counter) {
|
||||
int32_t status = 0;
|
||||
HAL_AddDMACounterPeriod(dmaHandle, counter->m_counter, &status);
|
||||
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
|
||||
}
|
||||
|
||||
void DMA::AddDigitalSource(const DigitalSource* digitalSource) {
|
||||
int32_t status = 0;
|
||||
HAL_AddDMADigitalSource(dmaHandle, digitalSource->GetPortHandleForRouting(),
|
||||
&status);
|
||||
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
|
||||
}
|
||||
|
||||
void DMA::AddDutyCycle(const DutyCycle* dutyCycle) {
|
||||
int32_t status = 0;
|
||||
HAL_AddDMADutyCycle(dmaHandle, dutyCycle->m_handle, &status);
|
||||
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
|
||||
}
|
||||
|
||||
void DMA::AddAnalogInput(const AnalogInput* analogInput) {
|
||||
int32_t status = 0;
|
||||
HAL_AddDMAAnalogInput(dmaHandle, analogInput->m_port, &status);
|
||||
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
|
||||
}
|
||||
|
||||
void DMA::AddAveragedAnalogInput(const AnalogInput* analogInput) {
|
||||
int32_t status = 0;
|
||||
HAL_AddDMAAveragedAnalogInput(dmaHandle, analogInput->m_port, &status);
|
||||
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
|
||||
}
|
||||
|
||||
void DMA::AddAnalogAccumulator(const AnalogInput* analogInput) {
|
||||
int32_t status = 0;
|
||||
HAL_AddDMAAnalogAccumulator(dmaHandle, analogInput->m_port, &status);
|
||||
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
|
||||
}
|
||||
|
||||
void DMA::SetExternalTrigger(DigitalSource* source, bool rising, bool falling) {
|
||||
int32_t status = 0;
|
||||
HAL_SetDMAExternalTrigger(dmaHandle, source->GetPortHandleForRouting(),
|
||||
static_cast<HAL_AnalogTriggerType>(
|
||||
source->GetAnalogTriggerTypeForRouting()),
|
||||
rising, falling, &status);
|
||||
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
|
||||
}
|
||||
|
||||
void DMA::StartDMA(int queueDepth) {
|
||||
int32_t status = 0;
|
||||
HAL_StartDMA(dmaHandle, queueDepth, &status);
|
||||
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
|
||||
}
|
||||
|
||||
void DMA::StopDMA() {
|
||||
int32_t status = 0;
|
||||
HAL_StopDMA(dmaHandle, &status);
|
||||
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
|
||||
}
|
||||
@@ -19,6 +19,8 @@
|
||||
namespace frc {
|
||||
|
||||
class SendableBuilder;
|
||||
class DMA;
|
||||
class DMASample;
|
||||
|
||||
/**
|
||||
* Analog input class.
|
||||
@@ -38,6 +40,8 @@ class AnalogInput : public ErrorBase,
|
||||
public SendableHelper<AnalogInput> {
|
||||
friend class AnalogTrigger;
|
||||
friend class AnalogGyro;
|
||||
friend class DMA;
|
||||
friend class DMASample;
|
||||
|
||||
public:
|
||||
static constexpr int kAccumulatorModuleNumber = 1;
|
||||
|
||||
@@ -21,6 +21,8 @@ namespace frc {
|
||||
|
||||
class DigitalGlitchFilter;
|
||||
class SendableBuilder;
|
||||
class DMA;
|
||||
class DMASample;
|
||||
|
||||
/**
|
||||
* Class for counting the number of ticks on a digital input channel.
|
||||
@@ -36,6 +38,9 @@ class Counter : public ErrorBase,
|
||||
public CounterBase,
|
||||
public Sendable,
|
||||
public SendableHelper<Counter> {
|
||||
friend class DMA;
|
||||
friend class DMASample;
|
||||
|
||||
public:
|
||||
enum Mode {
|
||||
kTwoPulse = 0,
|
||||
|
||||
57
wpilibc/src/main/native/include/frc/DMA.h
Normal file
57
wpilibc/src/main/native/include/frc/DMA.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* 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. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <hal/Types.h>
|
||||
|
||||
#include "frc/ErrorBase.h"
|
||||
|
||||
namespace frc {
|
||||
class Encoder;
|
||||
class Counter;
|
||||
class DigitalSource;
|
||||
class DutyCycle;
|
||||
class AnalogInput;
|
||||
class DMASample;
|
||||
|
||||
class DMA : public ErrorBase {
|
||||
friend class DMASample;
|
||||
|
||||
public:
|
||||
DMA();
|
||||
~DMA() override;
|
||||
|
||||
DMA& operator=(DMA&& other) = default;
|
||||
DMA(DMA&& other) = default;
|
||||
|
||||
void SetPause(bool pause);
|
||||
void SetRate(int cycles);
|
||||
|
||||
void AddEncoder(const Encoder* encoder);
|
||||
void AddEncoderPeriod(const Encoder* encoder);
|
||||
|
||||
void AddCounter(const Counter* counter);
|
||||
void AddCounterPeriod(const Counter* counter);
|
||||
|
||||
void AddDigitalSource(const DigitalSource* digitalSource);
|
||||
|
||||
void AddDutyCycle(const DutyCycle* digitalSource);
|
||||
|
||||
void AddAnalogInput(const AnalogInput* analogInput);
|
||||
void AddAveragedAnalogInput(const AnalogInput* analogInput);
|
||||
void AddAnalogAccumulator(const AnalogInput* analogInput);
|
||||
|
||||
void SetExternalTrigger(DigitalSource* source, bool rising, bool falling);
|
||||
|
||||
void StartDMA(int queueDepth);
|
||||
void StopDMA();
|
||||
|
||||
private:
|
||||
hal::Handle<HAL_DMAHandle> dmaHandle;
|
||||
};
|
||||
} // namespace frc
|
||||
108
wpilibc/src/main/native/include/frc/DMASample.h
Normal file
108
wpilibc/src/main/native/include/frc/DMASample.h
Normal file
@@ -0,0 +1,108 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* 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. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <hal/AnalogInput.h>
|
||||
#include <hal/DMA.h>
|
||||
#include <units/units.h>
|
||||
|
||||
#include "frc/AnalogInput.h"
|
||||
#include "frc/Counter.h"
|
||||
#include "frc/DMA.h"
|
||||
#include "frc/DutyCycle.h"
|
||||
#include "frc/Encoder.h"
|
||||
|
||||
namespace frc {
|
||||
class DMASample : public HAL_DMASample {
|
||||
public:
|
||||
HAL_DMAReadStatus Update(const DMA* dma, units::second_t timeout,
|
||||
int32_t* remaining, int32_t* status) {
|
||||
units::millisecond_t ms = timeout;
|
||||
auto timeoutMs = ms.to<int32_t>();
|
||||
return HAL_ReadDMA(dma->dmaHandle, this, timeoutMs, remaining, status);
|
||||
}
|
||||
|
||||
uint64_t GetTime() const { return timeStamp; }
|
||||
|
||||
units::second_t GetTimeStamp() const {
|
||||
return units::second_t{static_cast<double>(GetTime()) * 1.0e-6};
|
||||
}
|
||||
|
||||
int32_t GetEncoderRaw(const Encoder* encoder, int32_t* status) const {
|
||||
return HAL_GetDMASampleEncoderRaw(this, encoder->m_encoder, status);
|
||||
}
|
||||
|
||||
double GetEncoderDistance(const Encoder* encoder, int32_t* status) const {
|
||||
double val = GetEncoderRaw(encoder, status);
|
||||
val *= encoder->DecodingScaleFactor();
|
||||
val *= encoder->GetDistancePerPulse();
|
||||
return val;
|
||||
}
|
||||
|
||||
int32_t GetEncoderPeriodRaw(const Encoder* encoder, int32_t* status) const {
|
||||
return HAL_GetDMASampleEncoderPeriodRaw(this, encoder->m_encoder, status);
|
||||
}
|
||||
|
||||
int32_t GetCounter(const Counter* counter, int32_t* status) const {
|
||||
return HAL_GetDMASampleCounter(this, counter->m_counter, status);
|
||||
}
|
||||
|
||||
int32_t GetCounterPeriod(const Counter* counter, int32_t* status) const {
|
||||
return HAL_GetDMASampleCounterPeriod(this, counter->m_counter, status);
|
||||
}
|
||||
|
||||
bool GetDigitalSource(const DigitalSource* digitalSource,
|
||||
int32_t* status) const {
|
||||
return HAL_GetDMASampleDigitalSource(
|
||||
this, digitalSource->GetPortHandleForRouting(), status);
|
||||
}
|
||||
|
||||
int32_t GetAnalogInputRaw(const AnalogInput* analogInput,
|
||||
int32_t* status) const {
|
||||
return HAL_GetDMASampleAnalogInputRaw(this, analogInput->m_port, status);
|
||||
}
|
||||
|
||||
double GetAnalogInputVoltage(const AnalogInput* analogInput,
|
||||
int32_t* status) {
|
||||
return HAL_GetAnalogValueToVolts(
|
||||
analogInput->m_port, GetAnalogInputRaw(analogInput, status), status);
|
||||
}
|
||||
|
||||
int32_t GetAveragedAnalogInputRaw(const AnalogInput* analogInput,
|
||||
int32_t* status) const {
|
||||
return HAL_GetDMASampleAveragedAnalogInputRaw(this, analogInput->m_port,
|
||||
status);
|
||||
}
|
||||
|
||||
double GetAveragedAnalogInputVoltage(const AnalogInput* analogInput,
|
||||
int32_t* status) {
|
||||
return HAL_GetAnalogValueToVolts(
|
||||
analogInput->m_port, GetAveragedAnalogInputRaw(analogInput, status),
|
||||
status);
|
||||
}
|
||||
|
||||
void GetAnalogAccumulator(const AnalogInput* analogInput, int64_t* count,
|
||||
int64_t* value, int32_t* status) const {
|
||||
return HAL_GetDMASampleAnalogAccumulator(this, analogInput->m_port, count,
|
||||
value, status);
|
||||
}
|
||||
|
||||
int32_t GetDutyCycleOutputRaw(const DutyCycle* dutyCycle,
|
||||
int32_t* status) const {
|
||||
return HAL_GetDMASampleDutyCycleOutputRaw(this, dutyCycle->m_handle,
|
||||
status);
|
||||
}
|
||||
|
||||
double GetDutyCycleOutput(const DutyCycle* dutyCycle, int32_t* status) {
|
||||
return GetDutyCycleOutputRaw(dutyCycle, status) /
|
||||
static_cast<double>(dutyCycle->GetOutputScaleFactor());
|
||||
}
|
||||
};
|
||||
|
||||
static_assert(std::is_pod_v<frc::DMASample>, "DMA Sample MUST Be POD");
|
||||
} // namespace frc
|
||||
@@ -18,6 +18,8 @@
|
||||
namespace frc {
|
||||
class DigitalSource;
|
||||
class AnalogTrigger;
|
||||
class DMA;
|
||||
class DMASample;
|
||||
|
||||
/**
|
||||
* Class to read a duty cycle PWM input.
|
||||
@@ -34,6 +36,8 @@ class DutyCycle : public ErrorBase,
|
||||
public Sendable,
|
||||
public SendableHelper<DutyCycle> {
|
||||
friend class AnalogTrigger;
|
||||
friend class DMA;
|
||||
friend class DMASample;
|
||||
|
||||
public:
|
||||
/**
|
||||
|
||||
@@ -23,6 +23,8 @@ namespace frc {
|
||||
class DigitalSource;
|
||||
class DigitalGlitchFilter;
|
||||
class SendableBuilder;
|
||||
class DMA;
|
||||
class DMASample;
|
||||
|
||||
/**
|
||||
* Class to read quad encoders.
|
||||
@@ -44,6 +46,9 @@ class Encoder : public ErrorBase,
|
||||
public PIDSource,
|
||||
public Sendable,
|
||||
public SendableHelper<Encoder> {
|
||||
friend class DMA;
|
||||
friend class DMASample;
|
||||
|
||||
public:
|
||||
enum IndexingType {
|
||||
kResetWhileHigh,
|
||||
|
||||
Reference in New Issue
Block a user