cancel
Showing results for 
Search instead for 
Did you mean: 

Purpose of HAL_TIM_Encoder_MspInit?

HMorg.1
Associate II

I have been learning my way around the encoder mode in the hardware timers, specifically on a Nucleo L432KC. I got it working within CubeIDE, but I wanted to program using STM32Duino and PlatformIO, so I tried a library for this that someone else wrote (gianni-carbone/STM32encoder). It didn't work out of the box, and it appeared it was configuring and starting the timer, but not configuring the GPIO pins themselves correctly.

On a whim I added the code snippet below, which was from another STM32 encoder example from the mbed site...it appears to be redefining a function which was already being called somewhere in the encoder library I am using.

Is this the intended behavior? Or is this required because of a bug somewhere in the STM32Duino core or the HAL? I'm curious how this function is intended to work. I'd like to understand what's going on here so I can possibly pull-request the encoder library and make it work out of the box on this board.

// HAL_TIM_Encoder_MspInit()
// Overrides the __weak function stub in stm32l4xx_hal_tim.h
void HAL_TIM_Encoder_MspInit(TIM_HandleTypeDef *htim)
{
    GPIO_InitTypeDef GPIO_InitStruct;
 
    if (htim->Instance == TIM1) {       //PA8 PA9 = Nucleo D7 D8
        __TIM1_CLK_ENABLE();
        __GPIOA_CLK_ENABLE();
        GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_9;
        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
        GPIO_InitStruct.Pull = GPIO_PULLDOWN;
        GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
        GPIO_InitStruct.Alternate = GPIO_AF1_TIM1;
        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    }
    else if (htim->Instance == TIM2) {  //PA0 PA1 = Nucleo A0 A1
        __TIM2_CLK_ENABLE();
        __GPIOA_CLK_ENABLE();
        GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1;
        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
        GPIO_InitStruct.Pull = GPIO_PULLDOWN;
        GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
        GPIO_InitStruct.Alternate = GPIO_AF1_TIM2;
        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    }
}

2 REPLIES 2
Pavel A.
Evangelist III

The "MspInit" functions in ST "HAL" library initialize MCU pins for specific peripheral and mode.

If you are familiar with embedded Linux, this is analogous to "pinmux".

Cube generates these functions for specific MCU and board (or for pins selected by user for a custom board). If you copy these functions from a project for a different board, guess what will be result.

Thanks, that makes sense. I understand why it has to be MCU-specific, but is there anything about the timers that is board-specific? I would think that other than the SWD/UART stuff that's used for the ST-Link, it wouldn't matter if you were using a Nucleo board or the same MCU in a custom board.

Reason I ask is I'm wondering if somehow generating all these files for all the current MCUs and then including them in the encoder library would solve this issue and make the library a little more hardware agnostic.