#include "BSP.h"
#include "led.h"
#include "device.h"
#include "../APP/network/downlink.h"
#include "../APP/storage/AT24C128Opt.h"
#include "../APP/globalDef.h"
#include "uart_conf.h"
OS_TMR watch_tmr;

uint32_t mcuID[3];
uint8_t air_state = 0,lora_flag = 0;
//uint8_t lora_rcv[128];
uint16_t lora_rcv_len;
uint32_t mcutypeID;

//读取ChipID
void cpuidGetId(void)
{
    mcuID[0] = *(volatile uint32_t*)(GD32F10X_ID_ADDR);
    mcuID[1] = *(volatile uint32_t*)(GD32F10X_ID_ADDR+4);
    mcuID[2] = *(volatile uint32_t*)(GD32F10X_ID_ADDR+8);
}
/*------------------------------------------------------
 *  读取设备类型编码
 * -----------------------------------------------------*/
void getcpuTypeIdcode(void)
{
    mcutypeID = *(volatile uint32_t*)(0xE0042000);
    g_firmwareMsg.gatewayMsg.devicTypeID = (uint16_t)(mcutypeID&0xFFFF);
}

static void watchdog_feed_timer(void *p_tmr, void *p_arg)
{
	static uint8_t led_flag = 0;

#if 1
	IWDG_ReloadCounter();
	//printf("\r\n feed watchdog\r\n");
#endif
	#ifdef MSTS_C
		LED(GPIOD, GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15, led_flag);
		LED(GPIOC, GPIO_Pin_6 | GPIO_Pin_7, led_flag);
	#else
		LED(GPIOB, GPIO_Pin_13 | GPIO_Pin_14, led_flag);
	#endif	
	if(led_flag) {
		led_flag = 0;
	} else {
		led_flag = 1;		
	}
	RTC_Get();
}

void watchdog_init(uint8_t pre,uint16_t rlr)
{
	OS_ERR err;

#if 0
	IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
	IWDG_SetPrescaler(pre);
	IWDG_SetReload(rlr);
	IWDG_ReloadCounter();
	IWDG_Enable();
#endif
	OSTmrCreate(&watch_tmr, "watch_tmr", 1, 1, OS_OPT_TMR_PERIODIC, watchdog_feed_timer, NULL, &err);
	OSTmrStart(&watch_tmr, &err);	
}

void system_first_powerup(void)
{
    fram_init_config_msg();
    fram_init_gateway_msg();
    fram_init_gateway_resetnum();
    fram_init_gateway_version();

}

void gateway_info_get(void)
{

      uint8_t i = 0;

 //   fram_read_config_msg();
    fram_read_gateway_hardware_msg();
    fram_init_gateway_version();
    fram_read_mqtt_msg();
    g_firmwareMsg.gatewayMsg.gate_resetType = system_reset_flag_get();

    fram_read_oil_msg();
    //printf(" gateway_id:%010u\n",downlink_config.gateway_id);

    printf("\r\n软件版本:\r\n");
    printf("boot_ver    = 0x%08x\r\n",g_firmwareMsg.gatewayMsg.verMsg.gate_bootloaderVr);
    printf("pt_ver      = 0x%08x\r\n",g_firmwareMsg.gatewayMsg.verMsg.pt_version);
    printf("app1_ver    = 0x%08x\r\n",g_firmwareMsg.gatewayMsg.verMsg.gate_appVr);
    printf("app2_ver    = 0x%08x\r\n",g_firmwareMsg.gatewayMsg.verMsg.gate_appVr2);
    printf("app3_ver    = 0x%08x\r\n",g_firmwareMsg.gatewayMsg.verMsg.gate_appVr3);

    printf("\r\n设备出厂信息:\r\n");
    printf("device_pt_init  = 0x%02x\r\n",g_firmwareMsg.gatewayMsg.hardwareMsg.bInit);
    printf("device_type     = 0x%04x\r\n",0x0301);
    printf("device_sn       = %010u(0x%08x)\r\n",g_firmwareMsg.gatewayMsg.hardwareMsg.gateway_sn,g_firmwareMsg.gatewayMsg.hardwareMsg.gateway_sn);
    printf("uuid            = ");
    for(i=0;i<12;i++){
       printf("%02x ",g_firmwareMsg.gatewayMsg.Uuid[i]);
    }
    printf("\r\n");
    printf("pcb_ver         = 0x%02x\r\n",g_firmwareMsg.gatewayMsg.hardwareMsg.pcbVersion);
    printf("device_pd       = 0x%08x\r\n",g_firmwareMsg.gatewayMsg.hardwareMsg.data);
    printf("device_bn       = 0x%04x\r\n",g_firmwareMsg.gatewayMsg.hardwareMsg.seqNo);
    printf("device_mfrs     = 0x%04x\r\n",g_firmwareMsg.gatewayMsg.hardwareMsg.factoryMsg);

}

void gateway_power_info_get(void)
{
   if(g_ptTest.bTestStart==1) return;
    gateway_info_get();
    led_display_version();

    downlink_init();
}

void system_info_get(sys_eeprom_info_t *p_info)
{
	return;
	AT24CXX_Read(0, (uint8_t *)p_info, sizeof(sys_eeprom_info_t));
	//data_dump("sys_eeprom_info_t", (uint8_t *)&info, sizeof(sys_eeprom_info_t));
	printf("read dev_type : 0x%08x, dev_id : 0x%08x, NewVerFlag : %d\r\n", 
			p_info->DevType, p_info->DevId, p_info->NewVerFlag);
	printf("info.WdgRestCnt : %d, SftRestCnt : %d, PorRestCnt : %d\r\n", 
			p_info->WdgRestCnt, p_info->SftRestCnt, p_info->PorRestCnt);
	printf("info.APP1Ver : %d, APP2Ver : %d, APP3Ver : %d\r\n", 
			p_info->APP1Ver, p_info->APP2Ver, p_info->APP3Ver);

	return ;
}

void system_info_update_pos(uint32_t pos, uint32_t value)
{
    return;
	AT24CXX_Write(pos, (uint8_t *)&value, 4);
}

void system_info_update(sys_eeprom_info_t *p_info)
{
    return;
	AT24CXX_Write(0, (uint8_t *)p_info, sizeof(sys_eeprom_info_t));
}

uint32_t system_reset_flag_get(void) //sys_eeprom_info_t *p_info
{
    uint32_t RestFlag = 0;

     fram_read_gateway_resetnum();
     if(RCC_GetFlagStatus(RCC_FLAG_PINRST) != RESET) {//RST PIN复位标志
         RestFlag |= RESET_PINRST;
        // g_firmwareMsg.gatewayMsg.gate_resetnum++;
     }
     if(RCC_GetFlagStatus(RCC_FLAG_PORRST) != RESET) {//上电复位标志
         RestFlag |= RESET_PORRSTF;
        // g_firmwareMsg.gatewayMsg.gate_resetnum++;
     }
     if(RCC_GetFlagStatus(RCC_FLAG_SFTRST) != RESET) {//软件复位标志
         RestFlag |= RESET_SFTRSTF;
        // g_firmwareMsg.gatewayMsg.gate_resetnum++;
     }
    if (RCC_GetFlagStatus(RCC_FLAG_IWDGRST) != RESET) {//独立看门狗复位标志
        RestFlag |= RESET_IWDGRSTF;//
       // g_firmwareMsg.gatewayMsg.gate_resetnum++;
    }
    if (RCC_GetFlagStatus(RCC_FLAG_WWDGRST) != RESET) {//窗口看门狗复位标志
        RestFlag |= RESET_IWDGRSTF;//
       // g_firmwareMsg.gatewayMsg.gate_resetnum++;
    }
    if (RCC_GetFlagStatus(RCC_FLAG_LPWRRST) != RESET) {//功耗复位
        RestFlag |= RESET_LPWRRSTF;//
       // g_firmwareMsg.gatewayMsg.gate_resetnum++;
    }


		printf("\r\n retset type : %x \r\n",RestFlag);
    RCC_ClearFlag();//清楚复位状态标志位
    fram_wirte_gateway_resetnum();
    return RestFlag;
}

void SysTick_init(void)
{
	RCC_ClocksTypeDef RCC_Clocks;
	RCC_GetClocksFreq(&RCC_Clocks);
	SysTick_Config(RCC_Clocks.SYSCLK_Frequency / OS_CFG_TICK_RATE_HZ);
//SystemCoreClock
//	SysTick->CTRL |=  SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk; 
//	NVIC_EnableIRQ(SysTick_IRQn);
}

//LED IO初始化
void LED_Init(u32 clk, GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
{

    GPIO_InitTypeDef  GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(clk, ENABLE);	 //使能PB,PE端口时钟

    GPIO_InitStructure.GPIO_Pin =  GPIO_Pin;				 //LED0-->PC.1 端口配置
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 //推挽输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		 //IO口速度为50MHz
    GPIO_Init(GPIOx, &GPIO_InitStructure);					 //根据设定参数初始化GPIOC.1
    GPIO_SetBits(GPIOx,  GPIO_Pin);					 //PC.1 输出低
}

void KEY_Init(u32 clk, GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
{

    GPIO_InitTypeDef  GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(clk, ENABLE);	 //使能PB,PE端口时钟

    GPIO_InitStructure.GPIO_Pin =  GPIO_Pin;				 //LED0-->PC.1 端口配置
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; 		 //推挽输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		 //IO口速度为50MHz
    GPIO_Init(GPIOx, &GPIO_InitStructure);					 //根据设定参数初始化GPIOC.1
}

void GPIO_COMM_Init(u32 clk, GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIOMode_TypeDef mode, GPIOSpeed_TypeDef speed)
{

    GPIO_InitTypeDef  GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(clk, ENABLE);

    GPIO_InitStructure.GPIO_Pin =  GPIO_Pin;
    GPIO_InitStructure.GPIO_Mode = mode;
    GPIO_InitStructure.GPIO_Speed = speed;
    GPIO_Init(GPIOx, &GPIO_InitStructure);
	
    GPIO_SetBits(GPIOx,  GPIO_Pin);
}

void LED_Set(uint8_t pos) 
{
/*
pos     12  11  10  9   8   7   6   5   4   3   2   1
        L11	L10	L9	L8	L7	L6	L5	L4	L3	L2	L1	L0
bit3	1	  0	  1	  0	  1	  0	  ~	  ~	  ~	  ~	  ~	  ~
bit2	0	  1   ~	  ~	  ~	  ~	  1	  0	  1	  0	  ~	  ~
bit1	~	  ~	  0	  1	  ~	  ~	  0	  1	  ~	  ~	  1	  0
bit0	~	  ~	  ~	  ~	  0	  1	  ~	  ~	  0	  1	  0	  1
*/
	uint8_t i;
	GPIO_InitTypeDef  GPIO_InitStructure;
	GPIOMode_TypeDef GPIO_Mode = GPIO_Mode_Out_PP;
	uint16_t led_pin = 0;
	uint8_t led_val[12][4] = {
		{0xff, 0xff, 0, 1}, 
		{0xff, 0xff, 1, 0}, 
		{0xff, 0, 0xff, 1}, 
		{0xff, 1, 0xff, 0}, 
		{0, 0xff, 0xff, 1}, 
		{1, 0xff, 0xff, 0}, 
		{0xff, 0, 1, 0xff}, 
		{0xff, 1, 0, 0xff}, 
		{0, 0xff, 1, 0xff}, 
		{1, 0xff, 0, 0xff}, 
		{0, 1, 0xff, 0xff}, 
		{1, 0, 0xff, 0xff}, 
	};

	for(i = 0;i < 4;i++) {
		led_pin = 1<<(2+i);
		if(led_val[pos][i] == 0xff) {
			GPIO_Mode = GPIO_Mode_IN_FLOATING;
		} else {
			GPIO_Mode = GPIO_Mode_Out_PP;
		}
		GPIO_InitStructure.GPIO_Pin = led_pin;
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode;
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
		GPIO_Init(GPIOE, &GPIO_InitStructure);
		if(led_val[pos][i] == 1) {
			GPIO_SetBits(GPIOE, led_pin);
		} else if(led_val[pos][i] == 0){
			GPIO_ResetBits(GPIOE, led_pin);
		}
	}
}

void BSP_Init(void)
{
    u8 i;
    OS_ERR      err;
	  uint16_t flag = 0;
    SystemInit();
    SysTick_init();
    watchdog_init(IWDG_Prescaler_256, 4000);
    RTC_Init();
    OSSemCreate(&i2c_sem, "i2c_sem", 1, &err);
    I2C_init();
    adc_init();
  //  fram_init_config_msg();
    g_ptTest.bTestStart = PT_OFF;


    for(i = 0;i < UART_MAX;i++) {
        if((i == UART4_ID)||(i == UART5_ID)) {/* 液位仪 */
                uart_init(i, 9600, USART_WordLength_8b, USART_Parity_No);
        } else if(i == UART2_ID) {
                uart_init(i, 9600, USART_WordLength_8b, USART_Parity_No);
        } else if(i == UART3_ID) {
            uart_init(i, 115200, USART_WordLength_8b, USART_Parity_No);
        }
        else {
                uart_init(i, 115200, USART_WordLength_8b, USART_Parity_No);
        }
    }
	
	
	
#ifdef GAS_STATION
/*
	（1）GPIO_Mode_AIN 模拟输入 
	（2）GPIO_Mode_IN_FLOATING 浮空输入
	（3）GPIO_Mode_IPD 下拉输入 
	（4）GPIO_Mode_IPU 上拉输入 
	（5）GPIO_Mode_Out_OD 开漏输出
	（6）GPIO_Mode_Out_PP 推挽输出
	（7）GPIO_Mode_AF_OD 复用开漏输出 
	（8）GPIO_Mode_AF_PP 复用推挽输出
	GPIO_Speed_10MHz 最高输出速率10MHz 
	GPIO_Speed_2MHz 最高输出速率2MHz 
	GPIO_Speed_50MHz 最高输出速率50MHz
*/
//	//STM32_GUN_DET_EN_0
//	GPIO_COMM_Init(RCC_APB2Periph_GPIOE, GPIOE, 
//			GPIO_Pin_2, GPIO_Mode_Out_PP, GPIO_Speed_50MHz);

//	//KEY，PE0, PE1
//	GPIO_COMM_Init(RCC_APB2Periph_GPIOE, GPIOE, 
//			GPIO_Pin_0 | GPIO_Pin_1, GPIO_Mode_IN_FLOATING, GPIO_Speed_50MHz);
	
//	//STM32_LED_RUN(PD1)
//	GPIO_COMM_Init(RCC_APB2Periph_GPIOD, GPIOD, 
//			GPIO_Pin_1 , GPIO_Mode_Out_PP, GPIO_Speed_50MHz);
//	GPIO_SetBits(GPIOD, GPIO_Pin_1);

//	//MINI_PCIE_LED_WANN_N(PD12), 由4G模块驱动
//	GPIO_COMM_Init(RCC_APB2Periph_GPIOD, GPIOD, 
//			GPIO_Pin_12, GPIO_Mode_IN_FLOATING, GPIO_Speed_50MHz);

			
			
			
	//LED(PC1,PC2)
	GPIO_COMM_Init(RCC_APB2Periph_GPIOC, GPIOC, 
			GPIO_Pin_1|GPIO_Pin_2, GPIO_Mode_Out_PP, GPIO_Speed_50MHz);
	
	//RS485_CTL(PA1)
	GPIO_COMM_Init(RCC_APB2Periph_GPIOA, GPIOA, 
			GPIO_Pin_1, GPIO_Mode_Out_PP, GPIO_Speed_50MHz);
	RS485_RX();
	
	//KEY，PE12,13,14
	GPIO_COMM_Init(RCC_APB2Periph_GPIOE, GPIOE, 
			GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14, GPIO_Mode_IN_FLOATING, GPIO_Speed_50MHz);
	
	//开关切换 USIM0 PC9, USIM1 PA8
	GPIO_COMM_Init(RCC_APB2Periph_GPIOC, GPIOC, 
			GPIO_Pin_9, GPIO_Mode_Out_PP, GPIO_Speed_50MHz);
	GPIO_COMM_Init(RCC_APB2Periph_GPIOA, GPIOA, 
			GPIO_Pin_8, GPIO_Mode_Out_PP, GPIO_Speed_50MHz);
	
	//USIM检测 USIM_CD
	GPIO_COMM_Init(RCC_APB2Periph_GPIOD, GPIOD, 
			GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5, GPIO_Mode_IN_FLOATING, GPIO_Speed_50MHz);
	
	//USIM卡使能
	GPIO_COMM_Init(RCC_APB2Periph_GPIOC, GPIOC, 
			GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8, GPIO_Mode_Out_PP, GPIO_Speed_50MHz);
			
	//MINI_PCIE_LED_WANN_N(PD15), 由4G模块驱动
	GPIO_COMM_Init(RCC_APB2Periph_GPIOD, GPIOD, 
			GPIO_Pin_15, GPIO_Mode_IN_FLOATING, GPIO_Speed_50MHz);
			
	//NET_PWR_EN
	GPIO_COMM_Init(RCC_APB2Periph_GPIOD, GPIOD, 
			GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14, GPIO_Mode_Out_PP, GPIO_Speed_50MHz);
			GPIO_SetBits(GPIOD,GPIO_Pin_14);
	GPIO_COMM_Init(RCC_APB2Periph_GPIOC, GPIOC, 
			GPIO_Pin_3, GPIO_Mode_Out_PP, GPIO_Speed_50MHz);	
   	GPIO_ResetBits(GPIOC, GPIO_Pin_3);
		GPIO_ResetBits(GPIOD, GPIO_Pin_14);
	
	//for sim 1
//	//开关
//	USIM1_L();
//	USIM0_H();
//	
//	//使能
//	USIM1_PWR_ON();
//	USIM2_PWR_OFF();
//	USIM3_PWR_OFF();
	
	

#if 0
	//chip select
	//STM32_I2C2_EEPROM_WP
	GPIO_COMM_Init(RCC_APB2Periph_GPIOE, GPIOE, 
			GPIO_Pin_15, GPIO_Mode_Out_PP, GPIO_Speed_50MHz);
	GPIO_ResetBits(GPIOE, GPIO_Pin_15);

	//FLASH_WP_N
	GPIO_COMM_Init(RCC_APB2Periph_GPIOD, GPIOD, 
			GPIO_Pin_10, GPIO_Mode_Out_PP, GPIO_Speed_50MHz);
	GPIO_ResetBits(GPIOD, GPIO_Pin_10);

	//EEPROM_SPI2_NSS_N
	GPIO_COMM_Init(RCC_APB2Periph_GPIOB, GPIOB, 
			GPIO_Pin_12, GPIO_Mode_Out_PP, GPIO_Speed_50MHz);
	GPIO_SetBits(GPIOB, GPIO_Pin_12);
#endif

//	//NET_PWR_EN
//	GPIO_COMM_Init(RCC_APB2Periph_GPIOD, GPIOD, 
//			GPIO_Pin_0|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15, GPIO_Mode_Out_PP, GPIO_Speed_50MHz);
//	GPIO_SetBits(GPIOD, GPIO_Pin_0);

	{//EN_USIM_PWR_1 - 3   //SW_USIM_0 - 1
//		GPIO_COMM_Init(RCC_APB2Periph_GPIOC, GPIOC, 
//				GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9, GPIO_Mode_Out_PP, GPIO_Speed_50MHz);
//		GPIO_COMM_Init(RCC_APB2Periph_GPIOA, GPIOA, 
//				GPIO_Pin_8, GPIO_Mode_Out_PP, GPIO_Speed_50MHz);

	#if 1
//		//for sim 1
//		GPIO_SetBits(GPIOC, GPIO_Pin_6);
//		GPIO_ResetBits(GPIOC, GPIO_Pin_7);
//		GPIO_ResetBits(GPIOC, GPIO_Pin_8);

//		GPIO_SetBits(GPIOC, GPIO_Pin_9);
//		GPIO_ResetBits(GPIOA, GPIO_Pin_8);
	#else
		//for sim 2
		GPIO_ResetBits(GPIOC, GPIO_Pin_6);
		GPIO_ResetBits(GPIOC, GPIO_Pin_7);
		GPIO_SetBits(GPIOC, GPIO_Pin_8);

		GPIO_ResetBits(GPIOC, GPIO_Pin_9);
		GPIO_ResetBits(GPIOA, GPIO_Pin_8);
	#endif
		
	}
#else
	#ifdef MSTS_C
		LED_Init(RCC_APB2Periph_GPIOD, GPIOD, GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15);
		LED_Init(RCC_APB2Periph_GPIOC, GPIOC, GPIO_Pin_6 | GPIO_Pin_7);
	#else
		LED_Init(RCC_APB2Periph_GPIOB, GPIOB, GPIO_Pin_13 | GPIO_Pin_14);
	#endif
#endif	
}
/*-----------------------------------------------------------------
 * 检查usim卡的情况
 * 返回值 ：0： 没有卡 ，非0： 已经插入卡
 * ------------------------------------------------------------------*/
uint8_t check_usim_status(uint8_t type)
{
    uint8_t usmflag = 0;
    static uint8_t lastusmflag = 0xFF;

    printf("\r\n usim插入情况：\r\n");

    if(type==1){
        lastusmflag = 0xFF;
    }

    if(USIM1_CD)
    {
        usmflag |= 0x01;
        printf("usim1 on\n");

    }
    else
    {
        usmflag &= (~(0x01<<0));
        printf("usim1 off\n");
    }

    if(USIM2_CD)
    {
        usmflag |= 0x02;
        printf("usim2 on\n");
    }
    else
    {
        usmflag &= (~(0x01<<1));
        printf("usim2 off\n");
    }

    if(USIM3_CD)
    {
        usmflag |= 0x04;
        printf("usim3 on\n");
    }
    else
    {
        usmflag &= (~(0x01<<2));
        printf("usim3 off\n");
    }

    if((usmflag!=0) && (usmflag == lastusmflag)) return 0;

    sim_switch(usmflag);

    lastusmflag = usmflag;

    return usmflag;
}

void sim_switch(uint8_t code)
{
    printf("\r\n usim使用情况：\r\n");
    if((code&0x01)==0x01){
        USIM1_L();
        USIM0_H();

        //使能
        USIM1_PWR_ON();
        USIM2_PWR_OFF();
        USIM3_PWR_OFF();
        printf("use usim_01 \r\n");
    }
    else if((code&0x02) == 0x02) {
        USIM1_H();
        USIM0_L();

        //使能
        USIM1_PWR_OFF();
        USIM2_PWR_ON();
        USIM3_PWR_OFF();
        printf("use usim_02 \r\n");
    }
    else if((code&0x04) == 0x04) {

        USIM1_H();
        USIM0_H();

        //使能
        USIM1_PWR_OFF();
        USIM2_PWR_OFF();
        USIM3_PWR_ON();
        printf("use usim_03 \r\n");
    }
    else {
        printf("no usim \r\n");
    }
}



//按键处理函数
//返回按键值
//mode:0,不支持连续按;1,支持连续按;
//0，没有任何按键按下
//1，KEY0按下
//2，KEY1按下
//3，KEY2按下 
//4，KEY3按下 WK_UP
//注意此函数有响应优先级,KEY0>KEY1>KEY2>KEY3!!
uint8_t KEY_Scan(uint8_t mode)
{	   
    static int8_t key0PressPreStater=0;
    static int8_t key1PressPreStater=0;
    static int8_t key2PressPreStater=0;
    uint8_t key0_p=1;
    uint8_t key1_p=1;
    uint8_t key2_p=1;
    uint8_t res=0;

    key0_p = KEY0;
    if((key0_p == 0)&&(key0PressPreStater==1)){
        key0PressPreStater = 0;
        res = KEY0_PRES;
        return res;
    }
    else key0PressPreStater = KEY0;

    key1_p = KEY2;
    if((key1_p == 0)&&(key1PressPreStater==1)){
        key1PressPreStater = 0;
        res = KEY1_PRES;
       // key_info.keyvalue = KEY1_PRES;
        return res;
    }
    else {
        key1PressPreStater = KEY2;
       // key_info.keyvalue = KEY1_PRES;
    }

    key2_p = KEY1;
    if((key2_p == 0)&&(key2PressPreStater==1)){
        key2PressPreStater = 0;
        res = KEY2_PRES;
        return res;
    }
    else key2PressPreStater = KEY1;
    return 0;// 无按键按下
}


/*
*********************************************************************************************************
*                                            BSP_CPU_ClkFreq()
*
* Description : Read CPU registers to determine the CPU clock frequency of the chip.
*				读取cpu寄存器确定时钟频率
* Argument(s) : none.
*
* Return(s)   : The CPU clock frequency, in Hz.	 返回CPU始终频率
*
* Caller(s)   : Application.
*
* Note(s)     : none.
*********************************************************************************************************
*/

CPU_INT32U  BSP_CPU_ClkFreq (void)
{
    RCC_ClocksTypeDef  rcc_clocks;


    RCC_GetClocksFreq(&rcc_clocks);

    return ((CPU_INT32U)rcc_clocks.HCLK_Frequency);
}


#if (CPU_CFG_TS_TMR_EN == DEF_ENABLED)
void  CPU_TS_TmrInit (void)
{
    CPU_INT32U  cpu_clk_freq_hz;
    cpu_clk_freq_hz = BSP_CPU_ClkFreq();    
    CPU_TS_TmrFreqSet(cpu_clk_freq_hz);
}
#endif


/*$PAGE*/
/*
*********************************************************************************************************
*                                           CPU_TS_TmrRd()
*
* Description : Get current CPU timestamp timer count value.
*
* Argument(s) : none.
*
* Return(s)   : Timestamp timer count (see Notes #2a & #2b).
*
* Caller(s)   : CPU_TS_Init(),
*               CPU_TS_Get32(),
*               CPU_TS_Get64(),
*               CPU_IntDisMeasStart(),
*               CPU_IntDisMeasStop().
*
*               This function is an INTERNAL CPU module function & MUST be implemented by application/
*               BSP function(s) [see Note #1] but SHOULD NOT be called by application function(s).
*
* Note(s)     : (1) CPU_TS_TmrRd() is an application/BSP function that MUST be defined by the developer
*                   if either of the following CPU features is enabled :
*
*                   (a) CPU timestamps
*                   (b) CPU interrupts disabled time measurements
*
*                   See 'cpu_cfg.h  CPU TIMESTAMP CONFIGURATION  Note #1'
*                     & 'cpu_cfg.h  CPU INTERRUPTS DISABLED TIME MEASUREMENT CONFIGURATION  Note #1a'.
*
*               (2) (a) Timer count values MUST be returned via word-size-configurable 'CPU_TS_TMR'
*                       data type.
*
*                       (1) If timer has more bits, truncate timer values' higher-order bits greater
*                           than the configured 'CPU_TS_TMR' timestamp timer data type word size.
*
*                       (2) Since the timer MUST NOT have less bits than the configured 'CPU_TS_TMR'
*                           timestamp timer data type word size; 'CPU_CFG_TS_TMR_SIZE' MUST be
*                           configured so that ALL bits in 'CPU_TS_TMR' data type are significant.
*
*                           In other words, if timer size is not a binary-multiple of 8-bit octets
*                           (e.g. 20-bits or even 24-bits), then the next lower, binary-multiple
*                           octet word size SHOULD be configured (e.g. to 16-bits).  However, the
*                           minimum supported word size for CPU timestamp timers is 8-bits.
*
*                       See also 'cpu_cfg.h   CPU TIMESTAMP CONFIGURATION  Note #2'
*                              & 'cpu_core.h  CPU TIMESTAMP DATA TYPES     Note #1'.
*
*                   (b) Timer SHOULD be an 'up'  counter whose values increase with each time count.
*
*                       (1) If timer is a 'down' counter whose values decrease with each time count,
*                           then the returned timer value MUST be ones-complemented.
*
*                   (c) (1) When applicable, the amount of time measured by CPU timestamps is
*                           calculated by either of the following equations :
*
*                           (A) Time measured  =  Number timer counts  *  Timer period
*
*                                   where
*
*                                       Number timer counts     Number of timer counts measured
*                                       Timer period            Timer's period in some units of
*                                                                   (fractional) seconds
*                                       Time measured           Amount of time measured, in same
*                                                                   units of (fractional) seconds
*                                                                   as the Timer period
*
*                                                  Number timer counts
*                           (B) Time measured  =  ---------------------
*                                                    Timer frequency
*
*                                   where
*
*                                       Number timer counts     Number of timer counts measured
*                                       Timer frequency         Timer's frequency in some units
*                                                                   of counts per second
*                                       Time measured           Amount of time measured, in seconds
*
*                       (2) Timer period SHOULD be less than the typical measured time but MUST be less
*                           than the maximum measured time; otherwise, timer resolution inadequate to
*                           measure desired times.
*********************************************************************************************************
*/

//#if (CPU_CFG_TS_TMR_EN == DEF_ENABLED)
//CPU_TS_TMR  CPU_TS_TmrRd (void)
//{
//    return (CPU_TS_TMR)0;
//}
//#endif

//#if (CPU_CFG_TS_TMR_EN == DEF_ENABLED)

//void CPU_TS_TmrInit2 (void)

//{

//   CPU_INT32U  fclk_freq;

// 

// 

//   fclk_freq = BSP_CPU_ClkFreq();

// 

//   BSP_REG_DEM_CR    |= (CPU_INT32U)BSP_BIT_DEM_CR_TRCENA;  

//   BSP_REG_DWT_CYCCNT  = (CPU_INT32U)0u;

//   BSP_REG_DWT_CR    |= (CPU_INT32U)BSP_BIT_DWT_CR_CYCCNTENA;

// 

//   CPU_TS_TmrFreqSet((CPU_TS_TMR_FREQ)fclk_freq);

//}

//#endif

#if (CPU_CFG_TS_TMR_EN == DEF_ENABLED)

CPU_TS_TMR CPU_TS_TmrRd (void)

{

  extern volatile uint32_t TickCounter;
   return (TickCounter);

}

#endif

void board_info_get(uint16_t *flash_size, uint16_t *ram_size, uint8_t * chip_id)
{
    //0x36393359_ffffff39_43013637
    uint32_t *p_chip_id = (uint32_t *)chip_id;

    if(ram_size) {
        *ram_size = ( *( uint32_t* )0x1FFFF7E0 ) >> 16;
        //	printf("STM32 Flash memory's ram size = %dkB\r\n", *ram_size);
    }
    if(flash_size) {
        *flash_size = ( *( uint32_t* )0x1FFFF7E0 ) & 0xffff;
        //	printf("STM32 Flash memory's flash size = %dkB\r\n", *flash_size);
    }

    if(chip_id) {
        //memcpy(chip_id, ( ( uint8_t* )0x1FFFF7E8), 12);
        //p_chip_id = (uint32_t *)chip_id;
        memcpy(g_firmwareMsg.gatewayMsg.Uuid,( uint8_t* )(0x1FFFF7E8),12);
//        *p_chip_id = *(( uint32_t* )0x1FFFF7E8);
//        memcpy(g_firmwareMsg.gatewayMsg.Uuid,(uint8_t*)p_chip_id,4);
//        p_chip_id++;
//        *p_chip_id = *(( uint32_t* )0x1FFFF7EC);
//        memcpy(g_firmwareMsg.gatewayMsg.Uuid+4,(uint8_t*)p_chip_id,4);
//        p_chip_id++;
//        *p_chip_id = *(( uint32_t* )0x1FFFF7F0);
//        memcpy(g_firmwareMsg.gatewayMsg.Uuid+8,(uint8_t*)p_chip_id,4);
//        p_chip_id = (uint32_t *)chip_id;
        //	printf("Unique device ID register (96 bits). ID(Hex) = 0x%08x_%08x_%08x\r\n", *p_chip_id++, *p_chip_id++, *p_chip_id);
    }
}
