/**
******************************************************************************************************************************************************************************************
*@file                       hw_config.c
*@author         
*@data                       
*@version                    v1.0
*@par Copyright(c):
*
*@par History:
*     version:author,date,desc
*     v1.0   :create this file
*
*******************************************************************************************************************************************************************************************
*/
#include "hw_config.h"
#include "app_config.h"
#include "cpu_nvic.h"
#include "radio_calibration.h"
#include "app_trace.h "
#include "cpu_wdt.h"
#include "user_uart.h"
#include "system_sleep.h"
#include "common.h"
#include "cpu_radio.h"
#include "rfid.h"
#include "ws18xxx_interface_driver.h"
//系统切换

void nvic_configuration(void)
{
    nvic_init_type_def nvic_init_structure;
//【1】配置中断优先级格式，初级优先级0~3 次级优先级0~1    值越小优先级越高
    NVIC_SetPriorityGrouping(NVIC_PriorityGroup_2);
//【2】初级中断优先级1   (0~3)
    nvic_init_structure.nvic_irq_channel_preemption_priority 	= 1;
//【3】初级中断优先级0	 (0~1)
	nvic_init_structure.nvic_irq_channel_subpriority 			= 0;

//【4】使能中断配置	 	 (DISABLE~ENABLE)
    nvic_init_structure.nvic_irq_channel_cmd 					= ENABLE; 
    
//【5】配置中断通道 	 (DISABLE~ENABLE)
    nvic_init_structure.nvic_irq_channel 						= ROM_LIB_0_IRQN;

//【5】中断配置生效 	 (DISABLE~ENABLE)
	nvic_init(&nvic_init_structure);

	NVIC_ClearPendingIRQ(ROM_LIB_1_IRQN);
    nvic_init_structure.nvic_irq_channel 						= ROM_LIB_1_IRQN;
    nvic_init(&nvic_init_structure);
    nvic_init_structure.nvic_irq_channel 						= ROM_LIB_2_IRQN;
    nvic_init(&nvic_init_structure);
    nvic_init_structure.nvic_irq_channel 						= ROM_LIB_3_IRQN;
    nvic_init(&nvic_init_structure);
    nvic_init_structure.nvic_irq_channel 						= ROM_LIB_4_IRQN;
    nvic_init(&nvic_init_structure);
    nvic_init_structure.nvic_irq_channel 						= ROM_LIB_5_IRQN;
    nvic_init(&nvic_init_structure);
    nvic_init_structure.nvic_irq_channel 						= ROM_LIB_6_IRQN;
    nvic_init(&nvic_init_structure);
    nvic_init_structure.nvic_irq_channel 						= ROM_LIB_7_IRQN;
    nvic_init(&nvic_init_structure);
    nvic_init_structure.nvic_irq_channel 						= ROM_LIB_13_IRQN;
    nvic_init(&nvic_init_structure);

#if (DBG_UART == ws_uart1 || APP_UART == ws_uart1)
	nvic_init_structure.nvic_irq_channel = UART1_IRQn;
	nvic_init_structure.nvic_irq_channel_preemption_priority = 2;
	nvic_init_structure.nvic_irq_channel_subpriority = 0;
	nvic_init(&nvic_init_structure);
#endif

#if (DBG_UART == ws_uart0 || APP_UART == ws_uart0)
	nvic_init_structure.nvic_irq_channel = UART0_IRQn;
	nvic_init_structure.nvic_irq_channel_preemption_priority = 2;
	nvic_init_structure.nvic_irq_channel_subpriority = 0;
	nvic_init(&nvic_init_structure);
#endif	

#if TIMER01_IRQ_ENABLE
    nvic_init_structure.nvic_irq_channel = Timer0_IRQn;	
	nvic_init_structure.nvic_irq_channel_preemption_priority 	= 3;
	nvic_init_structure.nvic_irq_channel_subpriority 			= 0;
    nvic_init(&nvic_init_structure);
#endif

#if EXT_GPIO_IRQ
    nvic_init_structure.nvic_irq_channel = GPIO_INT0_IRQn;
    nvic_init(&nvic_init_structure);
    nvic_init_structure.nvic_irq_channel = GPIO_INT1_IRQn;
    nvic_init(&nvic_init_structure);
    nvic_init_structure.nvic_irq_channel = GPIO_INT2_IRQn;
    nvic_init(&nvic_init_structure);
    nvic_init_structure.nvic_irq_channel = GPIO_INT3_IRQn;
    nvic_init(&nvic_init_structure);
#endif

    //nvic_init_structure.nvic_irq_channel = GPADC_IRQn;
    //nvic_init(&nvic_init_structure);    
}

/*****************************************************************************
 函 数 名  : syscfg_configuration
 功能描述  : 系统配置
 输入参数  : void  
 输出参数  : 无
 返 回 值  : 
*****************************************************************************/
void syscfg_configuration(void)
{
#if (USE_EXT_XTAL_16M)
// 16M晶振
	syscfg_external_16M_xtal();
    //< 配置晶振匹配电容,外部无须电容
    
//替换前    
//    syscfg_set_oscxtal_config(RF_ADJUST);
//替换后
	syscfg_set_oscxtal_config(64);

#endif

#if (USE_EXT_XTAL_32M)
// 32M晶振
    syscfg_external_32M_xtal();
    //< 配置晶振匹配电容，外部无须电容
    syscfg_set_oscxtal_config(0x57);
#endif

#if (USE_EXT_XTAL_32K)
// 外部32K晶振
    syscfg_external_32k_xtal();
    //radio_set_32k_freq(32768);
   // radio_set_32k_ppm(20);
#endif

#if (USE_INTER_RC_32K)
// 内部32K晶振
    syscfg_internal_32k_rc();
    //radio_set_32k_ppm(300);   
#endif

	low_power_sleep_config_ex(SYSCFG_Retention_Sram_24k,SDK_ENABLE_SLEEP);

	mcu_osc_configure();

}

void gpio_configuration(void)
{
	gpio_config_default();
}

void user_deepsleep_prepare(void)
{
// 有其它配置，需要依此处理
#if is_uart_dev(DBG_UART)	
#if DBG_USART_FlowCtrl_EN
//	gpio_remap_config(GPIOD_Pin0,GPIO_Remap_GPIO);
//	gpio_remap_config(GPIOD_Pin1,GPIO_Remap_GPIO);
#endif

//	gpio_remap_config(GPIOD_Pin2,GPIO_Remap_GPIO);		
//	gpio_remap_config(GPIOD_Pin3,GPIO_Remap_GPIO);
#endif
}

void nfc_uart_configuration(uint8_t on,uint32_t baud_rate)
{
  uart_init_struct uart_init_structure;
	
	gpio_remap_config(GPIOA_Pin0,GPIO_Remap_UART0_RX);
	gpio_remap_config(GPIOA_Pin3,GPIO_Remap_UART0_TX);
	
	uart_init_structure.uart_baudrate = baud_rate;
	uart_init_structure.uart_word_len = UART_WordLength_8b;
	uart_init_structure.uart_stop_bits = UART_StopBits_1;
	uart_init_structure.uart_parity = UART_Parity_No;

	uart_init(UART0, &uart_init_structure);//UART1串口初始化

}


void dbg_uart_configuration(uint8_t on)
{
	uart_config Config={
		.boaud_rate	= 115200,
		.length_bit	= UART_WordLength_8b,	   
		.stop_bit	= UART_StopBits_1,		  
		.parity_bit	= UART_Parity_No, 
		.mode		= APP_USART_FIFO_IRQ,
		
#if DBG_USART_FlowCtrl_EN
		.rtsnPin	= GPIOD_Pin0, 				//串口接收流控脚
		.ctsnPin	= GPIOD_Pin1, 				//串口发送流控脚
#else
		.rtsnPin	= GPIO_INVAILD, 				//串口接收流控脚
		.ctsnPin	= GPIO_INVAILD, 				//串口发送流控脚
#endif

		.rxPin		= GPIOD_Pin2,					//串口接收脚
		.txPin		= GPIOD_Pin3					//串口发送脚
	};

	ui_uart_configuration(DBG_UART,&Config,on);
}

void app_uart_configuration(uint8_t on)
{
	uart_config Config={
		.boaud_rate	= 115200,
		.length_bit	= UART_WordLength_8b,	   
		.stop_bit	= UART_StopBits_1,		  
		.parity_bit	= UART_Parity_No, 
		.mode		= APP_USART_FIFO_IRQ,

#if APP_USART_FlowCtrl_EN
		.rtsnPin	= GPIOC_Pin0,				//串口接收流控脚
		.ctsnPin	= GPIOC_Pin1,				//串口发送流控脚
#else
		.rtsnPin	= GPIO_INVAILD, 			//串口接收流控脚
		.ctsnPin	= GPIO_INVAILD, 			//串口发送流控脚
#endif
		.rxPin		= GPIOC_Pin2,				//串口接收脚
		.txPin		= GPIOC_Pin3				//串口发送脚
	};

	Config.boaud_rate	= get_baudrate();

	ui_uart_configuration(APP_UART,&Config,on);
//	dbg_block_printf("init app uart %d... \n",Config.boaud_rate);
//	ui_uart_block_writebuf(APP_UART,"hello word\n",strlen("hello word\n"));
}



/*****************************************************************************
 函 数 名  : wdt_init
 功能描述  : 看门狗初始化
 输入参数  : void  
 输出参数  : 无
 返 回 值  : 
 调用函数  : 
 被调函数  : 

*****************************************************************************/
void wdt_init(void)
{
	wdt_set_reload(WDT_TIMEOUT*16000);
	wdt_mode_config(WDT_Mode_CPUReset);
	wdt_enable();
}

/*****************************************************************************
 函 数 名  : user_deepsleep_exit
 功能描述  : 退出DEEP_SLEEP 用户外设恢复，及用户数据恢复
 输入参数  : void  
 输出参数  : 无
 返 回 值  : 
*****************************************************************************/
void user_deepsleep_exit(void)
{	
#if (is_uart_dev(DBG_UART))
	dbg_uart_configuration(ON);
#endif

#if (is_uart_dev(APP_UART) && (APP_UART != DBG_UART))
	app_uart_configuration(ON);
#endif	
}


void hardware_init(void)
{
//	uint32_t periph_clk = CRM_PeriphClock_GPIO | CRM_PeriphClock_BT ;
//	uint32_t periph_rst = CRM_PeriphReset_GPIO | CRM_PeriphReset_BT ;
	uint32_t periph_clk = CRM_PeriphClock_GPIO  ;
	uint32_t periph_rst = CRM_PeriphReset_GPIO  ;

	
#if (APP_UART == ws_uart0 || DBG_UART == ws_uart0)
	periph_clk |= CRM_PeriphClock_UART0;
	periph_rst |= CRM_PeriphReset_UART0;
#endif

#if (APP_UART == ws_uart1 || DBG_UART == ws_uart1)
	periph_clk |= CRM_PeriphClock_UART1;
	periph_rst |= CRM_PeriphReset_UART1;
#endif

#if TIMER01_IRQ_ENABLE
	periph_clk |= CRM_PeriphClock_TIMER01;
	periph_rst |= CRM_PeriphReset_TIMER01;
#endif

#if WDT_ENABLE
	periph_clk |= CRM_PeriphClock_WDT;
	periph_rst |= CRM_PeriphReset_WDT;
#endif

#if SDK_GADC_ENABLE
	periph_clk |= CRM_PeriphClock_QPADC;
	periph_rst |= CRM_PeriphReset_GPADC;
#endif

	crm_cmd_periphclock(periph_clk,ENABLE);
	crm_reset_periph(periph_rst);

#if INTERFACE_UART
  crm_cmd_periphclock(CRM_PeriphClock_UART0,ENABLE);
	crm_reset_periph(CRM_PeriphReset_UART0);
#endif
    syscfg_configuration();
    gpio_configuration();
		
/*****************优先初始化调试串口**************/	
#if (is_uart_dev(DBG_UART))
	ui_uart_init(DBG_UART);
	dbg_uart_configuration(ON);
	set_uart_init(DBG_UART);
#endif


	load_config();
	
#if (WDT_ENABLE)
	wdt_init();
#endif

#if SDK_GADC_ENABLE
	gpio_dac_configuration(GPIOA_Pin4);
#endif

#if (is_uart_dev(APP_UART) && (APP_UART != DBG_UART))
	ui_uart_init(APP_UART);
	app_uart_configuration(ON);
	set_uart_init(APP_UART);
#endif
}



#if 0

/*****************************************************************************
 函 数 名  : user_gpio_cbk2
 功能描述  : nfc 接近触发中断，
 参数      : uint8_t intter_num  
 输出参数  : 无
 返 回 值  : 
 说明	   : 因高电平时间比较短，所以不影响低功耗
 示例      : 
*****************************************************************************/
void user_gpio_cbk2(uint8_t intter_num)
{
	dbg_block_printf("intter_num %x\n",intter_num);  
	get_card = 1;
}

uint8_t get_irq_pin_hight(void)
{
	return gpio_get_input(IRQ_PIN);
}

void set_spi_dile(void)
{

#if (HARD_SPI)

	gpio_remap_config(MISO_PIN,GPIO_Remap_GPIO);//MISO
	gpio_remap_config(MOSI_PIN,GPIO_Remap_GPIO);//MOSI
	gpio_remap_config(SCK_PIN,GPIO_Remap_GPIO);//SCK
	gpio_remap_config(NSS_PIN,GPIO_Remap_GPIO);//NSS

	gpio_init(MISO_PIN,GPIO_Mode_Input);//
	gpio_init(MOSI_PIN,GPIO_Mode_Output);//
	gpio_init(SCK_PIN,GPIO_Mode_Output);
	gpio_init(NSS_PIN,GPIO_Mode_Output);

	SET_CS_IDLE();		
	SET_CK_IDLE();	
	INIT_MISO_IDLE();

	SET_MOSI_IDLE();	
	SET_REST_IDLE();

#else

	SET_CS_IDLE();		
	SET_CK_IDLE();	
	INIT_MISO_IDLE();

	SET_MOSI_IDLE();	
	SET_REST_IDLE();
	
#endif

}


void nfc_master_spi_init(void)
{
//    uint32_t i;									//cnt = 0;
//    uint32_t ack_len;							//cnt = 0;
//    uint32_t status= 0;							//cnt = 0;
	spi_init_type_def spi_init_structure;

	crm_cmd_periphclock(CRM_CG_CTRL_SPI0,ENABLE);
	crm_reset_periph(CRM_SOFT_RST_SPI0 );

	gpio_remap_config(MISO_PIN,GPIO_Remap_GPIO);
	gpio_remap_config(MOSI_PIN,GPIO_Remap_GPIO);
	gpio_remap_config(SCK_PIN,GPIO_Remap_GPIO);
	gpio_remap_config(NSS_PIN,GPIO_Remap_GPIO);//NSS

	gpio_init(MISO_PIN,GPIO_Mode_Input);//
	gpio_init(MOSI_PIN,GPIO_Mode_Output);//
	gpio_init(SCK_PIN,GPIO_Mode_Output);
	gpio_init(NSS_PIN,GPIO_Mode_Output);					//NSS

//	gpio_remap_config(NSS_PIN,		GPIO_Remap_SPI0_CSN);
	gpio_remap_config(SCK_PIN,		GPIO_Remap_SPI0_CLK);	//SCK
	gpio_remap_config(MISO_PIN,	GPIO_Remap_SPI0_MISO);	//MISO
	gpio_remap_config(MOSI_PIN,	GPIO_Remap_SPI0_MOSI);	//MOSI

	spi_init_structure.spi_mode 					= SPI_Mode_Master;					//配置SPI主从模式：slave
	spi_init_structure.spi_direction				= SPI_Direction_2Lines_FullDuplex;	//设置SPI通信方式：全双工模式
	spi_init_structure.spi_data_size				= SPI_DataSize_8b;					//设置数据帧大小：8bit
	spi_init_structure.spi_cpol 					= SPI_CPOL_High;					//设置时钟极性:空闲状态时，时钟保持低电平
	spi_init_structure.spi_cpha 					= SPI_CPHA_2Edge;					//设置时钟相位：数据采样从第二个时钟边沿开始
//	spi_init_structure.spi_nss						= SPI_NSS_0;						//NSS信号控制选择	需要CS信号
	spi_init_structure.spi_nss						= SPI_NSS_1;						//NSS信号控制选择 	不需要CS信号，用户CS信号
//	spi_init_structure.spi_nss						= SPI_NSS_2;						//NSS信号控制选择
//	spi_init_structure.spi_nss						= SPI_NSS_3;						//NSS信号控制选择
	spi_init_structure.spi_nss						= SPI_NSS_All;						//NSS信号控制选择
//	spi_init_structure.spi_nss						= SPI_NSS_Null;						//NSS信号控制选择
	
	spi_init_structure.spi_baud_rate_prescaler		= SPI_BaudRatePrescaler_256;		//从机时钟不起作用，随主机  理论时钟要求 sclk < pclk/10
	spi_init_structure.spi_rx_fifo_full_threshold	= SPI_RXFIFOFullThreshold_1;		//接收FIFO空中断阈值：接收FIFO中数据1个及以上触发中断
	spi_init_structure.spi_tx_fifo_empty_threshold	= SPI_TXFIFOEmptyThreshold_0;		//发送FIFO满中断阈值：发送FIFO中数据数量为0触发中断
	
	spi_init(SPI0, &spi_init_structure);//SPI初始化
	spi_cmd(SPI0, ENABLE);//SPI使能

}
void nfc_d_init(void)
{
	gpio_remap_config(MISO_PIN,GPIO_Remap_GPIO);//MISO
	gpio_remap_config(MOSI_PIN,GPIO_Remap_GPIO);//MOSI
	gpio_remap_config(SCK_PIN,GPIO_Remap_GPIO);//SCK
	gpio_remap_config(NSS_PIN,GPIO_Remap_GPIO);//NSS

	gpio_init(MISO_PIN,GPIO_Mode_Input);//
	gpio_init(MOSI_PIN,GPIO_Mode_Output);//
	gpio_init(SCK_PIN,GPIO_Mode_Output);
	gpio_init(NSS_PIN,GPIO_Mode_Output);
}

void nfc_card_init(void)
{
  user_gpio_cfg_parameter_t 	p_parameter;
	gpio_remap_config(NREST_PIN,GPIO_Remap_GPIO);	//NRST
	gpio_remap_config(IRQ_PIN,GPIO_Remap_GPIO);	//IRQ	
	gpio_remap_config(SPEAK_PIN,GPIO_Remap_GPIO);	//SPEAK
	gpio_remap_config(LED1_PIN,GPIO_Remap_GPIO);	//LED2
	gpio_remap_config(LED2_PIN,GPIO_Remap_GPIO);	//LED1
	
	gpio_init(SPEAK_PIN,GPIO_Mode_Output);
	gpio_init(LED1_PIN,GPIO_Mode_Output);
	gpio_init(LED2_PIN,GPIO_Mode_Output);
	gpio_init(NREST_PIN,GPIO_Mode_Output);
	
#if (HARD_SPI)

	nfc_master_spi_init();
	dbg_printf("hard spi init \n");
	
	gpio_remap_config(NSS_PIN,GPIO_Remap_GPIO);//NSS
	gpio_init(NSS_PIN,GPIO_Mode_Output);
#else

	gpio_remap_config(MISO_PIN,GPIO_Remap_GPIO);//MISO
	gpio_remap_config(MOSI_PIN,GPIO_Remap_GPIO);//MOSI
	gpio_remap_config(SCK_PIN,GPIO_Remap_GPIO);//SCK
	gpio_remap_config(NSS_PIN,GPIO_Remap_GPIO);//NSS

	gpio_init(MISO_PIN,GPIO_Mode_Input);//
	gpio_init(MOSI_PIN,GPIO_Mode_Output);//
	gpio_init(SCK_PIN,GPIO_Mode_Output);
	gpio_init(NSS_PIN,GPIO_Mode_Output);

#endif

	gpio_init(IRQ_PIN,GPIO_Mode_Input);// 
	
	gpio_set(SPEAK_PIN);
	gpio_set(LED1_PIN);
	gpio_set(LED2_PIN);
	delay_ms(100);
	gpio_reset(SPEAK_PIN);
	gpio_reset(LED1_PIN);
	gpio_reset(LED2_PIN);
	
	p_parameter.gpio_handler = user_gpio_cbk2;
	user_gpio_config(&p_parameter);
	setup_gpio_irq(GPIO_Int1,gpio_to_value(NFC_IRQ),GPIO_Int_Type_BothEdge); 	// PB5
	
	dbg_printf("start read ver\n");
//	do
//	{
//		ver = IC_ver(); 	
//    dbg_printf("%02x",ver);		
//		ver_err_ct ++;		
//		if(ver_err_ct  >= 1000)
//		{
//			ver_err_ct = 0;
//			gpio_toggle(GPIOA_Pin1);
//			dbg_printf("%02x",ver);
//		}
//	}while((ver != 0x12) && (ver != 0x15));
}
#endif


uint16_t ver_err_ct=0;
uint16_t ver=0;
uint16_t get_card = 1;

/*****************************************************************************
 函 数 名  : user_gpio_cbk2
 功能描述  : nfc 接近触发中断，
 参数      : uint8_t intter_num  
 输出参数  : 无
 返 回 值  : 
 说明	   : 因高电平时间比较短，所以不影响低功耗
 示例      : 
*****************************************************************************/
void user_gpio_cbk2(uint8_t intter_num)
{
	dbg_block_printf("intter_num %x\n",intter_num);
	get_card = 1;
}

uint8_t get_irq_pin_hight(void)
{
	return gpio_get_input(WS_IRQ);
}

void nfc_interface_init(void)
{	
#if(INTERFACE_SPI)	
    gpio_init(WS_MOSI,GPIO_Mode_Output);  //MOSI
    gpio_init(WS_SCK,GPIO_Mode_Output);   //SCK
	  gpio_init(WS_NSS,GPIO_Mode_Output);   //NSS
    gpio_init(WS_MISO,GPIO_Mode_Input_Pull_Down_Resistor);   //MISO	
	  WS_NSS_HIGH;
#endif	 
#if(INTERFACE_I2C)	
    gpio_init(IIC_SCL,GPIO_Mode_Output);   //IIC_SCL	
#endif	   
	
#if(INTERFACE_UART)
    nfc_uart_configuration(ON,Baud_Rate);
#endif
	
	  gpio_init(NFC_RST,GPIO_Mode_Output);  //NRSTPD
	  gpio_init(WS_IRQ,GPIO_Mode_Input_Pull_Down_Resistor);    //IRQ
    
	  gpio_init(LED2,GPIO_Mode_Output);  //LED2
	  gpio_init(LED3,GPIO_Mode_Output);  //LED3
		gpio_init(BEEP,GPIO_Mode_Output);  //BEEP

		BEEP_ON;
		delay_ms(50);
		BEEP_OFF;
    delay_ms(50);
		delay_ms(50);
    IC_Version();
		
/*LPCD interrup config and io interrup type lever selcet*/
#if(LPCD_ENABLE)
    user_gpio_cfg_parameter_t   p_parameter;
		p_parameter.gpio_handler = user_gpio_cbk2;
	  user_gpio_config(&p_parameter);
	  setup_gpio_irq(GPIO_Int1,gpio_to_value(WS_IRQ),GPIO_Int_Type_RisingEdge); 	// PB5  GPIO_Int_Type_Disable //
	 	pcd_lpcd_start(DELAT,SWINGSCNT);
#endif
}

void nfc_card_process(void)
{
#if(LPCD_ENABLE)
	if(get_card == 0)
		return;
		get_card = 0;
#endif
	 PcdReset();
	 Card_Check();
	 NFC_RST_LOW;    //跑完读卡流程拉低复位脚，省功耗
	 delay_ms(200);
#if(LPCD_ENABLE)	
   PcdReset();
	 pcd_lpcd_start(DELAT,SWINGSCNT);
	 delay_ms(20); //等待系统稳定休眠
#endif
	
}


