mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-30 02:31:44 +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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user