P0/P1/P2功能实现:接入业务组合根(按键/LED/过零/配网/OTA),联动、11B定时、运行记录、灯泡寿命(DP3/DP4/DP25)、CBR0 VM、512分包
This commit is contained in:
@@ -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);
|
||||
}
|
||||
Reference in New Issue
Block a user