Skip to content

Commit 3c8e287

Browse files
committed
6-PWM is working
1 parent 218070d commit 3c8e287

File tree

1 file changed

+90
-11
lines changed

1 file changed

+90
-11
lines changed

src/drivers/hardware_specific/silabs/silabs_mcu.cpp

Lines changed: 90 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ void setupPWM(int pin_nr, long pwm_frequency, bool active_high, SilabsDriverPara
3535
int8_t timer_nr = getTimerNumber(timer);
3636
TIMER_InitCC_TypeDef timerCCInit = TIMER_INITCC_DEFAULT;
3737
timerCCInit.mode = timerCCModePWM;
38+
timerCCInit.coist = !active_high;
3839
timerCCInit.outInvert = !active_high;
3940
switch(channel) {
4041
case 0:
@@ -65,7 +66,7 @@ void setupPWM(int pin_nr, long pwm_frequency, bool active_high, SilabsDriverPara
6566
printPortLetter(port);
6667
SimpleFOCDebug::print((int)pin);
6768
SimpleFOCDebug::print(") on TIMER");
68-
SimpleFOCDebug::print(getTimerNumber(timer));
69+
SimpleFOCDebug::print(timer_nr);
6970
SimpleFOCDebug::print(" CH");
7071
SimpleFOCDebug::print(channel);
7172
SimpleFOCDebug::print(" top ");
@@ -74,6 +75,50 @@ void setupPWM(int pin_nr, long pwm_frequency, bool active_high, SilabsDriverPara
7475

7576

7677

78+
void setupComplementaryPWM(int pin_nr, SilabsDriverParams* params, uint8_t index, TIMER_TypeDef* timer, uint8_t channel){
79+
int8_t timer_nr = getTimerNumber(timer);
80+
PinName pin_n = pinToPinName(pin_nr);
81+
GPIO_Port_TypeDef port = getSilabsPortFromArduinoPin(pin_n);
82+
uint32_t pin = getSilabsPinFromArduinoPin(pin_n);
83+
switch(channel) {
84+
case 0:
85+
GPIO->TIMERROUTE[timer_nr].ROUTEEN |= GPIO_TIMER_ROUTEEN_CCC0PEN;
86+
GPIO->TIMERROUTE[timer_nr].CDTI0ROUTE = (port << _GPIO_TIMER_CDTI0ROUTE_PORT_SHIFT)
87+
| (pin << _GPIO_TIMER_CDTI0ROUTE_PIN_SHIFT);
88+
break;
89+
case 1:
90+
GPIO->TIMERROUTE[timer_nr].ROUTEEN |= GPIO_TIMER_ROUTEEN_CCC1PEN;
91+
GPIO->TIMERROUTE[timer_nr].CDTI1ROUTE = (port << _GPIO_TIMER_CDTI1ROUTE_PORT_SHIFT)
92+
| (pin << _GPIO_TIMER_CDTI1ROUTE_PIN_SHIFT);
93+
break;
94+
case 2:
95+
GPIO->TIMERROUTE[timer_nr].ROUTEEN |= GPIO_TIMER_ROUTEEN_CCC2PEN;
96+
GPIO->TIMERROUTE[timer_nr].CDTI2ROUTE = (port << _GPIO_TIMER_CDTI2ROUTE_PORT_SHIFT)
97+
| (pin << _GPIO_TIMER_CDTI2ROUTE_PIN_SHIFT);
98+
break;
99+
}
100+
101+
params->pins[index] = pin_nr;
102+
params->timer[index] = timer;
103+
params->channel[index] = channel;
104+
105+
SimpleFOCDebug::print("DRV (Silabs): Pin ");
106+
SimpleFOCDebug::print(pin_nr);
107+
SimpleFOCDebug::print(" (P");
108+
printPortLetter(port);
109+
SimpleFOCDebug::print((int)pin);
110+
SimpleFOCDebug::print(") on TIMER");
111+
SimpleFOCDebug::print(timer_nr);
112+
SimpleFOCDebug::print(" CH");
113+
SimpleFOCDebug::print(channel);
114+
SimpleFOCDebug::print("COMP top ");
115+
SimpleFOCDebug::println((int)params->resolution);
116+
}
117+
118+
119+
120+
121+
77122
bool isTimerUsed(TIMER_TypeDef* timer) {
78123
for (int i=0;i<num_configured_motors;i++) {
79124
for (int j=0;j<6;j++) {
@@ -139,9 +184,29 @@ void initTimer(TIMER_TypeDef* timer, long pwm_frequency, SilabsDriverParams* par
139184

140185

141186

142-
// if( !pwm_frequency || !_isset(pwm_frequency) ) pwm_frequency = _PWM_FREQUENCY;
143-
// else pwm_frequency = _constrain(pwm_frequency, _PWM_FREQUENCY_MIN, _PWM_FREQUENCY_MAX);
144-
// params->pwm_frequency = pwm_frequency;
187+
188+
void initDeadTimeInsertion(TIMER_TypeDef* timer, long pwm_frequency, bool highside_active_high, bool lowside_active_high, SilabsDriverParams* params){
189+
TIMER_InitDTI_TypeDef dtiInit = TIMER_INITDTI_DEFAULT;
190+
dtiInit.enable = false; // or true? need to check first PWM cycle for this
191+
dtiInit.activeLowOut = !highside_active_high;
192+
dtiInit.invertComplementaryOut = !lowside_active_high;
193+
dtiInit.riseTime = params->dead_zone * params->resolution; // divided by 2 for symmetric dead-time, times 2 due to up-down counting
194+
if (dtiInit.riseTime > 64) dtiInit.riseTime = 64; // max dead-time is 64 counts (each side)
195+
dtiInit.fallTime = dtiInit.riseTime;
196+
dtiInit.autoRestart = true;
197+
SimpleFOCDebug::print("DRV (Silabs): Dead time ");
198+
Serial.println(dtiInit.riseTime);
199+
dtiInit.outputsEnableMask = TIMER_DTOGEN_DTOGCC0EN | TIMER_DTOGEN_DTOGCDTI0EN
200+
| TIMER_DTOGEN_DTOGCC1EN | TIMER_DTOGEN_DTOGCDTI1EN
201+
| TIMER_DTOGEN_DTOGCC2EN | TIMER_DTOGEN_DTOGCDTI2EN;
202+
unsigned long long max = TIMER_MaxCount(timer) + 1;
203+
CMU_Clock_TypeDef timer_clock = getTimerClock(timer);
204+
dtiInit.prescale = (TIMER_Prescale_TypeDef)(CMU_ClockFreqGet(timer_clock) / pwm_frequency / 2 / max);
205+
TIMER_InitDTI(timer, &dtiInit);
206+
}
207+
208+
209+
145210

146211
void* _configure1PWM(long pwm_frequency, const int pinA) {
147212
SilabsDriverParams* params = new SilabsDriverParams();
@@ -203,14 +268,20 @@ void* _configure4PWM(long pwm_frequency, const int pin1A, const int pin1B, const
203268

204269
void* _configure6PWM(long pwm_frequency, float dead_zone, const int pinA_h, const int pinA_l, const int pinB_h, const int pinB_l, const int pinC_h, const int pinC_l) {
205270
SilabsDriverParams* params = new SilabsDriverParams();
271+
int pins[6] = {pinA_h, pinA_l, pinB_h, pinB_l, pinC_h, pinC_l};
272+
TIMER_TypeDef* timer = findFreeTimer(pins, 6);
273+
initTimer(timer, pwm_frequency, params);
274+
// init using DTI
206275
params->dead_zone = dead_zone;
207-
// TODO init using DTI if posssible
208-
// setupPWM(pinA_h, pwm_frequency, SIMPLEFOC_PWM_HIGHSIDE_ACTIVE_HIGH, params, 0);
209-
// setupPWM(pinB_h, pwm_frequency, SIMPLEFOC_PWM_HIGHSIDE_ACTIVE_HIGH, params, 2);
210-
// setupPWM(pinC_h, pwm_frequency, SIMPLEFOC_PWM_HIGHSIDE_ACTIVE_HIGH, params, 4);
211-
// setupPWM(pinA_l, pwm_frequency, SIMPLEFOC_PWM_LOWSIDE_ACTIVE_HIGH, params, 1);
212-
// setupPWM(pinB_l, pwm_frequency, SIMPLEFOC_PWM_LOWSIDE_ACTIVE_HIGH, params, 3);
213-
// setupPWM(pinC_l, pwm_frequency, SIMPLEFOC_PWM_LOWSIDE_ACTIVE_HIGH, params, 5);
276+
setupPWM(pinA_h, pwm_frequency, SIMPLEFOC_PWM_HIGHSIDE_ACTIVE_HIGH, params, 0, timer, 0);
277+
setupPWM(pinB_h, pwm_frequency, SIMPLEFOC_PWM_HIGHSIDE_ACTIVE_HIGH, params, 2, timer, 1);
278+
setupPWM(pinC_h, pwm_frequency, SIMPLEFOC_PWM_HIGHSIDE_ACTIVE_HIGH, params, 4, timer, 2);
279+
initDeadTimeInsertion(timer, pwm_frequency, SIMPLEFOC_PWM_HIGHSIDE_ACTIVE_HIGH, SIMPLEFOC_PWM_LOWSIDE_ACTIVE_HIGH, params);
280+
setupComplementaryPWM(pinA_l, params, 1, timer, 0);
281+
setupComplementaryPWM(pinB_l, params, 3, timer, 1);
282+
setupComplementaryPWM(pinC_l, params, 5, timer, 2);
283+
TIMER_EnableDTI(timer, true);
284+
TIMER_Enable(timer, true);
214285
return params;
215286
}
216287

@@ -256,6 +327,14 @@ void _writeDutyCycle4PWM(float dc_1a, float dc_1b, float dc_2a, float dc_2b, vo
256327
}
257328

258329

330+
void _writeDutyCycle6PWM(float dc_a, float dc_b, float dc_c, PhaseState *phase_state, void* params) {
331+
// TODO: handle phase state
332+
writeDutyCycle(dc_a, ((SilabsDriverParams*)params)->timer[0], ((SilabsDriverParams*)params)->channel[0]);
333+
writeDutyCycle(dc_b, ((SilabsDriverParams*)params)->timer[2], ((SilabsDriverParams*)params)->channel[2]);
334+
writeDutyCycle(dc_c, ((SilabsDriverParams*)params)->timer[4], ((SilabsDriverParams*)params)->channel[4]);
335+
}
336+
337+
259338

260339
CMU_Clock_TypeDef getTimerClock(TIMER_TypeDef* timer) {
261340
if(timer == TIMER0) return cmuClock_TIMER0;

0 commit comments

Comments
 (0)