/********************************** (C) COPYRIGHT *******************************
 * File Name          : main.c
 * Author             : WCH
 * Version            : V1.1
 * Date               : 2020/08/06
 * Description        : 外设从机应用主函数及任务系统初始化
 *********************************************************************************
 * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
 * Attention: This software (modified or not) and binary are used for
 * microcontroller manufactured by Nanjing Qinheng Microelectronics.
 *******************************************************************************/

#include "CONFIG.h"
#include "HAL.h"
#include "gattprofile.h"
#include "peripheral.h"

#include "bsp_adc.h"

#include "bsp_key.h"

#include "bsp_beep_led_emv.h"

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

#include "bsp_i2c.h"

#include "bsp_iwdg.h"
#include "bsp_flash.h"

#include "bsp_valve.h"

#include "bsp_bat.h"

#undef LOG_ENABLE
#define LOG_ENABLE 1

#undef LOG_TAG
#define LOG_TAG "main"

__attribute__((aligned(4))) uint32_t MEM_BUF[BLE_MEMHEAP_SIZE / 4];

static uint8_t key_press_cnt = 0;

#if 0
void app_task_handler(TeAppEvtType app_evt_type)
{
    BSP_BlockSleep();
    BSP_RequestBoost();

    // DelayMs(15);

    switch (app_evt_type)
    {
        case kKeyShort:
            tmos_set_event(vavle_task_id, VAVLE_DECT_SWITCH_START_EVT);
            logDebug("button short press");
            key_press_cnt++;
            logDebug("key_press_cnt = %d", key_press_cnt);

            if (valve_switch_dect_flag)
            {
                valve_switch_dect_flag = 0;

                logDebug("LED显示状态");
                // tmos_set_event(led_task_id, LED_SHOW_START_EVT);
                BSP_BlockSleep();
                BSP_RequestBoost();
                DelayMs(1);
                ShowLed();
            }
            if (key_press_cnt >= 2)
            {
                // if (gValveData.switch_status == kClosed)
                // {
                //     logDebug("kClosed-->kOpened");
                //     // tmos_set_event(led_task_id, LED_SHOW_START_EVT);
                //     gValveData.switch_status = kOpened;
                //     BSP_BlockSleep();
                //     BSP_RequestBoost();
                //     DelayMs(1);
                //     ShowLed();
                //     // tmos_stop_task(led_task_id, LED_SHOW_ONCE_EVT);
                //     // tmos_start_task(led_task_id, LED_SHOW_ONCE_EVT, 1000);
                // }
                // else
                if (gValveData.switch_status != kClosed)
                {
                    logDebug("kOpened-->kClosed");
                    gValveData.switch_status = kClosed;
                    tmos_set_event(vavle_task_id, VAVLE_CLOSE_START_EVT);

                    // tmos_set_event(led_task_id, LED_SHOW_START_EVT);
                    BSP_BlockSleep();
                    BSP_RequestBoost();
                    DelayMs(1);
                    ShowLed();
                    // tmos_stop_task(led_task_id, LED_SHOW_ONCE_EVT);
                    // tmos_start_task(led_task_id, LED_SHOW_ONCE_EVT, 1000);
                }
            }
            break;

        case kKeyLong:
            logDebug("button long press");

            break;
        case kKeyRelease:
            // BSP_KEY_EnterLowpower();
            // DelayMs(10);
            key_press_cnt = 0;
            // BSP_RequestSleep();
            // tmos_set_event(led_task_id, LED_SHOW_END_EVT);

            LED_ALL_OFF_DEINIT;
            BEEP_OFF_DEINIT;

            BSP_NoNeedBoost();
            BSP_RequestSleep();

            logDebug("gpio relase;BSP_RequestSleep");

            break;
        default:
            break;
    }
}

#endif

void app_task_handler(TeAppEvtType app_evt_type)
{
    BSP_BlockSleep();
    // BSP_BlockSleep();
    // BSP_RequestBoost();

    switch(app_evt_type)
    {
    case kKeyShort:
        logDebug("button short press");
        key_press_cnt++;
        logDebug("key_press_cnt = %d", key_press_cnt);
        if (key_press_cnt == 1)
        {
            logDebug("LED显示状态");
            // tmos_set_event(led_task_id, LED_SHOW_START_EVT);
            BSP_BlockSleep();
            // BSP_RequestBoost();
            DelayMs(3);
            ShowLed();
            // tmos_stop_task(led_task_id, LED_SHOW_ONCE_EVT);
            // tmos_start_task(led_task_id, LED_SHOW_ONCE_EVT, 1000);
        }
        else if (key_press_cnt == 2)
        {
            if (gValveData.switch_status == kClosed)
            {
                logDebug("kClosed-->kOpened");
                // tmos_set_event(led_task_id, LED_SHOW_START_EVT);
                gValveData.switch_status = kOpened;
                BSP_BlockSleep();
                // BSP_RequestBoost();
                DelayMs(3);
                ShowLed();
                // tmos_stop_task(led_task_id, LED_SHOW_ONCE_EVT);
                // tmos_start_task(led_task_id, LED_SHOW_ONCE_EVT, 1000);
            }
            else if (gValveData.switch_status != kClosed)
            {
                logDebug("kOpened-->kClosed");
                gValveData.switch_status = kClosed;
                tmos_set_event(vavle_task_id, VAVLE_CLOSE_START_EVT);

                // tmos_set_event(led_task_id, LED_SHOW_START_EVT);
                BSP_BlockSleep();
                // BSP_RequestBoost();
                DelayMs(3);
                ShowLed();
                // tmos_stop_task(led_task_id, LED_SHOW_ONCE_EVT);
                // tmos_start_task(led_task_id, LED_SHOW_ONCE_EVT, 1000);
            }
        }
        break;

    case kKeyLong:
        logDebug("button long press");

        break;
    case kKeyRelease:
        // BSP_KEY_EnterLowpower();
        // DelayMs(10);
        key_press_cnt = 0;
        // BSP_RequestSleep();
        // tmos_set_event(led_task_id, LED_SHOW_END_EVT);

        LED_ALL_OFF_DEINIT;
        BEEP_OFF_DEINIT;

        BSP_NoNeedBoost();
        BSP_RequestSleep();

        logDebug("gpio relase;BSP_RequestSleep");

        break;
    default:
        break;
    }
}

/*********************************************************************
 * @fn      Main_Circulation
 *
 * @brief   主循环
 *
 * @return  none
 */
__HIGH_CODE
__attribute__((noinline)) void Main_Circulation()
{
    while (1)
    {
        TMOS_SystemProcess();
        KEY_ProcessLoop();
        BSP_UART1_TxLoop();
        // FEED_IWDG();
    }
}

// https://www.cnblogs.com/gscw/p/18530905
// 在连接间隔和广播间隔到来时，会进入该回调，可以在回调函数加上其他执行逻辑代码，如喂狗等。
void BLE_AdvertiseEventCB(uint32_t timeUs)
{
    FEED_IWDG();
    logDebug("BLE_AdvertiseEventCB");
}

void BLE_ConnectEventCB(uint32_t timeUs)
{
    FEED_IWDG();
    logDebug("BLE_ConnectEventCB");
}

/*********************************************************************
 * @fn      main
 *
 * @brief   主函数
 *
 * @return  none
 */
int main(void)
{
#if (defined(DCDC_ENABLE)) && (DCDC_ENABLE == TRUE)
    PWR_DCDCCfg(ENABLE);
#endif
    HSECFG_Capacitance(HSECap_18p);
    SetSysClock(CLK_SOURCE_HSE_PLL_62_4MHz);

#if (defined(HAL_SLEEP)) && (HAL_SLEEP == TRUE)
    GPIOA_ModeCfg(GPIO_Pin_All, GPIO_ModeIN_PD);
    GPIOB_ModeCfg(GPIO_Pin_All, GPIO_ModeIN_PD);
#endif
#ifdef DEBUG
    // 改成 4000000 波特率了
    BSP_UART1_Init(4000000);
#endif
    ShowRestartReason();

    CH58x_BLEInit();

    HAL_Init();
    GAPRole_PeripheralInit();
    Peripheral_Init();

    DelayMs(1000 * 3);

    // HAL_Init();
    // GAPRole_PeripheralInit();
    // Peripheral_Init();

    logDebug("GetSysClock = %d Hz", GetSysClock());

    // extern void Peripheral_SetMacName(void);
    // Peripheral_SetMacName();
    // while(1)
    // {
    //     DelayMs(1000);
    // }

    BSP_FLASH_Init();

    BSP_BEEP_LED_EMV_Init();

    PRINT("PRINT\r\n");

    logDebug("Start @ChipID=%02X\n", R8_CHIP_ID);
    logError("中文测试 %2.2f", 123.456);

    logDebug("%s\n", VER_LIB);
    uint8_t MacAddr[6];
    GetMACAddress(MacAddr);
    // 手机APP显示是倒序的[5-0],不是[0-5]
    logDebug("MacAddr: %02X:%02X:%02X:%02X:%02X:%02X", MacAddr[0], MacAddr[1], MacAddr[2], MacAddr[3], MacAddr[4], MacAddr[5]);
    // log打印编译时间和编译日期
    logDebug("Compile Time: %s %s", __DATE__, __TIME__);

    GXHTC3C_Init();

    BSP_KEY_Init(app_task_handler);

    // IWDG_Init(1500);
    // DelayMs(1000 * 3);

    BSP_ADC_Init();

    BSP_VAVLE_Init();

    BSP_BlockSleep();
    BSP_RequestBoost();
    DelayMs(10);
#if 0
    DelayMs(1);
    EMV_CHARGE_EN;
    logDebug("EMV_CHARGE_EN");
    DelayMs(1500);

    BOOST_EN;
    // 关阀动作,一定要先关充电的，防止其他12V用电
    EMV_CHARGE_OFF_DEINIT;
    BEEP_ON;
    logDebug("EMV_CHARGE_OFF_DEINIT");
    EMV_ON;
    logDebug("EMV_ON");
    DelayMs(100);

    BEEP_OFF_DEINIT;
    EMV_CHARGE_OFF_DEINIT;
    EMV_OFF_DEINIT;
    LED_ALL_OFF_DEINIT;

    DelayMs(100);

    BSP_VAVLE_Init();
    VavleDect_Start();
    DelayMs(10);
    valve_switch_off_freq = VavleDect_GetFreq();
    logDebug("valve_switch_off_freq = %06d Hz", valve_switch_off_freq);

    while (1)
    {
        LED_ALL_OFF_DEINIT;
        DelayMs(500);
        LED_R_ON;
        DelayMs(500);
        if (IS_KEY_Vaild())
        {
            DelayMs(20);
            if (IS_KEY_Vaild())
            {
                break;
            }
        }
    }

    DelayMs(100);

    BSP_VAVLE_Init();
    VavleDect_Start();
    DelayMs(10);
    valve_switch_on_freq = VavleDect_GetFreq();
    logDebug("valve_switch_on_freq = %06d Hz", valve_switch_on_freq);
    valve_switch_freq = valve_switch_on_freq;
    VavleDect_Switch();
#endif
    // BSP_VAVLE_Init();

    ShowLed();
    BEEP_ON;

    DelayMs(500 * 1);

    // BSP_BAT_Init();

    // tmos_set_event(Peripheral_TaskID, SBP_REPLY_CMD_EVT);
#if 0
    // GPIOA_ModeCfg(GPIO_Pin_2, GPIO_ModeIN_Floating);

    // 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(FREQ_SYS ); // 设置捕捉超时时间
    TMR3_CAPTimeoutCfg(GetSysClock() / 100); // 设置捕捉超时时间 10ms

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

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

    // DelayMs(1000 * 30);

#endif

    LED_ALL_OFF_DEINIT;
    BEEP_OFF_DEINIT;

    BSP_NoNeedBoost();
    BSP_RequestSleep();

    IWDG_Init(IWDG_TIMEOUT_MS);

    logDebug("123");
    DelayMs(1000);
    logDebug("456");

    // 在连接间隔和广播间隔到来时，会进入回调中喂狗
    // LL_AdvertiseEventRegister(BLE_AdvertiseEventCB);
    // LL_ConnectEventRegister(BLE_ConnectEventCB);

    Main_Circulation();
}



/******************************** endfile @ main ******************************/
