1+ /* !
2+ * @file src/components/pwm/hardware.cpp
3+ *
4+ * Hardware for the pwm.proto message.
5+ *
6+ * Adafruit invests time and resources providing this open source code,
7+ * please support Adafruit and open-source hardware by purchasing
8+ * products from Adafruit!
9+ *
10+ * Copyright (c) Brent Rubell 2025 for Adafruit Industries.
11+ *
12+ * BSD license, all text here must be included in any redistribution.
13+ *
14+ */
15+ #include " hardware.h"
16+
17+ PWMHardware::PWMHardware () {
18+ _is_attached = false ;
19+ }
20+
21+ PWMHardware::~PWMHardware () {
22+ if (_is_attached)
23+ DetachPin ();
24+ }
25+
26+ bool PWMHardware::AttachPin (uint8_t pin, uint32_t frequency, uint32_t resolution) {
27+ #ifdef ARDUINO_ARCH_ESP32
28+ _is_attached = ledcAttach (_pin, _frequency, _resolution);
29+ #else
30+ _is_attached = true ;
31+ #endif
32+
33+ if (_is_attached) {
34+ _pin = pin;
35+ _frequency = frequency;
36+ _resolution = resolution;
37+ _duty_cycle = 0 ;
38+ }
39+
40+ return _is_attached;
41+ }
42+
43+ bool PWMHardware::DetachPin () {
44+ if (! _is_attached) {
45+ WS_DEBUG_PRINTLN (" [pwm] Pin not attached!" );
46+ return false ;
47+ }
48+ bool did_detach = false ;
49+ #ifdef ARDUINO_ARCH_ESP32
50+ did_detach = ledcDetach (_pin);
51+ #else
52+ did_detach = true ;
53+ #endif
54+
55+ // "Disable" the pin's output
56+ digitalWrite (_pin, LOW);
57+ }
58+
59+ bool PWMHardware::WriteDutyCycle (uint32_t duty) {
60+ if (! _is_attached) {
61+ WS_DEBUG_PRINTLN (" [pwm] Pin not attached!" );
62+ return false ;
63+ }
64+ bool did_write = false ;
65+ #ifdef defined(ARDUINO_ESP8266_ADAFRUIT_HUZZAH) && defined(STATUS_LED_PIN)
66+ // Adafruit Feather ESP8266's analogWrite() gets inverted since the builtin
67+ // LED is reverse-wired
68+ _duty_cycle = 255 - duty;
69+ #else
70+ _duty_cycle = duty;
71+ #endif
72+
73+ #ifdef ARDUINO_ARCH_ESP32
74+ did_write = analogWrite (_duty_cycle);
75+ #else
76+ analogWrite (_pin, duty);
77+ did_write = true ;
78+ #endif
79+
80+ return true ;
81+ }
82+
83+ // LEDC API Wrappers
84+ #ifdef ARDUINO_ARCH_ESP32
85+ bool PWMHardware::analogWrite (uint32_t value) {
86+ // clamp
87+ if (value > 255 || value < 0 ) {
88+ WS_DEBUG_PRINTLN (" [pwm] Value out of range!" );
89+ return false ;
90+ }
91+
92+ // Calculate duty cycle for the `value` passed in
93+ // (assumes 12-bit resolution, 2^12)
94+ uint32_t dutyCycle = (uint32_t )((4095.0 / 255.0 ) * min (value, (uint32_t )255 ));
95+ return ledcWrite (_pin, dutyCycle);
96+ }
97+
98+ #endif // ARDUINO_ARCH_ESP32
0 commit comments