mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-26 01:51:41 +00:00
[hal] Add support for DMA to Java (#3158)
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
#include <type_traits>
|
||||
|
||||
#include "AnalogInternal.h"
|
||||
#include "ConstantsInternal.h"
|
||||
#include "DigitalInternal.h"
|
||||
#include "EncoderInternal.h"
|
||||
#include "HALInternal.h"
|
||||
@@ -103,19 +104,25 @@ HAL_DMAHandle HAL_InitializeDMA(int32_t* status) {
|
||||
return HAL_kInvalidHandle;
|
||||
}
|
||||
|
||||
dma->aDMA->writeConfig_ExternalClock(false, status);
|
||||
if (*status != 0) {
|
||||
dmaHandles->Free(handle);
|
||||
return HAL_kInvalidHandle;
|
||||
std::memset(&dma->captureStore, 0, sizeof(dma->captureStore));
|
||||
|
||||
tDMA::tConfig config;
|
||||
std::memset(&config, 0, sizeof(config));
|
||||
config.Pause = true;
|
||||
dma->aDMA->writeConfig(config, status);
|
||||
|
||||
dma->aDMA->writeRate(1, status);
|
||||
|
||||
tDMA::tExternalTriggers newTrigger;
|
||||
std::memset(&newTrigger, 0, sizeof(newTrigger));
|
||||
for (unsigned char reg = 0; reg < tDMA::kNumExternalTriggersRegisters;
|
||||
reg++) {
|
||||
for (unsigned char bit = 0; bit < tDMA::kNumExternalTriggersElements;
|
||||
bit++) {
|
||||
dma->aDMA->writeExternalTriggers(reg, bit, newTrigger, status);
|
||||
}
|
||||
}
|
||||
|
||||
HAL_SetDMARate(handle, 1, status);
|
||||
if (*status != 0) {
|
||||
dmaHandles->Free(handle);
|
||||
return HAL_kInvalidHandle;
|
||||
}
|
||||
|
||||
HAL_SetDMAPause(handle, false, status);
|
||||
return handle;
|
||||
}
|
||||
|
||||
@@ -139,20 +146,44 @@ void HAL_SetDMAPause(HAL_DMAHandle handle, HAL_Bool pause, int32_t* status) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!dma->manager) {
|
||||
*status = HAL_INVALID_DMA_STATE;
|
||||
return;
|
||||
}
|
||||
|
||||
dma->aDMA->writeConfig_Pause(pause, status);
|
||||
}
|
||||
void HAL_SetDMARate(HAL_DMAHandle handle, int32_t cycles, int32_t* status) {
|
||||
|
||||
void HAL_SetDMATimedTrigger(HAL_DMAHandle handle, double seconds,
|
||||
int32_t* status) {
|
||||
constexpr double baseMultipler = kSystemClockTicksPerMicrosecond * 1000000;
|
||||
uint32_t cycles = static_cast<uint32_t>(baseMultipler * seconds);
|
||||
HAL_SetDMATimedTriggerCycles(handle, cycles, status);
|
||||
}
|
||||
|
||||
void HAL_SetDMATimedTriggerCycles(HAL_DMAHandle handle, uint32_t cycles,
|
||||
int32_t* status) {
|
||||
auto dma = dmaHandles->Get(handle);
|
||||
if (!dma) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
if (dma->manager) {
|
||||
*status = HAL_INVALID_DMA_ADDITION;
|
||||
return;
|
||||
}
|
||||
|
||||
if (cycles < 1) {
|
||||
cycles = 1;
|
||||
}
|
||||
|
||||
dma->aDMA->writeRate(static_cast<uint32_t>(cycles), status);
|
||||
dma->aDMA->writeConfig_ExternalClock(false, status);
|
||||
if (*status != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
dma->aDMA->writeRate(cycles, status);
|
||||
}
|
||||
|
||||
void HAL_AddDMAEncoder(HAL_DMAHandle handle, HAL_EncoderHandle encoderHandle,
|
||||
@@ -477,20 +508,20 @@ void HAL_AddDMAAnalogAccumulator(HAL_DMAHandle handle,
|
||||
}
|
||||
}
|
||||
|
||||
void HAL_SetDMAExternalTrigger(HAL_DMAHandle handle,
|
||||
HAL_Handle digitalSourceHandle,
|
||||
HAL_AnalogTriggerType analogTriggerType,
|
||||
HAL_Bool rising, HAL_Bool falling,
|
||||
int32_t* status) {
|
||||
int32_t HAL_SetDMAExternalTrigger(HAL_DMAHandle handle,
|
||||
HAL_Handle digitalSourceHandle,
|
||||
HAL_AnalogTriggerType analogTriggerType,
|
||||
HAL_Bool rising, HAL_Bool falling,
|
||||
int32_t* status) {
|
||||
auto dma = dmaHandles->Get(handle);
|
||||
if (!dma) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (dma->manager) {
|
||||
*status = HAL_INVALID_DMA_ADDITION;
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int index = 0;
|
||||
@@ -504,21 +535,21 @@ void HAL_SetDMAExternalTrigger(HAL_DMAHandle handle,
|
||||
|
||||
if (index == 8) {
|
||||
*status = NO_AVAILABLE_RESOURCES;
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
dma->captureStore.triggerChannels |= (1 << index);
|
||||
|
||||
auto channelIndex = index;
|
||||
|
||||
auto isExternalClock = dma->aDMA->readConfig_ExternalClock(status);
|
||||
if (*status == 0 && !isExternalClock) {
|
||||
dma->aDMA->writeConfig_ExternalClock(true, status);
|
||||
if (*status != 0) {
|
||||
return;
|
||||
}
|
||||
} else if (*status != 0) {
|
||||
return;
|
||||
dma->aDMA->writeConfig_ExternalClock(true, status);
|
||||
if (*status != 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
dma->aDMA->writeRate(1, status);
|
||||
if (*status != 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t pin = 0;
|
||||
@@ -532,7 +563,7 @@ void HAL_SetDMAExternalTrigger(HAL_DMAHandle handle,
|
||||
hal::SetLastError(status,
|
||||
"Digital Source unabled to be mapped properly. Likely "
|
||||
"invalid handle passed.");
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
tDMA::tExternalTriggers newTrigger;
|
||||
@@ -544,6 +575,55 @@ void HAL_SetDMAExternalTrigger(HAL_DMAHandle handle,
|
||||
|
||||
dma->aDMA->writeExternalTriggers(channelIndex / 4, channelIndex % 4,
|
||||
newTrigger, status);
|
||||
return index;
|
||||
}
|
||||
|
||||
void HAL_ClearDMASensors(HAL_DMAHandle handle, int32_t* status) {
|
||||
auto dma = dmaHandles->Get(handle);
|
||||
if (!dma) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
if (dma->manager) {
|
||||
*status = HAL_INVALID_DMA_STATE;
|
||||
return;
|
||||
}
|
||||
|
||||
bool existingExternal = dma->aDMA->readConfig_ExternalClock(status);
|
||||
if (*status != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
tDMA::tConfig config;
|
||||
std::memset(&config, 0, sizeof(config));
|
||||
config.Pause = true;
|
||||
config.ExternalClock = existingExternal;
|
||||
dma->aDMA->writeConfig(config, status);
|
||||
}
|
||||
|
||||
void HAL_ClearDMAExternalTriggers(HAL_DMAHandle handle, int32_t* status) {
|
||||
auto dma = dmaHandles->Get(handle);
|
||||
if (!dma) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
if (dma->manager) {
|
||||
*status = HAL_INVALID_DMA_STATE;
|
||||
return;
|
||||
}
|
||||
|
||||
dma->captureStore.triggerChannels = 0;
|
||||
tDMA::tExternalTriggers newTrigger;
|
||||
std::memset(&newTrigger, 0, sizeof(newTrigger));
|
||||
for (unsigned char reg = 0; reg < tDMA::kNumExternalTriggersRegisters;
|
||||
reg++) {
|
||||
for (unsigned char bit = 0; bit < tDMA::kNumExternalTriggersElements;
|
||||
bit++) {
|
||||
dma->aDMA->writeExternalTriggers(reg, bit, newTrigger, status);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HAL_StartDMA(HAL_DMAHandle handle, int32_t queueDepth, int32_t* status) {
|
||||
@@ -554,7 +634,7 @@ void HAL_StartDMA(HAL_DMAHandle handle, int32_t queueDepth, int32_t* status) {
|
||||
}
|
||||
|
||||
if (dma->manager) {
|
||||
*status = INCOMPATIBLE_STATE;
|
||||
*status = HAL_INVALID_DMA_STATE;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -598,12 +678,15 @@ void HAL_StartDMA(HAL_DMAHandle handle, int32_t queueDepth, int32_t* status) {
|
||||
dma->captureStore.captureSize = accum_size + 1;
|
||||
}
|
||||
|
||||
dma->manager = std::make_unique<tDMAManager>(
|
||||
g_DMA_index, queueDepth * dma->captureStore.captureSize, status);
|
||||
uint32_t byteDepth = queueDepth * dma->captureStore.captureSize;
|
||||
|
||||
dma->manager = std::make_unique<tDMAManager>(g_DMA_index, byteDepth, status);
|
||||
if (*status != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
dma->aDMA->writeConfig_Pause(false, status);
|
||||
|
||||
dma->manager->start(status);
|
||||
dma->manager->stop(status);
|
||||
dma->manager->start(status);
|
||||
@@ -617,6 +700,8 @@ void HAL_StopDMA(HAL_DMAHandle handle, int32_t* status) {
|
||||
}
|
||||
|
||||
if (dma->manager) {
|
||||
dma->aDMA->writeConfig_Pause(true, status);
|
||||
*status = 0;
|
||||
dma->manager->stop(status);
|
||||
dma->manager = nullptr;
|
||||
}
|
||||
@@ -629,7 +714,7 @@ void* HAL_GetDMADirectPointer(HAL_DMAHandle handle) {
|
||||
|
||||
enum HAL_DMAReadStatus HAL_ReadDMADirect(void* dmaPointer,
|
||||
HAL_DMASample* dmaSample,
|
||||
int32_t timeoutMs,
|
||||
double timeoutSeconds,
|
||||
int32_t* remainingOut,
|
||||
int32_t* status) {
|
||||
DMA* dma = static_cast<DMA*>(dmaPointer);
|
||||
@@ -637,12 +722,13 @@ enum HAL_DMAReadStatus HAL_ReadDMADirect(void* dmaPointer,
|
||||
size_t remainingBytes = 0;
|
||||
|
||||
if (!dma->manager) {
|
||||
*status = INCOMPATIBLE_STATE;
|
||||
*status = HAL_INVALID_DMA_STATE;
|
||||
return HAL_DMA_ERROR;
|
||||
}
|
||||
|
||||
dma->manager->read(dmaSample->readBuffer, dma->captureStore.captureSize,
|
||||
timeoutMs, &remainingBytes, status);
|
||||
static_cast<uint32_t>(timeoutSeconds * 1000),
|
||||
&remainingBytes, status);
|
||||
|
||||
*remainingOut = remainingBytes / dma->captureStore.captureSize;
|
||||
|
||||
@@ -667,15 +753,16 @@ enum HAL_DMAReadStatus HAL_ReadDMADirect(void* dmaPointer,
|
||||
}
|
||||
|
||||
enum HAL_DMAReadStatus HAL_ReadDMA(HAL_DMAHandle handle,
|
||||
HAL_DMASample* dmaSample, int32_t timeoutMs,
|
||||
int32_t* remainingOut, int32_t* status) {
|
||||
HAL_DMASample* dmaSample,
|
||||
double timeoutSeconds, int32_t* remainingOut,
|
||||
int32_t* status) {
|
||||
auto dma = dmaHandles->Get(handle);
|
||||
if (!dma) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return HAL_DMA_ERROR;
|
||||
}
|
||||
|
||||
return HAL_ReadDMADirect(dma.get(), dmaSample, timeoutMs, remainingOut,
|
||||
return HAL_ReadDMADirect(dma.get(), dmaSample, timeoutSeconds, remainingOut,
|
||||
status);
|
||||
}
|
||||
|
||||
|
||||
@@ -165,9 +165,17 @@ bool remapDigitalSource(HAL_Handle digitalSourceHandle,
|
||||
}
|
||||
analogTrigger = false;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
} else if (isHandleType(digitalSourceHandle, HAL_HandleEnum::PWM)) {
|
||||
// PWM's on MXP port are supported as a digital source
|
||||
int32_t index = getHandleIndex(digitalSourceHandle);
|
||||
if (index >= kNumPWMHeaders) {
|
||||
channel = remapMXPPWMChannel(index);
|
||||
module = 1;
|
||||
analogTrigger = false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int32_t remapMXPChannel(int32_t channel) {
|
||||
|
||||
@@ -254,7 +254,7 @@ bool GetEncoderBaseHandle(HAL_EncoderHandle handle,
|
||||
HAL_FPGAEncoderHandle* fpgaHandle,
|
||||
HAL_CounterHandle* counterHandle) {
|
||||
auto encoder = encoderHandles->Get(handle);
|
||||
if (!handle) {
|
||||
if (!encoder) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -219,6 +219,10 @@ const char* HAL_GetErrorMessage(int32_t code) {
|
||||
return HAL_CAN_BUFFER_OVERRUN_MESSAGE;
|
||||
case HAL_LED_CHANNEL_ERROR:
|
||||
return HAL_LED_CHANNEL_ERROR_MESSAGE;
|
||||
case HAL_INVALID_DMA_STATE:
|
||||
return HAL_INVALID_DMA_STATE_MESSAGE;
|
||||
case HAL_INVALID_DMA_ADDITION:
|
||||
return HAL_INVALID_DMA_ADDITION_MESSAGE;
|
||||
case HAL_USE_LAST_ERROR:
|
||||
return HAL_USE_LAST_ERROR_MESSAGE;
|
||||
default:
|
||||
|
||||
@@ -296,6 +296,22 @@ Java_edu_wpi_first_hal_AnalogJNI_getAnalogVoltsToValue
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_hal_AnalogJNI
|
||||
* Method: getAnalogValueToVolts
|
||||
* Signature: (II)D
|
||||
*/
|
||||
JNIEXPORT jdouble JNICALL
|
||||
Java_edu_wpi_first_hal_AnalogJNI_getAnalogValueToVolts
|
||||
(JNIEnv* env, jclass, jint id, jint rawValue)
|
||||
{
|
||||
int32_t status = 0;
|
||||
jdouble returnValue =
|
||||
HAL_GetAnalogValueToVolts((HAL_AnalogInputHandle)id, rawValue, &status);
|
||||
CheckStatus(env, status);
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_hal_AnalogJNI
|
||||
* Method: getAnalogVoltage
|
||||
|
||||
416
hal/src/main/native/cpp/jni/DMAJNI.cpp
Normal file
416
hal/src/main/native/cpp/jni/DMAJNI.cpp
Normal file
@@ -0,0 +1,416 @@
|
||||
// Copyright (c) FIRST and other WPILib contributors.
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
|
||||
#include "HALUtil.h"
|
||||
#include "edu_wpi_first_hal_DMAJNI.h"
|
||||
#include "hal/DMA.h"
|
||||
#include "hal/handles/HandlesInternal.h"
|
||||
|
||||
using namespace hal;
|
||||
|
||||
namespace hal {
|
||||
bool GetEncoderBaseHandle(HAL_EncoderHandle handle,
|
||||
HAL_FPGAEncoderHandle* fpgaEncoderHandle,
|
||||
HAL_CounterHandle* counterHandle);
|
||||
} // namespace hal
|
||||
|
||||
extern "C" {
|
||||
/*
|
||||
* Class: edu_wpi_first_hal_DMAJNI
|
||||
* Method: initialize
|
||||
* Signature: ()I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_edu_wpi_first_hal_DMAJNI_initialize
|
||||
(JNIEnv* env, jclass)
|
||||
{
|
||||
int32_t status = 0;
|
||||
auto handle = HAL_InitializeDMA(&status);
|
||||
CheckStatusForceThrow(env, status);
|
||||
return handle;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_hal_DMAJNI
|
||||
* Method: free
|
||||
* Signature: (I)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL
|
||||
Java_edu_wpi_first_hal_DMAJNI_free
|
||||
(JNIEnv* env, jclass, jint handle)
|
||||
{
|
||||
HAL_FreeDMA(handle);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_hal_DMAJNI
|
||||
* Method: setPause
|
||||
* Signature: (IZ)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL
|
||||
Java_edu_wpi_first_hal_DMAJNI_setPause
|
||||
(JNIEnv* env, jclass, jint handle, jboolean pause)
|
||||
{
|
||||
int32_t status = 0;
|
||||
HAL_SetDMAPause(handle, pause, &status);
|
||||
CheckStatus(env, status);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_hal_DMAJNI
|
||||
* Method: setTimedTrigger
|
||||
* Signature: (ID)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL
|
||||
Java_edu_wpi_first_hal_DMAJNI_setTimedTrigger
|
||||
(JNIEnv* env, jclass, jint handle, jdouble seconds)
|
||||
{
|
||||
int32_t status = 0;
|
||||
HAL_SetDMATimedTrigger(handle, seconds, &status);
|
||||
CheckStatus(env, status);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_hal_DMAJNI
|
||||
* Method: setTimedTriggerCycles
|
||||
* Signature: (II)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL
|
||||
Java_edu_wpi_first_hal_DMAJNI_setTimedTriggerCycles
|
||||
(JNIEnv* env, jclass, jint handle, jint cycles)
|
||||
{
|
||||
int32_t status = 0;
|
||||
HAL_SetDMATimedTriggerCycles(handle, static_cast<uint32_t>(cycles), &status);
|
||||
CheckStatus(env, status);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_hal_DMAJNI
|
||||
* Method: addEncoder
|
||||
* Signature: (II)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL
|
||||
Java_edu_wpi_first_hal_DMAJNI_addEncoder
|
||||
(JNIEnv* env, jclass, jint handle, jint encoderHandle)
|
||||
{
|
||||
int32_t status = 0;
|
||||
HAL_AddDMAEncoder(handle, encoderHandle, &status);
|
||||
CheckStatus(env, status);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_hal_DMAJNI
|
||||
* Method: addEncoderPeriod
|
||||
* Signature: (II)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL
|
||||
Java_edu_wpi_first_hal_DMAJNI_addEncoderPeriod
|
||||
(JNIEnv* env, jclass, jint handle, jint encoderHandle)
|
||||
{
|
||||
int32_t status = 0;
|
||||
HAL_AddDMAEncoderPeriod(handle, encoderHandle, &status);
|
||||
CheckStatus(env, status);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_hal_DMAJNI
|
||||
* Method: addCounter
|
||||
* Signature: (II)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL
|
||||
Java_edu_wpi_first_hal_DMAJNI_addCounter
|
||||
(JNIEnv* env, jclass, jint handle, jint counterHandle)
|
||||
{
|
||||
int32_t status = 0;
|
||||
HAL_AddDMACounter(handle, counterHandle, &status);
|
||||
CheckStatus(env, status);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_hal_DMAJNI
|
||||
* Method: addCounterPeriod
|
||||
* Signature: (II)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL
|
||||
Java_edu_wpi_first_hal_DMAJNI_addCounterPeriod
|
||||
(JNIEnv* env, jclass, jint handle, jint counterHandle)
|
||||
{
|
||||
int32_t status = 0;
|
||||
HAL_AddDMACounterPeriod(handle, counterHandle, &status);
|
||||
CheckStatus(env, status);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_hal_DMAJNI
|
||||
* Method: addDutyCycle
|
||||
* Signature: (II)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL
|
||||
Java_edu_wpi_first_hal_DMAJNI_addDutyCycle
|
||||
(JNIEnv* env, jclass, jint handle, jint dutyCycleHandle)
|
||||
{
|
||||
int32_t status = 0;
|
||||
HAL_AddDMADutyCycle(handle, dutyCycleHandle, &status);
|
||||
CheckStatus(env, status);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_hal_DMAJNI
|
||||
* Method: addDigitalSource
|
||||
* Signature: (II)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL
|
||||
Java_edu_wpi_first_hal_DMAJNI_addDigitalSource
|
||||
(JNIEnv* env, jclass, jint handle, jint digitalSourceHandle)
|
||||
{
|
||||
int32_t status = 0;
|
||||
HAL_AddDMADigitalSource(handle, digitalSourceHandle, &status);
|
||||
CheckStatus(env, status);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_hal_DMAJNI
|
||||
* Method: addAnalogInput
|
||||
* Signature: (II)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL
|
||||
Java_edu_wpi_first_hal_DMAJNI_addAnalogInput
|
||||
(JNIEnv* env, jclass, jint handle, jint analogInputHandle)
|
||||
{
|
||||
int32_t status = 0;
|
||||
HAL_AddDMAAnalogInput(handle, analogInputHandle, &status);
|
||||
CheckStatus(env, status);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_hal_DMAJNI
|
||||
* Method: addAveragedAnalogInput
|
||||
* Signature: (II)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL
|
||||
Java_edu_wpi_first_hal_DMAJNI_addAveragedAnalogInput
|
||||
(JNIEnv* env, jclass, jint handle, jint analogInputHandle)
|
||||
{
|
||||
int32_t status = 0;
|
||||
HAL_AddDMAAveragedAnalogInput(handle, analogInputHandle, &status);
|
||||
CheckStatus(env, status);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_hal_DMAJNI
|
||||
* Method: addAnalogAccumulator
|
||||
* Signature: (II)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL
|
||||
Java_edu_wpi_first_hal_DMAJNI_addAnalogAccumulator
|
||||
(JNIEnv* env, jclass, jint handle, jint analogInputHandle)
|
||||
{
|
||||
int32_t status = 0;
|
||||
HAL_AddDMAAnalogAccumulator(handle, analogInputHandle, &status);
|
||||
CheckStatus(env, status);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_hal_DMAJNI
|
||||
* Method: setExternalTrigger
|
||||
* Signature: (IIIZZ)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_edu_wpi_first_hal_DMAJNI_setExternalTrigger
|
||||
(JNIEnv* env, jclass, jint handle, jint digitalSourceHandle,
|
||||
jint analogTriggerType, jboolean rising, jboolean falling)
|
||||
{
|
||||
int32_t status = 0;
|
||||
int32_t idx = HAL_SetDMAExternalTrigger(
|
||||
handle, digitalSourceHandle,
|
||||
static_cast<HAL_AnalogTriggerType>(analogTriggerType), rising, falling,
|
||||
&status);
|
||||
CheckStatus(env, status);
|
||||
return idx;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_hal_DMAJNI
|
||||
* Method: clearSensors
|
||||
* Signature: (I)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL
|
||||
Java_edu_wpi_first_hal_DMAJNI_clearSensors
|
||||
(JNIEnv* env, jclass, jint handle)
|
||||
{
|
||||
int32_t status = 0;
|
||||
HAL_ClearDMASensors(handle, &status);
|
||||
CheckStatus(env, status);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_hal_DMAJNI
|
||||
* Method: clearExternalTriggers
|
||||
* Signature: (I)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL
|
||||
Java_edu_wpi_first_hal_DMAJNI_clearExternalTriggers
|
||||
(JNIEnv* env, jclass, jint handle)
|
||||
{
|
||||
int32_t status = 0;
|
||||
HAL_ClearDMAExternalTriggers(handle, &status);
|
||||
CheckStatus(env, status);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_hal_DMAJNI
|
||||
* Method: startDMA
|
||||
* Signature: (II)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL
|
||||
Java_edu_wpi_first_hal_DMAJNI_startDMA
|
||||
(JNIEnv* env, jclass, jint handle, jint queueDepth)
|
||||
{
|
||||
int32_t status = 0;
|
||||
HAL_StartDMA(handle, queueDepth, &status);
|
||||
CheckStatus(env, status);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_hal_DMAJNI
|
||||
* Method: stopDMA
|
||||
* Signature: (I)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL
|
||||
Java_edu_wpi_first_hal_DMAJNI_stopDMA
|
||||
(JNIEnv* env, jclass, jint handle)
|
||||
{
|
||||
int32_t status = 0;
|
||||
HAL_StopDMA(handle, &status);
|
||||
CheckStatus(env, status);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_hal_DMAJNI
|
||||
* Method: readDMA
|
||||
* Signature: (ID[I[I)J
|
||||
*/
|
||||
JNIEXPORT jlong JNICALL
|
||||
Java_edu_wpi_first_hal_DMAJNI_readDMA
|
||||
(JNIEnv* env, jclass, jint handle, jdouble timeoutSeconds, jintArray buf,
|
||||
jintArray store)
|
||||
{
|
||||
int32_t status = 0;
|
||||
HAL_DMASample dmaSample;
|
||||
std::memset(&dmaSample, 0, sizeof(dmaSample));
|
||||
int32_t remaining = 0;
|
||||
HAL_DMAReadStatus readStatus =
|
||||
HAL_ReadDMA(handle, &dmaSample, timeoutSeconds, &remaining, &status);
|
||||
CheckStatus(env, status);
|
||||
|
||||
static_assert(sizeof(uint32_t) == sizeof(jint), "Java ints must be 32 bits");
|
||||
|
||||
env->SetIntArrayRegion(buf, 0, dmaSample.captureSize,
|
||||
reinterpret_cast<jint*>(dmaSample.readBuffer));
|
||||
|
||||
int32_t* nativeArr =
|
||||
static_cast<int32_t*>(env->GetPrimitiveArrayCritical(store, nullptr));
|
||||
|
||||
std::copy_n(
|
||||
dmaSample.channelOffsets,
|
||||
sizeof(dmaSample.channelOffsets) / sizeof(dmaSample.channelOffsets[0]),
|
||||
nativeArr);
|
||||
nativeArr[22] = static_cast<int32_t>(dmaSample.captureSize);
|
||||
nativeArr[23] = static_cast<int32_t>(dmaSample.triggerChannels);
|
||||
nativeArr[24] = remaining;
|
||||
nativeArr[25] = readStatus;
|
||||
|
||||
env->ReleasePrimitiveArrayCritical(store, nativeArr, JNI_ABORT);
|
||||
|
||||
return dmaSample.timeStamp;
|
||||
}
|
||||
|
||||
// TODO sync these up
|
||||
enum DMAOffsetConstants {
|
||||
kEnable_AI0_Low = 0,
|
||||
kEnable_AI0_High = 1,
|
||||
kEnable_AIAveraged0_Low = 2,
|
||||
kEnable_AIAveraged0_High = 3,
|
||||
kEnable_AI1_Low = 4,
|
||||
kEnable_AI1_High = 5,
|
||||
kEnable_AIAveraged1_Low = 6,
|
||||
kEnable_AIAveraged1_High = 7,
|
||||
kEnable_Accumulator0 = 8,
|
||||
kEnable_Accumulator1 = 9,
|
||||
kEnable_DI = 10,
|
||||
kEnable_AnalogTriggers = 11,
|
||||
kEnable_Counters_Low = 12,
|
||||
kEnable_Counters_High = 13,
|
||||
kEnable_CounterTimers_Low = 14,
|
||||
kEnable_CounterTimers_High = 15,
|
||||
kEnable_Encoders_Low = 16,
|
||||
kEnable_Encoders_High = 17,
|
||||
kEnable_EncoderTimers_Low = 18,
|
||||
kEnable_EncoderTimers_High = 19,
|
||||
kEnable_DutyCycle_Low = 20,
|
||||
kEnable_DutyCycle_High = 21,
|
||||
};
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_hal_DMAJNI
|
||||
* Method: getSensorReadData
|
||||
* Signature: (I)Ljava/lang/Object;
|
||||
*/
|
||||
JNIEXPORT jobject JNICALL
|
||||
Java_edu_wpi_first_hal_DMAJNI_getSensorReadData
|
||||
(JNIEnv* env, jclass, jint handle)
|
||||
{
|
||||
HAL_Handle halHandle = static_cast<HAL_Handle>(handle);
|
||||
|
||||
// Check for encoder/counter handle
|
||||
HAL_FPGAEncoderHandle fpgaEncoderHandle = 0;
|
||||
HAL_CounterHandle counterHandle = 0;
|
||||
bool validEncoderHandle =
|
||||
hal::GetEncoderBaseHandle(halHandle, &fpgaEncoderHandle, &counterHandle);
|
||||
|
||||
if (validEncoderHandle) {
|
||||
if (counterHandle != HAL_kInvalidHandle) {
|
||||
int32_t cindex = getHandleIndex(counterHandle);
|
||||
if (cindex < 4) {
|
||||
return CreateDMABaseStore(env, kEnable_Counters_Low, cindex);
|
||||
} else {
|
||||
return CreateDMABaseStore(env, kEnable_Counters_High, cindex - 4);
|
||||
}
|
||||
} else {
|
||||
int32_t cindex = getHandleIndex(fpgaEncoderHandle);
|
||||
if (cindex < 4) {
|
||||
return CreateDMABaseStore(env, kEnable_Encoders_Low, cindex);
|
||||
} else {
|
||||
return CreateDMABaseStore(env, kEnable_Encoders_High, cindex - 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HAL_HandleEnum handleType = getHandleType(halHandle);
|
||||
int32_t index = getHandleIndex(halHandle);
|
||||
if (handleType == HAL_HandleEnum::DIO) {
|
||||
return CreateDMABaseStore(env, kEnable_DI, index);
|
||||
} else if (handleType == HAL_HandleEnum::AnalogTrigger) {
|
||||
return CreateDMABaseStore(env, kEnable_AnalogTriggers, index);
|
||||
} else if (handleType == HAL_HandleEnum::AnalogInput) {
|
||||
if (index < 4) {
|
||||
return CreateDMABaseStore(env, kEnable_AI0_Low, index);
|
||||
} else {
|
||||
return CreateDMABaseStore(env, kEnable_AI0_High, index - 4);
|
||||
}
|
||||
} else if (handleType == HAL_HandleEnum::DutyCycle) {
|
||||
if (index < 4) {
|
||||
return CreateDMABaseStore(env, kEnable_DutyCycle_Low, index);
|
||||
} else {
|
||||
return CreateDMABaseStore(env, kEnable_DutyCycle_High, index - 4);
|
||||
}
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
@@ -46,6 +46,7 @@ static JClass matchInfoDataCls;
|
||||
static JClass accumulatorResultCls;
|
||||
static JClass canDataCls;
|
||||
static JClass halValueCls;
|
||||
static JClass baseStoreCls;
|
||||
|
||||
static const JClassInit classes[] = {
|
||||
{"edu/wpi/first/hal/PWMConfigDataResult", &pwmConfigDataResultCls},
|
||||
@@ -53,7 +54,8 @@ static const JClassInit classes[] = {
|
||||
{"edu/wpi/first/hal/MatchInfoData", &matchInfoDataCls},
|
||||
{"edu/wpi/first/hal/AccumulatorResult", &accumulatorResultCls},
|
||||
{"edu/wpi/first/hal/CANData", &canDataCls},
|
||||
{"edu/wpi/first/hal/HALValue", &halValueCls}};
|
||||
{"edu/wpi/first/hal/HALValue", &halValueCls},
|
||||
{"edu/wpi/first/hal/DMAJNISample$BaseStore", &baseStoreCls}};
|
||||
|
||||
static const JExceptionInit exceptions[] = {
|
||||
{"java/lang/IllegalArgumentException", &illegalArgExCls},
|
||||
@@ -305,6 +307,11 @@ jobject CreateHALValue(JNIEnv* env, const HAL_Value& value) {
|
||||
halValueCls, fromNative, static_cast<jint>(value.type), value1, value2);
|
||||
}
|
||||
|
||||
jobject CreateDMABaseStore(JNIEnv* env, jint valueType, jint index) {
|
||||
static jmethodID ctor = env->GetMethodID(baseStoreCls, "<init>", "(II)V");
|
||||
return env->NewObject(baseStoreCls, ctor, valueType, index);
|
||||
}
|
||||
|
||||
JavaVM* GetJVM() {
|
||||
return jvm;
|
||||
}
|
||||
|
||||
@@ -75,6 +75,8 @@ jbyteArray SetCANDataObject(JNIEnv* env, jobject canData, int32_t length,
|
||||
|
||||
jobject CreateHALValue(JNIEnv* env, const HAL_Value& value);
|
||||
|
||||
jobject CreateDMABaseStore(JNIEnv* env, jint valueType, jint index);
|
||||
|
||||
JavaVM* GetJVM();
|
||||
|
||||
} // namespace hal
|
||||
|
||||
@@ -62,7 +62,7 @@ void HAL_SetCounterAverageSize(HAL_CounterHandle counterHandle, int32_t size,
|
||||
*
|
||||
* @param counterHandle the counter handle
|
||||
* @param digitalSourceHandle the digital source handle (either a
|
||||
* HAL_AnalogTriggerHandle of a HAL_DigitalHandle)
|
||||
* HAL_AnalogTriggerHandle or a HAL_DigitalHandle)
|
||||
* @param analogTriggerType the analog trigger type if the source is an analog
|
||||
* trigger
|
||||
*/
|
||||
@@ -96,7 +96,7 @@ void HAL_ClearCounterUpSource(HAL_CounterHandle counterHandle, int32_t* status);
|
||||
*
|
||||
* @param counterHandle the counter handle
|
||||
* @param digitalSourceHandle the digital source handle (either a
|
||||
* HAL_AnalogTriggerHandle of a HAL_DigitalHandle)
|
||||
* HAL_AnalogTriggerHandle or a HAL_DigitalHandle)
|
||||
* @param analogTriggerType the analog trigger type if the source is an analog
|
||||
* trigger
|
||||
*/
|
||||
|
||||
@@ -4,22 +4,29 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "hal/AnalogTrigger.h"
|
||||
#include "hal/Types.h"
|
||||
|
||||
/**
|
||||
* @defgroup hal_dma DMA Functions
|
||||
* @ingroup hal_capi
|
||||
* @{
|
||||
*/
|
||||
|
||||
// clang-format off
|
||||
/**
|
||||
* The DMA Read Status.
|
||||
*/
|
||||
HAL_ENUM(HAL_DMAReadStatus ) {
|
||||
HAL_ENUM(HAL_DMAReadStatus) {
|
||||
HAL_DMA_OK = 1,
|
||||
HAL_DMA_TIMEOUT = 2,
|
||||
HAL_DMA_ERROR = 3,
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
/**
|
||||
* Buffer for containing all DMA data for a specific sample.
|
||||
*/
|
||||
struct HAL_DMASample {
|
||||
uint32_t readBuffer[74];
|
||||
int32_t channelOffsets[22];
|
||||
@@ -32,91 +39,380 @@ struct HAL_DMASample {
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Initializes an object for peforming DMA transfers.
|
||||
*
|
||||
* @return the created dma handle
|
||||
*/
|
||||
HAL_DMAHandle HAL_InitializeDMA(int32_t* status);
|
||||
|
||||
/**
|
||||
* Frees a DMA object.
|
||||
*
|
||||
* @param handle the dma handle
|
||||
*/
|
||||
void HAL_FreeDMA(HAL_DMAHandle handle);
|
||||
|
||||
/**
|
||||
* Pauses or unpauses a DMA transfer.
|
||||
*
|
||||
* This can only be called while DMA is running.
|
||||
*
|
||||
* @param handle the dma handle
|
||||
* @param pause true to pause transfers, false to resume.
|
||||
*/
|
||||
void HAL_SetDMAPause(HAL_DMAHandle handle, HAL_Bool pause, int32_t* status);
|
||||
void HAL_SetDMARate(HAL_DMAHandle handle, int32_t cycles, int32_t* status);
|
||||
|
||||
/**
|
||||
* Sets DMA transfers to occur at a specific timed interval.
|
||||
*
|
||||
* This will remove any external triggers. Only timed or external is supported.
|
||||
*
|
||||
* Only 1 timed period is supported.
|
||||
*
|
||||
* This can only be called if DMA is not started.
|
||||
*
|
||||
* @param handle the dma handle
|
||||
* @param periodSeconds the period to trigger in seconds
|
||||
*/
|
||||
void HAL_SetDMATimedTrigger(HAL_DMAHandle handle, double periodSeconds,
|
||||
int32_t* status);
|
||||
|
||||
/**
|
||||
* Sets DMA transfers to occur at a specific timed interval in FPGA cycles.
|
||||
*
|
||||
* This will remove any external triggers. Only timed or external is supported.
|
||||
*
|
||||
* Only 1 timed period is supported
|
||||
*
|
||||
* The FPGA currently runs at 40 MHz, but this can change.
|
||||
* HAL_GetSystemClockTicksPerMicrosecond can be used to get a computable value
|
||||
* for this.
|
||||
*
|
||||
* This can only be called if DMA is not started.
|
||||
*
|
||||
* @param handle the dma handle
|
||||
* @param cycles the period to trigger in FPGA cycles
|
||||
*/
|
||||
void HAL_SetDMATimedTriggerCycles(HAL_DMAHandle handle, uint32_t cycles,
|
||||
int32_t* status);
|
||||
|
||||
/**
|
||||
* Adds position data for an encoder to be collected by DMA.
|
||||
*
|
||||
* This can only be called if DMA is not started.
|
||||
*
|
||||
* @param handle the dma handle
|
||||
* @param encoderHandle the encoder to add
|
||||
*/
|
||||
void HAL_AddDMAEncoder(HAL_DMAHandle handle, HAL_EncoderHandle encoderHandle,
|
||||
int32_t* status);
|
||||
|
||||
/**
|
||||
* Adds timer data for an encoder to be collected by DMA.
|
||||
*
|
||||
* This can only be called if DMA is not started.
|
||||
*
|
||||
* @param handle the dma handle
|
||||
* @param encoderHandle the encoder to add
|
||||
*/
|
||||
void HAL_AddDMAEncoderPeriod(HAL_DMAHandle handle,
|
||||
HAL_EncoderHandle encoderHandle, int32_t* status);
|
||||
|
||||
/**
|
||||
* Adds position data for an counter to be collected by DMA.
|
||||
*
|
||||
* This can only be called if DMA is not started.
|
||||
*
|
||||
* @param handle the dma handle
|
||||
* @param counterHandle the counter to add
|
||||
*/
|
||||
void HAL_AddDMACounter(HAL_DMAHandle handle, HAL_CounterHandle counterHandle,
|
||||
int32_t* status);
|
||||
|
||||
/**
|
||||
* Adds timer data for an counter to be collected by DMA.
|
||||
*
|
||||
* @param handle the dma handle
|
||||
* @param counterHandle the counter to add
|
||||
*/
|
||||
void HAL_AddDMACounterPeriod(HAL_DMAHandle handle,
|
||||
HAL_CounterHandle counterHandle, int32_t* status);
|
||||
|
||||
/**
|
||||
* Adds a digital source to be collected by DMA.
|
||||
*
|
||||
* This can only be called if DMA is not started.
|
||||
*
|
||||
* @param handle the dma handle
|
||||
* @param digitalSourceHandle the digital source to add
|
||||
*/
|
||||
void HAL_AddDMADigitalSource(HAL_DMAHandle handle,
|
||||
HAL_Handle digitalSourceHandle, int32_t* status);
|
||||
|
||||
/**
|
||||
* Adds an analog input to be collected by DMA.
|
||||
*
|
||||
* This can only be called if DMA is not started.
|
||||
*
|
||||
* @param handle the dma handle
|
||||
* @param aInHandle the analog input to add
|
||||
*/
|
||||
void HAL_AddDMAAnalogInput(HAL_DMAHandle handle,
|
||||
HAL_AnalogInputHandle aInHandle, int32_t* status);
|
||||
|
||||
/**
|
||||
* Adds averaged data of an analog input to be collected by DMA.
|
||||
*
|
||||
* This can only be called if DMA is not started.
|
||||
*
|
||||
* @param handle the dma handle
|
||||
* @param aInHandle the analog input to add
|
||||
*/
|
||||
void HAL_AddDMAAveragedAnalogInput(HAL_DMAHandle handle,
|
||||
HAL_AnalogInputHandle aInHandle,
|
||||
int32_t* status);
|
||||
|
||||
/**
|
||||
* Adds acuumulator data of an analog input to be collected by DMA.
|
||||
*
|
||||
* This can only be called if DMA is not started.
|
||||
*
|
||||
* @param handle the dma handle
|
||||
* @param aInHandle the analog input to add
|
||||
*/
|
||||
void HAL_AddDMAAnalogAccumulator(HAL_DMAHandle handle,
|
||||
HAL_AnalogInputHandle aInHandle,
|
||||
int32_t* status);
|
||||
|
||||
/**
|
||||
* Adds a duty cycle input to be collected by DMA.
|
||||
*
|
||||
* This can only be called if DMA is not started.
|
||||
*
|
||||
* @param handle the dma handle
|
||||
* @param dutyCycleHandle the duty cycle input to add
|
||||
*/
|
||||
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);
|
||||
/**
|
||||
* Sets DMA transfers to occur on an external trigger.
|
||||
*
|
||||
* This will remove any timed trigger set. Only timed or external is supported.
|
||||
*
|
||||
* Up to 8 external triggers are currently supported.
|
||||
*
|
||||
* This can only be called if DMA is not started.
|
||||
*
|
||||
* @param handle the dma handle
|
||||
* @param digitalSourceHandle the digital source handle (either a
|
||||
* HAL_AnalogTriggerHandle or a HAL_DigitalHandle)
|
||||
* @param analogTriggerType the analog trigger type if the source is an analog
|
||||
* trigger
|
||||
* @param risingEdge true to trigger on rising
|
||||
* @param fallingEdge true to trigger on falling
|
||||
* @return the index of the trigger
|
||||
*/
|
||||
int32_t HAL_SetDMAExternalTrigger(HAL_DMAHandle handle,
|
||||
HAL_Handle digitalSourceHandle,
|
||||
HAL_AnalogTriggerType analogTriggerType,
|
||||
HAL_Bool rising, HAL_Bool falling,
|
||||
int32_t* status);
|
||||
|
||||
/**
|
||||
* Clear all sensors from the DMA collection list.
|
||||
*
|
||||
* This can only be called if DMA is not started.
|
||||
*
|
||||
* @param handle the dma handle
|
||||
*/
|
||||
void HAL_ClearDMASensors(HAL_DMAHandle handle, int32_t* status);
|
||||
|
||||
/**
|
||||
* Clear all external triggers from the DMA trigger list.
|
||||
*
|
||||
* This can only be called if DMA is not started.
|
||||
*
|
||||
* @param handle the dma handle
|
||||
*/
|
||||
void HAL_ClearDMAExternalTriggers(HAL_DMAHandle handle, int32_t* status);
|
||||
|
||||
/**
|
||||
* Starts DMA Collection.
|
||||
*
|
||||
* @param handle the dma handle
|
||||
* @param queueDepth the number of objects to be able to queue
|
||||
*/
|
||||
void HAL_StartDMA(HAL_DMAHandle handle, int32_t queueDepth, int32_t* status);
|
||||
|
||||
/**
|
||||
* Stops DMA Collection.
|
||||
*
|
||||
* @param handle the dma handle
|
||||
*/
|
||||
void HAL_StopDMA(HAL_DMAHandle handle, int32_t* status);
|
||||
|
||||
/**
|
||||
* Gets the direct pointer to the DMA object.
|
||||
*
|
||||
* This is only to be used if absolute maximum performance is required. This
|
||||
* will only be valid until the handle is freed.
|
||||
*
|
||||
* @param handle the dma handle
|
||||
*/
|
||||
void* HAL_GetDMADirectPointer(HAL_DMAHandle handle);
|
||||
|
||||
/**
|
||||
* Reads a DMA sample using a direct DMA pointer.
|
||||
*
|
||||
* See HAL_ReadDMA for full documentation.
|
||||
*
|
||||
* @param handle the dma handle
|
||||
*/
|
||||
enum HAL_DMAReadStatus HAL_ReadDMADirect(void* dmaPointer,
|
||||
HAL_DMASample* dmaSample,
|
||||
int32_t timeoutMs,
|
||||
double timeoutSeconds,
|
||||
int32_t* remainingOut,
|
||||
int32_t* status);
|
||||
|
||||
/**
|
||||
* Reads a DMA sample from the queue.
|
||||
*
|
||||
*
|
||||
* @param handle the dma handle
|
||||
* @param dmaSample the sample object to place data into
|
||||
* @param timeoutSeconds the time to wait for data to be queued before timing
|
||||
* out
|
||||
* @param remainingOut the number of samples remaining in the queue
|
||||
* @return the succes result of the sample read
|
||||
*/
|
||||
enum HAL_DMAReadStatus HAL_ReadDMA(HAL_DMAHandle handle,
|
||||
HAL_DMASample* dmaSample, int32_t timeoutMs,
|
||||
int32_t* remainingOut, int32_t* status);
|
||||
HAL_DMASample* dmaSample,
|
||||
double timeoutSeconds, int32_t* remainingOut,
|
||||
int32_t* status);
|
||||
|
||||
// Sampling Code
|
||||
// The following are helper functions for reading data from samples
|
||||
|
||||
/**
|
||||
* Returns the timestamp of the sample.
|
||||
* This is in the same time domain as HAL_GetFPGATime().
|
||||
*
|
||||
* @param dmaSample the sample to read from
|
||||
* @return timestamp in microseconds since FPGA Initialization
|
||||
*/
|
||||
uint64_t HAL_GetDMASampleTime(const HAL_DMASample* dmaSample, int32_t* status);
|
||||
|
||||
/**
|
||||
* Returns the raw distance data for an encoder from the sample.
|
||||
*
|
||||
* This can be scaled with DistancePerPulse and DecodingScaleFactor to match the
|
||||
* result of GetDistance()
|
||||
*
|
||||
* @param dmaSample the sample to read from
|
||||
* @param encoderHandle the encoder handle
|
||||
* @return raw encoder ticks
|
||||
*/
|
||||
int32_t HAL_GetDMASampleEncoderRaw(const HAL_DMASample* dmaSample,
|
||||
HAL_EncoderHandle encoderHandle,
|
||||
int32_t* status);
|
||||
|
||||
/**
|
||||
* Returns the distance data for an counter from the sample.
|
||||
*
|
||||
* @param dmaSample the sample to read from
|
||||
* @param counterHandle the counter handle
|
||||
* @return counter ticks
|
||||
*/
|
||||
int32_t HAL_GetDMASampleCounter(const HAL_DMASample* dmaSample,
|
||||
HAL_CounterHandle counterHandle,
|
||||
int32_t* status);
|
||||
|
||||
/**
|
||||
* Returns the raw period data for an encoder from the sample.
|
||||
*
|
||||
* This can be scaled with DistancePerPulse and DecodingScaleFactor to match the
|
||||
* result of GetRate()
|
||||
*
|
||||
* @param dmaSample the sample to read from
|
||||
* @param encoderHandle the encoder handle
|
||||
* @return raw encoder period
|
||||
*/
|
||||
int32_t HAL_GetDMASampleEncoderPeriodRaw(const HAL_DMASample* dmaSample,
|
||||
HAL_EncoderHandle encoderHandle,
|
||||
int32_t* status);
|
||||
|
||||
/**
|
||||
* Returns the period data for an counter from the sample.
|
||||
*
|
||||
* @param dmaSample the sample to read from
|
||||
* @param counterHandle the counter handle
|
||||
* @return counter period
|
||||
*/
|
||||
int32_t HAL_GetDMASampleCounterPeriod(const HAL_DMASample* dmaSample,
|
||||
HAL_CounterHandle counterHandle,
|
||||
int32_t* status);
|
||||
|
||||
/**
|
||||
* Returns the state of a digital source from the sample.
|
||||
*
|
||||
* @param dmaSample the sample to read from
|
||||
* @param dSourceHandle the digital source handle
|
||||
* @return digital source state
|
||||
*/
|
||||
HAL_Bool HAL_GetDMASampleDigitalSource(const HAL_DMASample* dmaSample,
|
||||
HAL_Handle dSourceHandle,
|
||||
int32_t* status);
|
||||
|
||||
/**
|
||||
* Returns the raw analog data for an analog input from the sample.
|
||||
*
|
||||
* This can be scaled with HAL_GetAnalogValueToVolts to match GetVoltage().
|
||||
*
|
||||
* @param dmaSample the sample to read from
|
||||
* @param aInHandle the analog input handle
|
||||
* @return raw analog data
|
||||
*/
|
||||
int32_t HAL_GetDMASampleAnalogInputRaw(const HAL_DMASample* dmaSample,
|
||||
HAL_AnalogInputHandle aInHandle,
|
||||
int32_t* status);
|
||||
|
||||
/**
|
||||
* Returns the raw averaged analog data for an analog input from the sample.
|
||||
*
|
||||
* This can be scaled with HAL_GetAnalogValueToVolts to match
|
||||
* GetAveragedVoltage().
|
||||
*
|
||||
* @param dmaSample the sample to read from
|
||||
* @param aInHandle the analog input handle
|
||||
* @return raw averaged analog data
|
||||
*/
|
||||
int32_t HAL_GetDMASampleAveragedAnalogInputRaw(const HAL_DMASample* dmaSample,
|
||||
HAL_AnalogInputHandle aInHandle,
|
||||
int32_t* status);
|
||||
|
||||
/**
|
||||
* Returns the analog accumulator data for an analog input from the sample.
|
||||
*
|
||||
* @param dmaSample the sample to read from
|
||||
* @param aInHandle the analog input handle
|
||||
* @param count the accumulator count
|
||||
* @param value the accumulator value
|
||||
*/
|
||||
void HAL_GetDMASampleAnalogAccumulator(const HAL_DMASample* dmaSample,
|
||||
HAL_AnalogInputHandle aInHandle,
|
||||
int64_t* count, int64_t* value,
|
||||
int32_t* status);
|
||||
|
||||
/**
|
||||
* Returns the raw duty cycle input ratio data from the sample.
|
||||
*
|
||||
* Use HAL_GetDutyCycleOutputScaleFactor to scale this to a percentage.
|
||||
*
|
||||
* @param dmaSample the sample to read from
|
||||
* @param dutyCycleHandle the duty cycle handle
|
||||
* @return raw duty cycle input data
|
||||
*/
|
||||
int32_t HAL_GetDMASampleDutyCycleOutputRaw(const HAL_DMASample* dmaSample,
|
||||
HAL_DutyCycleHandle dutyCycleHandle,
|
||||
int32_t* status);
|
||||
@@ -124,3 +420,4 @@ int32_t HAL_GetDMASampleDutyCycleOutputRaw(const HAL_DMASample* dmaSample,
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
@@ -254,7 +254,7 @@ int32_t HAL_GetEncoderSamplesToAverage(HAL_EncoderHandle encoderHandle,
|
||||
*
|
||||
* @param encoderHandle the encoder handle
|
||||
* @param digitalSourceHandle the index source handle (either a
|
||||
* HAL_AnalogTriggerHandle of a HAL_DigitalHandle)
|
||||
* HAL_AnalogTriggerHandle or a HAL_DigitalHandle)
|
||||
* @param analogTriggerType the analog trigger type if the source is an analog
|
||||
* trigger
|
||||
* @param type the index triggering type
|
||||
|
||||
@@ -101,6 +101,10 @@
|
||||
#define HAL_INVALID_DMA_ADDITION_MESSAGE \
|
||||
"HAL_AddDMA() only works before HAL_StartDMA()"
|
||||
|
||||
#define HAL_INVALID_DMA_STATE -1103
|
||||
#define HAL_INVALID_DMA_STATE_MESSAGE \
|
||||
"HAL_SetPause() 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"
|
||||
|
||||
@@ -78,7 +78,7 @@ int64_t HAL_ReadInterruptFallingTimestamp(HAL_InterruptHandle interruptHandle,
|
||||
*
|
||||
* @param interruptHandle the interrupt handle
|
||||
* @param digitalSourceHandle the digital source handle (either a
|
||||
* HAL_AnalogTriggerHandle of a HAL_DigitalHandle)
|
||||
* HAL_AnalogTriggerHandle or a HAL_DigitalHandle)
|
||||
* @param analogTriggerType the trigger type if the source is an AnalogTrigger
|
||||
*/
|
||||
void HAL_RequestInterrupts(HAL_InterruptHandle interruptHandle,
|
||||
|
||||
@@ -11,7 +11,10 @@ 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_SetDMATimedTrigger(HAL_DMAHandle handle, double periodSeconds,
|
||||
int32_t* status) {}
|
||||
void HAL_SetDMATimedTriggerCycles(HAL_DMAHandle handle, uint32_t cycles,
|
||||
int32_t* status) {}
|
||||
|
||||
void HAL_AddDMAEncoder(HAL_DMAHandle handle, HAL_EncoderHandle encoderHandle,
|
||||
int32_t* status) {}
|
||||
@@ -40,11 +43,16 @@ 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) {}
|
||||
int32_t HAL_SetDMAExternalTrigger(HAL_DMAHandle handle,
|
||||
HAL_Handle digitalSourceHandle,
|
||||
HAL_AnalogTriggerType analogTriggerType,
|
||||
HAL_Bool rising, HAL_Bool falling,
|
||||
int32_t* status) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void HAL_ClearDMASensors(HAL_DMAHandle handle, int32_t* status) {}
|
||||
void HAL_ClearDMAExternalTriggers(HAL_DMAHandle handle, int32_t* status) {}
|
||||
|
||||
void HAL_StartDMA(HAL_DMAHandle handle, int32_t queueDepth, int32_t* status) {}
|
||||
void HAL_StopDMA(HAL_DMAHandle handle, int32_t* status) {}
|
||||
@@ -55,15 +63,16 @@ void* HAL_GetDMADirectPointer(HAL_DMAHandle handle) {
|
||||
|
||||
enum HAL_DMAReadStatus HAL_ReadDMADirect(void* dmaPointer,
|
||||
HAL_DMASample* dmaSample,
|
||||
int32_t timeoutMs,
|
||||
double timeoutSeconds,
|
||||
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) {
|
||||
HAL_DMASample* dmaSample,
|
||||
double timeoutSeconds, int32_t* remainingOut,
|
||||
int32_t* status) {
|
||||
return HAL_DMA_ERROR;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,8 @@ using namespace hal;
|
||||
namespace {
|
||||
struct Encoder {
|
||||
HAL_Handle nativeHandle;
|
||||
HAL_FPGAEncoderHandle fpgaHandle;
|
||||
HAL_CounterHandle counterHandle;
|
||||
HAL_EncoderEncodingType encodingType;
|
||||
double distancePerPulse;
|
||||
uint8_t index;
|
||||
@@ -46,6 +48,21 @@ void InitializeEncoder() {
|
||||
}
|
||||
} // namespace hal::init
|
||||
|
||||
namespace hal {
|
||||
bool GetEncoderBaseHandle(HAL_EncoderHandle handle,
|
||||
HAL_FPGAEncoderHandle* fpgaHandle,
|
||||
HAL_CounterHandle* counterHandle) {
|
||||
auto encoder = encoderHandles->Get(handle);
|
||||
if (!handle) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*fpgaHandle = encoder->fpgaHandle;
|
||||
*counterHandle = encoder->counterHandle;
|
||||
return true;
|
||||
}
|
||||
} // namespace hal
|
||||
|
||||
extern "C" {
|
||||
HAL_EncoderHandle HAL_InitializeEncoder(
|
||||
HAL_Handle digitalSourceHandleA, HAL_AnalogTriggerType analogTriggerTypeA,
|
||||
@@ -86,6 +103,13 @@ HAL_EncoderHandle HAL_InitializeEncoder(
|
||||
encoder->nativeHandle = nativeHandle;
|
||||
encoder->encodingType = encodingType;
|
||||
encoder->distancePerPulse = 1.0;
|
||||
if (encodingType == HAL_EncoderEncodingType::HAL_Encoder_k4X) {
|
||||
encoder->fpgaHandle = nativeHandle;
|
||||
encoder->counterHandle = HAL_kInvalidHandle;
|
||||
} else {
|
||||
encoder->fpgaHandle = HAL_kInvalidHandle;
|
||||
encoder->counterHandle = nativeHandle;
|
||||
}
|
||||
return handle;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user