P0/P1/P2功能实现:接入业务组合根(按键/LED/过零/配网/OTA),联动、11B定时、运行记录、灯泡寿命(DP3/DP4/DP25)、CBR0 VM、512分包

This commit is contained in:
2026-09-08 11:44:20 +08:00
parent 61821de0f8
commit 426bb8dab6
52 changed files with 6042 additions and 313 deletions
+192
View File
@@ -0,0 +1,192 @@
/******************************************************************************
* @file bsp_zc.c
* @brief PA1 过零:MCPWM FPIN 双沿中断,沿到则回调切继电器
* @author cyWu <1917507415@qq.com>
* @date 2026.09.04
* @version V3.1.0
* @history
* - V3.1.0, 2026.09.04, cyWu, 状态收进 BspZcCtx_t,去掉无用计数与排障史注释
* - V3.0.0, 2026.09.04, cyWu, MCPWM FPIN 硬件边沿中断
******************************************************************************/
#include "system/includes.h"
#include "asm/gpio.h"
#include "asm/mcpwm.h"
#include "asm/hwi.h"
#include "asm/irq.h"
#include "asm/timer.h"
#include "bsp_zc.h"
#include "board_pin.h"
#include <string.h>
#define LOG_TAG_CONST APP
#define LOG_TAG "[BSP_ZC]"
#define LOG_INFO_ENABLE
#include "debug.h"
extern PWM_CH_REG *get_pwm_ch_reg(pwm_ch_num_type index);
typedef struct {
BspZcEdgeCb_t edge_cb;
volatile uint32_t edge_cnt;
volatile uint32_t last_edge_ms;
volatile uint8_t last_level;
uint8_t initialized;
} BspZcCtx_t;
static BspZcCtx_t s_zc;
/**
* @brief FPIN 边沿 ISR:清 pending、记沿、执行切变回调
* @note 中断上下文:禁止 printf / 写 VM / 切 BLE
* @return 无
*/
___interrupt
static void bsp_zc_interrupt(void)
{
if (JL_MCPWM->CH0_CON1 & BIT(15)) {
JL_MCPWM->CH0_CON1 |= BIT(14);
} else if (JL_MCPWM->CH1_CON1 & BIT(15)) {
JL_MCPWM->CH1_CON1 |= BIT(14);
} else if (JL_MCPWM->CH2_CON1 & BIT(15)) {
JL_MCPWM->CH2_CON1 |= BIT(14);
} else if (JL_MCPWM->CH3_CON1 & BIT(15)) {
JL_MCPWM->CH3_CON1 |= BIT(14);
} else {
return;
}
s_zc.edge_cnt++;
s_zc.last_edge_ms = (uint32_t)timer_get_ms();
s_zc.last_level = (uint8_t)gpio_read(BOARD_ZC_PIN);
if (s_zc.edge_cb) {
s_zc.edge_cb();
}
}
/**
* @brief 把 PA1 接到一个 FPIN 通道(上升沿或下降沿)
* @param index FPIN 通道 0~3
* @param rising 1=上升沿,0=下降沿
* @return 无
*/
static void bsp_zc_fpin_channel_init(u8 index, u8 rising)
{
PWM_CH_REG *pwm_reg;
if (index > 3) {
return;
}
if (rising) {
JL_MCPWM->FPIN_CON |= BIT(16 + index);
} else {
JL_MCPWM->FPIN_CON &= ~BIT(16 + index);
}
#if BOARD_ZC_FPIN_FILTER_EN
JL_MCPWM->FPIN_CON |= BIT(8 + index);
JL_MCPWM->FPIN_CON |= ((u32)BOARD_ZC_FPIN_FILTER & 0x3FUL);
#else
JL_MCPWM->FPIN_CON &= ~BIT(8 + index);
#endif
gpio_ich_sel_iutput_signal(BOARD_ZC_PIN,
(enum INPUT_CH_SIGNAL)(INPUT_CH_SIGNAL_MC_FPIN0 + index),
INPUT_CH_TYPE_GP_ICH);
request_irq(IRQ_MCPWM_CHX_IDX, 3, bsp_zc_interrupt, 0);
pwm_reg = get_pwm_ch_reg((pwm_ch_num_type)index);
pwm_reg->ch_con1 = BIT(14) | BIT(11) | BIT(4) | (index << 0);
JL_MCPWM->MCPWM_CON0 |= BIT(index);
}
/**
* @brief 初始化 PA1 输入并挂双沿 FPIN 中断
* @param cb 沿回调,NULL 则只计数
* @return 无
*/
void bsp_zc_init(BspZcEdgeCb_t cb)
{
if (s_zc.initialized) {
return;
}
memset(&s_zc, 0, sizeof(s_zc));
s_zc.edge_cb = cb;
gpio_set_die(BOARD_ZC_PIN, 1);
gpio_set_direction(BOARD_ZC_PIN, 1);
gpio_set_pull_up(BOARD_ZC_PIN, BOARD_ZC_PULL_UP);
gpio_set_pull_down(BOARD_ZC_PIN, BOARD_ZC_PULL_DOWN);
s_zc.last_level = (uint8_t)gpio_read(BOARD_ZC_PIN);
#if BOARD_ZC_USE_IRQ
bsp_zc_fpin_channel_init((u8)BOARD_ZC_FPIN_FALL_CH, 0);
#if BOARD_ZC_FPIN_BOTH_EDGE
bsp_zc_fpin_channel_init((u8)BOARD_ZC_FPIN_RISE_CH, 1);
#endif
#endif
s_zc.initialized = 1;
log_info("zc init irq=%d fall=%d rise=%d filt=%d lvl=%d\n",
BOARD_ZC_USE_IRQ, BOARD_ZC_FPIN_FALL_CH,
#if BOARD_ZC_FPIN_BOTH_EDGE
BOARD_ZC_FPIN_RISE_CH,
#else
-1,
#endif
BOARD_ZC_FPIN_FILTER_EN, (int)s_zc.last_level);
}
/**
* @brief 1ms 软件采样兜底(须由真实 1ms 定时器调用)
* @return 无
*/
void bsp_zc_scan_1ms(void)
{
uint8_t lvl;
if (!s_zc.initialized) {
return;
}
lvl = (uint8_t)gpio_read(BOARD_ZC_PIN);
if (lvl != s_zc.last_level) {
s_zc.last_level = lvl;
s_zc.edge_cnt++;
s_zc.last_edge_ms = (uint32_t)timer_get_ms();
if (s_zc.edge_cb) {
s_zc.edge_cb();
}
}
}
/**
* @brief 累计过零沿次数
* @return 沿计数
*/
uint32_t bsp_zc_edge_count(void)
{
return s_zc.edge_cnt;
}
/**
* @brief 最近一次沿的时间戳
* @return timer_get_ms()0=从未检测到
*/
uint32_t bsp_zc_last_edge_ms(void)
{
return s_zc.last_edge_ms;
}
/**
* @brief 当前 PA1 电平
* @return 0 或 1
*/
uint8_t bsp_zc_level(void)
{
return (uint8_t)gpio_read(BOARD_ZC_PIN);
}