KT25-1015_AC695x_SDK310/apps/kaotings/kt_fan_ac.c

240 lines
7.4 KiB
C
Raw Permalink Normal View History

2026-04-20 06:50:04 +00:00
#include "kt_fan_ac.h"
#include "asm/mcpwm.h"
2026-05-20 07:00:27 +00:00
#include "system/timer.h"
2026-04-20 06:50:04 +00:00
#include "tone_player.h"
2026-04-24 08:03:25 +00:00
#include "kt_led7.h"
2026-04-20 06:50:04 +00:00
2026-04-24 08:03:25 +00:00
typedef struct _kt_fan_ac_var_
{
kt_fan_level_type front_fan_level; // 前风扇档位
kt_fan_level_type rear_fan_level; // 后风扇档位
kt_fan_level_type lr_fan_level; // 左右风扇档位
kt_ac_level_type ac_level; // 空调档位
2026-04-20 06:50:04 +00:00
} _kt_fan_ac_var;
static _kt_fan_ac_var kt_fan_ac_var;
2026-04-24 08:03:25 +00:00
#define __this (&kt_fan_ac_var)
2026-04-20 06:50:04 +00:00
2026-05-20 07:00:27 +00:00
#define KT_FAN_PWM_FREQ 50000
#define KT_AC_PWM_FREQ 100000
#define KT_AC_RUN_DUTY 4000 /* 空调运行占空比 40% */
#define KT_AC_BURST_MS 1000 /* AC1 断续1s 开 / 1s 关 */
/* 1: 上电即输出不同占空比,便于示波器/万用表区分各路;量产改 0 */
2026-05-20 20:03:53 +00:00
#define KT_PWM_BOOT_TEST_EN 0
2026-05-20 07:00:27 +00:00
2026-04-24 08:03:25 +00:00
const u32 fan_level_duty[7] = {0, 1500, 4000, 6000, 7000, 8000, 9500};
2026-05-20 07:00:27 +00:00
static u16 ac_burst_timer;
static u8 ac_burst_pwm_on;
2026-04-20 06:50:04 +00:00
const char *front_fan_level_tone[7] = {TONE_FFAN_L0, TONE_FFAN_L1, TONE_FFAN_L2, TONE_FFAN_L3, TONE_FFAN_L4, TONE_FFAN_L5, TONE_FFAN_L6};
const char *rear_fan_level_tone[7] = {TONE_BFAN_L0, TONE_BFAN_L1, TONE_BFAN_L2, TONE_BFAN_L3, TONE_BFAN_L4, TONE_BFAN_L5, TONE_BFAN_L6};
const char *lr_fan_level_tone[7] = {TONE_CFAN_L0, TONE_CFAN_L1, TONE_CFAN_L2, TONE_CFAN_L3, TONE_CFAN_L4, TONE_CFAN_L5, TONE_CFAN_L6};
const char *ac_level_tone[3] = {TONE_AC_L0, TONE_AC_L1, TONE_AC_L2};
2026-04-24 08:03:25 +00:00
extern void mcpwm_init(struct pwm_platform_data *arg);
extern void mcpwm_set_duty(pwm_ch_num_type pwm_ch, pwm_timer_num_type timer_ch, u16 duty);
2026-04-20 06:50:04 +00:00
2026-05-20 07:00:27 +00:00
static void kt_ac_burst_stop(void)
{
if (ac_burst_timer) {
sys_timer_del(ac_burst_timer);
ac_burst_timer = 0;
}
}
static void kt_ac_pwm_output(u16 duty)
{
2026-05-20 20:03:53 +00:00
mcpwm_set_duty(pwm_ch3, pwm_timer3, duty);
2026-05-20 07:00:27 +00:00
}
static void kt_ac_burst_cb(void *priv)
{
(void)priv;
if (__this->ac_level != ac_level_1) {
return;
}
ac_burst_pwm_on = !ac_burst_pwm_on;
kt_ac_pwm_output(ac_burst_pwm_on ? KT_AC_RUN_DUTY : 0);
}
static void kt_ac_apply_mode(void)
2026-04-20 06:50:04 +00:00
{
2026-05-20 07:00:27 +00:00
kt_ac_burst_stop();
switch (__this->ac_level) {
case ac_level_0:
ac_burst_pwm_on = 0;
kt_ac_pwm_output(0);
break;
case ac_level_1:
ac_burst_pwm_on = 1;
kt_ac_pwm_output(KT_AC_RUN_DUTY);
ac_burst_timer = sys_timer_add(NULL, kt_ac_burst_cb, KT_AC_BURST_MS);
break;
case ac_level_2:
ac_burst_pwm_on = 1;
kt_ac_pwm_output(KT_AC_RUN_DUTY);
break;
default:
ac_burst_pwm_on = 0;
kt_ac_pwm_output(0);
break;
}
}
2026-04-20 06:50:04 +00:00
2026-05-20 07:00:27 +00:00
void kt_fan_ac_init(void)
{
/*
* PB5 : MCPWM CH0 + output_channel 0
* PB6 : MCPWM CH2 L
* PA10: MCPWM CH4 L
2026-05-20 20:03:53 +00:00
* PB9 : MCPWM CH3 H 100kHz
2026-05-20 07:00:27 +00:00
*/
#if KT_PWM_BOOT_TEST_EN
/* 前15% / 后40% / 左右60% / 空调80%,上电即可区分四路 */
__this->front_fan_level = fan_level_1;
__this->rear_fan_level = fan_level_2;
__this->lr_fan_level = fan_level_3;
__this->ac_level = ac_level_2;
#else
2026-04-20 06:50:04 +00:00
__this->front_fan_level = fan_level_0;
__this->rear_fan_level = fan_level_0;
__this->lr_fan_level = fan_level_0;
__this->ac_level = ac_level_0;
2026-05-20 07:00:27 +00:00
#endif
2026-04-24 08:03:25 +00:00
struct pwm_platform_data pwm_p_data;
2026-05-20 07:00:27 +00:00
/* 前风扇 PB5 */
pwm_p_data.pwm_aligned_mode = pwm_edge_aligned;
pwm_p_data.frequency = KT_FAN_PWM_FREQ;
pwm_p_data.pwm_ch_num = pwm_ch0;
pwm_p_data.pwm_timer_num = pwm_timer0;
pwm_p_data.duty = fan_level_duty[__this->front_fan_level];
pwm_p_data.h_pin = KT_CFG_FRONT_FAN_PIN;
2026-04-24 08:03:25 +00:00
pwm_p_data.l_pin = -1;
2026-05-20 07:00:27 +00:00
pwm_p_data.h_pin_output_ch_num = 0;
pwm_p_data.complementary_en = 0;
2026-04-24 08:03:25 +00:00
mcpwm_init(&pwm_p_data);
2026-05-20 07:00:27 +00:00
/* 后风扇 PB6 */
pwm_p_data.pwm_aligned_mode = pwm_edge_aligned;
pwm_p_data.frequency = KT_FAN_PWM_FREQ;
pwm_p_data.pwm_ch_num = pwm_ch2;
pwm_p_data.pwm_timer_num = pwm_timer2;
pwm_p_data.duty = fan_level_duty[__this->rear_fan_level];
pwm_p_data.h_pin = -1;
pwm_p_data.l_pin = KT_CFG_REAR_FAN_PIN;
pwm_p_data.complementary_en = 0;
2026-04-24 08:03:25 +00:00
mcpwm_init(&pwm_p_data);
2026-05-20 07:00:27 +00:00
/* 左右风扇 PA10 */
pwm_p_data.pwm_aligned_mode = pwm_edge_aligned;
pwm_p_data.frequency = KT_FAN_PWM_FREQ;
pwm_p_data.pwm_ch_num = pwm_ch4;
pwm_p_data.pwm_timer_num = pwm_timer4;
pwm_p_data.duty = fan_level_duty[__this->lr_fan_level];
pwm_p_data.h_pin = -1;
pwm_p_data.l_pin = KT_CFG_LR_FAN_PIN;
pwm_p_data.complementary_en = 0;
mcpwm_init(&pwm_p_data);
2026-05-20 20:03:53 +00:00
/* 空调 PB9 */
pwm_p_data.pwm_aligned_mode = pwm_edge_aligned;
pwm_p_data.frequency = KT_AC_PWM_FREQ;
pwm_p_data.pwm_ch_num = pwm_ch3;
pwm_p_data.pwm_timer_num = pwm_timer3;
pwm_p_data.duty = 0;
pwm_p_data.h_pin = KT_CFG_AIR_COND_PIN;
pwm_p_data.l_pin = -1;
pwm_p_data.complementary_en = 0;
mcpwm_init(&pwm_p_data);
2026-05-20 07:00:27 +00:00
kt_ac_apply_mode();
#if KT_PWM_BOOT_TEST_EN
2026-05-20 20:03:53 +00:00
printf("PWM boot test: PB5=%u%% PB6=%u%% PA10=%u%% PB9=AC%d\n",
2026-05-20 07:00:27 +00:00
fan_level_duty[__this->front_fan_level] / 100,
fan_level_duty[__this->rear_fan_level] / 100,
fan_level_duty[__this->lr_fan_level] / 100,
__this->ac_level);
2026-04-24 08:03:25 +00:00
#endif
2026-04-20 06:50:04 +00:00
}
void kt_fan_level_tone_play(kt_fan_type fan)
{
if (fan == fan_type_front)
{
2026-04-24 08:03:25 +00:00
char str[6] = {0};
sprintf(str, "L-%d", __this->front_fan_level);
kt_led7_show_string(3, 0, (const u8 *)str, 0, 0);
2026-04-20 06:50:04 +00:00
tone_play(front_fan_level_tone[__this->front_fan_level], 0);
}
else if (fan == fan_type_rear)
{
2026-04-24 08:03:25 +00:00
char str[6] = {0};
sprintf(str, "F-%d", __this->rear_fan_level);
kt_led7_show_string(3, 0, (const u8 *)str, 0, 0);
2026-04-20 06:50:04 +00:00
tone_play(rear_fan_level_tone[__this->rear_fan_level], 0);
}
else if (fan == fan_type_lr)
{
2026-04-24 08:03:25 +00:00
char str[6] = {0};
sprintf(str, "C-%d", __this->lr_fan_level);
kt_led7_show_string(3, 0, (const u8 *)str, 0, 0);
2026-04-20 06:50:04 +00:00
tone_play(lr_fan_level_tone[__this->lr_fan_level], 0);
}
else
{
2026-04-24 08:03:25 +00:00
char str[6] = {0};
sprintf(str, "AC%d", __this->ac_level);
kt_led7_show_string(3, 0, (const u8 *)str, 0, 0);
2026-04-20 06:50:04 +00:00
tone_play(ac_level_tone[__this->ac_level], 0);
}
}
void kt_fan_level_change(kt_fan_type fan)
{
if (fan == fan_type_front)
{
__this->front_fan_level++;
if (__this->front_fan_level > fan_level_6)
{
__this->front_fan_level = fan_level_0;
}
kt_fan_level_tone_play(fan_type_front);
2026-04-24 08:03:25 +00:00
mcpwm_set_duty(pwm_ch0, pwm_timer0, fan_level_duty[__this->front_fan_level]);
2026-04-20 06:50:04 +00:00
}
else if (fan == fan_type_rear)
{
__this->rear_fan_level++;
if (__this->rear_fan_level > fan_level_6)
{
__this->rear_fan_level = fan_level_0;
}
kt_fan_level_tone_play(fan_type_rear);
2026-05-20 07:00:27 +00:00
mcpwm_set_duty(pwm_ch2, pwm_timer2, fan_level_duty[__this->rear_fan_level]);
2026-04-20 06:50:04 +00:00
}
else if (fan == fan_type_lr)
{
__this->lr_fan_level++;
if (__this->lr_fan_level > fan_level_6)
{
__this->lr_fan_level = fan_level_0;
}
kt_fan_level_tone_play(fan_type_lr);
2026-05-20 07:00:27 +00:00
mcpwm_set_duty(pwm_ch4, pwm_timer4, fan_level_duty[__this->lr_fan_level]);
2026-04-20 06:50:04 +00:00
}
else
{
__this->ac_level++;
if (__this->ac_level > ac_level_2)
{
__this->ac_level = ac_level_0;
}
kt_fan_level_tone_play(fan_type_ac);
2026-05-20 07:00:27 +00:00
kt_ac_apply_mode();
2026-04-20 06:50:04 +00:00
}
2026-05-20 07:00:27 +00:00
}