@@ -5,29 +5,36 @@ static XMC_CCU4_MODULE_t *active_pwm4_ccu = nullptr; // Active CCU4 module
55static XMC_CCU8_MODULE_t *active_pwm8_ccu = nullptr ; // Active CCU8 module
66volatile uint8_t slice_number_ccu4;
77volatile uint8_t slice_number_ccu8;
8+ volatile uint32_t software_counter = 0 ;
9+ volatile uint32_t required_duration_ticks = 0 ;
810
911
1012
1113#ifdef __cplusplus
1214extern " C" {
1315#endif
1416void CCU43_0_IRQHandler (void ) {
15- if (active_pwm4_slice != nullptr && active_pwm4_ccu != nullptr ) {
16- XMC_CCU4_SLICE_StopTimer (active_pwm4_slice);
17- XMC_CCU4_DisableClock (active_pwm4_ccu, slice_number_ccu4); // Disable the clock
18-
19- active_pwm4_slice = nullptr ; // Clear the active CCU4 slice
20- active_pwm4_ccu = nullptr ; // Clear the active CCU4 module
21- }
22- if (active_pwm8_slice != nullptr && active_pwm8_ccu != nullptr ) {
23- XMC_CCU8_SLICE_StopTimer (active_pwm8_slice);
24- XMC_CCU8_DisableClock (active_pwm8_ccu, slice_number_ccu8);
25- active_pwm8_slice = nullptr ; // Clear the active CCU8 slice
26- active_pwm8_ccu = nullptr ; // Clear the active CCU8 module
27- }
28- XMC_CCU4_SLICE_StopTimer (CCU43_CC40);
17+ software_counter++;
18+ if (software_counter >= required_duration_ticks){
19+ if (active_pwm4_slice != nullptr && active_pwm4_ccu != nullptr ) {
20+ XMC_CCU4_SLICE_StopTimer (active_pwm4_slice);
21+ XMC_CCU4_DisableClock (active_pwm4_ccu, slice_number_ccu4); // Disable the clock
22+
23+ active_pwm4_slice = nullptr ; // Clear the active CCU4 slice
24+ active_pwm4_ccu = nullptr ; // Clear the active CCU4 module
25+ }
26+ if (active_pwm8_slice != nullptr && active_pwm8_ccu != nullptr ) {
27+ XMC_CCU8_SLICE_StopTimer (active_pwm8_slice);
28+ XMC_CCU8_DisableClock (active_pwm8_ccu, slice_number_ccu8);
29+ active_pwm8_slice = nullptr ; // Clear the active CCU8 slice
30+ active_pwm8_ccu = nullptr ; // Clear the active CCU8 module
31+ }
32+ XMC_CCU4_SLICE_StopTimer (CCU43_CC40);
33+ XMC_CCU4_SLICE_ClearEvent (CCU43_CC40, XMC_CCU4_SLICE_IRQ_ID_PERIOD_MATCH);
34+ software_counter = 0 ;
35+ NVIC_DisableIRQ (CCU43_0_IRQn);
36+ }
2937 XMC_CCU4_SLICE_ClearEvent (CCU43_CC40, XMC_CCU4_SLICE_IRQ_ID_PERIOD_MATCH);
30-
3138}
3239
3340#ifdef __cplusplus
@@ -44,6 +51,7 @@ class Tone {
4451
4552 void play (pin_size_t pin, unsigned int frequency, unsigned long duration) {
4653 int pin_index;
54+ stop (pin);
4755 if ((pin_index = scanMapTable (mapping_pin_PWM4, pin)) >= 0 ) {
4856 XMC_PWM4_t *pwm4 = &mapping_pwm4[pin_index];
4957 active_pwm4_slice = pwm4->slice ; // Store the active CCU4 slice
@@ -91,6 +99,9 @@ class Tone {
9199 XMC_CCU8_DisableClock (pwm8->ccu , pwm8->slice_num ); // Disable the clock
92100 }
93101#endif
102+ software_counter = 0 ;
103+ required_duration_ticks = 0 ;
104+ NVIC_DisableIRQ (CCU43_0_IRQn);
94105 }
95106
96107private:
@@ -145,19 +156,22 @@ class Tone {
145156 }
146157
147158 void configureTimerInterrupt (unsigned long duration_ms) {
159+ software_counter = 0 ;
148160 XMC_CCU4_Init (CCU43, XMC_CCU4_SLICE_MCMS_ACTION_TRANSFER_PR_CR);
149161 XMC_CCU4_SLICE_COMPARE_CONFIG_t timer_config;
150162 timer_config.timer_mode = XMC_CCU4_SLICE_TIMER_COUNT_MODE_EA;
151- timer_config.monoshot = XMC_CCU4_SLICE_TIMER_REPEAT_MODE_SINGLE ;
163+ timer_config.monoshot = XMC_CCU4_SLICE_TIMER_REPEAT_MODE_REPEAT ;
152164 timer_config.prescaler_mode = XMC_CCU4_SLICE_PRESCALER_MODE_NORMAL;
153- timer_config.prescaler_initval = XMC_CCU4_SLICE_PRESCALER_32768 ;
165+ timer_config.prescaler_initval = XMC_CCU4_SLICE_PRESCALER_64 ;
154166 timer_config.float_limit = XMC_CCU4_SLICE_PRESCALER_32768;
155167 timer_config.passive_level = XMC_CCU4_SLICE_OUTPUT_PASSIVE_LEVEL_LOW;
156168 XMC_CCU4_SLICE_CompareInit (CCU43_CC40, &timer_config);
157169
158170 // Calculate period for the timer based on the duration
159- uint32_t timer_ticks = (PCLK / 32768 ) * duration_ms / 1000 ;
160- XMC_CCU4_SLICE_SetTimerPeriodMatch (CCU43_CC40, timer_ticks);
171+ uint32_t timer_freq = PCLK / 64 ;
172+ uint32_t timer_ticks_ms = timer_freq /1000 ;
173+ required_duration_ticks = duration_ms;
174+ XMC_CCU4_SLICE_SetTimerPeriodMatch (CCU43_CC40, timer_ticks_ms);
161175 XMC_CCU4_SetMultiChannelShadowTransferMode (CCU43, XMC_CCU4_MULTI_CHANNEL_SHADOW_TRANSFER_SW_SLICE0);
162176 XMC_CCU4_EnableShadowTransfer (CCU43,XMC_CCU4_SHADOW_TRANSFER_SLICE_0);
163177 XMC_CCU4_SLICE_SetInterruptNode (CCU43_CC40, XMC_CCU4_SLICE_IRQ_ID_PERIOD_MATCH, XMC_CCU4_SLICE_SR_ID_0);
0 commit comments