@@ -13,8 +13,6 @@ class PWMDriverESP32;
1313 * @brief Please use DriverPWMBase!
1414 */
1515using PWMDriver = PWMDriverESP32;
16- static PWMDriverESP32 *accessAudioPWM = nullptr ;
17- void IRAM_ATTR defaultPWMAudioOutputCallback ();
1816
1917
2018/* *
@@ -38,50 +36,45 @@ typedef PinInfoESP32 PinInfo;
3836
3937class PWMDriverESP32 : public DriverPWMBase {
4038 public:
41- friend void defaultPWMAudioOutputCallback ( );
39+ // friend void pwm_callback(void*ptr );
4240
4341 PWMDriverESP32 (){
4442 TRACED ();
45- accessAudioPWM = this ;
4643 }
4744
4845 // Ends the output
4946 virtual void end (){
5047 TRACED ();
51- timerAlarmDisable (timer);
48+ timer.end ();
49+ is_timer_started = false ;
5250 for (int j=0 ;j<audio_config.channels ;j++){
5351 ledcDetachPin (pins[j].gpio );
5452 }
55- is_timer_started = false ;
5653 }
5754
5855 // / when we get the first write -> we activate the timer to start with the output of data
5956 virtual void startTimer (){
60- if (!is_timer_started){
57+ if (!timer){
58+ TRACEI ();
6159 audio_config = audioInfo ();
62- LOGI ( " timerAlarmEnable " );
60+ timer. begin (pwm_callback, audio_config. sample_rate , HZ );
6361 is_timer_started = true ;
64- timerAlarmEnable (timer);
6562 }
6663 }
6764
6865 // / Setup LED PWM
6966 virtual void setupPWM (){
70- TRACED ();
7167 // 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 ;
7469
7570 pins.resize (audio_config.channels );
7671 for (int j=0 ;j<audio_config.channels ;j++){
77- LOGD (" Processing channel %d" , j);
7872 int pwmChannel = j;
7973 pins[j].pwm_channel = pwmChannel;
8074 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 );
8578 }
8679 logPins ();
8780 }
@@ -94,31 +87,18 @@ class PWMDriverESP32 : public DriverPWMBase {
9487
9588 // / Setup ESP32 timer with callback
9689 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 );
11192 }
11293
11394 // / write a pwm value to the indicated channel. The max value depends on the resolution
11495 virtual void pwmWrite (int channel, int value){
115- ledcWrite (pins[channel].pwm_channel , value);
96+ ledcWrite (pins[channel].pwm_channel , value);
11697 }
11798
11899 protected:
119100 Vector<PinInfo> pins;
120- hw_timer_t * timer = nullptr ;
121- portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;
101+ TimerAlarmRepeating timer;
122102
123103 // / provides the max value for the indicated resulution
124104 int maxUnsignedValue (int resolution){
@@ -143,17 +123,18 @@ class PWMDriverESP32 : public DriverPWMBase {
143123 case 11 : return 39.0625 ;
144124 }
145125 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+
147136};
148137
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- }
157138
158139}
159140
0 commit comments