/*
 * @Author       : stark1898y 1658608470@qq.com
 * @Date         : 2024-12-15 15:01:15
 * @LastEditors  : stark1898y 1658608470@qq.com
 * @LastEditTime : 2025-06-03 10:43:05
 * @FilePath     : \BLE_TYQ_CH584M\BSP\src\bsp_valve.c
 * @Description  :
 *
 * Copyright (c) 2024 by yzy, All Rights Reserved.
 */
#include "bsp_valve.h"
#include "bsp_flash.h"

#include "bsp_i2c.h"

#include "bsp_beep_led_emv.h"
// 0xAA CMD/DATA/ DATA_LEN (DATA) checksum 0x55

#include "bsp_uart.h"
#include "log.h"

#include "peripheral.h"

#include "SLEEP.h"

#include "bsp_adc.h"

#undef LOG_ENABLE
#define LOG_ENABLE 1

#undef LOG_TAG
#define LOG_TAG "BSP_VALVE"

volatile uint8_t boost_en_flag = 0;

TsValveData gValveData = {0};
uint16_t bat_mv;

TsRawFrameData RelyData;

// 存储 当前task id 的全局变量
tmosTaskID vavle_task_id = INVALID_TASK_ID;

#define ARRAY_SIZE(freq_arr) (sizeof(freq_arr) / sizeof((freq_arr)[0]))

volatile uint8_t cap_flag = 0;
__attribute__((aligned(4))) uint32_t cap_buf[20];

#define CAP_BUF_LEN  (20)

#define CAP_FREQ_MIN (2000U)
#define CAP_FREQ_MAX (10000U)

uint16_t valve_switch_on_freq = 6535;
uint16_t valve_switch_off_freq = 7508;

uint16_t valve_switch_freq = 0;

volatile uint8_t valve_switch_dect_flag = 0;

/**
 * @description: 从帧起始符开始到校验码之前所有字节的和的模256，即各字节不计超过255的溢出值的二进制算术和。
 * @param {uint8_t} *data
 * @param {uint16_t} len
 * @return {*}
 */
uint8_t CheckSum(const uint8_t *data, size_t len)
{
    uint8_t sum = 0;

    for (size_t i = 0; i < len; i++)
    {
        sum += data[i];
    }

    return sum;
}

void VavleDect_Start(void)
{
    BSP_BlockSleep();
    BSP_RequestBoost();
    DelayMs(1);

    tmos_memset(cap_buf, 0, sizeof(cap_buf));

    TMR3_CapInit(FallEdge_To_FallEdge);
    TMR3_CAPTimeoutCfg(GetSysClock() / 100); // 设置捕捉超时时间 10ms

    TMR3_DMACfg(ENABLE, (uint16_t)(uint32_t)&cap_buf[0]
        , (uint16_t)(uint32_t)&cap_buf[CAP_BUF_LEN], Mode_Single);
    TMR3_ITCfg(ENABLE, TMR0_3_IT_DMA_END); // 开启DMA完成中断
    PFIC_EnableIRQ(TMR3_IRQn);

    logDebug("VavleDect_Start");
}

// 一个数组中，去掉最大最小值，计算平均值
uint16_t VavleDect_CalFreq(uint16_t freq_arr[], uint8_t n)
{
    if (freq_arr == NULL || n <= 2)
    {
        logError("数组太小或为空，无法去除最大最小值");
        return 0;
    }

    uint16_t min, max;
    double average = 0;

    for (uint8_t i = 0; i < n; i++)
    {
        average += freq_arr[i];
        if (i == 0)
        {
            min = freq_arr[i];
            max = freq_arr[i];
        }
        min = ((min > freq_arr[i]) ? freq_arr[i] : min); // 软件滤波
        max = ((max < freq_arr[i]) ? freq_arr[i] : max);
    }
    logDebug("min = %d, max = %d", min, max);
    average = (average - min - max) / (CAP_BUF_LEN - 2);

    return (uint16_t)average;
}

uint16_t VavleDect_GetFreq(void)
{
    uint16_t freq = 0;
    if (cap_flag == 0)
    {
        // TMR3_ITCfg(DISABLE, TMR0_3_IT_DMA_END); // 使用单次DMA功能+中断，注意完成后关闭此中断使能，否则会一直上报中断。
        // TMR3_ClearITFlag(TMR0_3_IT_DMA_END);    // 清除中断标志
        logError("cap err");
        return 0;
    }
    cap_flag = 0;
    uint16_t t[CAP_BUF_LEN] = {0};
    uint16_t f[CAP_BUF_LEN] = {0};
    for (uint8_t i = 0; i < CAP_BUF_LEN; i++)
    {
        // logDebug("%08ld ", cap_buf[i] & 0x1ffffff); // 26bit, 最高位表示 高电平还是低电平
        t[i] = ((cap_buf[i] & 0x1ffffff) * 1.0f) / FREQ_SYS * 1000000;
        f[i] = 1000000 / t[i];
        logDebug("T = %04d us, f = %04d Hz", t[i], f[i]);
        BSP_UART1_TxLoop();
    }
    freq = VavleDect_CalFreq(&f[0], CAP_BUF_LEN);

    return freq;
}

void VavleDect_Switch(void)
{
    if (valve_switch_freq == 0)
    {
        gValveData.switch_status = kDisconnect;
        logError("valve_switch_freq err");
        return;
    }
    if (valve_switch_freq >= (valve_switch_off_freq - 100))
    {
        gValveData.switch_status = kOpened;
        logDebug("valve_switch_on");
    }
    else if (valve_switch_freq <= (valve_switch_on_freq + 100))
    {
        gValveData.switch_status = kClosed;
        logDebug("valve_switch_off");
    }
}

TsFrameData *BSP_VAVLE_GetFrameData(uint8_t *data, uint8_t len)
{
    int ret        = 0;
    uint16_t index = 0;

    TsFrameData *get_buffer = NULL;
    // 解析接收到的数据帧，先寻找AA开头，然后再找AA下一个字节，其代表了数据长度，然后找到代表长度的值的长度的下一位，其为校验码，校验码后为结束码0x55，
    // 如果数据正确，则提取数据，不正确，则不处理
    if (len < 4)
    { // 至少需要 4 个字节：起始码、长度、校验码、结束码
        logError("数据帧长度不足");
        // logHexDumpAll(data, len);
        // return 1;
        return NULL;
    }
    while (index < len && data[index] != FRAME_HEADER) // 寻找起始码 0xAA
    {
        index++;
    }
    if (index >= len - 3) // 不够空间容纳长度、校验码和结束码
    {
        logError("数据帧起始码错误");
        // logHexDumpAll(data, len);
        return NULL;
        // return 2;
    }
    uint16_t data_len = data[index + 2]; // 读取数据长度
    if (index + 3 + data_len + 1 >= len) // 检查数据长度是否合理 数据长度 + 校验码 + 结束码
    {
        logError("数据帧长度错误");
        // logHexDumpAll(data, len);
        return NULL;
        // return 3;
    }

    uint8_t check_sum      = data[index + 3 + data_len];           // 读取校验码
    uint8_t calculated_sum = CheckSum(&data[index], data_len + 3); // 计算校验码
    if (check_sum != calculated_sum)
    {
        logError("数据帧校验码错误 check_sum = %02X, calculated_sum = %02X", check_sum, calculated_sum);
        // logHexDumpAll(data, len);
        return NULL;
        // return 4;
    }
    if (data[index + 3 + data_len + 1] != FRAME_TAIL) // 检查结束码
    {
        logError("数据帧结束码错误");
        // logHexDumpAll(data, len);
        return NULL;
        // return 5;
    }
    logDebug("数据帧校验通过");

    get_buffer = (TsFrameData *)tmos_msg_allocate(sizeof(TsFrameData) + sizeof(uint8_t) * data_len);
    if (get_buffer == NULL)
    {
        logError("tmos_msg_allocate fail");
        return NULL;
    }

    get_buffer->cmd = data[index + 1];
    get_buffer->len = data_len;
    //    get_buffer->data = data;

    if (data_len > 0)
    {
        tmos_memcpy(get_buffer->data, &data[index + 3], data_len);
        return get_buffer;
    }

    // //有效数据长度
    // size_t data_len = (data_len + 5);
    // //到这一步说明数据没问题，将接收到的数据通过中心任务发送出去
    // uint8_t *p_data;
    // p_data = tmos_msg_allocate(data_len);
    // if (p_data)
    // {
    //     tmos_memcpy(p_data, data, data_len);
    //     tmos_msg_send(BtRxTaskId, p_data);
    //     tmos_start_task(BtRxTaskId, SYS_EVENT_MSG, 0);
    // }
}

uint8_t GenerateRawFrame(TsRawFrameData *pRawData, uint8_t cmd, const uint8_t *p_src, uint8_t src_len)
{
    // 0xAA CMD/DATA/ DATA_LEN (DATA) checksum 0x55
    pRawData->len = src_len + 5;

    tmos_memset(pRawData->buf, 0, sizeof(pRawData->buf));

    pRawData->buf[0] = FRAME_HEADER;
    pRawData->buf[1] = cmd;
    pRawData->buf[2] = src_len;

    tmos_memcpy(&pRawData->buf[3], p_src, src_len);

    // 从帧起始符开始到校验码之前所有字节的和的模256
    // ，即各字节不计超过255的溢出值的二进制算术和。
    pRawData->buf[pRawData->len - 2] = CheckSum(&pRawData->buf[0], pRawData->len - 2);
    pRawData->buf[pRawData->len - 1] = FRAME_TAIL;

    // logHexDumpAll(&pRawData->buf[0], pRawData->len);

    return 0;
}

void BSP_VALVE_Generate_UploadData(TsRawFrameData *pRawData)
{
    GenerateRawFrame(pRawData, kCmdData, (uint8_t *)&gValveData, sizeof(gValveData));
    // logHexDumpAll(&pRawData->buf[0], pRawData->len);
}

void BSP_VALVE_Generate_Data(TsRawFrameData *pRawData, uint8_t switch_status, uint8_t bat, int8_t temp, uint8_t humi)
{
    TsValveData ValveData;

    ValveData.switch_status = 0;
    ValveData.temp          = temp; // 阀门温度 有符号整数 25 ℃

    ValveData.in_pressure  = 0;
    ValveData.out_pressure = 0;
    ValveData.atm_pressure = 0;

    ValveData.type = kTyq; // 阀门类型
    ValveData.bat  = bat;  // 电池电压 30=3V,18=1.8V
    ValveData.humi  = humi;  // 阀门湿度 %RH

    ValveData.rssi = 0;

    GenerateRawFrame(pRawData, kCmdData, (uint8_t *)&ValveData, sizeof(ValveData));
    // logHexDumpAll(&pRawData->buf[0], pRawData->len);
}

void BSP_VALVE_Generate_ValveResponse(TsRawFrameData *pRawData, TeFrameCmd cmd, uint8_t status)
{
    uint8_t data = 0;
    data         = status;
    GenerateRawFrame(pRawData, cmd, &data, 1);
    // logHexDumpAll(&pRawData->buf[0], pRawData->len);
}

static void VAVLE_Task_ProcessTmosMsg(uint8_t *p_rev_msg)
{
    if (p_rev_msg)
    {
#if 1
        TsFrameData *HostFrameData = BSP_VAVLE_GetFrameData(&p_rev_msg[1], p_rev_msg[0]);
        if (HostFrameData != NULL)
        {
            // logHexDumpAll(&HostFrameData->data[0], HostFrameData->len); // 数据段
            switch (HostFrameData->cmd)
            {
                case kCmdCfg:
                    // uint8_t data_buf[64] = {0};
                    // tmos_memset(data_buf, 0, sizeof(data_buf));
                    // 处理数据帧
                    logDebug("kCmdCfg");
                    break;
                case kCmdCloseVavle:
                    logDebug("kCmdCloseVavle");
                    tmos_set_event(vavle_task_id, VAVLE_CLOSE_START_EVT);

                    // TODO:注意这里

                    // tmos_set_event(vavle_task_id, VAVLE_CLOSE_START_EVT);
                    // // TODO: 关阀动作
                    // peripheralChar4Notify((uint8_t *)&RawData.buf[0], RawData.len);
                    break;

                case kCmdOpenVavle:
                    logDebug("kCmdOpenVavle");

                    // BSP_UART1_TxLoop();
                    break;
                default:
                    logError("无效的命令");
                    //                    logHexDumpAll(data, len);
                    break;
            }
        }
        else
        {
            logError("数据帧解析失败");
        }
        tmos_msg_deallocate((uint8_t *)HostFrameData);
        // tmos_set_event(led_task_id, LED_SHOW_START_EVT);
        HostFrameData = NULL;
#endif
    }
    else
    {
        logError("pMsg is NULL");
    }
}

// task的event处理回调函数,需要在注册task时候,传进去
static uint16_t VAVLE_Task_ProcessEvent(uint8_t task_id, uint16_t events)
{
    if (events & SYS_EVENT_MSG)
    {
        uint8_t *p_rev_msg;
        if ((p_rev_msg = tmos_msg_receive(vavle_task_id)) != NULL)
        {
            VAVLE_Task_ProcessTmosMsg(p_rev_msg);
            // Release the TMOS message
            tmos_msg_deallocate(p_rev_msg);
        }
        // return unprocessed events
        return (events ^ SYS_EVENT_MSG);
    }
    if (events & VAVLE_RX_DATA_EVT)
    {
        logDebug("VAVLE_RX_DATA_EVT");

        return (events ^ VAVLE_RX_DATA_EVT);
    }
    if (events & VAVLE_TX_DATA_EVT)
    {
        logDebug("VAVLE_TX_DATA_EVT");

        return (events ^ VAVLE_TX_DATA_EVT);
    }
    if (events & VAVLE_CLOSE_START_EVT)
    {
        logDebug("VAVLE_CLOSE_START_EVT");
        // DelayMs(1);
        BSP_BlockSleep();
        BSP_RequestBoost();
        boost_en_flag = 1;
        // DelayMs(10);

        EMV_CHARGE_EN;

        logDebug("EMV_CHARGE_EN");

        // 开始一个定时event,1s后产生,当前语句只会产生一次event
        // 可以在event产生后去开启event,可以是别的task的,也可以是当前task的event
        tmos_start_task(vavle_task_id, VAVLE_CLOSE_ACTION_EVT, MS1_TO_SYSTEM_TIME(CHARGE_TIME_MS));

        return (events ^ VAVLE_CLOSE_START_EVT);
    }
    if (events & VAVLE_CLOSE_ACTION_EVT)
    {
        BSP_BlockSleep();
        BSP_RequestBoost();
        logDebug("VAVLE_CLOSE_ACTION_EVT");

        // BOOST_EN;
        // EMV_CHARGE_EN;
        // 关阀动作,一定要先关充电的，防止其他12V用电
        EMV_CHARGE_OFF_DEINIT;

        // BEEP_ON;
        LED_R_ON;

        logDebug("EMV_CHARGE_OFF_DEINIT");

        // DelayMs(10);

        // EMV_CTRL
        EMV_ON;
        // DelayMs(50);

        // {BEEP_OFF_DEINIT;

        // EMV_CHARGE_OFF_DEINIT;
        // EMV_OFF_DEINIT;

        // BSP_NoNeedBoost();

        // gValveData.switch_status = kClosed;

        // tmos_memset(&RelyData, 0, sizeof(RelyData));
        // BSP_VALVE_Generate_ValveResponse(&RelyData, kCmdCloseVavle, 1);

        // tmos_set_event(Peripheral_TaskID, SBP_REPLY_CMD_EVT);}

        logDebug("EMV_ON");
        tmos_start_task(vavle_task_id, VAVLE_CLOSE_END_EVT, MS1_TO_SYSTEM_TIME(100));

        return (events ^ VAVLE_CLOSE_ACTION_EVT);
    }
    if (events & VAVLE_CLOSE_END_EVT)
    {
        BEEP_OFF_DEINIT;

        EMV_CHARGE_OFF_DEINIT;
        EMV_OFF_DEINIT;

        LED_ALL_OFF_DEINIT;

        BSP_NoNeedBoost();

        gValveData.switch_status = kClosed;

        tmos_memset(&RelyData, 0, sizeof(RelyData));
        BSP_VALVE_Generate_ValveResponse(&RelyData, kCmdCloseVavle, 1);

        tmos_set_event(Peripheral_TaskID, SBP_REPLY_CMD_EVT);

        logDebug("VAVLE_CLOSE_END_EVT");
        boost_en_flag = 0;
        return (events ^ VAVLE_CLOSE_END_EVT);
    }
#if 0
    // 开始测量电磁铁电感
    if (events & VAVLE_DECT_SWITCH_START_EVT)
    {
        valve_switch_dect_flag = 0;
        logDebug("VAVLE_DECT_SWITCH_START_EVT");
        VavleDect_Start();
        tmos_start_task(vavle_task_id, VAVLE_DECT_SWITCH_END_EVT, MS1_TO_SYSTEM_TIME(12));
        return (events ^ VAVLE_DECT_SWITCH_START_EVT);
    }
    if (events & VAVLE_DECT_SWITCH_END_EVT)
    {
        logDebug("VAVLE_DECT_SWITCH_END_EVT");

        valve_switch_freq = VavleDect_GetFreq();
        logDebug("valve_switch_freq = 04%d Hz", valve_switch_freq);
        VavleDect_Switch();
        valve_switch_dect_flag = 1;

        logDebug("LED显示状态");
        // tmos_set_event(led_task_id, LED_SHOW_START_EVT);
        BSP_BlockSleep();
        BSP_RequestBoost();
        DelayMs(1);
        ShowLed();

        return (events ^ VAVLE_DECT_SWITCH_END_EVT);
    }
    if (events & VAVLE_DECT_SWITCH_CALIB_EVT)
    {
        logDebug("VAVLE_DECT_SWITCH_CALIB_EVT");

        return (events ^ VAVLE_DECT_SWITCH_CALIB_EVT);
    }
#endif
    if (events & VAVLE_LOW_VBAT_ALARM_EVT)
    {
        logDebug("VAVLE_LOW_VBAT_ALARM_EVT");

        // BSP_BlockSleep();
        // BSP_RequestBoost();

        // LED_ALL_OFF_DEINIT;
        // LED_Y_ON;

        // BEEP_ON;

        // DelayMs(10);

        // LED_ALL_OFF_DEINIT;
        // BEEP_OFF_DEINIT;

        // BSP_NoNeedBoost();
        // BSP_RequestSleep();

        // tmos_set_event(vavle_task_id, VAVLE_CLOSE_START_EVT);

        // tmos_start_task(vavle_task_id, VAVLE_LOW_VBAT_ALARM_EVT, MS1_TO_SYSTEM_TIME(VALVE_LOW_VBAT_ALARM_PERIOD_MS));

        return (events ^ VAVLE_LOW_VBAT_ALARM_EVT);
    }
    if (events & VAVLE_LOOP_DECT_EVT)
    {
        logDebug("VAVLE_LOOP_DECT_EVT");
        // if (GPIOA_ReadITFlagBit(BOOST_APIN) == 0)
        if (boost_en_flag == 0)
        {
            // TODO：亮灯或者蜂鸣器的时候读电压就低了
            gValveData.bat = BSP_ReadVbat();

            // 电压过低就关阀
            // if (gValveData.bat <= LOW_VABAT_CLOSE_VALUE)
            if (bat_mv <= LOW_VABAT_CLOSE_MV)
            {
                gValveData.switch_status = kClosed;
                logDebug("低压关阀");
                tmos_start_task(vavle_task_id, VAVLE_CLOSE_START_EVT, MS1_TO_SYSTEM_TIME(1100));
            }
            // else if (gValveData.bat <= LOW_VABAT_ALARM_VALUE)
            // {
            //     tmos_set_event(vavle_task_id, VAVLE_LOW_VBAT_ALARM_EVT);
            // }
            float _humi, _temp;
            if (BSP_ReadTempHumi(&_humi, &_temp) == 0)
            {
                gValveData.temp = (int8_t)_temp;
                gValveData.humi = (uint8_t)_humi;
                if (gValveData.temp >= HIGN_TEMP_CLOSE_C)
                {
                    logDebug("高温关阀");
                    tmos_start_task(vavle_task_id, VAVLE_CLOSE_START_EVT, MS1_TO_SYSTEM_TIME(1000));
                }
            }
            else
            {
                logError("Read TempHumi Err");
            }
            tmos_start_task(vavle_task_id, VAVLE_LOOP_DECT_EVT, MS1_TO_SYSTEM_TIME(VALVE_DECT_PERIOD_MS));
        }
        else
        {
            // 延后5s再测
            tmos_start_task(vavle_task_id, VAVLE_LOOP_DECT_EVT, MS1_TO_SYSTEM_TIME(5000));
        }

        return (events ^ VAVLE_LOOP_DECT_EVT);
    }
    // 连上主机后主动上传下阀门状态
    if (events & VAVLE_UPDATE_EVT)
    {
        // BEEP_OFF_DEINIT;

        // EMV_CHARGE_OFF_DEINIT;
        // EMV_OFF_DEINIT;

        // LED_ALL_OFF_DEINIT;

        // BSP_NoNeedBoost();

        gValveData.switch_status = kClosed;

        tmos_memset(&RelyData, 0, sizeof(RelyData));
        BSP_VALVE_Generate_ValveResponse(&RelyData, kCmdCloseVavle, 1);

        tmos_set_event(Peripheral_TaskID, SBP_REPLY_CMD_EVT);

        logDebug("VAVLE_UPDATE_EVT");

        return (events ^ VAVLE_UPDATE_EVT);
    }

    // Discard unknown events
    return 0;
}

void LDect_Deinit(void)
{
    // 休眠时候，这里下拉输入
    GPIOA_ModeCfg(GPIO_Pin_2, GPIO_ModeIN_PD);
}

void LDect_IoInit(void)
{
    // PA2
    /* 定时器3，CAP捕捉， */
    GPIOA_ResetBits(GPIO_Pin_2);
    GPIOA_ModeCfg(GPIO_Pin_2, GPIO_ModeIN_PU);
}

void LDect_Init(void)
{
    // 退出休眠需要重新设置
#if 1

    // TMR3功能引脚映射选择位：
    // 1：TMR3_/PWM3_/CAP3_映射到PA[2]；
    R16_PIN_ALTERNATE |= (1 << 3);
    logDebug("TMR3_CapInit 0");

    TMR3_CapInit(FallEdge_To_FallEdge);
    // (1 / 62.4MHz) * 2的26次方 = 0.01602564102564102564102564102564 us * 67108864 约等于 1.0754625641025641025641025641025 S

    TMR3_CAPTimeoutCfg(GetSysClock() / 100); // 设置捕捉超时时间 10ms

    // TMR3_CAPTimeoutCfg(0x3FFFFFF); // 设置捕捉超时时间
    TMR3_DMACfg(ENABLE, (uint16_t)(uint32_t)&cap_buf[0], (uint16_t)(uint32_t)&cap_buf[20], Mode_Single);
    TMR3_ITCfg(ENABLE, TMR0_3_IT_DMA_END); // 开启DMA完成中断
    PFIC_EnableIRQ(TMR3_IRQn);

    LDect_IoInit();

    logDebug("TMR3_CapInit");
    while(cap_flag == 0);
    cap_flag = 0;
    for(uint8_t i = 0; i < 20; i++)
    {
        logDebug("%08ld ", cap_buf[i] & 0x1ffffff); // 26bit, 最高位表示 高电平还是低电平
        uint16_t t = ((cap_buf[i] & 0x1ffffff) * 1.0f) / FREQ_SYS * 1000000;
        uint16_t f = 1000000 / t;
        logDebug("T = %04d us, f = %04d Hz", t, f);
        BSP_UART1_TxLoop();
    }
#endif
}

void BSP_VAVLE_Init(void)
{
    vavle_task_id = TMOS_ProcessEventRegister(VAVLE_Task_ProcessEvent);

    tmos_memset(&gValveData, 0, sizeof(gValveData));

    gValveData.switch_status = kClosed;
    gValveData.temp = -100;
    gValveData.in_pressure = 0;
    gValveData.out_pressure = 0;
    gValveData.atm_pressure = 0;

    gValveData.type = kTyq;
    gValveData.bat = BSP_ReadVbat();

    tmos_start_task(vavle_task_id, VAVLE_LOOP_DECT_EVT, MS1_TO_SYSTEM_TIME(VALVE_DECT_PERIOD_MS));

    // GPIOA_ResetBits(GPIO_Pin_2);
    // GPIOA_ModeCfg(GPIO_Pin_2, GPIO_ModeIN_PU);

    // LDect_Init();
#if 0
    // PA2
    /* 定时器3，CAP捕捉， */
    GPIOA_ResetBits(GPIO_Pin_2);
    GPIOA_ModeCfg(GPIO_Pin_2, GPIO_ModeIN_PU);

    // TMR3功能引脚映射选择位：
    // 1：TMR3_/PWM3_/CAP3_映射到PA[2]；
    R16_PIN_ALTERNATE |= (1 << 3);
    logDebug("TMR3_CapInit 0");

    TMR3_CapInit(FallEdge_To_FallEdge);
    // (1 / 62.4MHz) * 2的26次方 = 0.01602564102564102564102564102564 us * 67108864 约等于 1.0754625641025641025641025641025 S

    TMR3_CAPTimeoutCfg(GetSysClock() / 100); // 设置捕捉超时时间 10ms

    // TMR3_CAPTimeoutCfg(0x3FFFFFF); // 设置捕捉超时时间
    TMR3_DMACfg(ENABLE, (uint16_t)(uint32_t)&cap_buf[0], (uint16_t)(uint32_t)&cap_buf[20], Mode_Single);
    TMR3_ITCfg(ENABLE, TMR0_3_IT_DMA_END); // 开启DMA完成中断
    PFIC_EnableIRQ(TMR3_IRQn);

    logDebug("TMR3_CapInit");
    while(cap_flag == 0);
    cap_flag = 0;
    for(uint8_t i = 0; i < 20; i++)
    {
        logDebug("%08ld ", cap_buf[i] & 0x1ffffff); // 26bit, 最高位表示 高电平还是低电平
        uint16_t t = ((cap_buf[i] & 0x1ffffff) * 1.0f) / FREQ_SYS * 1000000;
        uint16_t f = 1000000 / t;
        logDebug("T = %04d us, f = %04d Hz", t, f);
        BSP_UART1_TxLoop();
    }
#endif

    // R8_TMR3_CTRL_MOD = RB_TMR_ALL_CLEAR;
    // TMR3_Disable();
    // // TMR3_ITCfg(DISABLE, TMR0_3_IT_DMA_END); // 关闭DMA完成中断
    // PFIC_DisableIRQ(TMR3_IRQn);

    // GPIOA_ResetBits(GPIO_Pin_2);
    // TODO:问题出在这里，这里会导致出错
    LDect_Deinit();

    logInfo("BSP_Valve_Init");
}



/*********************************************************************
 * @fn      TMR3_IRQHandler
 *
 * @brief   TMR3中断函数
 *
 * @return  none
 */
__INTERRUPT
__HIGH_CODE
void TMR3_IRQHandler(void) // TMR3 定时中断
{
    if (TMR3_GetITFlag(TMR0_3_IT_DMA_END))
    {
        TMR3_ITCfg(DISABLE, TMR0_3_IT_DMA_END); // 使用单次DMA功能+中断，注意完成后关闭此中断使能，否则会一直上报中断。
        TMR3_ClearITFlag(TMR0_3_IT_DMA_END);    // 清除中断标志
        cap_flag = 1;
    }
}
