@@ -13,8 +13,6 @@ class PWMDriverESP32;
13
13
* @brief Please use DriverPWMBase!
14
14
*/
15
15
using PWMDriver = PWMDriverESP32;
16
- static PWMDriverESP32 *accessAudioPWM = nullptr ;
17
- void IRAM_ATTR defaultPWMAudioOutputCallback ();
18
16
19
17
20
18
/* *
@@ -38,50 +36,45 @@ typedef PinInfoESP32 PinInfo;
38
36
39
37
class PWMDriverESP32 : public DriverPWMBase {
40
38
public:
41
- friend void defaultPWMAudioOutputCallback ( );
39
+ // friend void pwm_callback(void*ptr );
42
40
43
41
PWMDriverESP32 (){
44
42
TRACED ();
45
- accessAudioPWM = this ;
46
43
}
47
44
48
45
// Ends the output
49
46
virtual void end (){
50
47
TRACED ();
51
- timerAlarmDisable (timer);
48
+ timer.end ();
49
+ is_timer_started = false ;
52
50
for (int j=0 ;j<audio_config.channels ;j++){
53
51
ledcDetachPin (pins[j].gpio );
54
52
}
55
- is_timer_started = false ;
56
53
}
57
54
58
55
// / when we get the first write -> we activate the timer to start with the output of data
59
56
virtual void startTimer (){
60
- if (!is_timer_started){
57
+ if (!timer){
58
+ TRACEI ();
61
59
audio_config = audioInfo ();
62
- LOGI ( " timerAlarmEnable " );
60
+ timer. begin (pwm_callback, audio_config. sample_rate , HZ );
63
61
is_timer_started = true ;
64
- timerAlarmEnable (timer);
65
62
}
66
63
}
67
64
68
65
// / Setup LED PWM
69
66
virtual void setupPWM (){
70
- TRACED ();
71
67
// frequency is driven by selected resolution
72
- uint32_t freq = frequency (audio_config.resolution )*1000 ;
73
- audio_config.pwm_frequency = freq;
68
+ audio_config.pwm_frequency = frequency (audio_config.resolution ) * 1000 ;
74
69
75
70
pins.resize (audio_config.channels );
76
71
for (int j=0 ;j<audio_config.channels ;j++){
77
- LOGD (" Processing channel %d" , j);
78
72
int pwmChannel = j;
79
73
pins[j].pwm_channel = pwmChannel;
80
74
pins[j].gpio = audio_config.pins ()[j];
81
- LOGI (" -> ledcSetup: frequency=%d / resolution=%d" , freq, audio_config.resolution );
82
- ledcSetup (pwmChannel, freq, audio_config.resolution );
83
- LOGD (" -> ledcAttachPin: %d" , pins[j].gpio );
84
- ledcAttachPin (pins[j].gpio , pwmChannel);
75
+ ledcSetup (pins[j].pwm_channel , audio_config.pwm_frequency , audio_config.resolution );
76
+ ledcAttachPin (pins[j].gpio , pins[j].pwm_channel );
77
+ LOGI (" setupPWM: pin=%d, channel=%d, frequency=%d, resolution=%d" , pins[j].gpio , pins[j].pwm_channel , audio_config.pwm_frequency , audio_config.resolution );
85
78
}
86
79
logPins ();
87
80
}
@@ -94,31 +87,18 @@ class PWMDriverESP32 : public DriverPWMBase {
94
87
95
88
// / Setup ESP32 timer with callback
96
89
virtual void setupTimer () {
97
- TRACED ();
98
-
99
- // Attach timer int at sample rate
100
- int prescale = 2 ;
101
- bool rising_edge = true ;
102
- timer = timerBegin (audio_config.timer_id , prescale, rising_edge); // Timer at full 40Mhz, prescaling 2
103
- uint32_t counter = 20000000 / audio_config.sample_rate ;
104
- LOGI (" -> timer counter is %zu" , counter);
105
- LOGD (" -> timerAttachInterrupt" );
106
- bool interrupt_edge_type = true ;
107
- timerAttachInterrupt (timer, defaultPWMAudioOutputCallback, interrupt_edge_type);
108
- LOGD (" -> timerAlarmWrite" );
109
- bool auto_reload = true ;
110
- timerAlarmWrite (timer, counter, auto_reload); // Timer fires at ~44100Hz [40Mhz / 907]
90
+ timer.setCallbackParameter (this );
91
+ timer.setIsSave (false );
111
92
}
112
93
113
94
// / write a pwm value to the indicated channel. The max value depends on the resolution
114
95
virtual void pwmWrite (int channel, int value){
115
- ledcWrite (pins[channel].pwm_channel , value);
96
+ ledcWrite (pins[channel].pwm_channel , value);
116
97
}
117
98
118
99
protected:
119
100
Vector<PinInfo> pins;
120
- hw_timer_t * timer = nullptr ;
121
- portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;
101
+ TimerAlarmRepeating timer;
122
102
123
103
// / provides the max value for the indicated resulution
124
104
int maxUnsignedValue (int resolution){
@@ -143,17 +123,18 @@ class PWMDriverESP32 : public DriverPWMBase {
143
123
case 11 : return 39.0625 ;
144
124
}
145
125
return 312.5 ;
146
- }
126
+ }
127
+
128
+ // / timer callback: write the next frame to the pins
129
+ static void pwm_callback (void *ptr){
130
+ PWMDriverESP32 *accessAudioPWM = (PWMDriverESP32*)ptr;
131
+ if (accessAudioPWM!=nullptr ){
132
+ accessAudioPWM->playNextFrame ();
133
+ }
134
+ }
135
+
147
136
};
148
137
149
- // / timer callback: write the next frame to the pins
150
- void IRAM_ATTR defaultPWMAudioOutputCallback () {
151
- if (accessAudioPWM!=nullptr ){
152
- portENTER_CRITICAL_ISR (&(accessAudioPWM->timerMux ));
153
- accessAudioPWM->playNextFrame ();
154
- portEXIT_CRITICAL_ISR (&(accessAudioPWM->timerMux ));
155
- }
156
- }
157
138
158
139
}
159
140
0 commit comments