arduino-audio-tools
Loading...
Searching...
No Matches
PWMDriverZephyr.h
Go to the documentation of this file.
1#pragma once
2
3#include "AudioToolsConfig.h"
4
5#if defined(IS_ZEPHYR)
6
7#include <zephyr/drivers/pwm.h>
8#include <zephyr/kernel.h>
9
12
13namespace audio_tools {
14
15// forward declaration
16class PWMDriverZephyr;
17
22using PWMDriver = PWMDriverZephyr;
23
41 public:
42 PWMDriverZephyr() = default;
43
45 virtual void end() override {
46 TRACED();
47 timer.end(); // Stop the playback timer
48 is_timer_started = false;
49
50 // Stop and release PWM devices
51 for (size_t ch = 0; ch < audio_config.pins.size(); ch++) {
52 int rc = pwm_set_dt(&audio_config.pins[ch], 0, 0);
53 if (rc != 0) {
54 LOGE("Failed to disable PWM on channel %d: %d", ch, rc);
55 }
56 }
58 }
59
60 protected:
61 AudioTimer timer; // Callback timer for playback
63
65 virtual void startTimer() override {
66 if (!is_timer_started) {
67 TRACED();
68 // Calculate period in microseconds
69 long wait_time = 1000000L / audio_config.sample_rate;
70 LOGI("Starting PWM timer with period: %lu us", wait_time);
71
74 is_timer_started = true;
75 }
76 }
77
79 virtual void setupPWM() override {
80 TRACED();
81
82 if (audio_config.pwm_frequency == 0) {
84 }
85
86 LOGI("Setting up %d PWM channels at %u Hz", audio_config.channels,
88
89 // pwm_dt_spec is defined as
90 // struct pwm_dt_spec {
91 // const struct device *dev;
92 // uint32_t channel;
93 // uint32_t period;
94 // pwm_flags_t flags;
95 // };
96 int pin_count = audio_config.pins.size();
97 for (int ch = 0; ch < audio_config.channels; ch++) {
98 if (ch >= pin_count){
99 LOGE("Not enough pins defined: pins %d, channels=%d", pin_count, audio_config.channels);
100 continue;
101 }
102
104 if (spec.dev == nullptr) {
105 LOGE("Failed to get PWM device for audio channel %d (pwm_channel %u)", ch, spec.channel);
106 continue;
107 }
108
109 if (!device_is_ready(spec.dev)) {
110 LOGE("Device not ready for audio channel %d (pwm_channel %u)", ch, spec.channel);
111 continue;
112 }
113
114 period_ns =
115 1000000000UL / audio_config.pwm_frequency;
116 // Apply initial PWM configuration (0% duty cycle)
117 int rc = pwm_set_dt(&spec, period_ns, 0);
118 if (rc != 0) {
119 LOGE("Failed to configure PWM on channel %d: %d", ch, rc);
120 continue;
121 }
122 }
123
124 LOGI("PWM setup complete");
125 }
126
127
129 virtual void setupTimer() override {
130 TRACED();
131 // Timer is set up in startTimer() when needed
132 // Nothing to do here
133 }
134
136 virtual int maxChannels() override {
137 // Zephyr PWM typically supports up to 8 channels per device
138 return 8;
139 }
140
142 virtual int maxOutputValue() override {
143 // Using 16-bit resolution for consistency with audio data
144 return 65535;
145 }
146
148 virtual void pwmWrite(int channel, int value) override {
149 // prevent writes to undefined channels
150 if (channel >= audio_config.pins.size()) return;
151 // set duty cycle
152 pwm_dt_spec spec = audio_config.pins[channel];
153 // Clamp value to valid range
155 value > maxOutputValue() ? maxOutputValue() : value;
156
157 // Calculate duty cycle in cycles
162 if (rc != 0) {
163 LOGD("Failed to set PWM duty on channel %d: %d", channel, rc);
164 }
165 }
166
170 if (driver != nullptr) {
171 driver->playNextFrame();
172 }
173 }
174};
175
176} // namespace audio_tools
177
178#endif
#define TRACED()
Definition AudioLoggerIDF.h:31
#define LOGI(...)
Definition AudioLoggerIDF.h:28
#define LOGD(...)
Definition AudioLoggerIDF.h:27
#define LOGE(...)
Definition AudioLoggerIDF.h:30
#define PWM_AUDIO_FREQUENCY
Definition AudioToolsConfig.h:178
Common Interface definition for AudioTimer.
Definition AudioTimer.h:30
void setCallbackParameter(void *obj)
Definition AudioTimer.h:57
bool begin(repeating_timer_callback_t callback_f, uint32_t time, TimeUnit unit=MS)
Definition AudioTimer.h:44
bool end()
Definition AudioTimer.h:52
Base Class for all PWM drivers.
Definition PWMDriverBase.h:36
void playNextFrame()
writes the next frame to the output pins
Definition PWMDriverBase.h:196
bool is_timer_started
Definition PWMDriverBase.h:182
PWMConfig audio_config
Definition PWMDriverBase.h:173
void deleteBuffer()
Definition PWMDriverBase.h:187
Audio output to PWM pins for Zephyr RTOS.
Definition PWMDriverZephyr.h:40
virtual void setupTimer() override
Configure timer parameters (called after setupPWM)
Definition PWMDriverZephyr.h:129
uint32_t period_ns
Definition PWMDriverZephyr.h:62
virtual void startTimer() override
Start the timer for periodic playback.
Definition PWMDriverZephyr.h:65
virtual int maxOutputValue() override
Maximum output value (resolution-dependent)
Definition PWMDriverZephyr.h:142
AudioTimer timer
Definition PWMDriverZephyr.h:61
virtual int maxChannels() override
Maximum supported PWM channels.
Definition PWMDriverZephyr.h:136
virtual void pwmWrite(int channel, int value) override
Write PWM value to a specific channel.
Definition PWMDriverZephyr.h:148
virtual void end() override
Ends PWM output.
Definition PWMDriverZephyr.h:45
virtual void setupPWM() override
Setup PWM pins and devices.
Definition PWMDriverZephyr.h:79
static void defaultPWMAudioOutputCallback(void *obj)
Timer callback: invoked periodically to write the next audio frame.
Definition PWMDriverZephyr.h:168
@ US
Definition AudioTypes.h:44
PWMDriverAVR PWMDriver
Platform-specific PWM driver alias for AVR.
Definition PWMDriverAVR.h:13
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition AudioCodecsBase.h:10
void defaultPWMAudioOutputCallback()
Definition PWMDriverAVR.h:134
size_t writeData(Print *p_out, T *data, int samples, int maxSamples=512)
Definition AudioTypes.h:508
sample_rate_t sample_rate
Sample Rate: e.g 44100.
Definition AudioTypes.h:53
uint16_t channels
Number of channels: 2=stereo, 1=mono.
Definition AudioTypes.h:55
uint32_t pwm_frequency
additinal info which might not be used by all processors
Definition PWMConfigAVR.h:24