idfxx 1.0.0
Modern C++23 components for ESP-IDF
Loading...
Searching...
No Matches
pwm.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: Apache-2.0
2// Copyright 2026 Chris Leishman
3
4#pragma once
5
24#include <idfxx/error>
25#include <idfxx/gpio>
26#include <idfxx/intr_alloc>
27
28#include <algorithm>
29#include <chrono>
30#include <frequency/frequency>
31#include <functional>
32#include <memory>
33#include <optional>
34#include <span>
35#include <string>
36#include <utility>
37
38namespace idfxx::pwm {
39
40// ======================================================================
41// Enums
42// ======================================================================
43
51enum class speed_mode : int {
52 low_speed = 0,
53#if SOC_LEDC_SUPPORT_HS_MODE
55#endif
56};
57
65enum class channel : int {
66 ch_0 = 0,
67 ch_1,
68 ch_2,
69 ch_3,
70 ch_4,
71 ch_5,
72#if SOC_LEDC_CHANNEL_NUM > 6
73 ch_6,
74#endif
75#if SOC_LEDC_CHANNEL_NUM > 7
76 ch_7,
77#endif
78};
79
87enum class clk_source : int {
88 auto_select = 0,
89#if SOC_LEDC_SUPPORT_APB_CLOCK
90 apb,
91#endif
92#if SOC_LEDC_SUPPORT_REF_TICK
93 ref_tick,
94#endif
95#if SOC_LEDC_SUPPORT_PLL_DIV_CLOCK
96 pll_div,
97#endif
98#if SOC_LEDC_SUPPORT_XTAL_CLOCK
99 xtal,
100#endif
101};
102
107enum class fade_mode : int {
108 no_wait = 0,
109 wait_done,
110};
111
116enum class sleep_mode : int {
117 no_alive_no_pd = 0,
119 keep_alive,
120};
121
132
133// ======================================================================
134// Forward declarations
135// ======================================================================
136
138class output;
139struct output_config;
140template<int N, speed_mode M>
141struct timer_constant;
144// ======================================================================
145// timer (value type)
146// ======================================================================
147
169class timer {
170 template<int N, speed_mode M>
171 friend struct timer_constant;
172 friend std::optional<timer> get_timer(enum channel, enum speed_mode);
173
174public:
184
185 timer(const timer&) = default;
186 timer& operator=(const timer&) = default;
187 timer(timer&&) = default;
188 timer& operator=(timer&&) = default;
189
190 constexpr bool operator==(const timer& other) const = default;
191
193 [[nodiscard]] constexpr unsigned int num() const noexcept { return _num; }
194
196 [[nodiscard]] constexpr enum speed_mode speed_mode() const noexcept { return _speed_mode; }
197
198#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
214 void configure(const struct config& cfg) { unwrap(try_configure(cfg)); }
215
229#endif
230
244
255 return try_configure({.frequency = frequency, .resolution_bits = resolution_bits});
256 }
257
267
276
285
295
303 [[nodiscard]] std::chrono::nanoseconds period() const;
304
314
315#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
326#endif
327
340
341#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
358 template<typename Rep, typename Period>
359 void set_period(const std::chrono::duration<Rep, Period>& period) {
361 }
362#endif
363
377 template<typename Rep, typename Period>
378 [[nodiscard]] result<void> try_set_period(const std::chrono::duration<Rep, Period>& period) {
379 auto ns = std::chrono::ceil<std::chrono::nanoseconds>(period).count();
380 if (ns <= 0) {
381 return error(errc::invalid_arg);
382 }
383 return try_set_frequency(freq::hertz{1'000'000'000 / ns});
384 }
385
386#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
393 void pause() { unwrap(try_pause()); }
394#endif
395
402
403#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
410 void resume() { unwrap(try_resume()); }
411#endif
412
419
420#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
427 void reset() { unwrap(try_reset()); }
428#endif
429
436
437private:
439
440 constexpr timer(unsigned int num, enum speed_mode mode) noexcept
441 : _num(num)
442 , _speed_mode(mode) {}
443
444 unsigned int _num;
445 enum speed_mode _speed_mode;
446};
447
449template<int N, speed_mode M>
450struct timer_constant {
451 static_assert(N >= 0 && N < SOC_LEDC_TIMER_NUM, "Invalid PWM timer number");
452 static constexpr timer value{N, M};
453};
462inline constexpr timer timer_0 = timer_constant<0, speed_mode::low_speed>::value;
463inline constexpr timer timer_1 = timer_constant<1, speed_mode::low_speed>::value;
464inline constexpr timer timer_2 = timer_constant<2, speed_mode::low_speed>::value;
465inline constexpr timer timer_3 = timer_constant<3, speed_mode::low_speed>::value;
466
467#if SOC_LEDC_SUPPORT_HS_MODE
468inline constexpr timer hs_timer_0 = timer_constant<0, speed_mode::high_speed>::value;
469inline constexpr timer hs_timer_1 = timer_constant<1, speed_mode::high_speed>::value;
470inline constexpr timer hs_timer_2 = timer_constant<2, speed_mode::high_speed>::value;
471inline constexpr timer hs_timer_3 = timer_constant<3, speed_mode::high_speed>::value;
472#endif
// end of Timer Constants
474
475// ======================================================================
476// start / try_start — free functions for starting PWM output
477// ======================================================================
478
489
490#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
520
524
546
550
553void stop(
554 enum channel ch,
557);
558#endif
559
588
603
629
643
653
662[[nodiscard]] std::optional<timer> get_timer(enum channel ch, enum speed_mode mode = speed_mode::low_speed);
663
677 enum channel ch,
680);
681
682// ======================================================================
683// output (RAII, move-only)
684// ======================================================================
685
710class output {
711public:
718
719 output(const output&) = delete;
720 output& operator=(const output&) = delete;
721 output(output&& other) noexcept;
722 output& operator=(output&& other) noexcept;
723
729 [[nodiscard]] class timer timer() const noexcept { return _timer; }
730
736 [[nodiscard]] enum channel channel() const noexcept { return _channel; }
737
740
743
749 [[nodiscard]] float duty() const;
750
759
760#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
771#endif
772
785
786#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
797
809#endif
810
820
831
837 [[nodiscard]] std::chrono::nanoseconds pulse_width() const;
838
839#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
854 template<typename Rep, typename Period>
855 void set_pulse_width(const std::chrono::duration<Rep, Period>& width) {
857 }
858#endif
859
870 template<typename Rep, typename Period>
871 [[nodiscard]] result<void> try_set_pulse_width(const std::chrono::duration<Rep, Period>& width) {
872 return _try_set_pulse_width(std::chrono::ceil<std::chrono::nanoseconds>(width));
873 }
874
875#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
889 template<typename Rep, typename Period>
891 float target,
892 const std::chrono::duration<Rep, Period>& duration,
893 enum fade_mode mode = fade_mode::no_wait
894 ) {
895 unwrap(try_fade_to(target, duration, mode));
896 }
897#endif
898
914 template<typename Rep, typename Period>
916 float target,
917 const std::chrono::duration<Rep, Period>& duration,
918 enum fade_mode mode = fade_mode::no_wait
919 ) {
920 return _try_fade_to_duty(
921 static_cast<uint32_t>(std::clamp(target, 0.0f, 1.0f) * static_cast<float>(ticks_max())),
922 std::chrono::ceil<std::chrono::milliseconds>(duration),
923 mode
924 );
925 }
926
927#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
941 template<typename Rep, typename Period>
944 const std::chrono::duration<Rep, Period>& duration,
945 enum fade_mode mode = fade_mode::no_wait
946 ) {
947 unwrap(try_fade_to_duty_ticks(target_duty, duration, mode));
948 }
949#endif
950
966 template<typename Rep, typename Period>
969 const std::chrono::duration<Rep, Period>& duration,
970 enum fade_mode mode = fade_mode::no_wait
971 ) {
972 return _try_fade_to_duty(target_duty, std::chrono::ceil<std::chrono::milliseconds>(duration), mode);
973 }
974
975#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
991 template<typename Rep1, typename Period1, typename Rep2, typename Period2>
993 const std::chrono::duration<Rep1, Period1>& target_width,
994 const std::chrono::duration<Rep2, Period2>& duration,
995 enum fade_mode mode = fade_mode::no_wait
996 ) {
998 }
999#endif
1000
1018 template<typename Rep1, typename Period1, typename Rep2, typename Period2>
1020 const std::chrono::duration<Rep1, Period1>& target_width,
1021 const std::chrono::duration<Rep2, Period2>& duration,
1022 enum fade_mode mode = fade_mode::no_wait
1023 ) {
1024 return _try_fade_to_pulse_width(
1025 std::chrono::ceil<std::chrono::nanoseconds>(target_width),
1026 std::chrono::ceil<std::chrono::milliseconds>(duration),
1027 mode
1028 );
1029 }
1030
1031#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
1044 void
1046 unwrap(try_fade_with_step(target_duty, scale, cycle_num, mode));
1047 }
1048#endif
1049
1066 uint32_t scale,
1067 uint32_t cycle_num,
1068 enum fade_mode mode = fade_mode::no_wait
1069 );
1070
1071#if SOC_LEDC_GAMMA_CURVE_FADE_SUPPORTED
1072#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
1086 void multi_fade(uint32_t start_duty, std::span<const fade_param> steps, enum fade_mode mode = fade_mode::no_wait) {
1088 }
1089#endif
1090
1107 try_multi_fade(uint32_t start_duty, std::span<const fade_param> steps, enum fade_mode mode = fade_mode::no_wait);
1108
1109#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
1121#endif
1122
1132
1133#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
1152 [[nodiscard]] std::vector<fade_param> fill_multi_fade_params(
1158 ) {
1159 return unwrap(
1161 );
1162 }
1163#endif
1164
1186 );
1187#endif // SOC_LEDC_GAMMA_CURVE_FADE_SUPPORTED
1188
1189#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
1202 void register_fade_end_callback(std::move_only_function<bool() const> callback) {
1203 unwrap(try_register_fade_end_callback(std::move(callback)));
1204 }
1205#endif
1206
1219 [[nodiscard]] result<void> try_register_fade_end_callback(std::move_only_function<bool() const> callback);
1220
1221#if SOC_LEDC_SUPPORT_FADE_STOP
1222#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
1231 void fade_stop() { unwrap(try_fade_stop()); }
1232#endif
1233
1242#endif
1243
1244#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
1256 static void
1260#endif
1261
1274 [[nodiscard]] static result<void>
1276
1283
1284#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
1293#endif
1294
1302
1313
1314private:
1318
1321
1323
1324 [[nodiscard]] result<void> _try_set_pulse_width(std::chrono::nanoseconds width);
1325
1326 [[nodiscard]] result<void> _try_fade_to_pulse_width(
1327 std::chrono::nanoseconds target_width,
1328 std::chrono::milliseconds duration,
1329 enum fade_mode mode
1330 );
1331
1332 [[nodiscard]] result<void>
1333 _try_fade_to_duty(uint32_t target_duty, std::chrono::milliseconds duration, enum fade_mode mode);
1334
1335 void _delete() noexcept;
1336
1337 class timer _timer;
1338 enum channel _channel;
1339 std::optional<uint32_t> _gen;
1340 uint32_t _duty_ticks = 0;
1341 std::unique_ptr<std::move_only_function<bool() const>> _fade_cb;
1342};
1343
1344#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
1346 return unwrap(try_start(gpio, tmr, ch));
1347}
1349 return unwrap(try_start(gpio, tmr, ch, cfg));
1350}
1352 return unwrap(try_start(gpio, cfg));
1353}
1358 unwrap(try_stop(ch, mode, idle_level));
1359}
1360#endif
1361
// end of idfxx_pwm
1363
1364} // namespace idfxx::pwm
1365
1366namespace idfxx {
1367
1375[[nodiscard]] inline std::string to_string(const pwm::timer& t) {
1376 std::string s;
1377#if SOC_LEDC_SUPPORT_HS_MODE
1378 if (t.speed_mode() == pwm::speed_mode::high_speed) {
1379 s = "PWM_HS_TIMER_";
1380 } else {
1381 s = "PWM_TIMER_";
1382 }
1383#else
1384 s = "PWM_TIMER_";
1385#endif
1386 s += std::to_string(t.num());
1387 return s;
1388}
1389
1397[[nodiscard]] inline std::string to_string(pwm::channel ch) {
1398 return "PWM_CH_" + std::to_string(std::to_underlying(ch));
1399}
1400
1408[[nodiscard]] inline std::string to_string(pwm::speed_mode m) {
1409 switch (m) {
1410 case pwm::speed_mode::low_speed:
1411 return "low_speed";
1412#if SOC_LEDC_SUPPORT_HS_MODE
1413 case pwm::speed_mode::high_speed:
1414 return "high_speed";
1415#endif
1416 default:
1417 return "unknown(" + std::to_string(std::to_underlying(m)) + ")";
1418 }
1419}
1420
1421} // namespace idfxx
1422
1423#include "sdkconfig.h"
1424#ifdef CONFIG_IDFXX_STD_FORMAT
1426#include <format>
1427namespace std {
1428template<>
1429struct formatter<idfxx::pwm::timer> {
1430 constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
1431
1432 template<typename FormatContext>
1433 auto format(const idfxx::pwm::timer& t, FormatContext& ctx) const {
1434 auto s = idfxx::to_string(t);
1435 return std::copy(s.begin(), s.end(), ctx.out());
1436 }
1437};
1438template<>
1439struct formatter<idfxx::pwm::channel> {
1440 constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
1441
1442 template<typename FormatContext>
1443 auto format(idfxx::pwm::channel ch, FormatContext& ctx) const {
1444 auto s = idfxx::to_string(ch);
1445 return std::copy(s.begin(), s.end(), ctx.out());
1446 }
1447};
1448template<>
1449struct formatter<idfxx::pwm::speed_mode> {
1450 constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
1451
1452 template<typename FormatContext>
1453 auto format(idfxx::pwm::speed_mode m, FormatContext& ctx) const {
1454 auto s = idfxx::to_string(m);
1455 return std::copy(s.begin(), s.end(), ctx.out());
1456 }
1457};
1458} // namespace std
1460#endif // CONFIG_IDFXX_STD_FORMAT
A GPIO pin.
Definition gpio.hpp:62
level
GPIO output/input level.
Definition gpio.hpp:68
@ low
Logic low (0)
An active PWM output binding a timer, channel, and GPIO pin.
Definition pwm.hpp:710
result< void > try_fade_to(float target, const std::chrono::duration< Rep, Period > &duration, enum fade_mode mode=fade_mode::no_wait)
Fades to a target duty ratio over the specified duration.
Definition pwm.hpp:915
bool is_active() const noexcept
Returns true if the output is still actively driving the channel.
enum channel release() noexcept
Releases ownership of the channel without stopping the PWM output.
static result< void > try_install_fade_service(idfxx::intr_levels levels=intr_level_lowmed, idfxx::flags< intr_flag > flags={})
Installs the PWM fade service.
result< void > try_fade_to_duty_ticks(uint32_t target_duty, const std::chrono::duration< Rep, Period > &duration, enum fade_mode mode=fade_mode::no_wait)
Fades to a target duty in ticks over the specified duration.
Definition pwm.hpp:967
void fade_to_duty_ticks(uint32_t target_duty, const std::chrono::duration< Rep, Period > &duration, enum fade_mode mode=fade_mode::no_wait)
Fades to a target duty in ticks over the specified duration.
Definition pwm.hpp:942
result< void > try_set_pulse_width(const std::chrono::duration< Rep, Period > &width)
Sets the PWM duty cycle as a pulse width duration.
Definition pwm.hpp:871
result< void > try_set_duty_ticks(uint32_t duty)
Sets the PWM duty cycle in ticks.
void set_duty_ticks(uint32_t duty)
Sets the PWM duty cycle in ticks.
Definition pwm.hpp:796
void fade_with_step(uint32_t target_duty, uint32_t scale, uint32_t cycle_num, enum fade_mode mode=fade_mode::no_wait)
Starts a fade to a target duty in ticks with step control.
Definition pwm.hpp:1045
uint32_t ticks_max() const noexcept
Returns the maximum duty ticks for the configured resolution.
result< void > try_stop(idfxx::gpio::level idle_level=idfxx::gpio::level::low)
Stops PWM output and sets the GPIO to an idle level.
result< void > try_set_duty(float duty)
Sets the PWM duty cycle as a ratio.
output(output &&other) noexcept
float duty() const
Returns the current duty cycle as a ratio.
void register_fade_end_callback(std::move_only_function< bool() const > callback)
Registers a callback for fade-end events.
Definition pwm.hpp:1202
output & operator=(output &&other) noexcept
~output()
Destroys the output, stopping PWM on the bound GPIO.
output(const output &)=delete
result< void > try_fade_with_step(uint32_t target_duty, uint32_t scale, uint32_t cycle_num, enum fade_mode mode=fade_mode::no_wait)
Starts a fade to the target duty with step control.
void stop(idfxx::gpio::level idle_level=idfxx::gpio::level::low)
Stops PWM output and sets the GPIO to an idle level.
Definition pwm.hpp:1292
result< void > try_fade_to_pulse_width(const std::chrono::duration< Rep1, Period1 > &target_width, const std::chrono::duration< Rep2, Period2 > &duration, enum fade_mode mode=fade_mode::no_wait)
Fades to a target pulse width over the specified duration.
Definition pwm.hpp:1019
static void install_fade_service(idfxx::intr_levels levels=intr_level_lowmed, idfxx::flags< intr_flag > flags={})
Installs the PWM fade service.
Definition pwm.hpp:1257
void fade_to_pulse_width(const std::chrono::duration< Rep1, Period1 > &target_width, const std::chrono::duration< Rep2, Period2 > &duration, enum fade_mode mode=fade_mode::no_wait)
Fades to a target pulse width over the specified duration.
Definition pwm.hpp:992
result< void > try_register_fade_end_callback(std::move_only_function< bool() const > callback)
Registers a callback for fade-end events.
std::chrono::nanoseconds pulse_width() const
Returns the current pulse width as a duration.
result< void > try_set_duty_ticks(uint32_t duty, uint32_t hpoint)
Sets the PWM duty cycle in ticks with high point.
enum channel channel() const noexcept
Returns the channel slot that was bound to this output.
Definition pwm.hpp:736
static void uninstall_fade_service()
Uninstalls the PWM fade service.
output & operator=(const output &)=delete
void set_pulse_width(const std::chrono::duration< Rep, Period > &width)
Sets the PWM duty cycle as a pulse width duration.
Definition pwm.hpp:855
friend result< output > try_start(idfxx::gpio gpio, const class timer &tmr, enum channel ch, const output_config &cfg)
void set_duty(float duty)
Sets the PWM duty cycle as a ratio.
Definition pwm.hpp:770
void set_duty_ticks(uint32_t duty, uint32_t hpoint)
Sets the PWM duty cycle in ticks with high point.
Definition pwm.hpp:808
uint32_t duty_ticks() const
Returns the current duty cycle in ticks.
void fade_to(float target, const std::chrono::duration< Rep, Period > &duration, enum fade_mode mode=fade_mode::no_wait)
Fades to a target duty ratio over the specified duration.
Definition pwm.hpp:890
A lightweight identifier for a hardware PWM timer.
Definition pwm.hpp:169
void configure(const struct config &cfg)
Configures the timer with the given parameters.
Definition pwm.hpp:214
result< void > try_configure(const struct config &cfg)
Configures the timer with the given parameters.
timer(timer &&)=default
uint32_t ticks_max() const noexcept
Returns the maximum duty ticks for the configured resolution.
uint8_t resolution_bits() const noexcept
Returns the configured resolution in bits.
timer & operator=(timer &&)=default
friend result< output > try_start(idfxx::gpio, const config &, const output_config &)
Starts PWM output with automatic allocation and custom output configuration.
constexpr unsigned int num() const noexcept
Returns the timer number (0-3).
Definition pwm.hpp:193
freq::hertz frequency() const
Returns the current timer frequency.
result< void > try_set_frequency(freq::hertz frequency)
Changes the timer frequency.
friend struct timer_constant
Definition pwm.hpp:171
result< void > try_configure(freq::hertz frequency, uint8_t resolution_bits=13)
Configures the timer with frequency and resolution.
Definition pwm.hpp:254
constexpr enum speed_mode speed_mode() const noexcept
Returns the speed mode.
Definition pwm.hpp:196
void resume()
Resumes the timer counter.
Definition pwm.hpp:410
timer(const timer &)=default
std::chrono::nanoseconds tick_period() const
Returns the duration of a single timer tick.
timer & operator=(const timer &)=default
constexpr bool operator==(const timer &other) const =default
std::chrono::nanoseconds period() const
Returns the PWM period (1 / frequency) as a duration.
void set_period(const std::chrono::duration< Rep, Period > &period)
Changes the timer period.
Definition pwm.hpp:359
result< void > try_pause()
Pauses the timer counter.
result< void > try_resume()
Resumes the timer counter.
void pause()
Pauses the timer counter.
Definition pwm.hpp:393
void reset()
Resets the timer counter.
Definition pwm.hpp:427
void configure(freq::hertz frequency, uint8_t resolution_bits=13)
Configures the timer with frequency and resolution.
Definition pwm.hpp:226
result< void > try_reset()
Resets the timer counter.
void set_frequency(freq::hertz frequency)
Changes the timer frequency.
Definition pwm.hpp:325
result< void > try_set_period(const std::chrono::duration< Rep, Period > &period)
Changes the timer period.
Definition pwm.hpp:378
bool is_configured() const noexcept
Returns true if the timer has been configured.
friend std::optional< timer > get_timer(enum channel, enum speed_mode)
Returns the timer associated with an active channel, if any.
High-resolution timer with microsecond precision.
Definition timer.hpp:41
std::string to_string(core_id c)
Returns a string representation of a CPU core identifier.
Definition cpu.hpp:52
constexpr timer timer_2
Definition pwm.hpp:464
constexpr timer timer_1
Definition pwm.hpp:463
constexpr timer timer_0
Definition pwm.hpp:462
constexpr timer timer_3
Definition pwm.hpp:465
result< output > try_start(idfxx::gpio gpio, const timer &tmr, enum channel ch)
Starts PWM output on a GPIO pin.
sleep_mode
Channel behavior during light sleep.
Definition pwm.hpp:116
bool is_active(enum channel ch, enum speed_mode mode=speed_mode::low_speed)
Returns true if the specified channel currently has an active output.
speed_mode
PWM speed mode selection.
Definition pwm.hpp:51
void stop(enum channel ch, enum speed_mode mode=speed_mode::low_speed, idfxx::gpio::level idle_level=idfxx::gpio::level::low)
Stops PWM output on a channel and sets it to an idle level.
Definition pwm.hpp:1357
channel
PWM channel slot identifiers.
Definition pwm.hpp:65
output start(idfxx::gpio gpio, const timer &tmr, enum channel ch)
Starts PWM output on a GPIO pin.
Definition pwm.hpp:1345
fade_mode
Fade operation blocking mode.
Definition pwm.hpp:107
result< void > try_stop(enum channel ch, enum speed_mode mode=speed_mode::low_speed, idfxx::gpio::level idle_level=idfxx::gpio::level::low)
Stops PWM output on a channel and sets it to an idle level.
std::optional< timer > get_timer(enum channel ch, enum speed_mode mode=speed_mode::low_speed)
Returns the timer associated with an active channel, if any.
clk_source
PWM timer clock source.
Definition pwm.hpp:87
@ no_alive_no_pd
No output, keep power domain on (default)
@ keep_alive
Maintain PWM output during light sleep.
@ no_alive_allow_pd
No output, allow power domain off (saves power)
@ low_speed
Low-speed mode (available on all targets)
@ no_wait
Return immediately, fade runs in background.
@ wait_done
Block until the fade completes.
@ auto_select
Automatic clock source selection.
constexpr std::unexpected< std::error_code > error(E e) noexcept
Creates an unexpected error from an error code enum.
Definition error.hpp:187
T unwrap(result< T > result)
Throws a std::system_error if the result is an error.
Definition error.hpp:307
@ invalid_arg
Invalid argument.
std::expected< T, std::error_code > result
result type wrapping a value or error code.
Definition error.hpp:120
constexpr intr_levels intr_level_lowmed
Low and medium priority levels (1-3). These can be handled in C / C++.
Parameters for a single step in a multi-step hardware fade.
Definition pwm.hpp:126
bool increasing
Duty change direction: true = increase, false = decrease.
Definition pwm.hpp:127
uint32_t scale
Duty change per step.
Definition pwm.hpp:129
uint32_t cycle_num
Number of PWM cycles per step.
Definition pwm.hpp:128
uint32_t step_num
Total number of steps.
Definition pwm.hpp:130
Output configuration parameters.
Definition pwm.hpp:483
bool output_invert
Invert the output signal.
Definition pwm.hpp:486
float duty
Initial duty cycle ratio (0.0 to 1.0).
Definition pwm.hpp:484
int hpoint
High point in the PWM cycle.
Definition pwm.hpp:485
Timer configuration parameters.
Definition pwm.hpp:179
uint8_t resolution_bits
Duty resolution in bits (1 to SOC_LEDC_TIMER_BIT_WIDTH).
Definition pwm.hpp:181
freq::hertz frequency
PWM frequency.
Definition pwm.hpp:180