542 lines
14 KiB
C
542 lines
14 KiB
C
/**********************************TIM**************************************
|
||
Данный файл содержит базовые функции для инициализации таймеров.
|
||
//-------------------Функции-------------------//
|
||
@func users
|
||
- TIM_Base_Init Инициализация TIM
|
||
- TIM_Output_PWM_Init Инициализация PWM с выводом на GPIO
|
||
|
||
@func tim initialize
|
||
- TIM_Base_MspInit Аналог HAL_MspInit для таймера
|
||
- TIM_Base_MspDeInit Аналог HAL_MspDeInit для таймера
|
||
***************************************************************************/
|
||
#include "tim_general.h"
|
||
|
||
//-------------------------------------------------------------------
|
||
//-------------------------TIM INIT FUNCTIONS------------------------
|
||
/**
|
||
* @brief Initialize TIM with TIM_SettingsTypeDef structure.
|
||
* @param stim - указатель на структуру с настройками таймера.
|
||
* @return HAL status.
|
||
* @note Данная структура содержит хендл таймера и структуры для его настройки.
|
||
*/
|
||
HAL_StatusTypeDef TIM_Base_Init(TIM_SettingsTypeDef *stim)
|
||
{ // function takes structure for init
|
||
// check that htim is defined
|
||
if (stim->htim.Instance == NULL)
|
||
return HAL_ERROR;
|
||
|
||
|
||
|
||
if(stim->sTickBaseMHz) // if tickbase isnt disable
|
||
{
|
||
if((stim->sTimAHBFreqMHz == NULL))
|
||
return HAL_ERROR;
|
||
stim->htim.Init.Prescaler = (stim->sTimAHBFreqMHz*stim->sTickBaseMHz) - 1;
|
||
|
||
if ((stim->sTimFreqHz != NULL))
|
||
stim->htim.Init.Period = ((1000000/stim->sTickBaseMHz) / stim->sTimFreqHz) - 1;
|
||
else if (stim->htim.Init.Period == NULL)
|
||
stim->htim.Init.Period = 0xFFFF;
|
||
}
|
||
// // if freq is too high (period too small for choosen base) OR base is too high (period too small for choosen base)
|
||
// if((stim->htim.Init.Period == NULL) || (stim->htim.Init.Prescaler == NULL))
|
||
// {
|
||
// return HAL_ERROR;
|
||
// }
|
||
|
||
// fix overflow of presc and period if need
|
||
for(int i = 0; (stim->htim.Init.Prescaler > 0xFFFF) || (stim->htim.Init.Period > 0xFFFFFFFF); i++)
|
||
{
|
||
if (i>10) // if it isnt fixed after 10 itteration - return HAL_ERRPOR
|
||
{
|
||
return HAL_ERROR;
|
||
}
|
||
|
||
// if timbase is too big (prescaller too big for choosen base from MHZ)
|
||
if(stim->htim.Init.Prescaler > 0xFFFF)
|
||
{
|
||
// переносим часть пресскалера в период
|
||
stim->htim.Init.Prescaler = ((stim->htim.Init.Prescaler + 1)/2) - 1;
|
||
stim->htim.Init.Period = ((stim->htim.Init.Period + 1)*2) - 1;
|
||
// обновляем TickBase
|
||
stim->sTickBaseMHz /= 2;
|
||
}
|
||
// if freq is too low (period too big for choosen base)
|
||
if(stim->htim.Init.Period > 0xFFFF)
|
||
{
|
||
// переносим часть периода в прескалер
|
||
stim->htim.Init.Period = ((stim->htim.Init.Period + 1)/2) - 1;
|
||
stim->htim.Init.Prescaler = ((stim->htim.Init.Prescaler + 1)*2) - 1;
|
||
// обновляем TickBase
|
||
stim->sTickBaseMHz *= 2;
|
||
}
|
||
}
|
||
|
||
//-------------TIM BASE INIT----------------
|
||
// tim base init
|
||
TIM_Base_MspInit(&stim->htim, stim->sTimMode);
|
||
if (HAL_TIM_Base_Init(&stim->htim) != HAL_OK)
|
||
{
|
||
ERROR_HANDLER_NAME();
|
||
return HAL_ERROR;
|
||
}
|
||
|
||
//-------------CLOCK SRC INIT---------------
|
||
// fill sClockSourceConfig if its NULL
|
||
if (stim->sClockSourceConfig.ClockSource == NULL)
|
||
stim->sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
|
||
// clock source init
|
||
if (HAL_TIM_ConfigClockSource(&stim->htim, &stim->sClockSourceConfig) != HAL_OK)
|
||
{
|
||
ERROR_HANDLER_NAME();
|
||
return HAL_ERROR;
|
||
}
|
||
|
||
//--------------SLAVE INIT------------------
|
||
// if slave mode enables - config it
|
||
if (stim->sSlaveConfig.SlaveMode)
|
||
{
|
||
// slave mode init
|
||
if (HAL_TIM_SlaveConfigSynchro(&stim->htim, &stim->sSlaveConfig) != HAL_OK)
|
||
{
|
||
ERROR_HANDLER_NAME();
|
||
return HAL_ERROR;
|
||
}
|
||
}
|
||
//--------------MASTER INIT-----------------
|
||
// master mode init
|
||
if (HAL_TIMEx_MasterConfigSynchronization(&stim->htim, &stim->sMasterConfig) != HAL_OK)
|
||
{
|
||
ERROR_HANDLER_NAME();
|
||
return HAL_ERROR;
|
||
}
|
||
|
||
//--------------BDTR INIT-----------------
|
||
if (HAL_TIMEx_ConfigBreakDeadTime(&stim->htim, &stim->sBreakDeadTimeConfig) != HAL_OK)
|
||
{
|
||
ERROR_HANDLER_NAME();
|
||
return HAL_ERROR;
|
||
}
|
||
|
||
//----------------IT CLEAR-------------------
|
||
__HAL_TIM_CLEAR_IT(&stim->htim, TIM_IT_UPDATE);
|
||
|
||
|
||
// обновляем TickBase
|
||
stim->sTickBaseMHz = (stim->htim.Instance->PSC+1)/stim->sTimAHBFreqMHz;
|
||
stim->htim.Instance->CNT = 0;
|
||
return HAL_OK;
|
||
}
|
||
|
||
|
||
|
||
/**
|
||
* @brief Initialize TIM Encoder functional.
|
||
* @param htim - указатель на хендл таймера.
|
||
* @param sConfigOC - указатель на настрйоки канала таймера.
|
||
* @param GPIOx - порт для приема енкодера.
|
||
* @param GPIO_PIN1 - первый пин для енкодера.
|
||
* @param GPIO_PIN2 - второй пин для енкодера.
|
||
* @param GPIO_PIN_SW - пин для кнопки енкодера.
|
||
* @return HAL status.
|
||
*/
|
||
HAL_StatusTypeDef TIM_Encoder_Init(TIM_EncoderTypeDef *henc1, TIM_HandleTypeDef *htim)
|
||
{
|
||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||
HAL_StatusTypeDef RES = HAL_ERROR;
|
||
henc1->htim = htim;
|
||
|
||
// setup channel for pwm
|
||
RES = HAL_TIM_Encoder_Init(henc1->htim, &henc1->sConfig);
|
||
if (RES != HAL_OK)
|
||
{
|
||
ERROR_HANDLER_NAME();
|
||
return RES;
|
||
}
|
||
// choose port for enable clock
|
||
RES = GPIO_Clock_Enable(henc1->GPIOx);
|
||
if(RES != HAL_OK)
|
||
{
|
||
ERROR_HANDLER_NAME();
|
||
return RES;
|
||
}
|
||
|
||
GPIO_InitStruct.Pin = henc1->GPIO_PIN_TI1|henc1->GPIO_PIN_TI2;
|
||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||
GPIO_InitStruct.Alternate = TIM_Alternate_Mapping(henc1->htim->Instance);
|
||
if(GPIO_InitStruct.Alternate)
|
||
HAL_GPIO_Init(henc1->GPIOx, &GPIO_InitStruct);
|
||
|
||
if(henc1->GPIO_PIN_SW)
|
||
{
|
||
/*Configure switch pin */
|
||
GPIO_InitStruct.Pin = henc1->GPIO_PIN_SW;
|
||
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||
}
|
||
|
||
return HAL_OK;
|
||
}
|
||
|
||
/**
|
||
* @brief Initialize PWM Channel and GPIO for output.
|
||
* @param htim - указатель на хендл таймера.
|
||
* @param sConfigOC - указатель на настрйоки канала таймера.
|
||
* @param TIM_CHANNEL - канал таймера для настройки.
|
||
* @param GPIOx - порт для вывода ШИМ.
|
||
* @param GPIO_PIN - пин для вывода ШИМ.
|
||
* @return HAL status.
|
||
*/
|
||
HAL_StatusTypeDef TIM_Output_PWM_Init(TIM_HandleTypeDef *htim, TIM_OC_InitTypeDef *sConfigOC, uint32_t TIM_CHANNEL, GPIO_TypeDef *GPIOx, uint32_t GPIO_PIN)
|
||
{
|
||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||
HAL_StatusTypeDef RES = HAL_ERROR;
|
||
|
||
// setup channel for pwm
|
||
RES = HAL_TIM_PWM_ConfigChannel(htim, sConfigOC, TIM_CHANNEL);
|
||
if (RES != HAL_OK)
|
||
{
|
||
ERROR_HANDLER_NAME();
|
||
return RES;
|
||
}
|
||
// choose port for enable clock
|
||
RES = GPIO_Clock_Enable(GPIOx);
|
||
if(RES != HAL_OK)
|
||
{
|
||
ERROR_HANDLER_NAME();
|
||
return RES;
|
||
}
|
||
|
||
GPIO_InitStruct.Pin = GPIO_PIN;
|
||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||
if(sConfigOC->OCPolarity == TIM_OCNPOLARITY_HIGH)
|
||
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
|
||
else
|
||
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||
GPIO_InitStruct.Alternate = TIM_Alternate_Mapping(htim->Instance);
|
||
if(GPIO_InitStruct.Alternate)
|
||
HAL_GPIO_Init(GPIOx, &GPIO_InitStruct);
|
||
|
||
return HAL_OK;
|
||
}
|
||
|
||
/**
|
||
* @brief Initialize TIMs clock and interrupt.
|
||
* @param htim - указатель на хендл таймера.
|
||
* @note Чтобы не генерировать функцию с иницилизацией неиспользуемых таймеров,
|
||
дефайнами в tim_general.h определяются используемые таймеры.
|
||
*/
|
||
void TIM_Base_MspInit(TIM_HandleTypeDef* htim, TIM_ITModeTypeDef it_mode)
|
||
{
|
||
it_mode = it_mode&TIM_IT_CONF;
|
||
#ifdef USE_TIM1
|
||
if(htim->Instance==TIM1)
|
||
{
|
||
/* TIM2 clock enable */
|
||
__HAL_RCC_TIM1_CLK_ENABLE();
|
||
|
||
/* TIM2 interrupt Init */
|
||
if(it_mode)
|
||
{
|
||
HAL_NVIC_SetPriority(TIM1_UP_TIM10_IRQn, 0, 0);
|
||
HAL_NVIC_EnableIRQ(TIM1_UP_TIM10_IRQn);
|
||
}
|
||
}
|
||
#endif
|
||
#ifdef USE_TIM2
|
||
if(htim->Instance==TIM2)
|
||
{
|
||
/* TIM2 clock enable */
|
||
__HAL_RCC_TIM2_CLK_ENABLE();
|
||
|
||
/* TIM2 interrupt Init */
|
||
if(it_mode)
|
||
{
|
||
HAL_NVIC_SetPriority(TIM2_IRQn, 0, 0);
|
||
HAL_NVIC_EnableIRQ(TIM2_IRQn);
|
||
}
|
||
}
|
||
#endif
|
||
#ifdef USE_TIM3
|
||
if(htim->Instance==TIM3)
|
||
{
|
||
/* TIM3 clock enable */
|
||
__HAL_RCC_TIM3_CLK_ENABLE();
|
||
|
||
/* TIM3 interrupt Init */
|
||
if(it_mode)
|
||
{
|
||
HAL_NVIC_SetPriority(TIM3_IRQn, 0, 0);
|
||
HAL_NVIC_EnableIRQ(TIM3_IRQn);
|
||
}
|
||
}
|
||
#endif
|
||
#ifdef USE_TIM4
|
||
if(htim->Instance==TIM4)
|
||
{
|
||
/* TIM4 clock enable */
|
||
__HAL_RCC_TIM4_CLK_ENABLE();
|
||
|
||
/* TIM4 interrupt Init */
|
||
if(it_mode)
|
||
{
|
||
HAL_NVIC_SetPriority(TIM4_IRQn, 0, 0);
|
||
HAL_NVIC_EnableIRQ(TIM4_IRQn);
|
||
}
|
||
}
|
||
#endif
|
||
#ifdef USE_TIM5
|
||
if(htim->Instance==TIM5)
|
||
{
|
||
/* TIM5 clock enable */
|
||
__HAL_RCC_TIM5_CLK_ENABLE();
|
||
|
||
/* TIM5 interrupt Init */
|
||
if(it_mode)
|
||
{
|
||
HAL_NVIC_SetPriority(TIM5_IRQn, 0, 0);
|
||
HAL_NVIC_EnableIRQ(TIM5_IRQn);
|
||
}
|
||
}
|
||
#endif
|
||
#ifdef USE_TIM6
|
||
if(htim->Instance==TIM6)
|
||
{
|
||
/* TIM6 clock enable */
|
||
__HAL_RCC_TIM6_CLK_ENABLE();
|
||
|
||
/* TIM6 interrupt Init */
|
||
if(it_mode)
|
||
{
|
||
HAL_NVIC_SetPriority(TIM6_DAC_IRQn, 0, 0);
|
||
HAL_NVIC_EnableIRQ(TIM6_DAC_IRQn);
|
||
}
|
||
}
|
||
#endif
|
||
#ifdef USE_TIM7
|
||
if(htim->Instance==TIM7)
|
||
{
|
||
/* TIM7 clock enable */
|
||
__HAL_RCC_TIM7_CLK_ENABLE();
|
||
|
||
/* TIM7 interrupt Init */
|
||
if(it_mode)
|
||
{
|
||
HAL_NVIC_SetPriority(TIM7_IRQn, 0, 0);
|
||
HAL_NVIC_EnableIRQ(TIM7_IRQn);
|
||
}
|
||
}
|
||
#endif
|
||
#ifdef USE_TIM8
|
||
if(htim->Instance==TIM8)
|
||
{
|
||
/* TIM8 clock enable */
|
||
__HAL_RCC_TIM8_CLK_ENABLE();
|
||
|
||
/* TIM8 interrupt Init */
|
||
if(it_mode)
|
||
{
|
||
HAL_NVIC_SetPriority(TIM8_UP_TIM13_IRQn, 0, 0);
|
||
HAL_NVIC_EnableIRQ(TIM8_UP_TIM13_IRQn);
|
||
}
|
||
}
|
||
#endif
|
||
#ifdef USE_TIM9
|
||
if(htim->Instance==TIM9)
|
||
{
|
||
/* TIM9 clock enable */
|
||
__HAL_RCC_TIM9_CLK_ENABLE();
|
||
|
||
/* TIM9 interrupt Init */
|
||
if(it_mode)
|
||
{
|
||
HAL_NVIC_SetPriority(TIM1_BRK_TIM9_IRQn, 0, 0);
|
||
HAL_NVIC_EnableIRQ(TIM1_BRK_TIM9_IRQn);
|
||
}
|
||
}
|
||
#endif
|
||
#ifdef USE_TIM10
|
||
if(htim->Instance==TIM10)
|
||
{
|
||
/* TIM10 clock enable */
|
||
__HAL_RCC_TIM10_CLK_ENABLE();
|
||
|
||
/* TIM10 interrupt Init */
|
||
if(it_mode)
|
||
{
|
||
HAL_NVIC_SetPriority(TIM1_UP_TIM10_IRQn, 0, 0);
|
||
HAL_NVIC_EnableIRQ(TIM1_UP_TIM10_IRQn);
|
||
}
|
||
}
|
||
#endif
|
||
#ifdef USE_TIM11
|
||
if(htim->Instance==TIM11)
|
||
{
|
||
/* TIM11 clock enable */
|
||
__HAL_RCC_TIM11_CLK_ENABLE();
|
||
|
||
/* TIM11 interrupt Init */
|
||
if(it_mode)
|
||
{
|
||
HAL_NVIC_SetPriority(TIM1_TRG_COM_TIM11_IRQn, 0, 0);
|
||
HAL_NVIC_EnableIRQ(TIM1_TRG_COM_TIM11_IRQn);
|
||
}
|
||
}
|
||
#endif
|
||
#ifdef USE_TIM12
|
||
if(htim->Instance==TIM12)
|
||
{
|
||
/* TIM12 clock enable */
|
||
__HAL_RCC_TIM12_CLK_ENABLE();
|
||
|
||
/* TIM12 interrupt Init */
|
||
if(it_mode)
|
||
{
|
||
HAL_NVIC_SetPriority(TIM8_BRK_TIM12_IRQn, 0, 0);
|
||
HAL_NVIC_EnableIRQ(TIM8_BRK_TIM12_IRQn);
|
||
}
|
||
}
|
||
#endif
|
||
#ifdef USE_TIM13
|
||
if(htim->Instance==TIM13)
|
||
{
|
||
/* TIM13 clock enable */
|
||
__HAL_RCC_TIM13_CLK_ENABLE();
|
||
|
||
/* TIM13 interrupt Init */
|
||
if(it_mode)
|
||
{
|
||
HAL_NVIC_SetPriority(TIM8_UP_TIM13_IRQn, 0, 0);
|
||
HAL_NVIC_EnableIRQ(TIM8_UP_TIM13_IRQn);
|
||
}
|
||
}
|
||
#endif
|
||
#ifdef USE_TIM14
|
||
if(htim->Instance==TIM14)
|
||
{
|
||
/* TIM14 clock enable */
|
||
__HAL_RCC_TIM14_CLK_ENABLE();
|
||
|
||
/* TIM14 interrupt Init */
|
||
if(it_mode)
|
||
{
|
||
HAL_NVIC_SetPriority(TIM8_TRG_COM_TIM14_IRQn, 0, 0);
|
||
HAL_NVIC_EnableIRQ(TIM8_TRG_COM_TIM14_IRQn);
|
||
}
|
||
}
|
||
#endif
|
||
}
|
||
/**
|
||
* @brief DeInitialize TIMs clock and interrupt.
|
||
* @param htim - указатель на хендл таймера.
|
||
* @note Чтобы не генерировать функцию с деиницилизацией неиспользуемых таймеров,
|
||
дефайнами в tim_general.h определяются используемые таймеры.
|
||
*/
|
||
void TIM_Base_MspDeInit(TIM_HandleTypeDef* htim)
|
||
{
|
||
#ifdef USE_TIM1
|
||
if(htim->Instance==TIM1)
|
||
{
|
||
__HAL_RCC_TIM1_FORCE_RESET();
|
||
__HAL_RCC_TIM1_RELEASE_RESET();
|
||
}
|
||
#endif
|
||
#ifdef USE_TIM2
|
||
if(htim->Instance==TIM2)
|
||
{
|
||
__HAL_RCC_TIM2_FORCE_RESET();
|
||
__HAL_RCC_TIM2_RELEASE_RESET();
|
||
}
|
||
#endif
|
||
#ifdef USE_TIM3
|
||
if(htim->Instance==TIM3)
|
||
{
|
||
__HAL_RCC_TIM3_FORCE_RESET();
|
||
__HAL_RCC_TIM3_RELEASE_RESET();
|
||
}
|
||
#endif
|
||
#ifdef USE_TIM4
|
||
if(htim->Instance==TIM4)
|
||
{
|
||
__HAL_RCC_TIM4_FORCE_RESET();
|
||
__HAL_RCC_TIM4_RELEASE_RESET();
|
||
}
|
||
#endif
|
||
#ifdef USE_TIM5
|
||
if(htim->Instance==TIM5)
|
||
{
|
||
__HAL_RCC_TIM5_FORCE_RESET();
|
||
__HAL_RCC_TIM5_RELEASE_RESET();
|
||
}
|
||
#endif
|
||
#ifdef USE_TIM6
|
||
if(htim->Instance==TIM6)
|
||
{
|
||
__HAL_RCC_TIM6_FORCE_RESET();
|
||
__HAL_RCC_TIM6_RELEASE_RESET();
|
||
}
|
||
#endif
|
||
#ifdef USE_TIM7
|
||
if(htim->Instance==TIM7)
|
||
{
|
||
__HAL_RCC_TIM7_FORCE_RESET();
|
||
__HAL_RCC_TIM7_RELEASE_RESET();
|
||
}
|
||
#endif
|
||
#ifdef USE_TIM8
|
||
if(htim->Instance==TIM8)
|
||
{
|
||
__HAL_RCC_TIM8_FORCE_RESET();
|
||
__HAL_RCC_TIM8_RELEASE_RESET();
|
||
}
|
||
#endif
|
||
#ifdef USE_TIM9
|
||
if(htim->Instance==TIM9)
|
||
{
|
||
__HAL_RCC_TIM9_FORCE_RESET();
|
||
__HAL_RCC_TIM9_RELEASE_RESET();
|
||
}
|
||
#endif
|
||
#ifdef USE_TIM10
|
||
if(htim->Instance==TIM10)
|
||
{
|
||
__HAL_RCC_TIM10_FORCE_RESET();
|
||
__HAL_RCC_TIM10_RELEASE_RESET();
|
||
}
|
||
#endif
|
||
#ifdef USE_TIM11
|
||
if(htim->Instance==TIM11)
|
||
{
|
||
__HAL_RCC_TIM11_FORCE_RESET();
|
||
__HAL_RCC_TIM11_RELEASE_RESET();
|
||
}
|
||
#endif
|
||
#ifdef USE_TIM12
|
||
if(htim->Instance==TIM12)
|
||
{
|
||
__HAL_RCC_TIM12_FORCE_RESET();
|
||
__HAL_RCC_TIM12_RELEASE_RESET();
|
||
}
|
||
#endif
|
||
#ifdef USE_TIM13
|
||
if(htim->Instance==TIM13)
|
||
{
|
||
__HAL_RCC_TIM13_FORCE_RESET();
|
||
__HAL_RCC_TIM13_RELEASE_RESET();
|
||
}
|
||
#endif
|
||
#ifdef USE_TIM14
|
||
if(htim->Instance==TIM14)
|
||
{
|
||
__HAL_RCC_TIM14_FORCE_RESET();
|
||
__HAL_RCC_TIM14_RELEASE_RESET();
|
||
}
|
||
#endif
|
||
}
|
||
//-------------------------TIM INIT FUNCTIONS------------------------
|
||
//-------------------------------------------------------------------
|