#include "timer_driver.h" #include "py32md530.h" #include "system_py32md530.h" #include "config.h" ret_code_t timer_pwm_init(uint32_t freq_hz) { uint32_t prescaler, period; RCC->APB2ENR |= RCC_APB2ENR_TIM1EN; TIM1->CR1 &= ~TIM_CR1_CEN; TIM1->SR = 0; TIM1->BDTR |= TIM_BDTR_MOE_Msk; TIM1->BDTR &= ~TIM_BDTR_BKE_Msk; prescaler = (SystemCoreClock / 1000000) - 1; period = (1000000 / freq_hz) - 1; TIM1->PSC = prescaler; TIM1->ARR = period; TIM1->CCMR1 = (0x6 << 4) | (0x6 << 12); TIM1->CCMR2 = (0x6 << 4); TIM1->CCER |= TIM_CCER_CC1E_Msk | TIM_CCER_CC2E_Msk | TIM_CCER_CC3E_Msk; TIM1->CCER |= TIM_CCER_CC1NE_Msk | TIM_CCER_CC2NE_Msk | TIM_CCER_CC3NE_Msk; TIM1->BDTR |= TIM_BDTR_MOE_Msk; TIM1->EGR |= TIM_EGR_UG_Msk; TIM1->CR1 |= TIM_CR1_ARPE_Msk; TIM1->CR1 |= TIM_CR1_CEN_Msk; return RET_OK; } ret_code_t timer_stepper_pwm_init(uint32_t freq_hz, uint16_t resolution) { if (resolution == 0) return RET_INVALID_PARAM; RCC->APB2ENR |= RCC_APB2ENR_TIM1EN; TIM1->CR1 &= ~TIM_CR1_CEN; TIM1->SR = 0; TIM1->PSC = 0; TIM1->ARR = resolution - 1; TIM1->CCMR1 = (0x6 << 4) | (0x6 << 12); TIM1->CCMR2 = 0; TIM1->CCER |= TIM_CCER_CC1E_Msk | TIM_CCER_CC2E_Msk; TIM1->CCER |= TIM_CCER_CC1NE_Msk | TIM_CCER_CC2NE_Msk; TIM1->CCER &= ~(TIM_CCER_CC3E_Msk | TIM_CCER_CC3NE_Msk); TIM1->BDTR |= TIM_BDTR_MOE_Msk; TIM1->EGR |= TIM_EGR_UG_Msk; TIM1->CR1 |= TIM_CR1_ARPE_Msk; TIM1->CR1 |= TIM_CR1_CEN_Msk; (void)freq_hz; return RET_OK; } ret_code_t timer_pwm_set_duty(timer_channel_t ch, uint16_t duty) { switch (ch) { case TIMER_CHANNEL_1: TIM1->CCR1 = duty; break; case TIMER_CHANNEL_2: TIM1->CCR2 = duty; break; case TIMER_CHANNEL_3: TIM1->CCR3 = duty; break; default: return RET_INVALID_PARAM; } return RET_OK; } ret_code_t timer_pwm_set_compare(timer_channel_t ch, uint16_t compare) { return timer_pwm_set_duty(ch, compare); } ret_code_t timer_pwm_start(void) { TIM1->CR1 |= TIM_CR1_CEN_Msk; TIM1->BDTR |= TIM_BDTR_MOE_Msk; return RET_OK; } ret_code_t timer_pwm_stop(void) { TIM1->BDTR &= ~TIM_BDTR_MOE_Msk; TIM1->CR1 &= ~TIM_CR1_CEN_Msk; return RET_OK; } ret_code_t timer_pwm_deinit(void) { TIM1->CR1 &= ~TIM_CR1_CEN_Msk; TIM1->BDTR = 0; TIM1->CCER = 0; TIM1->SR = 0; RCC->APB2ENR &= ~RCC_APB2ENR_TIM1EN; return RET_OK; } ret_code_t timer_encoder_init(void) { RCC->APB1ENR |= RCC_APB1ENR_TIM3EN; TIM3->CR1 &= ~TIM_CR1_CEN; TIM3->SR = 0; TIM3->PSC = 0; TIM3->ARR = 0xFFFF; TIM3->SMCR = (0x3 << 0); TIM3->CCMR1 = (0x01 << 0) | (0x01 << 8); TIM3->CCER = 0; TIM3->EGR |= TIM_EGR_UG_Msk; TIM3->CR1 |= TIM_CR1_CEN_Msk; return RET_OK; } uint16_t timer_encoder_get_count(void) { return (uint16_t)TIM3->CNT; } void timer_encoder_clear_count(void) { TIM3->CNT = 0; }