diff --git a/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_timer32.h b/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_timer32.h index 9b3f67e..e044dfd 100644 --- a/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_timer32.h +++ b/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_timer32.h @@ -226,6 +226,7 @@ static inline __attribute__((always_inline)) HAL_StatusTypeDef HAL_Timer32_WaitF void HAL_TIMER32_MspInit(TIMER32_HandleTypeDef* htimer32); void HAL_TIMER32_Channel_MspInit(TIMER32_CHANNEL_HandleTypeDef* timerChannel); 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_Top_Set(TIMER32_HandleTypeDef *timer, uint32_t top); void HAL_Timer32_Prescaler_Set(TIMER32_HandleTypeDef *timer, uint32_t prescaler); diff --git a/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_timer32.c b/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_timer32.c index f5b3fe0..ff715ce 100644 --- a/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_timer32.c +++ b/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_timer32.c @@ -78,6 +78,41 @@ HAL_StatusTypeDef HAL_Timer32_Init(TIMER32_HandleTypeDef *timer) 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) { timer->State = state; @@ -199,7 +234,7 @@ HAL_StatusTypeDef HAL_Timer32_Channel_Init(TIMER32_CHANNEL_HandleTypeDef *timerC return HAL_ERROR; } - HAL_TIMER32_Channel_MspInit(timerChannel); + // HAL_TIMER32_Channel_MspInit(timerChannel); // здесь инициализируются сразу все каналы выбранного таймера, а нам такого не надо 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; } + timerChannel->Instance = (TIMER32_CHANNEL_TypeDef *)&(timerChannel->TimerInstance->CHANNELS[timerChannel->ChannelIndex]); + HAL_Timer32_Channel_Disable(timerChannel); HAL_Timer32_Channel_CaptureEdge_Set(timerChannel, 0); HAL_Timer32_Channel_ICR_Clear(timerChannel); diff --git a/cores/arduino/wiring_analog.c b/cores/arduino/wiring_analog.c index 75449a2..2a8421a 100644 --- a/cores/arduino/wiring_analog.c +++ b/cores/arduino/wiring_analog.c @@ -68,25 +68,8 @@ static TIMER32_HandleTypeDef htimer32; static TIMER32_CHANNEL_HandleTypeDef htimer32_channel; static uint32_t WriteValMax = WRITE_VAL_MAX_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: @@ -120,15 +103,15 @@ void analogWrite(uint32_t PinNumber, uint32_t writeVal) htimer32_channel.PWM_Invert = TIMER32_CHANNEL_NON_INVERTED_PWM; htimer32_channel.Mode = TIMER32_CHANNEL_MODE_PWM; 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.Noise = TIMER32_CHANNEL_FILTER_OFF; - Timer32_Channel_Init(&htimer32_channel); + HAL_Timer32_Channel_Init(&htimer32_channel); + // start timer with initialized channel HAL_Timer32_Channel_Enable(&htimer32_channel); HAL_Timer32_Value_Clear(&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 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) { - if (pwmIsInited) + if (pwmIsInited > 0) { // load the timer address and channel number corresponding to the specified pin htimer32.Instance = pwmPinToTimer(PinNumber); htimer32_channel.TimerInstance = htimer32.Instance; htimer32_channel.ChannelIndex = pwmPinToTimerChannel(PinNumber); - // in the initChannel function they do it inside, but in deinit they don't. We do it outside - 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); + // deinit channel HAL_Timer32_Channel_DeInit(&htimer32_channel); - HAL_Timer32_Stop(&htimer32); - pwmIsInited = false; + pwmIsInited--; // decrease inited channels qty + + // stop timer if no inited channels left + if (pwmIsInited == 0) + { + HAL_Timer32_Stop(&htimer32); + HAL_Timer32_Deinit(&htimer32); + } } }