blob: 538dc102b633cd599c72f8f3d75d22ba9ecfb3ae [file] [log] [blame]
Austin Schuh812d0d12021-11-04 20:16:48 -07001// Copyright (c) FIRST and other WPILib contributors.
2// Open Source Software; you can modify and/or share it under the terms of
3// the WPILib BSD license file in the root directory of this project.
Brian Silverman8fce7482020-01-05 13:18:21 -08004
5#include "frc/AddressableLED.h"
6
7#include <hal/AddressableLED.h>
8#include <hal/FRCUsageReporting.h>
9#include <hal/HALBase.h>
10#include <hal/PWM.h>
11#include <hal/Ports.h>
Austin Schuh812d0d12021-11-04 20:16:48 -070012#include <wpi/StackTrace.h>
Brian Silverman8fce7482020-01-05 13:18:21 -080013
Austin Schuh812d0d12021-11-04 20:16:48 -070014#include "frc/Errors.h"
Brian Silverman8fce7482020-01-05 13:18:21 -080015
16using namespace frc;
17
Austin Schuh812d0d12021-11-04 20:16:48 -070018AddressableLED::AddressableLED(int port) : m_port{port} {
Brian Silverman8fce7482020-01-05 13:18:21 -080019 int32_t status = 0;
20
Austin Schuh812d0d12021-11-04 20:16:48 -070021 auto stack = wpi::GetStackTrace(1);
22 m_pwmHandle =
23 HAL_InitializePWMPort(HAL_GetPort(port), stack.c_str(), &status);
24 FRC_CheckErrorStatus(status, "Port {}", port);
Brian Silverman8fce7482020-01-05 13:18:21 -080025 if (m_pwmHandle == HAL_kInvalidHandle) {
26 return;
27 }
28
29 m_handle = HAL_InitializeAddressableLED(m_pwmHandle, &status);
Austin Schuh812d0d12021-11-04 20:16:48 -070030 FRC_CheckErrorStatus(status, "Port {}", port);
Brian Silverman8fce7482020-01-05 13:18:21 -080031 if (m_handle == HAL_kInvalidHandle) {
32 HAL_FreePWMPort(m_pwmHandle, &status);
33 }
34
35 HAL_Report(HALUsageReporting::kResourceType_AddressableLEDs, port + 1);
36}
37
38AddressableLED::~AddressableLED() {
39 HAL_FreeAddressableLED(m_handle);
40 int32_t status = 0;
41 HAL_FreePWMPort(m_pwmHandle, &status);
Austin Schuh812d0d12021-11-04 20:16:48 -070042 FRC_ReportError(status, "Port {}", m_port);
Brian Silverman8fce7482020-01-05 13:18:21 -080043}
44
45void AddressableLED::SetLength(int length) {
46 int32_t status = 0;
47 HAL_SetAddressableLEDLength(m_handle, length, &status);
Austin Schuh812d0d12021-11-04 20:16:48 -070048 FRC_CheckErrorStatus(status, "Port {} length {}", m_port, length);
Brian Silverman8fce7482020-01-05 13:18:21 -080049}
50
51static_assert(sizeof(AddressableLED::LEDData) == sizeof(HAL_AddressableLEDData),
52 "LED Structs MUST be the same size");
53
James Kuszmaulcf324122023-01-14 14:07:17 -080054void AddressableLED::SetData(std::span<const LEDData> ledData) {
Brian Silverman8fce7482020-01-05 13:18:21 -080055 int32_t status = 0;
James Kuszmaulcf324122023-01-14 14:07:17 -080056 HAL_WriteAddressableLEDData(m_handle, ledData.data(), ledData.size(),
Brian Silverman8fce7482020-01-05 13:18:21 -080057 &status);
Austin Schuh812d0d12021-11-04 20:16:48 -070058 FRC_CheckErrorStatus(status, "Port {}", m_port);
Brian Silverman8fce7482020-01-05 13:18:21 -080059}
60
61void AddressableLED::SetData(std::initializer_list<LEDData> ledData) {
62 int32_t status = 0;
63 HAL_WriteAddressableLEDData(m_handle, ledData.begin(), ledData.size(),
64 &status);
Austin Schuh812d0d12021-11-04 20:16:48 -070065 FRC_CheckErrorStatus(status, "Port {}", m_port);
Brian Silverman8fce7482020-01-05 13:18:21 -080066}
67
68void AddressableLED::SetBitTiming(units::nanosecond_t lowTime0,
69 units::nanosecond_t highTime0,
70 units::nanosecond_t lowTime1,
71 units::nanosecond_t highTime1) {
72 int32_t status = 0;
73 HAL_SetAddressableLEDBitTiming(
74 m_handle, lowTime0.to<int32_t>(), highTime0.to<int32_t>(),
75 lowTime1.to<int32_t>(), highTime1.to<int32_t>(), &status);
Austin Schuh812d0d12021-11-04 20:16:48 -070076 FRC_CheckErrorStatus(status, "Port {}", m_port);
Brian Silverman8fce7482020-01-05 13:18:21 -080077}
78
79void AddressableLED::SetSyncTime(units::microsecond_t syncTime) {
80 int32_t status = 0;
81 HAL_SetAddressableLEDSyncTime(m_handle, syncTime.to<int32_t>(), &status);
Austin Schuh812d0d12021-11-04 20:16:48 -070082 FRC_CheckErrorStatus(status, "Port {}", m_port);
Brian Silverman8fce7482020-01-05 13:18:21 -080083}
84
85void AddressableLED::Start() {
86 int32_t status = 0;
87 HAL_StartAddressableLEDOutput(m_handle, &status);
Austin Schuh812d0d12021-11-04 20:16:48 -070088 FRC_CheckErrorStatus(status, "Port {}", m_port);
Brian Silverman8fce7482020-01-05 13:18:21 -080089}
90
91void AddressableLED::Stop() {
92 int32_t status = 0;
93 HAL_StopAddressableLEDOutput(m_handle, &status);
Austin Schuh812d0d12021-11-04 20:16:48 -070094 FRC_CheckErrorStatus(status, "Port {}", m_port);
Brian Silverman8fce7482020-01-05 13:18:21 -080095}
96
97void AddressableLED::LEDData::SetHSV(int h, int s, int v) {
Austin Schuh1e69f942020-11-14 15:06:14 -080098 SetLED(Color::FromHSV(h, s, v));
Brian Silverman8fce7482020-01-05 13:18:21 -080099}