/*!
    \file    main.c
    \brief   construct a USB custom HID device

    \version 2020-08-01, V3.0.0, firmware for GD32F30x
*/

/*
    Copyright (c) 2020, GigaDevice Semiconductor Inc.

    Redistribution and use in source and binary forms, with or without modification, 
are permitted provided that the following conditions are met:

    1. Redistributions of source code must retain the above copyright notice, this 
       list of conditions and the following disclaimer.
    2. Redistributions in binary form must reproduce the above copyright notice, 
       this list of conditions and the following disclaimer in the documentation 
       and/or other materials provided with the distribution.
    3. Neither the name of the copyright holder nor the names of its contributors 
       may be used to endorse or promote products derived from this software without 
       specific prior written permission.

    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
OF SUCH DAMAGE.
*/

#include "custom_hid_core.h"
#include "drv_usb_hw.h"

#include 	"platform.h"
#include 	"base_core_user.h"
#include "function_interface.h"
#include "platform_interface.h"
#include "HW_MCUIO.h"
#include "function.h"

//????"function.h" ???"base_config.h"??????,????????1K?????,
//???????????,????????????????????1K?????1mS,
//??????????????20220624
#include "function.h"//#include "base_config.h"
#define VECT_TAB_OFFSET 0x8000 //???????8K

usb_core_driver custom_hid;

void TIMER1_Init(void);
void TIMER2_Init(void);
void GPIO_Init(void);

extern hid_fop_handler fop_handler;



/*!
    \brief      main routine
    \param[in]  none
    \param[out] none
    \retval     none
    
*/

int main(void)
{
    nvic_vector_table_set(NVIC_VECTTAB_FLASH, VECT_TAB_OFFSET);
    __enable_irq();
    PLATFORM_DISABLE_IRQ();//__disable_irq();
    /* system clocks configuration */
    
    rcu_config();
	
	usb_timer_init();
//    /* GPIO configuration */
//    gpio_config();

    custom_hid_itfop_register(&custom_hid, &fop_handler);
	
	
	PLATFORM_ENABLE_IRQ();//__enable_irq();
    /* USB device configuration */
	usbd_init (&custom_hid, USB_CORE_ENUM_FS, &custom_hid_desc, &usbd_custom_hid_cb);

    /* NVIC configuration */
    usb_intr_config();//nvic_config();

//    /* GPIO configuration */
//    gpio_config();
    systick_config();
    
    GPIO_Init();
    /* enabled USB pull-up */
//    usbd_connect(&custom_hid);
    
    HW_RF_SPI_Init();
    
//    void gpio_config(void);
//    gpio_config();
    base_core.core_init();////???????????
    function.aes__init();
    
    
//    PLATFORM_ENABLE_IRQ();//__enable_irq();
    TIMER1_Init();
    TIMER2_Init();
//    while (USBD_CONFIGURED != custom_hid.cur_status) {
//        /* wait for standard USB enumeration is finished */
//    }
    
    /* confiure FWDGT counter clock: 40KHz(IRC40K) / 64 = 0.625 KHz */
    fwdgt_config(2*500,FWDGT_PSC_DIV64);
    /* After 1.6 seconds to generate a reset */
	fwdgt_enable();// watch dog 1.6 S
	
    while(1){
		fwdgt_counter_reload();//reload watch dog
        base_core.core_loop();
//        msg_polling();//function.msg__polling();
        //uint8_t Send_buf[64] = {0x00};
        //custom_hid_report_send (&usbd_custom_hid, Send_buf, 64U);
    }
}

void TIMER1_Init(void)
{
    timer_parameter_struct initpara = {0};

    initpara.prescaler = 1200 - 1;// 120M / 1200 = 100KHz
    initpara.alignedmode = TIMER_COUNTER_EDGE;
    initpara.counterdirection = TIMER_COUNTER_UP;
    initpara.period = 250 - 1;
    initpara.clockdivision = TIMER_CKDIV_DIV1;
    initpara.repetitioncounter = 0;
    timer_init(TIMER1, &initpara);

    nvic_irq_enable(TIMER1_IRQn, 3U, 0U);//(TIMER1_IRQn, 3U, 0U);

    timer_counter_value_config(TIMER1, 0);
    timer_prescaler_config(TIMER1, 1200 - 1, TIMER_PSC_RELOAD_NOW);
    timer_autoreload_value_config(TIMER1, 250 - 1);
    timer_interrupt_disable(TIMER1, TIMER_INT_UP);
    timer_interrupt_flag_clear(TIMER1, TIMER_INT_FLAG_UP);
    timer_interrupt_enable(TIMER1, TIMER_INT_UP);
    timer_enable(TIMER1);
}

void TIMER2_Init(void)
{
    timer_parameter_struct initpara = {0};

    initpara.prescaler = 1200 - 1;// 120M / 1200 = 100KHz
    initpara.alignedmode = TIMER_COUNTER_EDGE;
    initpara.counterdirection = TIMER_COUNTER_UP;
    initpara.period = 2000 - 1;
    initpara.clockdivision = TIMER_CKDIV_DIV1;
    initpara.repetitioncounter = 0;
    timer_init(TIMER2, &initpara);

    nvic_irq_enable(TIMER2_IRQn, 4U, 0U);

    timer_counter_value_config(TIMER2, 0);
    timer_prescaler_config(TIMER2, 1200 - 1, TIMER_PSC_RELOAD_NOW);
    timer_autoreload_value_config(TIMER2, 2000 - 1);
    timer_interrupt_disable(TIMER2, TIMER_INT_UP);
    timer_interrupt_flag_clear(TIMER2, TIMER_INT_FLAG_UP);
    timer_interrupt_enable(TIMER2, TIMER_INT_UP);
    timer_enable(TIMER2);
}

void GPIO_Init(void)
{
    HW_GPIO_InitTypeDef  GPIO_InitStruct;
    
//     /*Configure GPIO pin Output Level */
	HW_GPIO_ResetPin(GPIOC, GPIO_PIN_1|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6);

//    /*Configure GPIO pin Output Level */
	HW_GPIO_ResetPin(GPIOA, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_8);

//    /*Configure GPIO pin Output Level */
	HW_GPIO_ResetPin(GPIOB, GPIO_PIN_8|GPIO_PIN_9);
    
    /*Configure GPIO pins : PC1 PC4 PC5 PC6 */
    GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6;
    GPIO_InitStruct.Mode = HW_GPIO_MODE_OUT_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = HW_GPIO_SPEED_VERY_HIGH;
    HW_GPIO_Init(GPIOC, &GPIO_InitStruct);
    
    /*Configure GPIO pins : PA0 PA1 PA2 PA8 */
    GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10;
    GPIO_InitStruct.Mode = HW_GPIO_MODE_OUT_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = HW_GPIO_SPEED_VERY_HIGH;
    HW_GPIO_Init(GPIOA, &GPIO_InitStruct);

    /*Configure GPIO pin : PC7 */
    GPIO_InitStruct.Pin = GPIO_PIN_7;
    GPIO_InitStruct.Mode = HW_GPIO_MODE_FLOATING;//GPIO_MODE_IT_RISING;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HW_GPIO_Init(GPIOC, &GPIO_InitStruct);

    /*Configure GPIO pins : PB8 PB9 */
    GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9;
    GPIO_InitStruct.Mode = HW_GPIO_MODE_OUT_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = HW_GPIO_SPEED_VERY_HIGH;
    HW_GPIO_Init(GPIOB, &GPIO_InitStruct);
	
	HW_GPIO_SetPin(GPIOA, GPIO_PIN_8);//USB 1.5K Pull_up

#ifdef DEBUG_IO	
	HW_GPIO_ResetPin(GPIOA, GPIO_PIN_9);
	HW_GPIO_ResetPin(GPIOA, GPIO_PIN_10);
#endif	
    
    
}
