[hal, wpilib] Update Addressable LED support (#8100)

This commit is contained in:
Peter Johnson
2025-07-21 21:52:10 -07:00
committed by GitHub
parent 8aa312fb6f
commit f3af50fc8e
40 changed files with 857 additions and 1104 deletions

View File

@@ -4,6 +4,8 @@
#include "frc/AddressableLED.h"
#include <algorithm>
#include <hal/AddressableLED.h>
#include <hal/HALBase.h>
#include <hal/PWM.h>
@@ -12,39 +14,39 @@
#include <wpi/StackTrace.h>
#include "frc/Errors.h"
#include "frc/SensorUtil.h"
using namespace frc;
AddressableLED::AddressableLED(int port) : m_port{port} {
AddressableLED::AddressableLED(int channel) : m_channel{channel} {
if (!SensorUtil::CheckDigitalChannel(channel)) {
throw FRC_MakeError(err::ChannelIndexOutOfRange, "Channel {}", channel);
}
int32_t status = 0;
auto stack = wpi::GetStackTrace(1);
m_pwmHandle = HAL_InitializePWMPort(port, stack.c_str(), &status);
FRC_CheckErrorStatus(status, "Port {}", port);
if (m_pwmHandle == HAL_kInvalidHandle) {
return;
}
m_handle = HAL_InitializeAddressableLED(channel, stack.c_str(), &status);
FRC_CheckErrorStatus(status, "Channel {}", channel);
m_handle = HAL_InitializeAddressableLED(m_pwmHandle, &status);
FRC_CheckErrorStatus(status, "Port {}", port);
if (m_handle == HAL_kInvalidHandle) {
HAL_FreePWMPort(m_pwmHandle);
}
HAL_ReportUsage("IO", port, "AddressableLED");
HAL_ReportUsage("IO", channel, "AddressableLED");
}
void AddressableLED::SetColorOrder(AddressableLED::ColorOrder order) {
m_colorOrder = order;
}
void AddressableLED::SetStart(int start) {
m_start = start;
int32_t status = 0;
HAL_SetAddressableLEDColorOrder(
m_handle, static_cast<HAL_AddressableLEDColorOrder>(order), &status);
FRC_CheckErrorStatus(status, "Port {} Color order {}", m_port, order);
HAL_SetAddressableLEDStart(m_handle, start, &status);
FRC_CheckErrorStatus(status, "Channel {} start {}", m_channel, start);
}
void AddressableLED::SetLength(int length) {
m_length = length;
int32_t status = 0;
HAL_SetAddressableLEDLength(m_handle, length, &status);
FRC_CheckErrorStatus(status, "Port {} length {}", m_port, length);
FRC_CheckErrorStatus(status, "Channel {} length {}", m_channel, length);
}
static_assert(sizeof(AddressableLED::LEDData) == sizeof(HAL_AddressableLEDData),
@@ -52,45 +54,25 @@ static_assert(sizeof(AddressableLED::LEDData) == sizeof(HAL_AddressableLEDData),
void AddressableLED::SetData(std::span<const LEDData> ledData) {
int32_t status = 0;
HAL_WriteAddressableLEDData(m_handle, ledData.data(), ledData.size(),
&status);
FRC_CheckErrorStatus(status, "Port {}", m_port);
HAL_SetAddressableLEDData(
m_start, std::min(static_cast<size_t>(m_length), ledData.size()),
static_cast<HAL_AddressableLEDColorOrder>(m_colorOrder), ledData.data(),
&status);
FRC_CheckErrorStatus(status, "Port {}", m_channel);
}
void AddressableLED::SetData(std::initializer_list<LEDData> ledData) {
int32_t status = 0;
HAL_WriteAddressableLEDData(m_handle, ledData.begin(), ledData.size(),
&status);
FRC_CheckErrorStatus(status, "Port {}", m_port);
SetData(std::span{ledData.begin(), ledData.end()});
}
void AddressableLED::SetBitTiming(units::nanosecond_t highTime0,
units::nanosecond_t lowTime0,
units::nanosecond_t highTime1,
units::nanosecond_t lowTime1) {
void AddressableLED::SetGlobalData(int start, ColorOrder colorOrder,
std::span<const LEDData> ledData) {
int32_t status = 0;
HAL_SetAddressableLEDBitTiming(
m_handle, highTime0.to<int32_t>(), lowTime0.to<int32_t>(),
highTime1.to<int32_t>(), lowTime1.to<int32_t>(), &status);
FRC_CheckErrorStatus(status, "Port {}", m_port);
}
void AddressableLED::SetSyncTime(units::microsecond_t syncTime) {
int32_t status = 0;
HAL_SetAddressableLEDSyncTime(m_handle, syncTime.to<int32_t>(), &status);
FRC_CheckErrorStatus(status, "Port {}", m_port);
}
void AddressableLED::Start() {
int32_t status = 0;
HAL_StartAddressableLEDOutput(m_handle, &status);
FRC_CheckErrorStatus(status, "Port {}", m_port);
}
void AddressableLED::Stop() {
int32_t status = 0;
HAL_StopAddressableLEDOutput(m_handle, &status);
FRC_CheckErrorStatus(status, "Port {}", m_port);
HAL_SetAddressableLEDData(
start, ledData.size(),
static_cast<HAL_AddressableLEDColorOrder>(colorOrder), ledData.data(),
&status);
FRC_CheckErrorStatus(status, "");
}
void AddressableLED::LEDData::SetHSV(int h, int s, int v) {

View File

@@ -9,108 +9,90 @@
#include <hal/simulation/AddressableLEDData.h>
#include "frc/AddressableLED.h"
using namespace frc;
using namespace frc::sim;
AddressableLEDSim::AddressableLEDSim() : m_index{0} {}
AddressableLEDSim::AddressableLEDSim(int channel) : m_channel{channel} {}
AddressableLEDSim::AddressableLEDSim(const AddressableLED& addressableLED)
: m_index{0} {}
AddressableLEDSim AddressableLEDSim::CreateForChannel(int pwmChannel) {
int index = HALSIM_FindAddressableLEDForChannel(pwmChannel);
if (index < 0) {
throw std::out_of_range("no addressable LED found for PWM channel");
}
return AddressableLEDSim{index};
}
AddressableLEDSim AddressableLEDSim::CreateForIndex(int index) {
return AddressableLEDSim{index};
}
: m_channel{addressableLED.GetChannel()} {}
std::unique_ptr<CallbackStore> AddressableLEDSim::RegisterInitializedCallback(
NotifyCallback callback, bool initialNotify) {
auto store = std::make_unique<CallbackStore>(
m_index, -1, callback, &HALSIM_CancelAddressableLEDInitializedCallback);
m_channel, -1, callback, &HALSIM_CancelAddressableLEDInitializedCallback);
store->SetUid(HALSIM_RegisterAddressableLEDInitializedCallback(
m_index, &CallbackStoreThunk, store.get(), initialNotify));
m_channel, &CallbackStoreThunk, store.get(), initialNotify));
return store;
}
bool AddressableLEDSim::GetInitialized() const {
return HALSIM_GetAddressableLEDInitialized(m_index);
return HALSIM_GetAddressableLEDInitialized(m_channel);
}
void AddressableLEDSim::SetInitialized(bool initialized) {
HALSIM_SetAddressableLEDInitialized(m_index, initialized);
HALSIM_SetAddressableLEDInitialized(m_channel, initialized);
}
std::unique_ptr<CallbackStore> AddressableLEDSim::RegisterOutputPortCallback(
std::unique_ptr<CallbackStore> AddressableLEDSim::RegisterStartCallback(
NotifyCallback callback, bool initialNotify) {
auto store = std::make_unique<CallbackStore>(
m_index, -1, callback, &HALSIM_CancelAddressableLEDOutputPortCallback);
store->SetUid(HALSIM_RegisterAddressableLEDOutputPortCallback(
m_index, &CallbackStoreThunk, store.get(), initialNotify));
m_channel, -1, callback, &HALSIM_CancelAddressableLEDStartCallback);
store->SetUid(HALSIM_RegisterAddressableLEDStartCallback(
m_channel, &CallbackStoreThunk, store.get(), initialNotify));
return store;
}
int AddressableLEDSim::GetOutputPort() const {
return HALSIM_GetAddressableLEDOutputPort(m_index);
int AddressableLEDSim::GetStart() const {
return HALSIM_GetAddressableLEDStart(m_channel);
}
void AddressableLEDSim::SetOutputPort(int outputPort) {
HALSIM_SetAddressableLEDOutputPort(m_index, outputPort);
void AddressableLEDSim::SetStart(int start) {
HALSIM_SetAddressableLEDStart(m_channel, start);
}
std::unique_ptr<CallbackStore> AddressableLEDSim::RegisterLengthCallback(
NotifyCallback callback, bool initialNotify) {
auto store = std::make_unique<CallbackStore>(
m_index, -1, callback, &HALSIM_CancelAddressableLEDLengthCallback);
m_channel, -1, callback, &HALSIM_CancelAddressableLEDLengthCallback);
store->SetUid(HALSIM_RegisterAddressableLEDLengthCallback(
m_index, &CallbackStoreThunk, store.get(), initialNotify));
m_channel, &CallbackStoreThunk, store.get(), initialNotify));
return store;
}
int AddressableLEDSim::GetLength() const {
return HALSIM_GetAddressableLEDLength(m_index);
return HALSIM_GetAddressableLEDLength(m_channel);
}
void AddressableLEDSim::SetLength(int length) {
HALSIM_SetAddressableLEDLength(m_index, length);
HALSIM_SetAddressableLEDLength(m_channel, length);
}
std::unique_ptr<CallbackStore> AddressableLEDSim::RegisterRunningCallback(
NotifyCallback callback, bool initialNotify) {
auto store = std::make_unique<CallbackStore>(
m_index, -1, callback, &HALSIM_CancelAddressableLEDRunningCallback);
store->SetUid(HALSIM_RegisterAddressableLEDRunningCallback(
m_index, &CallbackStoreThunk, store.get(), initialNotify));
return store;
int AddressableLEDSim::GetData(struct HAL_AddressableLEDData* data) const {
return GetGlobalData(GetStart(), GetLength(), data);
}
int AddressableLEDSim::GetRunning() const {
return HALSIM_GetAddressableLEDRunning(m_index);
}
void AddressableLEDSim::SetRunning(bool running) {
HALSIM_SetAddressableLEDRunning(m_index, running);
void AddressableLEDSim::SetData(struct HAL_AddressableLEDData* data) {
SetGlobalData(GetStart(), GetLength(), data);
}
std::unique_ptr<CallbackStore> AddressableLEDSim::RegisterDataCallback(
ConstBufferCallback callback, bool initialNotify) {
auto store = std::make_unique<CallbackStore>(
m_index, -1, callback, &HALSIM_CancelAddressableLEDDataCallback);
-1, callback, &HALSIM_CancelAddressableLEDDataCallback);
store->SetUid(HALSIM_RegisterAddressableLEDDataCallback(
m_index, &ConstBufferCallbackStoreThunk, store.get()));
&ConstBufferCallbackStoreThunk, store.get()));
return store;
}
int AddressableLEDSim::GetData(struct HAL_AddressableLEDData* data) const {
return HALSIM_GetAddressableLEDData(m_index, data);
int AddressableLEDSim::GetGlobalData(int start, int length,
struct HAL_AddressableLEDData* data) {
return HALSIM_GetAddressableLEDData(start, length, data);
}
void AddressableLEDSim::SetData(struct HAL_AddressableLEDData* data,
int length) {
HALSIM_SetAddressableLEDData(m_index, data, length);
void AddressableLEDSim::SetGlobalData(int start, int length,
struct HAL_AddressableLEDData* data) {
HALSIM_SetAddressableLEDData(start, length, data);
}