Files
allwpilib/hal/src/main/native/athena/InterruptManager.cpp
Thad House ad53fb19b4 [hal] Use new HMB api for addressable LED (#4479)
Theres is now a built in HMB api, but you have to dlopen it to access it. Moved our existing infrastructure for this to its own class, added the new functions, then updated interrupts and LEDs to use it.
2022-10-24 18:26:07 -07:00

73 lines
2.0 KiB
C++

// 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 "hal/roborio/InterruptManager.h"
#include <fmt/format.h>
#include "FPGACalls.h"
#include "HALInternal.h"
#include "dlfcn.h"
#include "hal/Errors.h"
using namespace hal;
InterruptManager& InterruptManager::GetInstance() {
static InterruptManager manager;
return manager;
}
void InterruptManager::Initialize(tSystemInterface* baseSystem) {
auto& manager = GetInstance();
manager.fpgaSession = baseSystem->getHandle();
}
NiFpga_IrqContext InterruptManager::GetContext() noexcept {
NiFpga_IrqContext context;
HAL_NiFpga_ReserveIrqContext(fpgaSession, &context);
return context;
}
void InterruptManager::ReleaseContext(NiFpga_IrqContext context) noexcept {
HAL_NiFpga_UnreserveIrqContext(fpgaSession, context);
}
uint32_t InterruptManager::WaitForInterrupt(NiFpga_IrqContext context,
uint32_t mask, bool ignorePrevious,
uint32_t timeoutMs,
int32_t* status) {
{
// Make sure we can safely use this
std::scoped_lock lock(currentMaskMutex);
if ((currentMask & mask) != 0) {
*status = PARAMETER_OUT_OF_RANGE;
hal::SetLastError(
status, fmt::format("Interrupt mask {} has bits {} already in use",
mask, (currentMask & mask)));
return 0;
}
currentMask |= mask;
}
if (ignorePrevious) {
HAL_NiFpga_AcknowledgeIrqs(fpgaSession, mask);
}
uint32_t irqsAsserted = 0;
NiFpga_Bool timedOut = 0;
*status = HAL_NiFpga_WaitOnIrqs(fpgaSession, context, mask, timeoutMs,
&irqsAsserted, &timedOut);
if (!timedOut) {
HAL_NiFpga_AcknowledgeIrqs(fpgaSession, irqsAsserted);
}
{
std::scoped_lock lock(currentMaskMutex);
currentMask &= ~mask;
}
return irqsAsserted;
}