//*********************************************************************** 
//Copyright (c) 2024   HuaXin Micro-electronics Co.,Ltd 

//HS16F1211
//SLEEP
//configuration introduction

//designer:LvBuWei
//updata：20240612

//*********************************************************************** 
//Files include 
#include 	"hs16f1211.h" 
#include 	"main.h"		


unsigned char tmp;

//****interrupt function****//
void interrupt myIsr(void)
{
	if(FT0IF)
	{
		FT0IF = 0;
		//PORTB = PORTB^0xFF;
	}
	if(FTC0IF)
	{
		FTC0IF = 0;
		PORTB = PORTB^0xFF;
	}
	if(FPBIF)
	{
		FPBIF = 0;
		//PORTB = PORTB^0x01;
	}
	if(FINTIF)
	{
		FINTIF = 0;
		//PORTB = PORTB^0x04;
	}
	if(FCOMINTF)
	{
		FCOMINTF = 0;
		//PORTB = PORTB^0x04;
	}
}


//****main function****//
void main(void)
{
	GPIO_Init();
	
	CLR_BANK0_RAM();
	CLR_BANK1_RAM();
	
	/*SLEEP，wakeup choose*/
	//RESET				//config(hardware reset)
	//WDT_Init();		//when WDT overflow,MCU Reset；
	
	//EXIT_INT_INIT();	//wakeup,goto interrupt or goto next code；
	//PB_CHANGE_INIT();	//wakeup,goto interrupt or goto next code；
	
	//TC0_SLEEP_SET();	//wakeup
	
	//CMPCON_Init(MODE1);	//wakeup
	
 	
	while(1)
	{
		CLRWDT
		PORTA = PORTA^0xff;
		
		TC0_SLEEP_SET();	//睡眠低速定时器唤醒
		
		//WDTE = 0;
		//SLEEP
		//WDTE = 1;
		//while(1)	CLRWDT
		//PORTB = PORTB^0xff;
		//DelayUs(1);
	} 
} 
 



//*********************************************************************** 
/****WDT overflow reset，have no wakeup funtions****；

这里有一点需要注意，TMR0和WDT有一个预分频分配使能位；
S1.预分频分配给WDT：TMR0的时钟源固定为Fcpu；
	看门狗复位时间config加上<预分频比率选择位PS2:PS0>构成
				config	1:1		1:2		1:4		1:8		1:16	1:32	1:64	1:128
	1档：WDT	4.5ms	4.5ms	9ms		18ms	36ms	72ms	144ms	288ms	576ms
	2档：WDT	18ms	18ms	36ms	72ms	144ms	288ms	576ms	1152ms	2304ms
	3档：WDT	72ms	72ms	144ms	288ms	576ms	1152ms	2304ms	4608ms	9216ms
	4档：WDT	288ms	288ms	576ms	1152ms	2304ms	4608ms	9216ms	18432ms	36864ms		
	
S2.预分频分配给TMR0：
	看门狗复位时间仅有config构成：4.5ms；18ms；72ms；288ms；
*/
void WDT_Init(void) 
{
	CLRWDT  
	 
//;option attentions 
	OPTION= 0b00001000; //-000 1001
			//;Bit7：INT1EDG：外部中断1触发方式选择位（PB1）;0-falling edge, 1-rising edge
			//;Bit6：INTEDG：外部中断触发方式选择位（PB0）	;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
			//;Bit2~Bit0：PS2:PS0：预分频比率选择位
	
//;PCON 
	PCON  = 0b10000000;	//100- ----	
			//;Bit7：WDTE: WDT（看门狗定时器）使能位	;0-DIS, 1-EN
			//;Bit6：EIS: IOB0/INT引脚定义位			;0-DIS, 1-EN
			//;Bit5：LVREN: 低电压复位使能位			;0-DIS, 1-EN		
}


//****EXIT_INT configuration****
//;PB0-EXIT_INT pin-PB0：input with Up_pull
//;PCON.bit6-INT Set pin;
//;***********************************************************************
void EXIT_INT_INIT(void)
{
//option
	OPTION= 0b01000001; // -000 0001
						//;Bit7：INT1EDG：外部中断1触发方式选择位（PB1）;0-falling edge, 1-rising edge
						//;Bit6：INTEDG：外部中断触发方式选择位（PB0）	;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
						//;Bit2~Bit0：PS2:PS0：预分频比率选择位

	
//PCON
	PCON  = 0b11000000;	//010- ----
						//PCON.bit7:WDTE:WDT enable;1-EN;0-DIS
						//PCON.bit6:EIS:INT pin define;1=INT;0=IOB0，INT Function Disable
						//PCON.bit5:LVDTE:Low Voltage Detect enable
	
	IOSTB = 0b00000001;	//(0-OUT;1-IN) 
	
	PHCON = 0b11111110;	//1111 1111 :1-DIS;0-EN  

	FINTIF = 0;		//INTIF【INTFLAG.bit2】INT interrupt flag,software reset
	
	FINTIE = 1;		//INTIE【INTEN.bit2】INT interrupt enable (1=EN,0=DIS)	
	
	FGIE  = 1;		//GIE【INTEN.bit7】:global interrupt enable bit
}


//****PB_CHANGE_INT Config****//
//PB input state change can make interrupt;
//PB pin must be set input with up_pull or down_pull;
//WUCON pin must be enable；

void PB_CHANGE_INIT(void)
{
//option
	OPTION= 0b00000001; //-000 0001
			//;Bit7：INT1EDG：外部中断1触发方式选择位（PB1）;0-falling edge, 1-rising edge
			//;Bit6：INTEDG：外部中断触发方式选择位（PB0）	;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
			//;Bit2~Bit0：PS2:PS0：预分频比率选择位
	
//PB7 as example 
	IOSTB = 0b10000000;	
	
//UP_PULL	:bit must be set 
//input with UP_Pull;
//bit:PORTB7~PORTB0；
	PHCON = 0b01111111;	//1111 1111 :1-DIS;0-EN  	

//pin state change interrupt enable
	WUCON = 0b10000000;	//0000 0000	:1-EN;0=DIS 
	
	FPBIF = 0;	//INTIF【INTFLAG.bit1】PB interrupt flag,software reset
	
	FPBIE = 1;	//FPBIE【INTEN.bit1】PB interrupt enable (1=EN,0=DIS)	
	
	FGIE  = 1;	//GIE【INTEN.bit7】:global interrupt enable bit

}


//****TC0 overflow：TC0 choose low clock，TC0 interruot must be set****//
void TC0_SLEEP_SET(void)
{
	/*****TC0 ：8bit/16bit  
	Config：4Mhz 4' **********/
//Tc0 init 
	TC0H=0XFE;
	TC0L=0X51;
	
 	PWMCON = 0x00;	//0000 0000;
 					//;Bit7~Bit6：<PWM2XR1：PWM2XR0>
					//;Bit5~Bit4：<PWM1XR1：PWM1XR0>
					//;Bit3：PWM2S: PWM2 端口选择位, 1=PB4,0=PB0
					//;Bit2：PWM1S: PWM1 端口选择位, 1=PB5,0=PB1
					//;Bit1：PWM2EN: PWM2 使能位, 1=EN,0=DIS
					//;Bit0：PWM1EN: PWM1 使能位, 1=EN,0=DIS


  	//TC0IF: TC0 overflow flag,software reset
 	//TC0M = 0x64;	//0110 0100;//Fcpu 4'-16bit-
	TC0M = 0x70;	//0110 0000;//Fcpu 4'-8bit-
					//;Bit7：TC0TR:TC0 启动控制位。
					//;Bit6~Bit4：TC0S[2:0]:TC0 分频选择位
					//;Bit3：TCCKS:TC0 时钟信号控制位
					//;Bit2：T16SEL:8/16 位溢出位选择。仅当所有 PWMEN = 0 且 BUZ=0 时有效
					//;Bit1：BUZ:BUZ 输出使能位
					//;Bit0：PWM0:PWM0 使能位

	CLRWDT
	FWDTE=0;
	FTC0IF=0;
	FTC0IE=1;    	//;需要 使能
	FTC0TR=1;    	//;TC0 定时器使能
	FGIE=0;
	
	OSCM=0X01;		//-101 1011
	OSCM=0X53;		//-101 1011
					//;Bit6：WAKEMODE：睡眠唤醒后系统时钟选择位;0=InsideLowRC,1=HighRC
					//;Bit5：GREENEN：绿色模式使能位		;0=GeneralMode，1=GreenMode
					//;Bit4：SLT0CON：TC0低速时钟控制位(用于唤醒睡眠、绿色);0=HighRC,1=LowRC
					//;Bit3：SLCON：内外低速时钟控制位	;0=OpenLowRC,1=CloseLowRC
					//;Bit2：XTSEL：内外低速选择位		;0=InsideLowRC,1=OutSideLowRC
					//;Bit1：STPHX：内部高速振荡器控制位	;0=Work,1=Stop
					//;Bit0：CLKMD：系统时钟模式控制位	;0=GeneralMode，1=LowMode
	NOP
	SLEEP
	NOP
	 
	while(FTC0IF==0);
	FTC0IF=0;
	
	CLRWDT
	FWDTE=1;
	FTC0IE=0;
	FTC0TR=0;
    
	OSCM=0X40;
}


//****CMPCON configuration****//
/*
CMPCON'+'positive choose：External base input "PB0" or internal base ；
CMPCON'-'negative choose: VDD、PB4、PB6、PB1；
*/
/*
program_1：CMPCON'-'negative CONFIG{VDD}；CMPCON'+'positive CONFIG internal base；
program_2：CMPCON'-'negative CONFIG{PIN}；CMPCON'+'positive CONFIG internal base；
program_3：CMPCON'-'negative CONFIG{PIN}；CMPCON'+'positive CONFIG External base input "PB0"；
*/
void CMPCON_Init(unsigned char mode)
{
	if(mode==MODE1)		//program_1：CMPCON'-'negative config[VDD]D；CMPCON'+'positive config internal base ;
	{
		CMPM = 0x10;	//-001 0000 //CMPCON'-'negative CONFIG[VDD]；XRVSEL=1；VRS<3:0>=0；(voltage of cmopare:4.69);
						//;Bit6~Bit5：CPIINS[1:0]: 比较器负端输入选择;	00=VDD;01=PB4;10=PB6;11=PB1
						//;Bit4：XRVSEL 比较电压点档位选择
						//;Bit3~Bit0：负端电压档位选择
						
		CMPCON= 0xD4;	//1*11 010- //System clock；3-clock delay；'+'positive config internal base 1.25V；polarity not contrary；
						//;Bit7：CMPEN: CMP 使能位
						//;Bit6：COMIF: 比较器转换标志
						//;Bit5：FTCKS: 输出使能滤波时钟选择
						//;Bit4：CODEB: 输出滤波
						//;Bit3：CPEN+: 比较器+端
						//;Bit2：CVEN+: 比较器+端
						//;Bit1：COPOL: 比较器输出极性选择
	
	}
	else if(mode == MODE2)//program_2：CMPCON'-'negative config[pin]；CMPCON'+'positive config internal base；
	{
		CMPM = 0x70;	//-111 0000 //CMPCON'-'negative CONFIG[PB1]；XRVSEL=1；VRS<3:0>=0；(voltage of cmopare:4.69)
						//;Bit6~Bit5：CPIINS[1:0]: 比较器负端输入选择;	00=VDD;01=PB4;10=PB6;11=PB1
						//;Bit4：XRVSEL 比较电压点档位选择
						//;Bit3~Bit0：负端电压档位选择
						
		CMPCON= 0xD4;	//1*11 010- //System clock；3-clock delay；'+'positive config internal base 1.25V；polarity not contrary；
						//;Bit7：CMPEN: CMP 使能位
						//;Bit6：COMIF: 比较器转换标志
						//;Bit5：FTCKS: 输出使能滤波时钟选择
						//;Bit4：CODEB: 输出滤波
						//;Bit3：CPEN+: 比较器+端
						//;Bit2：CVEN+: 比较器+端
						//;Bit1：COPOL: 比较器输出极性选择
	}
	else if(mode == MODE3)//program_3：CMPCON'-'negative config[pin]；CMPCON'+'positive config External base input "PB0"；
	{
		CMPM = 0x70;	//-111 0000 //CMPCON'-'negative CONFIG[PB1];XRVSEL=1;VRS<3:0>=0;(voltage of cmopare：Calculated from external base PB0)
						//;Bit6~Bit5：CPIINS[1:0]: 比较器负端输入选择;	00=VDD;01=PB4;10=PB6;11=PB1
						//;Bit4：XRVSEL 比较电压点档位选择
						//;Bit3~Bit0：负端电压档位选择
						
		CMPCON= 0xD8;	//1*11 100- //System clock；3-clock delay；+positive config External base(PB0)；polarity not contrary；
						//;Bit7：CMPEN: CMP 使能位
						//;Bit6：COMIF: 比较器转换标志
						//;Bit5：FTCKS: 输出使能滤波时钟选择
						//;Bit4：CODEB: 输出滤波
						//;Bit3：CPEN+: 比较器+端
						//;Bit2：CVEN+: 比较器+端
						//;Bit1：COPOL: 比较器输出极性选择
	}
	
	FCOMINTF = 0;	//CMPCON overflow flag
	FCOMINTEN = 1; 	//CMPCON overflow enable bit(1=EN,0=DIS)

	FGIE  = 1;		//【INTEN.bit7】GIE:global interrupt enable bit  
}



//****GPIO configuration****//
void GPIO_Init(void) 
{
	OPTION= 0b000000000;//0000 0000	
			//;Bit7：INT1EDG：外部中断1触发方式选择位（PB1）;0-falling edge, 1-rising edge
			//;Bit6：INTEDG：外部中断触发方式选择位（PB0）	;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
			//;Bit2~Bit0：PS2:PS0：预分频比率选择位

	PCON  = 0b00100000;	//101- ----		
			//;Bit7：WDTE: WDT（看门狗定时器）使能位	;0-DIS, 1-EN
			//;Bit6：EIS: IOB0/INT引脚定义位			;0-DIS, 1-EN
			//;Bit5：LVREN: 低电压复位使能位			;0-DIS, 1-EN
					
//PORTA //----------------------------------------------------------------------
	PORTA = 0b00000000;	
	TRISA = 0b00000000;	//(0-OUT;1-IN) 		
	PAHCON= 0b11111111;	//--11 1111 :1-DIS;0-EN 
	PADCON= 0b11111111;	//--11 ---- :1-DIS;0-EN 	
	PAIC0 = 0b00000000;	//--00 0000 :1-EN;0-DIS
	
	PDCON = 0b11111111;	//0000 0000 :1-DIS;0-EN[pdb3/pdb2/pdb1/pdb0/ /pda3/pda2/pda1/pda0]
	PDCON2= 0b11111111;	//--00 0000 :1-DIS;0-EN[-/-/pda5/pda4/ /pdb7/pdb6/pdb5/pdb4]
//PORTB //----------------------------------------------------------------------
	PORTB = 0b00000000;	
	TRISB = 0b00000000;	//(0-OUT;1-IN) 		
	PBIC0 = 0b00000000;	//1111 1111 :1-EN;0-DIS	
	WUCON = 0b00000000;	//0000 0000	:1-EN;0=DIS 
	ODCON = 0b00000000;	//1111 -111 :1-EN;0-DIS 	
	PHCON = 0b11111111;	//1111 1111 :1-DIS;0-EN 
	//----------------------------------------------------------------------
}


//****************************************************  
//CLR_BANK0_RAM: 
//C中嵌入ASM，指令操作特殊寄存器前面需要加下划线“_”;
//****************************************************    
void CLR_BANK0_RAM(void)
{
#asm  
	MOVLW	0X5F
	MOVWF	020H
	MOVLW	0X7F
	MOVWF	_FSR
	
BANK0_RAM_CLR_LOOP:	
	CLRF	_INDF
	DECF	_FSR,F
	DECFSZ	020H,F
	GOTO	BANK0_RAM_CLR_LOOP
#endasm
}


//****************************************************
//CLR_BANK1_RAM: 
//C中嵌入ASM，指令操作特殊寄存器前面需要加下划线“_”;
//****************************************************
void CLR_BANK1_RAM(void)
{
#asm  	
	MOVLW	(0x80 | 03FH)
	MOVWF	_FSR
	MOVLW	020H	//;32*reg-bank1
	MOVWF	020H
	
BANK1_RAM_CLR_LOOP:
	CLRF	_INDF
	DECF	_FSR,F
	DECFSZ	020H,F
	GOTO	BANK1_RAM_CLR_LOOP
	RETURN
#endasm
}

//****delay function****//
//;Fcpu=1MHz;DelayUs = 11+7x
void DelayUs(unsigned char delayUs)
{
	while(delayUs--);
} 