mcu_ab568x/app/platform/bsp/bsp_pwm.c
2025-05-30 18:03:10 +08:00

247 lines
6.8 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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;
}