/********************************** (C) COPYRIGHT *******************************
 * File Name          : main.c
 * Author             : WCH
 * Version            : V1.1
 * Date               : 2020/08/06
 * Description        : Peripheral slave application main function and task system initialization
 *********************************************************************************
 * 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.
 *******************************************************************************/

/******************************************************************************/
/* Header file contains */
#include "CONFIG.h"
#include "HAL.h"
#include "gattprofile.h"
#include "peripheral.h"
#include "cmcng.h"
#include <string.h>
#include "dbn_ble_srv.h"
#include "eth_driver.h"
#include "net_srv.h"
#include "storage.h"
#include "tcp_json_srv.h"
#include "loop_uart_proto.h"

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

#define     KEY_GPIO    (RCC_APB2Periph_GPIOA)
#define     KEY_BV     BV(0)
#define     KEY_IN       (GPIO_ReadInputDataBit(KEY_GPIO, KEY_BV)==0)
#define     HAL_PUSH_BUTTON()       (KEY1_IN) //Add custom button

#if(defined(BLE_MAC)) && (BLE_MAC == TRUE)
const uint8_t MacAddr[6] = {0x84, 0xC2, 0xE4, 0x03, 0x02, 0x02};
// #else
// uint8_t MACAddr[6] = {0x84, 0xC2, 0xE4, 0x03, 0x02, 0x02};
#endif
uint8_t gMacAddr[6] = { 0x38, 0x3B, 0x26, 0x11, 0xA4 ,0x35  };  

/* Used for app judgment file effectiveness */
const uint32_t Address = 0xFFFFFFFF;

__attribute__((aligned(4))) uint32_t Image_Flag __attribute__((section(".ImageFlag"))) = (uint32_t)&Address;

uint8_t g_dev_number[6] = "";           // �豸���  ��Ʒ���
uint8_t g_dev_password[6] = {0x31, 0x32, 0x33, 0x34, 0x35, 0x36};
uint8_t g_ble_safe_flag = 0;  
uint32_t g_ble_safe_counter_ori = 0;       
uint32_t g_ble_safe_counter_dst = 0;

char g_flag_debug = 1;

uint8_t g_dg_device_type = DDType_DLD950V4;			// ???����?????????????
uint8_t g_dg_sub_dev_type = DDType_DLD950V4; 

Sub_Code_Enable g_sub_code_enable = {0,};

uint32_t g_activ_counter = 0;

uint32_t g_counter_bt_timeout = 0;
uint8_t g_flag_bt_state = 0;
uint8_t g_flag_bt_disable = 0;

uint8_t g_max_counter_bt_min = 0;
uint32_t g_max_counter_bt_timeout = 0; //BT_DISABLE_IDLE_TIMEOUT * 60 * 1000; // ms unit


__IO uint32_t TimingDelayInc;
__IO uint32_t TimingDelayDec;

uint8_t trigB;
Pkg_Uart g_pkg_uart_1 = { 0, 0, 0, "", 0};
Pkg_Uart g_pkg_uart_2 = { 0, 0, 0, "", 0};

Flag_Counter g_flag_counter_key = {0, 0, 0};
Flag_Counter g_flag_counter_ota = {0, 0, 0};

uint8_t g_storage_uart_num = 0;
uint32_t g_storage_uart_baud = 19200;//9600;
uint8_t g_storage_uart_num_2 = 1;
uint32_t g_storage_uart_baud_2 = 115200; //115200;

uint32_t mstick(void){
    return TimingDelayInc;
}


void InitPkgUart(Pkg_Uart * pkg){
    memset(pkg->pkg, 0, BUFF_STACK_SIZE);
    pkg->flag = 0;
    pkg->tick = 0;
    pkg->len = 0;
    pkg->offset = 0;
}



/*********************************************************************
 * @fn      TIM2_Init
 *
 * @brief   Initializes TIM2.
 *
 * @return  none
 */
void TIM2_Init( void )
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure={0};

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

    TIM_TimeBaseStructure.TIM_Period = SystemCoreClock / 1000000;
    TIM_TimeBaseStructure.TIM_Prescaler = WCHNETTIMERPERIOD * 1000 - 1;
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
    TIM_ITConfig(TIM2, TIM_IT_Update ,ENABLE);

    TIM_Cmd(TIM2, ENABLE);
    TIM_ClearITPendingBit(TIM2, TIM_IT_Update );
    NVIC_EnableIRQ(TIM2_IRQn);
}

/*********************************************************************
 * @fn      TIM3_Init
 *
 * @brief   Initializes TIM3.
 *
 * @return  none
 */
void TIM3_Init(void)
{
    NVIC_InitTypeDef NVIC_InitStructure={0};
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure = { 0 };

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

    ////10ms
    // TIM_TimeBaseStructure.TIM_Period = SystemCoreClock / 1000000;
    // TIM_TimeBaseStructure.TIM_Prescaler = 10 * 1000 - 1;

    //1ms
    TIM_TimeBaseStructure.TIM_Period = SystemCoreClock / 1000000;
    TIM_TimeBaseStructure.TIM_Prescaler = 1 * 1000 - 1;


    TIM_TimeBaseStructure.TIM_ClockDivision = 0;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
    TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);

    TIM_Cmd(TIM3, ENABLE);
    TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
    NVIC_EnableIRQ(TIM3_IRQn);
}


void key_event_srv(void){
    // if(g_flag_counter_key.tick > 1000){
    //     PRINT("key_tick_timeup_______: %d\n", GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0));
    //     g_flag_counter_key.tick = 0;
    // }
    if(g_flag_counter_key.flag){
        uint8_t _pkg[7] = {0};
        uint8_t i = 0;
        switch (g_flag_counter_key.flag) {
            case KEY_ET_BLE_ENABLE: {
                PRINT("______KEY_ET_BLE_ENABLE\n");
                NVIC_SystemReset();    
            } break;
            case KEY_ET_REBOOT: {
                PRINT("__________KEY_ET_REBOOT\n");
                _pkg[i++] = 0x7F;
                _pkg[i++] = 0x00;
                _pkg[i++] = 0x01;
                _pkg[i++] = 0x6D;
                _pkg[i++] = 0x6C;
                _pkg[i++] = 0x6E;
                UART2_SendString(_pkg, i);  //1 send loop mcu reboot;

                Delay_Ms(10);
                // 2 DBN dev reboot
                NVIC_SystemReset();     
            } break;
            case KEY_ET_FACTORY: {
                PRINT("_____________KEY_ET_FACTORY\n");
                _pkg[i++] = 0x7F;
                _pkg[i++] = 0x00;
                _pkg[i++] = 0x01;
                _pkg[i++] = 0x92;
                _pkg[i++] = 0x93;
                _pkg[i++] = 0x93;
                UART2_SendString(_pkg, i);  //1 send loop mcu factory init

                
            } break;
            case KEY_ET_NETBLE_FACTORY: {
                //2 DBN dev factory init;
                factory_dev_info();
                Delay_Ms(10);

                NVIC_SystemReset();
            } break;
        
        }
        g_flag_counter_key.flag = 0;
    }

    
}


/*********************************************************************
 * @fn      Main_Circulation
 *
 * @brief   Main loop
 *
 * @return  none
 */
__attribute__((section(".highcode")))
__attribute__((noinline))
void Main_Circulation(void)
{
    uint32_t _counter = 0;
    while(1)
    {
        TMOS_SystemProcess();

        if(g_net_state.flag < 2)
        {
            net_srv_init();
        }
        if(g_net_state.flag == 2)
        {
#if NET_SSC_ENABLE
            if(g_sub_code_enable.iot_enable){
                if(iot_net_info.mode == IOT_Addr_IP_Mode){
                    if(get_ipstr_to_array(iot_net_info.remote_addr, RemoteIP) == 0){
                        WCHNET_CreateTcpMqttSocket();
                    }
                }
                else{
                    //DNS 
                }
                
            }
            else
            {
                WCHNET_CreateTcpSocket();                
            }
#endif
        }
        
        
        /*Ethernet library main task function,
         * which needs to be called cyclically*/
        WCHNET_MainTask();
        /*Query the Ethernet global interrupt,
         * if there is an interrupt, call the global interrupt handler*/
        if(WCHNET_QueryGlobalInt())
        {
            WCHNET_HandleGlobalInt();
        }

        uart_srv();

        poll_dbn_ble();

        tcp_json_push_sensor();     // Push 0xC0 sensor data to TCP JSON client

        tcp_json_poll();

        key_event_srv();
    }
}



/*********************************************************************
 * @fn      main
 *
 * @brief   Main function
 *
 * @return  none
 */
int main(void)
{
    SystemCoreClockUpdate();
    Delay_Init();
#ifdef DEBUG
    // USART_Printf_Init( 115200 );
    USART_Printf_Init( 256000 );
#endif
    PRINT("%s\n", VER_LIB);
    PRINT("SystemCoreClock:%d\n", SystemCoreClock);
    GetMacAddr(gMacAddr);
    storage_init();
    load_cfg_from_flash();
    output_cfg_from_flash();

    PRINT("MAC: %02X %02X %02X %02X %02X %02X\r\n", gMacAddr[0],gMacAddr[1], gMacAddr[2], gMacAddr[3],gMacAddr[4],gMacAddr[5]);
    PRINT("net version:%x\n", WCHNET_GetVer());
    WCHBLE_Init();
    HAL_Init();

    uart_init();
    TIM3_Init();
    TIM2_Init();

    GAPRole_PeripheralInit();
    Peripheral_Init();
    Main_Circulation();
}


void TIM3_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
/*********************************************************************
 * @fn      TIM3_IRQHandler, 1ms
 *
 * @brief   This function handles TIM2 exception.
 *
 * @return  none
 */
void TIM3_IRQHandler(void)
{
    TimingDelayInc++;
    g_activ_counter++;

    if(g_pkg_uart_2.offset){
        if(g_pkg_uart_2.flag == 0){
            g_pkg_uart_2.tick++;
            if(g_pkg_uart_2.tick > 8){
                g_pkg_uart_2.flag = 1;
            }
        }        
    }
    // Safety: reset frame parser if stuck in non-IDLE state too long
    if(g_lup_parser.state != LUP_FRAME_STATE_IDLE){
        if(g_pkg_uart_2.tick > 20){
            lup_frame_reset();
            g_pkg_uart_2.tick = 0;
        }
    }

    if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == 0){//HAL_PUSH_BUTTON()){
       g_flag_counter_key.tick++;
    }
    else{
        if(g_flag_counter_key.tick){
            if(g_flag_counter_key.tick < 2000){
                g_flag_counter_key.flag = KEY_ET_BLE_ENABLE;
            }
            else if(g_flag_counter_key.tick < 6000){
                g_flag_counter_key.flag = KEY_ET_REBOOT;
            }
            else if(g_flag_counter_key.tick < 10000){
                g_flag_counter_key.flag = KEY_ET_FACTORY;
            }
            else{
                g_flag_counter_key.flag = KEY_ET_NETBLE_FACTORY;
            }
            g_flag_counter_key.tick = 0;
        }
    }


    TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
}


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