#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 "rtthread.h"
#include "ff.h"

//#define	USE_BOOTLOADER

//#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 RAM_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)

/* flash rom map  存储分区*/
//boot 16k
#define FLASH_BASE                ((uint32_t)0x00000000)  
#define FLASH_SECTOR_SIZE          0x2000ul    

#define	FLASH_BOOT_BASE			(FLASH_BASE)
#define	FLASH_BOOT_SIZE			(4*FLASH_SECTOR_SIZE)
//app
#define	FLASH_APP_BASE			(FLASH_BOOT_BASE+ FLASH_BOOT_SIZE)
#define	FLASH_APP_SIZE		    (58*FLASH_SECTOR_SIZE)

//boot info
#define FLASH_BINFO_BASE		(FLASH_APP_BASE + FLASH_APP_SIZE)
#define	FLASH_BINFO_SIZE		(1*FLASH_SECTOR_SIZE)

//user config
#define FLASH_CFG_BASE          (FLASH_BINFO_BASE + FLASH_BINFO_SIZE)
#define FLASH_CFG_SIZE          (1*FLASH_SECTOR_SIZE)

#define FLASH_CFG_MAGIC         (0xa5)

#define	APP_START_FLAG						0x55AA5A5A
#define	APP_UPDATE_FLAG						0xA5A5AA55


#define	WATCH_DOG					1

#define	DEBUG															1
#define	USE_SD_CARD												0

#define	RTC_IRQn													Int001_IRQn

#define	LORA_DIO0_IRQn										Int005_IRQn

#define	DBGUART_IRQn											Int006_IRQn
#define	DBGUART_EI_IRQn										Int007_IRQn

#define	RS485CH1_UART_IRQn								Int008_IRQn
#define	RS485CH1_UART_EI_IRQn							Int009_IRQn

#define	RS485CH2_UART_IRQn								Int010_IRQn
#define	RS485CH2_UART_EI_IRQn							Int011_IRQn

#define	ETH_OR_CAT1_UART_IRQn							Int012_IRQn
#define	ETH_OR_CAT1_UART_EI_IRQn					Int013_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)

//#define	RS485_CH1_VOL_CTRL_PORT						(PortA)				
//#define RS485_CH1_VOL_CTRL_PIN            (Pin15)
//#define	RS485_CH1_VOL_5V()								PORT_SetBits(RS485_CH1_VOL_CTRL_PORT, RS485_CH1_VOL_CTRL_PIN)
//#define	RS485_CH1_VOL_12V()								PORT_ResetBits(RS485_CH1_VOL_CTRL_PORT, RS485_CH1_VOL_CTRL_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)

//#define	RS485_CH2_VOL_CTRL_PORT						(PortB)				
//#define RS485_CH2_VOL_CTRL_PIN            (Pin10)
//#define	RS485_CH2_VOL_5V()								PORT_SetBits(RS485_CH2_VOL_CTRL_PORT, RS485_CH2_VOL_CTRL_PIN)
//#define	RS485_CH2_VOL_12V()								PORT_ResetBits(RS485_CH2_VOL_CTRL_PORT, RS485_CH2_VOL_CTRL_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)

/* SPI_MOSI Port/Pin definition */
#define SPI_NSS_PORT                   	(PortC)
#define SPI_NSS_PIN                  	  (Pin00)
#define SPI_NSS_FUNC                 	  (Func_Spi1_Nss0)
#define	SPI_NSS_SET()										PORT_SetBits(SPI_NSS_PORT, SPI_NSS_PIN)
#define	SPI_NSS_CLR()										PORT_ResetBits(SPI_NSS_PORT, SPI_NSS_PIN)

/* SPI_SCK Port/Pin definition */
#define SPI_SCK_PORT                    (PortC)
#define SPI_SCK_PIN                     (Pin02)
#define SPI_SCK_FUNC                    (Func_Spi1_Sck)

/* SPI_MOSI Port/Pin definition */
#define SPI_MOSI_PORT                   (PortC)
#define SPI_MOSI_PIN                    (Pin03)
#define SPI_MOSI_FUNC                   (Func_Spi1_Mosi)

/* SPI_MISO Port/Pin definition */
#define SPI_MISO_PORT                   (PortC)
#define SPI_MISO_PIN                    (Pin01)
#define SPI_MISO_FUNC                   (Func_Spi1_Miso)

/* SPI unit and clock definition */
#define SPI_UNIT                        (M4_SPI1)
#define SPI_UNIT_CLOCK                  (PWC_FCG1_PERIPH_SPI1)


//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	POWER_LED_PORT										(PortB)
#define	POWER_LED_PIN											(Pin04)
#define	POWER_LED_ON()										PORT_SetBits(POWER_LED_PORT, POWER_LED_PIN)
#define	POWER_LED_OFF() 									PORT_ResetBits(POWER_LED_PORT, POWER_LED_PIN)	
#define	POWER_TOGGLE()										PORT_Toggle(POWER_LED_PORT, POWER_LED_PIN)

#if USE_SD_CARD
#include "sd_card.h"
/* SDIOC Port/Pin definition */
#define SDIOC_CD_PORT										  (PortA)
#define SDIOC_CD_PIN										  (Pin10)

#define SDIOC_CK_PORT										  (PortC)
#define SDIOC_CK_PIN										  (Pin12)

#define SDIOC_CMD_PORT										(PortD)
#define SDIOC_CMD_PIN										  (Pin02)

#define SDIOC_D0_PORT										  (PortC)
#define SDIOC_D0_PIN										  (Pin08)

#define SDIOC_D1_PORT										  (PortC)
#define SDIOC_D1_PIN										  (Pin09)

#define SDIOC_D2_PORT										  (PortA)
#define SDIOC_D2_PIN										  (Pin09)

#define SDIOC_D3_PORT										  (PortC)
#define SDIOC_D3_PIN										  (Pin11)

/* SD sector && count */
#define SD_SECTOR_START										 (0u)
#define SD_SECTOR_COUNT										 (4u)
										  
/* SDIOC unit */
#define SDIOC_UNIT										  	(M4_SDIOC1)

en_result_t SdioInit(void);
bool SDCardErase(uint32_t u32BlkStartAddr, uint32_t u32BlkEndAddr);
bool SDCardReadBlocks(uint32_t u32BlkStartAddr, uint32_t u32BlkEndAddr, uint8_t *ReadBuff);
bool SDCardWriteBlocks(uint32_t u32BlkStartAddr, uint32_t u32BlkEndAddr, uint8_t *WriteBuff);
#endif

#define	BAT_COLL_ADC_CH										(ADC1_CH1)

//帧头结构体
typedef struct {
	uint8_t Header;
	uint8_t SlvAddr;
	uint8_t Cmd;		
	uint8_t PayloadLen;
}update_protocol_hd_t;

//主机下发升级请求载荷结构体
typedef struct {
	uint16_t PackageNum;
	uint32_t AppSize;
	uint32_t AppCrc32;
}__attribute__ ((packed))update_protocol_req_t;

//从机请求下发结构体
typedef struct {
	uint16_t PackageIndex;
	uint32_t PackageNum;
}__attribute__ ((packed))update_protocol_get_t;

//主机应答下发数据结构体
typedef struct {
	uint16_t PackageIndex;
	uint16_t PackageNum;
	uint8_t  DataLen;
}__attribute__ ((packed))update_protocol_rsp_t;

typedef struct {
	uint32_t AppFlag;
	uint32_t DevType;
	uint32_t DevAddr;
	uint32_t UpdateFlag;
	uint32_t PackageNum;
	uint32_t AppSize;
	uint32_t Crc32Check;
}boot_para_t;

void BSP_Init(void);

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

void RS485Ch1_Config(uint32_t BaudRate);
void RS485Ch1UartSend(uint8_t *sData, uint16_t sLen);
void RS485Ch1RxIrqCallback(uint8_t rData);

void RS485Ch2_Config(uint32_t BaudRate);
void RS485Ch2UartSend(uint8_t *sData, uint16_t sLen);
void RS485Ch2RxIrqCallback(uint8_t rData);

void EthOrCat1UartSend(uint8_t *sData, uint16_t sLen);
void EthOrCat1RxIrqCallback(uint8_t rData);

void LoraTxRxIrqCallback(void);

uint16_t Spi1SendReceive(uint16_t sData);
uint16_t Spi2SendReceive(uint16_t sData);

//void ReadAdcValue(uint16_t *ADValue);
uint16_t GetADCBuffPoint(void);
void ADC_Start(void) ;

void FeedDog(void);
void Error_Handler(void);

int TimeTs(void);
void TimeShow(uint32_t dwStamp);
void TimeSync(time_t ts) ;
void TimeGet(struct tm *cTime);
void TimeSync2(uint8_t Year, uint8_t Month, uint8_t Day, uint8_t Hour, uint8_t Min, uint8_t Sec);

void FlashWrite(uint32_t Addr, uint32_t *wData, uint8_t wLen);
void FlashRead(uint32_t Addr,uint32_t *rData, uint8_t rLen);
void dev_boot_read_param(boot_para_t *pParam);
int  dev_boot_write_param(boot_para_t  Param);
//extern stc_sd_handle_t stcSdhandle;
#endif

