#include "include.h" #include "app_variable.h" #include "m_remind.h" /* G1 G2 G3 G4 G5 PWM0: PA0 PA6 PB4 PE0 PF0 PWM1: PA1 PA7 PB5 PE1 PF1 PWM2: PA2 PB0 PB6 PE2 PF2 PWM3: PA3 PB1 PB7 PE3 PF3 PWM4: PA4 PB2 PE6 PE4 PF4 PWM5: PA5 PB3 PE7 PE5 PF5 */ static const int pwm_gpio_reg[GPIO_PWM0_MAX] = { IO_PA0, IO_PA6, IO_PB4, IO_PE0, IO_PF0, IO_PA1, IO_PA7, IO_PB5, IO_PE1, IO_PF1, IO_PA2, IO_PB0, IO_PB6, IO_PE2, IO_PF2, IO_PA3, IO_PB1, IO_PB7, IO_PE3, IO_PF3, IO_PA4, IO_PB2, IO_PE6, IO_PE4, IO_PF4, IO_PA5, IO_PB3, IO_PE7, IO_PE5, IO_PF5, }; static bool pwm_freq_is_init = 0; static co_timer_t motor_timer; static motor_t motor_st; /** * @brief 设置PWM的频率 硬件PWM共用一个timer5,频率是一样的,只是占空比分开可调; * @param[in] freq 设置频率 Hz * * @return 返回是否成功 **/ bool bsp_pwm_freq_set(u32 freq) { // TMR5CON = 0; TMR5PR = 26000000/freq; TMR5CPND = BIT(9); TMR5CNT = 0; TMR5CON |= (2<<1) | BIT(0); // xosc26 pwm_freq_is_init = 1; return true; } /** * @brief 设置PWM0的占空比 * @param[in] gpio PWM0对应的GPIO选项 * @param[in] duty 占空比,0-100% * @param[in] invert 输出是否反向 * * @return 返回是否成功 **/ bool bsp_pwm_duty_set(pwm_gpio gpio, u32 duty, bool invert) { // printf("bsp_pwm_duty_set gpio: %d %d\n", gpio,sys_cb.gui_sleep_sta); // printf("bsp_pwm_duty_set duty: %d\n", duty); gpio_t gpio_reg; int group_num, group_id; volatile uint32_t *duty_reg; static bool gpio_motor_is_init = 0; // if (sys_cb.gui_sleep_sta && sys_cb.msg_motor ==false) // { // return false; // } if(gpio >= GPIO_PWM0_MAX){ return false; } if(duty > 100){ duty = 100; } if(pwm_freq_is_init == 0){ bsp_pwm_freq_set(500); // 如果没初始化频率,默认设置为500Hz } //IO Init bsp_gpio_cfg_init(&gpio_reg, pwm_gpio_reg[gpio]); gpio_reg.sfr[GPIOxDE] |= BIT(gpio_reg.num); gpio_reg.sfr[GPIOxPU] &= ~BIT(gpio_reg.num); gpio_reg.sfr[GPIOxDIR] &= ~ BIT(gpio_reg.num); gpio_reg.sfr[GPIOxDRV] |= BIT(gpio_reg.num); if((gpio_motor_is_init == 0) || (gpio != MOTOR_PORT)) { group_num = gpio/5; group_id = gpio - group_num*5; TMR5CON |= BIT(16 + group_num*2); TMR5CON |= invert << (17 + group_num*2); duty_reg = (void *)&TMR5DUTY0 + group_num*4; *duty_reg = TMR5PR*duty/100; FUNCMCON1 = (FUNCMCON1 & (~(0xf << (8 + group_num*4)))) | ((group_id+1) << (8 + group_num*4)); } if(gpio == MOTOR_PORT){ gpio_motor_is_init = 1; } return true; } /** * @brief 关闭pwmx * @param[in] gpio PWMx对应的GPIO选项 * * @return 返回是否成功 **/ bool bsp_pwm_disable(pwm_gpio gpio) { // printf("bsp_pwm_disable: %d\n", gpio); gpio_t gpio_reg; int pwm_num; // if(0 == pwm_freq_is_init) { // return false; // } if(gpio >= GPIO_PWM0_MAX) { return false; } //IO deinit bsp_gpio_cfg_init(&gpio_reg, pwm_gpio_reg[gpio]); gpio_reg.sfr[GPIOxDE] &= ~BIT(gpio_reg.num); gpio_reg.sfr[GPIOxDIR] |= BIT(gpio_reg.num); //TMR5CON deinit if(gpio != MOTOR_PORT){ pwm_num = gpio / 5; TMR5CON &= ~BIT(16 + pwm_num * 2); FUNCMCON1 = (FUNCMCON1 & (~(0xf << (8 + pwm_num * 4)))); } //pwm_freq_is_init = false; return true; } co_timer_callback_t bsp_motor_time_callback(co_timer_t *timer, void *param) { motor_st.time_cnt++; //震动时间 if(motor_st.vibration_times == motor_st.time_cnt && motor_st.motor_sta == true){ bsp_pwm_disable(motor_st.gpio); motor_st.vibration_cnt--; motor_st.time_cnt = 0; motor_st.motor_sta = false; } if (motor_st.interval == motor_st.time_cnt && motor_st.motor_sta == false) { bsp_pwm_duty_set(motor_st.gpio, motor_st.duty, false); motor_st.time_cnt = 0; motor_st.motor_sta = true; } if(motor_st.vibration_cnt == 0){ motor_st.work = false; motor_st.time_cnt = 0; bsp_pwm_disable(motor_st.gpio); co_timer_del(&motor_timer); if(sys_cb.gui_sleep_sta && sys_cb.msg_motor == true) { sys_cb.msg_motor = false; } } return 0; } /** * @brief 设置PWM0的占空比 * @param[in] gpio PWM IO * @param[in] duty 占空比,0-100% * @param[in] vibrationtimes 震动时间,单位100ms * @param[in] interval 震动时间间隔,单位100ms * @param[in] cnt 震动次数 * @return void **/ void bsp_motor_set(pwm_gpio gpio, u32 duty, u32 vibrationtimes, u32 interval, u32 cnt) { // printf("func_cb.sta ==%d\n",func_cb.sta); if(cnt == 0||SysVariable.motor_level == 0||((judge_disturd() == 1)&&(func_cb.sta !=FUNC_REMIND_ALARM && func_cb.sta !=FUNC_FACTORY_TEST_DETAILS&& func_cb.sta !=FUNC_FIND_DEVICE&& func_cb.sta !=FUNC_CAMERA))) { // printf("bbb bsp_motor_set:cnt = %d,SysVariable.motor_level =%d,func_cb.sta =%d,judge_disturd() =%d",cnt,SysVariable.motor_level,func_cb.sta,judge_disturd()); return; } if(motor_st.motor_sta) { return; } motor_st.vibration_times = vibrationtimes; motor_st.interval = interval; motor_st.duty = duty; motor_st.vibration_cnt = cnt; motor_st.motor_sta = true; motor_st.work = true; motor_st.gpio = gpio; motor_st.time_cnt = 0; bsp_pwm_duty_set(motor_st.gpio, duty, false); co_timer_set(&motor_timer, 100, true, false, (void*)bsp_motor_time_callback, 0); return; } void bsp_motor_set_for_alarm(pwm_gpio gpio, u32 duty, u32 vibrationtimes, u32 interval, u32 cnt) { // printf("%s: %d %d %d\n", __func__, duty,cnt,SysVariable.motor_level); if(cnt == 0) { return; } if(motor_st.motor_sta) { return; } motor_st.vibration_times = vibrationtimes; motor_st.interval = interval; motor_st.duty = duty; motor_st.vibration_cnt = cnt; motor_st.motor_sta = true; motor_st.work = true; motor_st.gpio = gpio; bsp_pwm_duty_set(motor_st.gpio, duty, false); co_timer_set(&motor_timer, 100, true, false, (void*)bsp_motor_time_callback, 0); return; } void bsp_motor_stop(pwm_gpio gpio) { motor_st.vibration_cnt = 0; motor_st.motor_sta = false; motor_st.work = false; motor_st.gpio = gpio; bsp_pwm_disable(motor_st.gpio); co_timer_del(&motor_timer); return; } u8 motor_get_state(void) { return motor_st.work; }