Skip to content

Commit 39c4e3d

Browse files
dineshgit411LinjingZhang
authored andcommitted
cores/xmc: Implemented Tone function.
Signed-off-by: MDin <Dinesh.M-EE@infineon.com>
1 parent 6cb8f3f commit 39c4e3d

1 file changed

Lines changed: 142 additions & 0 deletions

File tree

cores/xmc/Tone.cpp

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
#include "Arduino.h"
2+
#define CCU8V2
3+
4+
class Tone {
5+
public:
6+
Tone() {}
7+
8+
~Tone() {}
9+
10+
void play(pin_size_t pin, unsigned int frequency) { play(pin, frequency, 0); }
11+
12+
void play(pin_size_t pin, unsigned int frequency, unsigned long duration) {
13+
int pin_index;
14+
if ((pin_index = scanMapTable(mapping_pin_PWM4, pin)) >= 0) {
15+
XMC_PWM4_t *pwm4 = &mapping_pwm4[pin_index];
16+
configureTone(pin, frequency);
17+
XMC_GPIO_SetMode(pwm4->port_pin.port, pwm4->port_pin.pin,
18+
XMC_GPIO_MODE_OUTPUT_PUSH_PULL | pwm4->port_mode);
19+
XMC_CCU4_SLICE_StartTimer(pwm4->slice);
20+
21+
if (duration > 0) {
22+
uint32_t required_pulses = frequency * duration / 1000;
23+
for (uint32_t i = 0; i < required_pulses; i++) {
24+
while (
25+
!XMC_CCU4_SLICE_GetEvent(pwm4->slice, XMC_CCU4_SLICE_IRQ_ID_PERIOD_MATCH)) {
26+
}
27+
XMC_CCU4_SLICE_ClearEvent(pwm4->slice, XMC_CCU4_SLICE_IRQ_ID_PERIOD_MATCH);
28+
}
29+
XMC_CCU4_SLICE_StopTimer(pwm4->slice);
30+
}
31+
32+
}
33+
#if defined(CCU8V2) || defined(CCU8V1)
34+
else if ((pin_index = scanMapTable(mapping_pin_PWM8, pin)) >= 0) {
35+
XMC_PWM8_t *pwm8 = &mapping_pwm8[pin_index];
36+
configureTone(pin, frequency);
37+
XMC_GPIO_SetMode(pwm8->port_pin.port, pwm8->port_pin.pin,
38+
XMC_GPIO_MODE_OUTPUT_PUSH_PULL | pwm8->port_mode);
39+
XMC_CCU8_SLICE_StartTimer(pwm8->slice);
40+
// calculate pulses
41+
if (duration > 0) {
42+
uint32_t required_pulses = frequency * duration / 1000;
43+
for (uint32_t i = 0; i < required_pulses; i++) {
44+
while (
45+
!XMC_CCU8_SLICE_GetEvent(pwm8->slice, XMC_CCU8_SLICE_IRQ_ID_PERIOD_MATCH)) {
46+
}
47+
XMC_CCU8_SLICE_ClearEvent(pwm8->slice, XMC_CCU8_SLICE_IRQ_ID_PERIOD_MATCH);
48+
}
49+
XMC_CCU8_SLICE_StopTimer(pwm8->slice);
50+
}
51+
}
52+
#endif
53+
}
54+
55+
void stop(pin_size_t pin) {
56+
int pin_index;
57+
if ((pin_index = scanMapTable(mapping_pin_PWM4, pin)) >= 0) {
58+
XMC_PWM4_t *pwm4 = &mapping_pwm4[pin_index];
59+
XMC_CCU4_SLICE_StopTimer(pwm4->slice); // stop the timer
60+
XMC_CCU4_DisableClock(pwm4->ccu, pwm4->slice_num); // Disable the clock
61+
}
62+
#if defined(CCU8V2) || defined(CCU8V1)
63+
else if ((pin_index = scanMapTable(mapping_pin_PWM8, pin)) >= 0) {
64+
XMC_PWM8_t *pwm8 = &mapping_pwm8[pin_index];
65+
XMC_CCU8_SLICE_StopTimer(pwm8->slice); // stop the timer
66+
XMC_CCU8_DisableClock(pwm8->ccu, pwm8->slice_num); // Disable the clock
67+
}
68+
#endif
69+
}
70+
71+
private:
72+
void configureTone(pin_size_t pin, unsigned int frequency) {
73+
int pin_index;
74+
if ((pin_index = scanMapTable(mapping_pin_PWM4, pin)) >= 0) {
75+
XMC_PWM4_t *pwm4 = &mapping_pwm4[pin_index];
76+
XMC_CCU4_SLICE_COMPARE_CONFIG_t compare_config;
77+
memset(&compare_config, 0, sizeof(compare_config));
78+
compare_config.prescaler_initval = pwm4->prescaler;
79+
compare_config.passive_level = XMC_CCU4_SLICE_OUTPUT_PASSIVE_LEVEL_LOW;
80+
81+
XMC_CCU4_Init(pwm4->ccu, XMC_CCU4_SLICE_MCMS_ACTION_TRANSFER_PR_CR);
82+
XMC_CCU4_SLICE_CompareInit(pwm4->slice, &compare_config);
83+
XMC_CCU4_EnableClock(pwm4->ccu, pwm4->slice_num);
84+
85+
uint32_t period = (PCLK / 64) / frequency; // calculate period
86+
XMC_CCU4_SLICE_SetTimerPeriodMatch(pwm4->slice, period);
87+
XMC_CCU4_SLICE_SetTimerCompareMatch(pwm4->slice, period / 2);
88+
89+
XMC_CCU4_EnableShadowTransfer(
90+
pwm4->ccu, XMC_CCU4_SHADOW_TRANSFER_SLICE_0 | XMC_CCU4_SHADOW_TRANSFER_SLICE_2 |
91+
XMC_CCU4_SHADOW_TRANSFER_SLICE_3 | XMC_CCU4_SHADOW_TRANSFER_SLICE_1);
92+
}
93+
#if defined(CCU8V2) || defined(CCU8V1)
94+
else if ((pin_index = scanMapTable(mapping_pin_PWM8, pin)) >= 0) {
95+
Serial.println("pin_index");
96+
XMC_PWM8_t *pwm8 = &mapping_pwm8[pin_index];
97+
XMC_CCU8_SLICE_COMPARE_CONFIG_t compare_config;
98+
memset(&compare_config, 0, sizeof(compare_config));
99+
100+
compare_config.prescaler_initval = pwm8->prescaler;
101+
compare_config.passive_level_out0 = XMC_CCU8_SLICE_OUTPUT_PASSIVE_LEVEL_LOW;
102+
compare_config.passive_level_out1 = XMC_CCU8_SLICE_OUTPUT_PASSIVE_LEVEL_LOW;
103+
compare_config.passive_level_out2 = XMC_CCU8_SLICE_OUTPUT_PASSIVE_LEVEL_LOW;
104+
compare_config.passive_level_out3 = XMC_CCU8_SLICE_OUTPUT_PASSIVE_LEVEL_LOW;
105+
106+
XMC_CCU8_Init(pwm8->ccu, XMC_CCU8_SLICE_MCMS_ACTION_TRANSFER_PR_CR);
107+
XMC_CCU8_SLICE_CompareInit(pwm8->slice, &compare_config);
108+
XMC_CCU8_EnableClock(pwm8->ccu, pwm8->slice_num);
109+
110+
uint32_t period = (PCLK / 64) / frequency; // calculate period
111+
XMC_CCU8_SLICE_SetTimerPeriodMatch(pwm8->slice, period);
112+
XMC_CCU8_SLICE_SetTimerCompareMatch(pwm8->slice, pwm8->slice_channel, period / 2);
113+
114+
XMC_CCU8_EnableShadowTransfer(
115+
pwm8->ccu, XMC_CCU8_SHADOW_TRANSFER_SLICE_0 | XMC_CCU8_SHADOW_TRANSFER_SLICE_2 |
116+
XMC_CCU8_SHADOW_TRANSFER_SLICE_3 | XMC_CCU8_SHADOW_TRANSFER_SLICE_1);
117+
}
118+
#endif
119+
}
120+
121+
// Scan the pwm pin mapping table
122+
int16_t scanMapTable(const uint8_t table[][2], uint8_t pin) {
123+
int16_t i = 0;
124+
while (table[i][0] != 255) {
125+
if (table[i][0] == pin) {
126+
return table[i][1];
127+
}
128+
i++;
129+
}
130+
return -1;
131+
}
132+
};
133+
134+
static Tone inst_Tone;
135+
136+
void tone(pin_size_t pin, unsigned int frequency) { inst_Tone.play(pin, frequency); }
137+
138+
void tone(pin_size_t pin, unsigned int frequency, unsigned long duration) {
139+
inst_Tone.play(pin, frequency, duration);
140+
}
141+
142+
void noTone(pin_size_t pin) { inst_Tone.stop(pin); }

0 commit comments

Comments
 (0)