Has anyone tried enabling the timer BKIN function on an stm32 board?

I have got some over current protection on my board in the form of a comparator, in which the output is pulled low in the event of an over current event. I have connected this to a pin that supports the BKIN function which will immediately shut down the PWM.

I dont suppose anyone has enabled the BKIN function within the stm32 arduino environment and could give me any tips? I cant seem to see any related functions within the hardwaretimer files

Stm32duino doesn’t seem to configure this at all.

I did it in the past for stm32f1 with the HAL (here)

You could probably use this and this in this function, simplefoc is also configuring the deadtime there.
You might also have to configure PB6/PB12 as inputs.

Absolute legend, ill give it a go today and hopefully I’ll be able to protect my board if s*** hits the fan

One thing to be careful about.
If you are using low side sensing, when break input is triggered, phase current sensing might break. It’s not a problem if you don’t exit from that break state and restart the board.

Otherwise phase currents might still be sampled with the low side mosfets being off, and those wrong values will be used for current control. But it depends if the timer is still triggering the adc events during the break state, I can’t remember that.

Let me know if this happens.
Your experiments might help understand if break input is something we might be able to add to the library.

This document could help:
https://www.st.com/resource/en/application_note/an4277-how-to-use-pwm-shutdown-for-motor-control-and-digital-power-conversion-on-stm32-mcus-stmicroelectronics.pdf

Arduino has no concept of such advanced timer features, unfortunately.
And because there is no PinMap for these signals, it also won’t be easily possible to program it in a MCU independent way.

If you go ahead and implement it, we’d love to hear about the results.

As Candas has pointed out I fear the interaction with current sensing will be a bit complicated, and it it would be very helpful to learn about your findings.

Hey @Candas1 & @runger
I’ve made some quick and dirty code get get BKIN working and all seems to be functioning well!
I used the stm32 LL functions as it exposes just what we need to configure the pin and BKIN functionality while retaining all other settings configured during driver.init().

I call this function after driver.init().

void configureTIM1BKIN() {
  // Assuming the timer TIM1 has already been by driver.init()
  TIM_HandleTypeDef htim1;
  htim1.Instance = TIM1;

    // Set PB12 to Alternate Function mode
  LL_GPIO_SetPinMode(GPIOB, LL_GPIO_PIN_12, LL_GPIO_MODE_ALTERNATE);

  // Set PB12 to the appropriate Alternate Function (AF) for TIM1 BRK
  LL_GPIO_SetAFPin_8_15(GPIOB, LL_GPIO_PIN_12, LL_GPIO_AF_1);

  // Set the pin speed, output type, and pull-up/pull-down as needed
  LL_GPIO_SetPinSpeed(GPIOB, LL_GPIO_PIN_12, LL_GPIO_SPEED_FREQ_HIGH);
  LL_GPIO_SetPinOutputType(GPIOB, LL_GPIO_PIN_12, LL_GPIO_OUTPUT_PUSHPULL);
  LL_GPIO_SetPinPull(GPIOB, LL_GPIO_PIN_12, LL_GPIO_PULL_NO);

  LL_TIM_ConfigBRK(htim1.Instance, LL_TIM_BREAK_POLARITY_LOW);
  // Configure the Break function
  LL_TIM_EnableBRK(htim1.Instance);
}

I simulated an overcurrent event by pulling PB12 low and the motor stops immediately (rather aggressively so it may briefly be activating multiple high side, or multiple low side, FETs briefly).

Then to check whether there is any erroneous interaction with the current sensing I re-enabled the PWMs by including the following in the main loop:

  // Check whether the BRK has been triggered
  if (LL_TIM_IsActiveFlag_BRK(TIM1)) {
      // Wait 2 secs
      delay(2000);

      // Clear the Break Interrupt Flag to acknowledge the event
      LL_TIM_ClearFlag_BRK(TIM1);

      // Re-enable the PWM outputs
      LL_TIM_EnableAllOutputs(TIM1);
  }

Then the motor sprung back to life and was working absolutely fine!
Utilising the BRK interrupt will be way more elegant but this worked well for basic testing

edit: formatting

2 Likes

Nice.
Is setting the pin mode and alternate function mandatory for the code to work?
Unfortunately I couldn’t find a mapping of the BRK pin so that it could be found programmatically.

This MACRO could help make this code more generic so it could take a timer as a parameter and enable BRK only if the Timer has it.

In context of Arduino, you would need a “PinMap” that includes the BRK pins and their mapping to the timers.
Unfortunately Arduino doesn’t deal with this kind of stuff so BRK and ETR pins aren’t in the pinmap at the moment. Perhaps we could see if such a pinmap can be added to stm32duino.

It would be cool to make this code available, except for this issue of mapping the pins it seems easy enough to encapsulate it into its own class which we can put in the drivers repository for people that need it.

I don’t think I have a driver handy with comparators for testing this out. I suppose I could test it just using a button as a simulated overcurrent event…

Does the B-G431-ESC1 have this signal connected? I suppose on that board it would use the internal comparator input rather than the BRK pin? It might be worth checking into this as a lot of people burn their B-G431-ESC1s…

Yeah I think that snippet would be useful in the library.

So if I understood correctly:

  • You can use your own overcurrent digital signal to stop pwm signal, that’s what was done in this thread
  • You can additionally use a comparator on the MCU and an external voltage reference to generate that signal
  • You can also use the DAC to generate the voltage reference so the overcurrent protection is configurable

I am not sure what is done on the B-G431-ESC1, it would be worth generating a project in the motor control workbench and check.