работа с регистрами перенесена на уровень hal. Таймер на шим выключается, только если не осталось больше инициализированных каналов

This commit is contained in:
klassents 2024-09-05 11:47:55 +07:00
parent 0ea1ec5b97
commit 4b030d1ad8
3 changed files with 53 additions and 31 deletions

View File

@ -226,6 +226,7 @@ static inline __attribute__((always_inline)) HAL_StatusTypeDef HAL_Timer32_WaitF
void HAL_TIMER32_MspInit(TIMER32_HandleTypeDef* htimer32); void HAL_TIMER32_MspInit(TIMER32_HandleTypeDef* htimer32);
void HAL_TIMER32_Channel_MspInit(TIMER32_CHANNEL_HandleTypeDef* timerChannel); void HAL_TIMER32_Channel_MspInit(TIMER32_CHANNEL_HandleTypeDef* timerChannel);
HAL_StatusTypeDef HAL_Timer32_Init(TIMER32_HandleTypeDef *timer); HAL_StatusTypeDef HAL_Timer32_Init(TIMER32_HandleTypeDef *timer);
HAL_StatusTypeDef HAL_Timer32_Deinit(TIMER32_HandleTypeDef *timer);
void HAL_Timer32_State_Set(TIMER32_HandleTypeDef *timer, HAL_TIMER32_StateTypeDef state); void HAL_Timer32_State_Set(TIMER32_HandleTypeDef *timer, HAL_TIMER32_StateTypeDef state);
void HAL_Timer32_Top_Set(TIMER32_HandleTypeDef *timer, uint32_t top); void HAL_Timer32_Top_Set(TIMER32_HandleTypeDef *timer, uint32_t top);
void HAL_Timer32_Prescaler_Set(TIMER32_HandleTypeDef *timer, uint32_t prescaler); void HAL_Timer32_Prescaler_Set(TIMER32_HandleTypeDef *timer, uint32_t prescaler);

View File

@ -78,6 +78,41 @@ HAL_StatusTypeDef HAL_Timer32_Init(TIMER32_HandleTypeDef *timer)
return HAL_OK; return HAL_OK;
} }
HAL_StatusTypeDef HAL_Timer32_Deinit(TIMER32_HandleTypeDef *timer)
{
if ((timer->Instance != TIMER32_0) && (timer->Instance != TIMER32_1) && (timer->Instance != TIMER32_2))
{
return HAL_ERROR;
}
if (timer->Instance == TIMER32_0)
{
__HAL_PCC_TIMER32_0_CLK_DISABLE();
}
if (timer->Instance == TIMER32_1)
{
__HAL_PCC_TIMER32_1_CLK_DISABLE();
if (timer->Clock.Source == TIMER32_SOURCE_TX_PAD)
HAL_GPIO_PinConfig(GPIO_0, GPIO_PIN_4, HAL_GPIO_MODE_GPIO_INPUT, HAL_GPIO_PULL_NONE, HAL_GPIO_DS_2MA);
}
if (timer->Instance == TIMER32_2)
{
__HAL_PCC_TIMER32_2_CLK_DISABLE();
if (timer->Clock.Source == TIMER32_SOURCE_TX_PAD)
HAL_GPIO_PinConfig(GPIO_1, GPIO_PIN_4, HAL_GPIO_MODE_GPIO_INPUT, HAL_GPIO_PULL_NONE, HAL_GPIO_DS_2MA);
}
HAL_Timer32_InterruptMask_Clear(timer, 0xFFFFFFFF);
HAL_Timer32_Prescaler_Set(timer, 0);
HAL_Timer32_InterruptFlags_ClearMask(timer, 0xFFFFFFFF);
HAL_Timer32_InterruptFlags_Clear(timer);
return HAL_OK;
}
void HAL_Timer32_State_Set(TIMER32_HandleTypeDef *timer, HAL_TIMER32_StateTypeDef state) void HAL_Timer32_State_Set(TIMER32_HandleTypeDef *timer, HAL_TIMER32_StateTypeDef state)
{ {
timer->State = state; timer->State = state;
@ -199,7 +234,7 @@ HAL_StatusTypeDef HAL_Timer32_Channel_Init(TIMER32_CHANNEL_HandleTypeDef *timerC
return HAL_ERROR; return HAL_ERROR;
} }
HAL_TIMER32_Channel_MspInit(timerChannel); // HAL_TIMER32_Channel_MspInit(timerChannel); // здесь инициализируются сразу все каналы выбранного таймера, а нам такого не надо
timerChannel->Instance = (TIMER32_CHANNEL_TypeDef *)&(timerChannel->TimerInstance->CHANNELS[timerChannel->ChannelIndex]); timerChannel->Instance = (TIMER32_CHANNEL_TypeDef *)&(timerChannel->TimerInstance->CHANNELS[timerChannel->ChannelIndex]);
@ -220,6 +255,8 @@ HAL_StatusTypeDef HAL_Timer32_Channel_DeInit(TIMER32_CHANNEL_HandleTypeDef *time
return HAL_ERROR; return HAL_ERROR;
} }
timerChannel->Instance = (TIMER32_CHANNEL_TypeDef *)&(timerChannel->TimerInstance->CHANNELS[timerChannel->ChannelIndex]);
HAL_Timer32_Channel_Disable(timerChannel); HAL_Timer32_Channel_Disable(timerChannel);
HAL_Timer32_Channel_CaptureEdge_Set(timerChannel, 0); HAL_Timer32_Channel_CaptureEdge_Set(timerChannel, 0);
HAL_Timer32_Channel_ICR_Clear(timerChannel); HAL_Timer32_Channel_ICR_Clear(timerChannel);

View File

@ -68,25 +68,8 @@ static TIMER32_HandleTypeDef htimer32;
static TIMER32_CHANNEL_HandleTypeDef htimer32_channel; static TIMER32_CHANNEL_HandleTypeDef htimer32_channel;
static uint32_t WriteValMax = WRITE_VAL_MAX_DEFAULT; static uint32_t WriteValMax = WRITE_VAL_MAX_DEFAULT;
static uint32_t pwmTopVal = PWM_TOP_VAL_DEFAULT; static uint32_t pwmTopVal = PWM_TOP_VAL_DEFAULT;
static bool pwmIsInited = false; static uint8_t pwmIsInited = 0;
HAL_StatusTypeDef Timer32_Channel_Init(TIMER32_CHANNEL_HandleTypeDef *timerChannel)
{
if (timerChannel->TimerInstance == TIMER32_0)
return HAL_ERROR;
// gpio init removed from standard function
timerChannel->Instance = (TIMER32_CHANNEL_TypeDef *)&(timerChannel->TimerInstance->CHANNELS[timerChannel->ChannelIndex]);
HAL_Timer32_Channel_PWM_Invert_Set(timerChannel, timerChannel->PWM_Invert);
HAL_Timer32_Channel_Mode_Set(timerChannel, timerChannel->Mode);
HAL_Timer32_Channel_CaptureEdge_Set(timerChannel, timerChannel->CaptureEdge);
HAL_Timer32_Channel_OCR_Set(timerChannel, timerChannel->OCR);
HAL_Timer32_Channel_ICR_Clear(timerChannel);
HAL_Timer32_Channel_Noise_Set(timerChannel, timerChannel->Noise);
return HAL_OK;
}
/* /*
It is recommended to enable the timer in the following order: It is recommended to enable the timer in the following order:
@ -120,15 +103,15 @@ void analogWrite(uint32_t PinNumber, uint32_t writeVal)
htimer32_channel.PWM_Invert = TIMER32_CHANNEL_NON_INVERTED_PWM; htimer32_channel.PWM_Invert = TIMER32_CHANNEL_NON_INVERTED_PWM;
htimer32_channel.Mode = TIMER32_CHANNEL_MODE_PWM; htimer32_channel.Mode = TIMER32_CHANNEL_MODE_PWM;
htimer32_channel.CaptureEdge = TIMER32_CHANNEL_CAPTUREEDGE_RISING; htimer32_channel.CaptureEdge = TIMER32_CHANNEL_CAPTUREEDGE_RISING;
// cast to uint64_t to avoid overflow when multiplying
htimer32_channel.OCR = (uint32_t) (((uint64_t)pwmTopVal * writeVal) / WriteValMax); htimer32_channel.OCR = (uint32_t) (((uint64_t)pwmTopVal * writeVal) / WriteValMax);
htimer32_channel.Noise = TIMER32_CHANNEL_FILTER_OFF; htimer32_channel.Noise = TIMER32_CHANNEL_FILTER_OFF;
Timer32_Channel_Init(&htimer32_channel); HAL_Timer32_Channel_Init(&htimer32_channel);
// start timer with initialized channel // start timer with initialized channel
HAL_Timer32_Channel_Enable(&htimer32_channel); HAL_Timer32_Channel_Enable(&htimer32_channel);
HAL_Timer32_Value_Clear(&htimer32); HAL_Timer32_Value_Clear(&htimer32);
HAL_Timer32_Start(&htimer32); HAL_Timer32_Start(&htimer32);
pwmIsInited = true; // if at least one channel is working, say that the module is initialized pwmIsInited++; // increase inited channels qty
} }
else if(PinNumber == 10) // pin d10 has pwm, but you cannot use it while spi is running else if(PinNumber == 10) // pin d10 has pwm, but you cannot use it while spi is running
ErrorMsgHandler("analogWrite(): D10 cannot be used as PWM pin while SPI is running"); ErrorMsgHandler("analogWrite(): D10 cannot be used as PWM pin while SPI is running");
@ -165,21 +148,22 @@ It is recommended to turn off the timer in the following order:
*/ */
void analogWriteStop(uint32_t PinNumber) void analogWriteStop(uint32_t PinNumber)
{ {
if (pwmIsInited) if (pwmIsInited > 0)
{ {
// load the timer address and channel number corresponding to the specified pin // load the timer address and channel number corresponding to the specified pin
htimer32.Instance = pwmPinToTimer(PinNumber); htimer32.Instance = pwmPinToTimer(PinNumber);
htimer32_channel.TimerInstance = htimer32.Instance; htimer32_channel.TimerInstance = htimer32.Instance;
htimer32_channel.ChannelIndex = pwmPinToTimerChannel(PinNumber); htimer32_channel.ChannelIndex = pwmPinToTimerChannel(PinNumber);
// in the initChannel function they do it inside, but in deinit they don't. We do it outside // deinit channel
htimer32_channel.Instance = (TIMER32_CHANNEL_TypeDef *)&(htimer32_channel.TimerInstance->CHANNELS[htimer32_channel.ChannelIndex]);
// и все чистим/отключаем
HAL_Timer32_InterruptMask_Clear(&htimer32, 0xFFFFFFFF);
HAL_Timer32_Prescaler_Set(&htimer32, 0);
HAL_Timer32_InterruptFlags_ClearMask(&htimer32, 0xFFFFFFFF);
HAL_Timer32_Channel_DeInit(&htimer32_channel); HAL_Timer32_Channel_DeInit(&htimer32_channel);
pwmIsInited--; // decrease inited channels qty
// stop timer if no inited channels left
if (pwmIsInited == 0)
{
HAL_Timer32_Stop(&htimer32); HAL_Timer32_Stop(&htimer32);
pwmIsInited = false; HAL_Timer32_Deinit(&htimer32);
}
} }
} }