#ifndef __BSP_H
#define __BSP_H

#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include "hc32_ddl.h"
#include "ff.h"


/*版本信息*/
typedef enum {
	GW_V1_0 = 0x81,						          //1-网关Ver1.0：具有LORA通信、4G通讯、以太网通信，支持DC12V供
	GW_V2_0 = 0x82,											//2-网关Ver2.0：具有LORA通信、4G通讯、以太网通信、光纤通信，支持AC-220V供电，DC-12V供电
}VER_INFO_M;
/*项目编号*/
typedef enum {
	TEST = 0x000000,						        //测试项目
	CASST = 0x000001,										//安科院项目
  BJTU = 0x000002,                    //北交大项目
  BSM = 0x000003,                     //巴拉水电边坡监测项目
  FSTM  = 0x000004,                   //铁一院川藏铁路隧道监测项目
  CSTM  = 0x000005,                   //铁二院川藏铁路隧道监测项目
  LYT = 0x000003,                     //雅下项目
}PRJ_NUM_M;
/*Lora频率：433100000ul + 200000*N */
typedef enum {
	CH0 = (433100000ul + 0),									//测试频率												
	CH1 =	(433100000ul + 200000),
	CH2 =	(433100000ul + 400000),
	CH3 =	(433100000ul + 600000),
	CH4 =	(433100000ul + 800000),
	CH5 =	(433100000ul + 1000000),
	CH6 =	(433100000ul + 1200000),
	CH7 =	(433100000ul + 1400000),
	CH8 =	(433100000ul + 1600000),
	CH9 =	(433100000ul + 1800000),
	CH10 = (433100000ul + 2000000),	
}LORA_FREQ_M;

/*版本选择*/
#define VERINFO     GW_V1_0
/*项目选择*/
#define PRJNUM      LYT
/*网关序号设置*/
#define GW_NUM_M    (0x0000)
/*Lora频率配置*/
#define LORA_FREQ		CH0

#define FLASH_SECTOR_SIZE           		0x2000ul                     
#define FLASH_BASE                  		((uint32_t)0x00000000)   
#define FLASH_SIZE                  		(64u * FLASH_SECTOR_SIZE) 

#define SRAM_BASE												((uint32_t)0x1FFF8000)
#define SRAM_SIZE												0x2F000ul

#define BOOT_SIZE												(4 * FLASH_SECTOR_SIZE)
#define	APP_ADDRESS											(FLASH_BASE + BOOT_SIZE)

#define BOOT_PARA_ADDRESS								(FLASH_SIZE - FLASH_SECTOR_SIZE)
#define	BOOT_PARA_SIZE									(FLASH_SECTOR_SIZE)


#define	DEV_TYPE												(0x0001)

#define	DEBUG															1
#define	USE_SD_CARD												0
#define WATCH_DOG                         1


#if(VERINFO == GW_V1_0)
#define	DBGUART_IRQn											Int006_IRQn
#define	DBGUART_EI_IRQn										Int007_IRQn
#define	DBG_RXPIN_IRQn										Int002_IRQn

//DEBUG
#define	DBG_USART_CH											(M4_USART1)
#define	DBG_USART_RX_PORT									(PortA)
#define	DBG_USART_RX_PIN									(Pin11)
#define	DBG_USART_TX_PORT									(PortA)
#define	DBG_USART_TX_PIN									(Pin12)
#define	DBG_USART_RX_FUNC									(Func_Usart1_Rx)
#define DBG_USART_TX_FUNC       	  			(Func_Usart1_Tx)
#define DBG_USART_RI_NUM									(INT_USART1_RI)
#define DBG_USART_EI_NUM									(INT_USART1_EI)
#define DBG_USART_TI_NUM									(INT_USART1_TI)
#define DBG_USART_TCI_NUM									(INT_USART1_TCI)
#define	DBG_FCG1_PERIPH										(PWC_FCG1_PERIPH_USART1)

//RS485 Ch1
#define	RS485_CH1_USART_CH								(M4_USART2)
#define	RS485_CH1_USART_RX_PORT						(PortA)
#define	RS485_CH1_USART_RX_PIN						(Pin10)
#define	RS485_CH1_USART_TX_PORT						(PortA)
#define	RS485_CH1_USART_TX_PIN						(Pin08)
#define	RS485_CH1_USART_RX_FUNC						(Func_Usart2_Rx)
#define RS485_CH1_USART_TX_FUNC       	  (Func_Usart2_Tx)
#define RS485_CH1_USART_RI_NUM						(INT_USART2_RI)
#define RS485_CH1_USART_EI_NUM						(INT_USART2_EI)
#define RS485_CH1_USART_TI_NUM						(INT_USART2_TI)
#define RS485_CH1_USART_TCI_NUM						(INT_USART2_TCI)
#define	RS485_CH1_FCG1_PERIPH							(PWC_FCG1_PERIPH_USART2)

#define RS485_CH1_CTRL_PORT               (PortC)
#define RS485_CH1_CTRL_PIN                (Pin07)
#define	RS485_CH1_TX()										PORT_SetBits(RS485_CH1_CTRL_PORT, RS485_CH1_CTRL_PIN)
#define	RS485_CH1_RX()										PORT_ResetBits(RS485_CH1_CTRL_PORT, RS485_CH1_CTRL_PIN)

#define RS485_CH1_POW_PORT              	(PortC)
#define RS485_CH1_POW_PIN               	(Pin10)
#define	RS485_CH1_POW_ON()								PORT_SetBits(RS485_CH1_POW_PORT, RS485_CH1_POW_PIN)
#define	RS485_CH1_POW_OFF()								PORT_ResetBits(RS485_CH1_POW_PORT, RS485_CH1_POW_PIN)

//RS485 Ch2
#define	RS485_CH2_USART_CH								(M4_USART3)
#define	RS485_CH2_USART_RX_PORT						(PortB)
#define	RS485_CH2_USART_RX_PIN						(Pin14)
#define	RS485_CH2_USART_TX_PORT						(PortB)
#define	RS485_CH2_USART_TX_PIN						(Pin12)
#define	RS485_CH2_USART_RX_FUNC						(Func_Usart3_Rx)
#define RS485_CH2_USART_TX_FUNC       	  (Func_Usart3_Tx)
#define RS485_CH2_USART_RI_NUM						(INT_USART3_RI)
#define RS485_CH2_USART_EI_NUM						(INT_USART3_EI)
#define RS485_CH2_USART_TI_NUM						(INT_USART3_TI)
#define RS485_CH2_USART_TCI_NUM						(INT_USART3_TCI)
#define	RS485_CH2_FCG1_PERIPH							(PWC_FCG1_PERIPH_USART3)

#define RS485_CH2_CTRL_PORT               (PortB)
#define RS485_CH2_CTRL_PIN                (Pin13)
#define	RS485_CH2_TX()										PORT_SetBits(RS485_CH2_CTRL_PORT, RS485_CH2_CTRL_PIN)
#define	RS485_CH2_RX()										PORT_ResetBits(RS485_CH2_CTRL_PORT, RS485_CH2_CTRL_PIN)

#define RS485_CH2_POW_PORT              	(PortB)
#define RS485_CH2_POW_PIN               	(Pin02)
#define	RS485_CH2_POW_ON()								PORT_SetBits(RS485_CH2_POW_PORT, RS485_CH2_POW_PIN)
#define	RS485_CH2_POW_OFF()								PORT_ResetBits(RS485_CH2_POW_PORT, RS485_CH2_POW_PIN)

//ETH OR CAT1
#define	ETH_OR_CAT1_USART_CH							(M4_USART4)
#define	ETH_OR_CAT1_USART_RX_PORT					(PortB)
#define	ETH_OR_CAT1_USART_RX_PIN					(Pin09)
#define	ETH_OR_CAT1_USART_TX_PORT					(PortC)
#define	ETH_OR_CAT1_USART_TX_PIN					(Pin13)
#define	ETH_OR_CAT1_USART_RX_FUNC					(Func_Usart4_Rx)
#define ETH_OR_CAT1_USART_TX_FUNC       	(Func_Usart4_Tx)
#define ETH_OR_CAT1_USART_RI_NUM					(INT_USART4_RI)
#define ETH_OR_CAT1_USART_EI_NUM					(INT_USART4_EI)
#define ETH_OR_CAT1_USART_TI_NUM					(INT_USART4_TI)
#define ETH_OR_CAT1_USART_TCI_NUM					(INT_USART4_TCI)
#define	ETH_OR_CAT1_FCG1_PERIPH						(PWC_FCG1_PERIPH_USART4)

#define ETH_OR_CAT1_CTRL_PORT							(PortB)
#define ETH_OR_CAT1_CTRL_PIN							(Pin08)
#define	ETH_ON()													PORT_SetBits(ETH_OR_CAT1_CTRL_PORT, ETH_OR_CAT1_CTRL_PIN)
#define	CAT1_ON()													PORT_ResetBits(ETH_OR_CAT1_CTRL_PORT, ETH_OR_CAT1_CTRL_PIN)

//#define ETH_OR_CAT1_TX_CTRL_PORT					(PortH)
//#define ETH_OR_CAT1_TX_CTRL_PIN						(Pin02)
//#define	ETH_ON()													{ PORT_SetBits(ETH_OR_CAT1_CTRL_PORT, ETH_OR_CAT1_CTRL_PIN); PORT_SetBits(ETH_OR_CAT1_TX_CTRL_PORT, ETH_OR_CAT1_TX_CTRL_PIN); }
//#define	CAT1_ON()													{ PORT_ResetBits(ETH_OR_CAT1_CTRL_PORT, ETH_OR_CAT1_CTRL_PIN); PORT_ResetBits(ETH_OR_CAT1_TX_CTRL_PORT, ETH_OR_CAT1_TX_CTRL_PIN);}

#define	CAT1_PWR_KEY_PORT									(PortA)
#define	CAT1_PWR_KEY_PIN									(Pin03)
#define	CAT1_PWR_KEY_CLR()								PORT_SetBits(CAT1_PWR_KEY_PORT, CAT1_PWR_KEY_PIN)
#define	CAT1_PWR_KEY_SET()								PORT_ResetBits(CAT1_PWR_KEY_PORT, CAT1_PWR_KEY_PIN)

#define	CAT1_RESET_PORT										(PortA)
#define	CAT1_RESET_PIN										(Pin00)
#define	CAT1_RESET_CLR()									PORT_SetBits(CAT1_RESET_PORT, CAT1_RESET_PIN)
#define	CAT1_RESET_SET()									PORT_ResetBits(CAT1_RESET_PORT, CAT1_RESET_PIN)

//#define	CAT1_POW_PORT											(PortA)
//#define	CAT1_POW_PIN											(Pin00)
//#define	CAT1_POW_ON()											PORT_SetBits(CAT1_POW_PORT, CAT1_POW_PIN)
//#define	CAT1_POW_OFF()										PORT_ResetBits(CAT1_POW_PORT, CAT1_POW_PIN)

#define	ETH_RESET_PORT										(PortB)
#define	ETH_RESET_PIN											(Pin05)
#define	ETH_RESET_SET()										PORT_SetBits(ETH_RESET_PORT, ETH_RESET_PIN)
#define	ETH_RESET_CLR()										PORT_ResetBits(ETH_RESET_PORT, ETH_RESET_PIN)

#define	ETH_DEF_PORT											(PortB)
#define	ETH_DEF_PIN												(Pin07)
#define	ETH_DEF_SET()											PORT_SetBits(ETH_DEF_PORT, ETH_DEF_PIN)
#define	ETH_DEF_CLR()											PORT_ResetBits(ETH_DEF_PORT, ETH_DEF_PIN)

#define	ETH_LINK_PORT											(PortB)
#define	ETH_LINK_PIN											(Pin06)
#define	ETH_LINK_GET()										PORT_GetBit(ETH_LINK_PORT, ETH_LINK_PIN)

//LORA IO
/* SPI_SCK Port/Pin definition */
#define SPI2_SCK_PORT                    (PortC)
#define SPI2_SCK_PIN                     (Pin04)
#define SPI2_SCK_FUNC                    (Func_Spi2_Sck)

/* SPI_MOSI Port/Pin definition */
#define SPI2_MOSI_PORT                   (PortA)
#define SPI2_MOSI_PIN                    (Pin07)
#define SPI2_MOSI_FUNC                   (Func_Spi2_Mosi)

/* SPI_MISO Port/Pin definition */
#define SPI2_MISO_PORT                   (PortA)
#define SPI2_MISO_PIN                    (Pin06)
#define SPI2_MISO_FUNC                   (Func_Spi2_Miso)

/* SPI_MOSI Port/Pin definition */
#define SPI2_NSS_PORT                   	(PortC)
#define SPI2_NSS_PIN                  	  (Pin05)
#define SPI2_NSS_FUNC                 	  (Func_Spi2_Nss0)
#define	SPI2_NSS_SET()										PORT_SetBits(SPI2_NSS_PORT, SPI2_NSS_PIN)
#define	SPI2_NSS_CLR()										PORT_ResetBits(SPI2_NSS_PORT, SPI2_NSS_PIN)

/* SPI unit and clock definition */
#define SPI2_UNIT                       	(M4_SPI2)
#define SPI2_UNIT_CLOCK                 	(PWC_FCG1_PERIPH_SPI2)

#define	LORA_DIO_PORT											(PortA)
#define	LORA_DIO_PIN											(Pin04)
#define	LORA_DIO_GET()										PORT_GetBit(LORA_DIO_PORT, LORA_DIO_PIN)
#define	LORA_DIO_EXIT_CH									(ExtiCh04)
#define	LORA_DIO_EXIT_SRC									(INT_PORT_EIRQ4)

#define	LORA_RESET_PORT										(PortA)
#define	LORA_RESET_PIN										(Pin05)
#define	LORA_RESET_SET()									PORT_SetBits(LORA_RESET_PORT, LORA_RESET_PIN)
#define	LORA_RESET_CLR()									PORT_ResetBits(LORA_RESET_PORT, LORA_RESET_PIN)

#define	LORA_RXEN_PORT										(PortB)
#define	LORA_RXEN_PIN											(Pin00)
#define	LORA_RXEN_SET()										PORT_SetBits(LORA_RXEN_PORT, LORA_RXEN_PIN)
#define	LORA_RXEN_CLR()										PORT_ResetBits(LORA_RXEN_PORT, LORA_RXEN_PIN)

#define	LORA_TXEN_PORT										(PortB)
#define	LORA_TXEN_PIN											(Pin01)
#define	LORA_TXEN_SET()										PORT_SetBits(LORA_TXEN_PORT, LORA_TXEN_PIN)
#define	LORA_TXEN_CLR()										PORT_ResetBits(LORA_TXEN_PORT, LORA_TXEN_PIN)

#define	LORA_RX_LED_PORT									(PortB)
#define	LORA_RX_LED_PIN										(Pin03)     
#define	LORA_RX_LED_SET()									PORT_SetBits(LORA_RX_LED_PORT, LORA_RX_LED_PIN)
#define	LORA_RX_LED_CLR()									PORT_ResetBits(LORA_RX_LED_PORT, LORA_RX_LED_PIN)	
#define	LORA_RX_TOGGLE()									PORT_Toggle(LORA_RX_LED_PORT, LORA_RX_LED_PIN)

#define	LORA_POW_PORT											(PortC)      
#define	LORA_POW_PIN											(Pin06)
#define	LORA_POW_ON()											PORT_SetBits(LORA_POW_PORT, LORA_POW_PIN)
#define	LORA_POW_OFF()										PORT_ResetBits(LORA_POW_PORT, LORA_POW_PIN)	

//开关按钮灯
#define	KEY_LED_PORT									    (PortB)
#define	KEY_LED_PIN										    (Pin04)

typedef struct {
	bool Enable;		//串口使能
	bool CommUnitEnable;		//通讯单元使能，开启（使用内部通讯单元功能，直接和传感器通讯），关闭（直接和RS485类型的通讯单元通讯）
	bool QuerySensorFlag;		//查询传感器标志
	bool UpgradeEnable;//升级功能使能
	uint8_t Power;
	uint32_t BaudRate;
	SendData RS485Send;
	CommUnit_t CUData;
}__attribute__((packed))RS485Para_t, *RS485Para;

typedef struct {
	bool OnOff;
	SendData LoraSend;
	uint8_t ucChannel;
	int8_t ucPower;
	uint8_t SignalBw;
	uint8_t SpreadFactor;
	uint8_t ErrorCoding;
	uint8_t RegPreamble;
	uint32_t FreqCent;
}LoraPara_t, *pLoraPara;

typedef struct {
	uint32_t SavFlag;									//存储标志
	CommType_m Comm;									//网关通讯方式
	uint8_t GwMac[6];									//网关mac
	char SvrAddr[4];									//服务器地址
	uint32_t SvrPort;									//服务器端口
	uint32_t CommUnitReadInterval;				//通讯单元读取时间间隔,单位S
	RS485Para_t Rs485Ch1;							//RS485通道1配置
	RS485Para_t Rs485Ch2;							//RS485通道2配置
	uint8_t DebugChannel;							//调试通道
	LoraPara_t Lora;									//Lora配置
}__attribute__((packed))GWConfigPara_t, *GWConfigPara;

typedef struct {
	uint32_t AppFlag;
	uint32_t UpdateFlag;
	uint32_t PackageCnt;
	uint32_t AppSize;
	uint32_t Crc32Check;
  uint32_t	FirstRunFlag;//第一次运行
}BootPara_t, *BootPara;

void BSP_Init(void);

void DbgUart_Config(uint32_t BaudRate);
void DebugUartSend(uint8_t *sData, uint16_t sLen);
void DbgRxIrqCallback(uint8_t rData);

void FeedDog(void);
void Error_Handler(void);
void FlashWrite(uint32_t Addr, uint32_t *wData, uint8_t wLen);
void ReadBootPara(BootPara rData);
void WriteBootPara(BootPara wData);
void EraseFlash(void);
//extern stc_sd_handle_t stcSdhandle;
#endif
