//*********************************************************************** 
//Copyright (c) 2022   HuaXin Micro-electronics Co.,Ltd 
//
//HS16F2612 
//EEPROM
//configuration introduction
//
//designer:LvBuWei
//updata：20230808
//
//***********************************************************************  
//RAM: 176*8bytes
//ROM: 2K
//STACK: 8-level
//EEPROM: 256*8bytes
//*********************************************************************** 
#include 	"main.h"		


//--------------------------------------------------------------------------------------------------
/*
//　　　　                           ╔══════╗　 ╔══════╗
//            	  	            VDD  ╬1 ●   ╚═══╝    16╬   GND
//      OSCI /       /        / PA7  ╬2              15╬   PA0 /        / AIN0 / C1IN+ / ISPCK
//      OSCO / EVREF / T1G	  / PA6  ╬3     SOP16    14╬   PA1 /        / AIN1 / C1IN- / ISPDA
//      RSTB /       /        / PA5  ╬4              13╬   PA2 / T0CKI  / AIN2 / C1OUT /
//           /  P1C  / T4PWM  / PC3  ╬5              12╬   PA3 /        / AIN3 /       /
// AIN6/     /  P1D  / T5PWM  / PC2  ╬6              11╬   PC0 /        / AIN4 / C2IN+ /      / P1F
//           /       /        / PA4  ╬7              10╬   PC1 /        / AIN5 / C2IN- / INT  / P1E
//           /  P1A  /        / PC5  ╬8              9 ╬   PC4 / T3PWM  /      / C2OUT /      / P1B
//                                   ╚═════════════════╝
*/
//--------------------------------------------------------------------------------------------------
/*
//　　　　                           ╔══════╗　 ╔══════╗
//            	  	            VDD  ╬1 ●   ╚═══╝    14╬   GND
//      OSCI /       /        / PA7  ╬2              13╬   PA0 /        / AIN0 / C1IN+ / ISPCK
//      OSCO / EVREF / T1G	  / PA6  ╬3     SOP14    12╬   PA1 /        / AIN1 / C1IN- / ISPDA
//      RSTB /       /        / PA5  ╬4              11╬   PA2 / T0CKI  / AIN2 / C1OUT /
//           /  P1C  / T4PWM  / PC3  ╬5              10╬   PA3 /        / AIN3 /       /
// AIN6/     /  P1D  / T5PWM  / PC2  ╬6              9 ╬   PC0 /        / AIN4 / C2IN+ /      / P1F
//      C2OUT/  P1B  / T3PWM  / PC4  ╬7              8 ╬   PC1 /        / AIN5 / C2IN- / INT  / P1E
//                                   ╚═════════════════╝
*/
//*********************************************************************** 


//EE 寄存器汇总

//EECON 
				//Bit7 空	
				//Bit6 TIMEE[1:0] EE操作时长选择 00：默认 01：默认一半  10：默认两倍  11：默认4倍 
				//Bit4 ERS16								  1-使能16Byte擦操作 0-禁止16Byte擦操作  	
				//Bit3 ERSALLEE 全擦操作使能  1-使能全擦操作      0-禁止全擦操作
				//Bit2 ERASEEE  位擦操作使能  1-使能位擦		      0-禁止位擦
				//Bit1 PROGEE	写操作使能      1-使能写操作        0-禁止写操作
				//Bit0 READEE   读操作使能    1-使能读           0-禁止读	
//EEADR
				//EE 地址
//EEDATL
				//EE 数据





//==============================================
//1.>中断函数
//==============================================
void interrupt myIsr(void) {
	//----User Code ----/
}

/********EEPROM_CLR_ALL********** 20230809 ****
EEPROM : 256*8
entrance parameter：
	EEPROM_Addr：EE-write Addr （任意地址）
注意：执行全擦操作时，需先使能ERSALLEE，再使能ERASEEE。
******************************/
void EEPROM_CLR_ALL(unsigned char EEPROM_Addr) {
	EECON = 0x00;			//-0-- 0000;//EE control reg clr；
	EEADRL = EEPROM_Addr;	//EE 地址
	NOP();
	FERSALLEE = 1;			//全擦使能
	FERASEEE = 1;			  //使能擦除
	NOP();
	while (FERASEEE);		//等待擦除完毕
}


/********EEPROM_CLR_16Byte**********
EEPROM : Sector:16byte(一共16个扇区)
entrance parameter：
	EEPROM_Addr：EE-write Sector Addr 【0~16】
注意：执行16byte擦操作时，需先使能ERS16，再使能ERASEEE
******************************/
void EEPROM_CLR_16Byte(unsigned char EEPROM_Sector_Addr) {
	EECON = 0x00;		 	//-0-- 0000;//EE control reg clr；

	EEPROM_Sector_Addr &= 0x0f;	//扇区地址不会溢出
	EEADRL = EEPROM_Sector_Addr * 16;	//EE-write Addr
	NOP();

	ERS16 = 1;				//Bit-ERS16 Enable：1=EN；0=DIS
	FERASEEE = 1;			//Bit-ERASE Enable：1=EN；0=DIS 
	NOP();
	while (FERASEEE);//PORTC = PORTC^0xff;;		//Bit-ERASE over flag 
}

/********EEPROM-Write-1byte**********  20230809 ****
entrance parameter：
	EEPROM_Addr：EE-write Addr
	EEPROM_Data：EE-write Data
******************************/
void EEPROM_Write_1Byte(unsigned char EEPROM_Addr, unsigned char EEPROM_Data) {

	//写入流程-----设置操作时间=>写擦除地址=>使能擦除=>等待擦除完毕=>写数据寄存器=>使能写入=>等待写入完成

	EECON = 0x00;

	//Bit7 空	
	//Bit6 TIMEE[1:0] EE操作时长选择 00：默认 01：默认一半  10：默认两倍  11：默认4倍 
	//Bit4 ERS16 0-禁止16Byte擦操作  	 1-使能16Byte擦操作
	//Bit3 ERSALLEE 全擦操作使能  1-使能全擦操作    0-禁止全擦操作
	//Bit2 ERASEEE  位擦操作使能  1-使能位擦		0-禁止位擦
	//Bit1 PROGEE	写操作使能    1-使能写操作      0-禁止写操作
	//Bit0 READEE   读操作使能    1-使能读          0-禁止读		
	FTIMEE1 = 0;			//ERASE-Time
	FTIMEE0 = 0;			//ERASE-Time
	//TIMEE1:FTIMEE0
		//00:EEPROM 操作默认时长 *1
		//01:EEPROM 操作默认时长 *1/2
		//10:EEPROM 操作默认时长 *2
		//11:EEPROM 操作默认时长 *4



	EEADRL = EEPROM_Addr;	//擦除地址
	NOP();
	FERASEEE = 1;			//擦除
	NOP();
	while (FERASEEE);//等待擦除完毕
	EEDATL = EEPROM_Data;	//EE数据
	FPROGEE = 1;			//使能EE写入
	NOP();
	while (FPROGEE);//等待写入完成
}


/********EEPROM-Read-1byte********
entrance parameter：
	EEPROM_Addr：EE-write Addr
exit parameter:
	EEPROM_Data：EE-read Data
******************************/
unsigned char EEPROM_Read_1Byte(unsigned char EEPROM_Addr) {
	unsigned char ReadEeprom_Data;

	//读取流程 设置操作时间=>写读取的地址=>使能读取=>等待读取完成=>从数据寄存器中获取数据

	EECON = 0x00;
	//Bit7 空	
	//Bit6 TIMEE[1:0] EE操作时长选择 00：默认 01：默认一半  10：默认两倍  11：默认4倍 
	//Bit4 ERS16 0-禁止16Byte擦操作  	 1-使能16Byte擦操作
	//Bit3 ERSALLEE 全擦操作使能  1-使能全擦操作    0-禁止全擦操作
	//Bit2 ERASEEE  位擦操作使能  1-使能位擦		0-禁止位擦
	//Bit1 PROGEE	写操作使能    1-使能写操作      0-禁止写操作
	//Bit0 READEE   读操作使能    1-使能读          0-禁止读	

	EEADRL = EEPROM_Addr;	//读取EE的地址

	FREADEE = 1;			//使能读取操作
	NOP();
	NOP();
	ReadEeprom_Data = EEDATL;//获取读取的数据

	return ReadEeprom_Data;	//Return data 
}


u16 temp;
u8  i;




void main(void) {
	System_Init();
	GPIO_Init();
	CLR_RAM_EveryBank();

	temp = 0;


	EEPROM_CLR_16Byte(0);
	EEPROM_CLR_ALL(0);  //擦除所有的数据



	//将数据填满EE
	for (temp = 0; temp < 256; temp++) {
		CLRWDT();
		EEPROM_Write_1Byte(temp, temp);	//EE 全地址写数据
	}

	while (1) {
		i++;
		CLRWDT();
		//读取数据比较
		if (EEPROM_Read_1Byte(i) == i) {
			PA7 = ~PA7;
		}
		DelayUs(200);
	}
}


//****GPIO configuration****//
void GPIO_Init(void) {
	//;PORTA
	PORTA = 0b00000000;		//--00 0000	
	TRISA = 0b00000000;		//0000 0000 :0-OUT;1-IN 	

	PAODCON = 0b00000000;	//--11 -111 :1-EN;0-DIS (Open-drain)	
	PAHCON = 0b11111111;	//--11 1111 :1-DIS;0-EN (UpPull)	
	PADCON = 0b11111111;	//--11 1111 :1-DIS;0-EN (DownPull)	
	WUACON = 0b00000000;	//--00 0000	:1-EN;0=DIS (WakeUp)	
	PAIC0 = 0b00000000;		//1111 1111 :1-EN;0-DIS (Drive)


	//;PORTC
	PORTC = 0b00000000;
	TRISC = 0b00000000;		//--00 0000 :0-OUT;1-IN

	PCDCON = 0b11111111;	//---- 1111 :1-DIS;0-EN (DownPull)
	PCHCON = 0b11111111;	//---- 1111 :1-DIS;0-EN (UpPull)	
	PCIC0 = 0b00000000;		//1111 1111 :1-EN;0-DIS (Drive)
}


//****System _Init function****// 
void System_Init(void) {

	OPTION = 0b000000001;	 //-000 0000	(Initialization state:0011 1111)
	//;Bit6：INTEDG：外部中断触发方式选择位（PC1）	;0-falling edge, 1-rising edge
	//;Bit5：T0CS：TMR0时钟源选择位					;0-fcpu, 1-ExitClock
	//;Bit4：T0SE：TMR0时钟源边沿选择位				;0-falling edge, 1-rising edge
	//;Bit3：PSA：预分频分配位						;0-TMR0, 1-WDT
	//;B2~0：PS2:PS0：预分频比率选择位
		//000		2T-TMR0			1T-WDT
		//001		4T-TMR0			2T-WDT
		//010		8T-TMR0			4T-WDT
		//011		16T-TMR0		8T-WDT
		//100		32T-TMR0		16T-WDT
		//101		64T-TMR0		32T-WDT
		//110		128T-TMR0		64T-WDT
		//111		256T-TMR0		128T-WDT


	PCON = 0b10110000;		//1-1- ----	(Initialization state:1011 1111)
	//;Bit7：WDTE: WDT（看门狗定时器）使能位	;0-DIS, 1-EN
	//;Bit5：LVREN: 低电压复位使能位			;0-DIS, 1-EN

	INTCON = 0B00000000;	//0000 0000 (Initialization state:0000 0000)
	//;Bit7：GIE：全局中断使能位	;0-DIS, 1-EN
	//;Bit6：PEIE：外设总中断使能	;0-DIS, 1-EN
	//;Bit5：T0IE：Timer0 溢出中断使能位	;0-DIS, 1-EN
	//;Bit4：INTIE：外部中断使能位（PC1）	;0-DIS, 1-EN
	//;Bit3：PAIE: PORTA 输入状态变化中断使能位
	//;Bit2: T0IF: Timer0 溢出中断标志位，软件复位
	//;Bit1: INTIF:	外部中断标志位（PC1），软件复位
	//;Bit0: PAIF: PORTA 输入状态变化中断标志位，软件复位

	PIE1 = 0B00000000;		//-0-- -000
	//;Bit6：ADCIE：ADC 中断使能位
	//;Bit2: CCP1IE: 捕捉、比较中断使能位
	//;Bit1: T2IE: 定时器 T2 中断使能位
	//;Bit0: T1IE: 定时器 T1 中断使能位

	PIR1 = 0B00000000;	//-0-- -000
	//;Bit6：ADCIF：ADC 中断使能标志位，软件复位
	//;Bit2: CCP1IF: 捕捉、比较中断标志位，软件复位
	//;Bit1: T2IF: 定时器 T2 中断标志位，软件复位
	//;Bit0: T1IF: 定时器 T1 中断标志位，软件复位

	PIE2 = 0B00000000;	//-00- 000-
	//;Bit6：C2IE: 比较器 C2 中断使能位
	//;Bit5：C1IE: 比较器 C1 中断使能位

	//;Bit3：T5IE: 定时器 T5 中断使能位
	//;Bit2: T4IE: 定时器 T4 中断使能位
	//;Bit1: T3IE: 定时器 T3 中断使能位

	PIR2 = 0B00000000;	//-00- 000-
	//;Bit6：C2IE: 比较器 C2 中断标志位，软件复位
	//;Bit5：C1IE: 比较器 C1 中断标志位，软件复位

	//;Bit3：T5IE: 定时器 T5 中断标志位，软件复位
	//;Bit2: T4IE: 定时器 T4 中断标志位，软件复位
	//;Bit1: T3IE: 定时器 T3 中断标志位，软件复位

	OSCM = 0B00000000;	//0000 0000
	//;Bit7：MONIF：外振时钟停振监测标志位; 0= 未监测到外振时钟停振，1=测到外振时钟停振
	//;Bit6：WAKEMODE：低速模式下睡眠唤醒后系统时钟选择位; 0=内外低速，1=高速RC
	//;Bit5：GREENEN：绿色模式使能位；0=普通模式，1=绿色模式
	//;Bit4：RTCEN：RTC 模式软件使能位；0=EN，1=DIS
	//;Bit3：SLCON：内外低速时钟控制位；0=Open内外低速，1=关闭内外低速
	//;Bit2: XTSEL：内外低速选择位；0=内部低速，1=外部低速
	//;Bit1: STPHX：内部高速振荡器控制位；0=run，1=Stop
	//;Bit0: CLKMD: Timer0 溢出中断使能位；0=普通模式，1=低速模式

//RCREG = 0;
}


//****************************************************  
//对用户寄存器进行清0操作 
//分BANK区清楚 
//嵌入汇编操作 
//IRP:FSR7:	间接寻址寻址空间（充分理解 间接寻址操作原理）
//	0 0		BANK0
//	0 1		BANK1
//	1 0		BANK2
//	1 1		BANK3
//****************************************************    
void CLR_RAM_EveryBank(void) {
	#asm
		MOVLW	0x5F  //个数
		MOVWF	0x20  //个数存放地址 
		MOVLW 	0x7F  //REG从后往前 清理 
		MOVWF	_FSR, F
		CLR_RAM_LOOP :
	CALL	CLR_RAM_Demo

		DECF	_FSR, F
		DECFSZ	0X20, F
		GOTO	CLR_RAM_LOOP

		CALL	CLR_RAM_Demo
		RETURN

		CLR_RAM_Demo :
	//	0 1		BANK1
		//BCF	_STATUS,7	//IRP
	BSF		_FSR, 7		//01:BANK1
		CLRF	_INDF

		//	0 0		BANK0
			//BCF		_STATUS,7
		BCF		_FSR, 7	//00:BANK0
		CLRF	_INDF

		RETURN
		#endasm
}


//****delay function****// 
//;Fcpu=8MHz （误差4us）
void DelayUs(unsigned char delayUs) {
	while (delayUs--);
}