2020-12-26 14:12:05 -08:00
|
|
|
// 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.
|
2016-01-02 03:02:34 -08:00
|
|
|
|
2014-05-02 17:54:01 -04:00
|
|
|
#pragma once
|
2013-12-15 18:30:16 -05:00
|
|
|
|
2017-06-25 09:05:49 -07:00
|
|
|
#include <stdint.h>
|
|
|
|
|
|
2024-09-07 13:58:15 -04:00
|
|
|
#include <hal/PWM.h>
|
2018-07-20 00:03:45 -07:00
|
|
|
#include <hal/Types.h>
|
2023-06-22 19:43:16 -07:00
|
|
|
#include <units/time.h>
|
2021-06-13 16:38:05 -07:00
|
|
|
#include <wpi/sendable/Sendable.h>
|
|
|
|
|
#include <wpi/sendable/SendableHelper.h>
|
2013-12-15 18:30:16 -05:00
|
|
|
|
2016-11-01 22:33:12 -07:00
|
|
|
namespace frc {
|
2019-11-17 16:39:38 -08:00
|
|
|
class AddressableLED;
|
2019-09-14 15:22:54 -05:00
|
|
|
|
2013-12-15 18:30:16 -05:00
|
|
|
/**
|
|
|
|
|
* Class implements the PWM generation in the FPGA.
|
2014-06-13 17:45:10 -04:00
|
|
|
*
|
2015-06-25 15:07:55 -04:00
|
|
|
* The values supplied as arguments for PWM outputs range from -1.0 to 1.0. They
|
2023-06-22 19:43:16 -07:00
|
|
|
* are mapped to the microseconds to keep the pulse high, with a range of 0
|
|
|
|
|
* (off) to 4096. Changes are immediately sent to the FPGA, and the update
|
|
|
|
|
* occurs at the next FPGA cycle (5.05ms). There is no delay.
|
2013-12-15 18:30:16 -05:00
|
|
|
*/
|
2021-06-13 16:38:05 -07:00
|
|
|
class PWM : public wpi::Sendable, public wpi::SendableHelper<PWM> {
|
2015-06-25 15:07:55 -04:00
|
|
|
public:
|
2019-11-17 16:39:38 -08:00
|
|
|
friend class AddressableLED;
|
2017-09-04 22:03:02 -07:00
|
|
|
/**
|
2025-03-20 19:23:22 -07:00
|
|
|
* Represents the output period in microseconds.
|
2017-09-04 22:03:02 -07:00
|
|
|
*/
|
2025-03-20 19:23:22 -07:00
|
|
|
enum OutputPeriod {
|
2017-09-04 22:03:02 -07:00
|
|
|
/**
|
2025-03-20 19:23:22 -07:00
|
|
|
* PWM pulses occur every 5 ms
|
2017-09-04 22:03:02 -07:00
|
|
|
*/
|
2025-03-20 19:23:22 -07:00
|
|
|
kOutputPeriod_5Ms = 1,
|
2017-09-04 22:03:02 -07:00
|
|
|
/**
|
2025-03-20 19:23:22 -07:00
|
|
|
* PWM pulses occur every 10 ms
|
2017-09-04 22:03:02 -07:00
|
|
|
*/
|
2025-03-20 19:23:22 -07:00
|
|
|
kOutputPeriod_10Ms = 2,
|
2017-09-04 22:03:02 -07:00
|
|
|
/**
|
2025-03-20 19:23:22 -07:00
|
|
|
* PWM pulses occur every 20 ms
|
2017-09-04 22:03:02 -07:00
|
|
|
*/
|
2025-03-20 19:23:22 -07:00
|
|
|
kOutputPeriod_20Ms = 4
|
2015-06-25 15:07:55 -04:00
|
|
|
};
|
2013-12-15 18:30:16 -05:00
|
|
|
|
2018-05-31 20:47:15 -07:00
|
|
|
/**
|
|
|
|
|
* Allocate a PWM given a channel number.
|
|
|
|
|
*
|
|
|
|
|
* Checks channel value range and allocates the appropriate channel.
|
|
|
|
|
* The allocation is only done to help users ensure that they don't double
|
|
|
|
|
* assign channels.
|
|
|
|
|
*
|
|
|
|
|
* @param channel The PWM channel number. 0-9 are on-board, 10-19 are on the
|
|
|
|
|
* MXP port
|
2021-03-21 11:12:49 -07:00
|
|
|
* @param registerSendable If true, adds this instance to SendableRegistry
|
2018-05-31 20:47:15 -07:00
|
|
|
*/
|
2021-03-21 11:12:49 -07:00
|
|
|
explicit PWM(int channel, bool registerSendable = true);
|
2018-05-31 20:47:15 -07:00
|
|
|
|
2024-09-07 13:58:15 -04:00
|
|
|
PWM(PWM&&) = default;
|
|
|
|
|
PWM& operator=(PWM&&) = default;
|
|
|
|
|
|
2018-05-31 20:47:15 -07:00
|
|
|
/**
|
|
|
|
|
* Free the PWM channel.
|
|
|
|
|
*
|
|
|
|
|
* Free the resource associated with the PWM channel and set the value to 0.
|
|
|
|
|
*/
|
2017-12-04 23:28:33 -08:00
|
|
|
~PWM() override;
|
2018-05-31 20:47:15 -07:00
|
|
|
|
|
|
|
|
/**
|
2023-06-22 19:43:16 -07:00
|
|
|
* Set the PWM pulse time directly to the hardware.
|
2018-05-31 20:47:15 -07:00
|
|
|
*
|
2023-06-22 19:43:16 -07:00
|
|
|
* Write a microsecond value to a PWM channel.
|
2018-05-31 20:47:15 -07:00
|
|
|
*
|
2023-06-22 19:43:16 -07:00
|
|
|
* @param time Microsecond PWM value.
|
2018-05-31 20:47:15 -07:00
|
|
|
*/
|
2025-03-20 19:23:22 -07:00
|
|
|
void SetPulseTime(units::microsecond_t time);
|
2018-05-31 20:47:15 -07:00
|
|
|
|
|
|
|
|
/**
|
2023-06-22 19:43:16 -07:00
|
|
|
* Get the PWM pulse time directly from the hardware.
|
2018-05-31 20:47:15 -07:00
|
|
|
*
|
2023-06-22 19:43:16 -07:00
|
|
|
* Read a microsecond value from a PWM channel.
|
2018-05-31 20:47:15 -07:00
|
|
|
*
|
2023-06-22 19:43:16 -07:00
|
|
|
* @return Microsecond PWM control value.
|
2018-05-31 20:47:15 -07:00
|
|
|
*/
|
2025-03-20 19:23:22 -07:00
|
|
|
units::microsecond_t GetPulseTime() const;
|
2018-05-31 20:47:15 -07:00
|
|
|
|
|
|
|
|
/**
|
2023-02-26 15:06:37 -08:00
|
|
|
* Temporarily disables the PWM output. The next set call will re-enable
|
2018-05-31 20:47:15 -07:00
|
|
|
* the output.
|
|
|
|
|
*/
|
2025-03-20 19:23:22 -07:00
|
|
|
void SetDisabled();
|
2018-05-31 20:47:15 -07:00
|
|
|
|
|
|
|
|
/**
|
2025-03-20 19:23:22 -07:00
|
|
|
* Sets the PWM output period.
|
2018-05-31 20:47:15 -07:00
|
|
|
*
|
2025-03-20 19:23:22 -07:00
|
|
|
* @param mult The output period to apply to this channel
|
2024-01-05 07:35:59 -08:00
|
|
|
*/
|
2025-03-20 19:23:22 -07:00
|
|
|
void SetOutputPeriod(OutputPeriod mult);
|
2018-05-31 20:47:15 -07:00
|
|
|
|
2025-03-20 19:23:22 -07:00
|
|
|
int GetChannel() const;
|
2018-05-31 20:47:15 -07:00
|
|
|
|
|
|
|
|
/**
|
2025-03-20 19:23:22 -07:00
|
|
|
* Indicates this input is used by a simulated device.
|
2018-05-31 20:47:15 -07:00
|
|
|
*
|
2025-03-20 19:23:22 -07:00
|
|
|
* @param device simulated device handle
|
2018-05-31 20:47:15 -07:00
|
|
|
*/
|
2025-03-20 19:23:22 -07:00
|
|
|
void SetSimDevice(HAL_SimDeviceHandle device);
|
2013-12-15 18:30:16 -05:00
|
|
|
|
2015-06-25 15:07:55 -04:00
|
|
|
protected:
|
2021-06-13 16:38:05 -07:00
|
|
|
void InitSendable(wpi::SendableBuilder& builder) override;
|
2013-12-15 18:30:16 -05:00
|
|
|
|
2015-06-25 15:07:55 -04:00
|
|
|
private:
|
2016-09-06 00:01:45 -07:00
|
|
|
int m_channel;
|
2024-09-07 13:58:15 -04:00
|
|
|
hal::Handle<HAL_DigitalHandle, HAL_FreePWMPort> m_handle;
|
2013-12-15 18:30:16 -05:00
|
|
|
};
|
2016-11-01 22:33:12 -07:00
|
|
|
|
|
|
|
|
} // namespace frc
|