Skip to content

Commit ec0eb4a

Browse files
nefelim4agKevinOConnor
authored andcommitted
stm32: hard pwm allow scale PWM frequency
To support the cartographer, it is required to output 24 MHz. With current defaults max output frequency is: 48 MHz/256 = 187.5 KHz Adjusting the PWM scale allows for ramping up the frequency. To not mess up with existing PWM users, define the STM32-specific command. Signed-off-by: Timofey Titovets <[email protected]>
1 parent 12cc944 commit ec0eb4a

File tree

1 file changed

+31
-3
lines changed

1 file changed

+31
-3
lines changed

src/stm32/hard_pwm.c

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,8 @@ static const struct gpio_pwm_info pwm_regs[] = {
300300
};
301301

302302
struct gpio_pwm
303-
gpio_pwm_setup(uint8_t pin, uint32_t cycle_time, uint32_t val)
303+
gpio_timer_setup(uint8_t pin, uint32_t cycle_time, uint32_t val,
304+
int is_clock_out)
304305
{
305306
// Find pin in pwm_regs table
306307
const struct gpio_pwm_info* p = pwm_regs;
@@ -316,7 +317,18 @@ gpio_pwm_setup(uint8_t pin, uint32_t cycle_time, uint32_t val)
316317
uint32_t pclock_div = CONFIG_CLOCK_FREQ / pclk;
317318
if (pclock_div > 1)
318319
pclock_div /= 2; // Timers run at twice the normal pclock frequency
319-
uint32_t prescaler = cycle_time / (pclock_div * (MAX_PWM - 1));
320+
uint32_t max_pwm = MAX_PWM;
321+
uint32_t pcycle_time = cycle_time / pclock_div;
322+
uint32_t prescaler = pcycle_time / (max_pwm - 1);
323+
// CLK output
324+
if (is_clock_out) {
325+
prescaler = 1;
326+
while (pcycle_time > UINT16_MAX) {
327+
prescaler = prescaler * 2;
328+
pcycle_time /= 2;
329+
}
330+
max_pwm = pcycle_time;
331+
}
320332
if (prescaler > UINT16_MAX) {
321333
prescaler = UINT16_MAX;
322334
} else if (prescaler > 0) {
@@ -334,9 +346,12 @@ gpio_pwm_setup(uint8_t pin, uint32_t cycle_time, uint32_t val)
334346
if (p->timer->PSC != (uint16_t) prescaler) {
335347
shutdown("PWM already programmed at different speed");
336348
}
349+
if (p->timer->ARR != (uint16_t) max_pwm - 1) {
350+
shutdown("PWM already programmed with different pulse duration");
351+
}
337352
} else {
338353
p->timer->PSC = (uint16_t) prescaler;
339-
p->timer->ARR = MAX_PWM - 1;
354+
p->timer->ARR = max_pwm - 1;
340355
p->timer->EGR |= TIM_EGR_UG;
341356
}
342357

@@ -393,6 +408,19 @@ gpio_pwm_setup(uint8_t pin, uint32_t cycle_time, uint32_t val)
393408
return channel;
394409
}
395410

411+
struct gpio_pwm
412+
gpio_pwm_setup(uint8_t pin, uint32_t cycle_time, uint32_t val) {
413+
return gpio_timer_setup(pin, cycle_time, val, 0);
414+
}
415+
416+
void
417+
command_stm32_timer_output(uint32_t *args)
418+
{
419+
gpio_timer_setup(args[0], args[1], args[2], 1);
420+
}
421+
DECL_COMMAND(command_stm32_timer_output,
422+
"stm32_timer_output pin=%u cycle_ticks=%u on_ticks=%hu");
423+
396424
void
397425
gpio_pwm_write(struct gpio_pwm g, uint32_t val) {
398426
*(volatile uint32_t*) g.reg = val;

0 commit comments

Comments
 (0)