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

//HS16F1211
//TC0
//configuration introduction

//designer:LvBuWei
//updata：20240612

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

 
unsigned char modeCnt;
unsigned char PWM_MODE;
unsigned char PWM0_Duty;
//****interrupt function****//
void interrupt myIsr(void)    
{ 
	if(FTC0IF) 
	{ 
		FTC0IF = 0; 
	 /*TC0_Mode_8bit*/
		TC0L = 158;	//TC0 Low_8bit
	 /*TC0_Mode_16bit*/
	 	//TC0L = (0xff-1000)%256;	//TC0 Low_8bit
	 	//TC0H = (0xff-1000)/256;	//TC0 High_8bit
	 /*TC0_Mode_BUZ*/
		//TC0L = 56;	//TC0 Low_8bit
	 /*TC0_Mode_PWM*/
		//TC0L = 00;		//TC0 Low_8bit
		//PWM0_Duty++;
		PORTB = PORTB^0xc0;	
		modeCnt++;
		if(modeCnt>2)
		{
			modeCnt = 0;
			PWM_MODE++;
			PWM_MODE = PWM_MODE&0x0f;
		}
	} 
} 

//PWM0_PB2
#define		EN_PWM0_PB2		TC0M |= 0x01;
#define		DIS_PWM0_PB2	TC0M &= ~0x01;
//PWM1_PB1
//PWM1_PB5
#define		EN_PWM1			PWMCON |= 0x01;
#define		DIS_PWM1		PWMCON &= ~0x01;
#define		SetPWM1_PB1		PWMCON &= ~0x04;
#define		SetPWM1_PB5		PWMCON |= 0x04;
//PWM2_PB0
//PWM2_PB4
#define		EN_PWM2			PWMCON |= 0x02;
#define		DIS_PWM2		PWMCON &= ~0x02;
#define		SetPWM2_PB0		PWMCON &= ~0x08;
#define		SetPWM2_PB4		PWMCON |= 0x08;

void TC0_PWM_ModeSet(unsigned char mode)
{
	switch(mode)
	{
		case 0:	//PWM0-PB2==ok
			EN_PWM0_PB2			DIS_PWM1					DIS_PWM2					break;
		case 1:	//PWM1-PB1==ok
			DIS_PWM0_PB2		SetPWM1_PB1		EN_PWM1		DIS_PWM2					break;
		case 2:	//PWM2-PB0==ok
			DIS_PWM0_PB2		DIS_PWM1					SetPWM2_PB0		EN_PWM2		break;
		case 3:	//PWM1-PB5==ok
			DIS_PWM0_PB2		SetPWM1_PB5		EN_PWM1		DIS_PWM2					break;
		case 4:	//PWM2-PB4==ok
			DIS_PWM0_PB2		DIS_PWM1					SetPWM2_PB4		EN_PWM2		break;
			
		case 5:	//PWM0-PB2+PWM1-PB1
			EN_PWM0_PB2			SetPWM1_PB1		EN_PWM1		DIS_PWM2					break;
		case 6:	//PWM0-PB2+PWM2-PB0
			EN_PWM0_PB2			DIS_PWM1					SetPWM2_PB0		EN_PWM2		break;
		case 7:	//PWM0-PB2+PWM1-PB5
			EN_PWM0_PB2			SetPWM1_PB5		EN_PWM1		DIS_PWM2					break;			
		case 8:	//PWM0-PB2+PWM2-PB4
			EN_PWM0_PB2			DIS_PWM1					SetPWM2_PB4		EN_PWM2		break;
			
		case 9:	//PWM1-PB1+PWM2-PB0
			DIS_PWM0_PB2		SetPWM1_PB1		EN_PWM1		SetPWM2_PB0		EN_PWM2		break;
		case 10://PWM1-PB1+PWM2-PB4
			DIS_PWM0_PB2		SetPWM1_PB1		EN_PWM1		SetPWM2_PB4		EN_PWM2		break;
		case 11://PWM2-PB0+PWM1-PB5
			DIS_PWM0_PB2		SetPWM2_PB0		EN_PWM2		SetPWM1_PB5		EN_PWM1		break;
		case 12://PWM0-PB2+PWM1-PB1+PWM2-PB0==ok
			EN_PWM0_PB2			SetPWM1_PB1		EN_PWM1		SetPWM2_PB0		EN_PWM2		break;
		case 13://PWM0-PB2+PWM1-PB5+PWM2-PB4==ok
			EN_PWM0_PB2			SetPWM1_PB5		EN_PWM1		SetPWM2_PB4		EN_PWM2		break;
		default: break;
	}
}

//****main function****//
void main(void) 
{ 
	GPIO_Init(); 
	CLR_BANK0_RAM();
	CLR_BANK1_RAM();
	
	TC0_Init(TC0_Mode_8bit);
	//TC0_Init(TC0_Mode_16bit);
	//TC0_Init(TC0_Mode_BUZ);
	//TC0_Init(TC0_Mode_PWM);
	//TC0_Init(TC0_Mode_LOW);
	
	//PWM_MODE = 13;
	//TC0_PWM_ModeSet(PWM_MODE);	
	//PWM0_Duty = 0xf0;
	while(1) 
	{ 
		CLRWDT  
		PORTA = PORTA^0xff;		
		//;PORTB = PORTB^0xff;
		DelayUs(1);
		//PWM0_Duty++;
		//TC0H = PWM0_Duty;
		//TC0_PWM_ModeSet(PWM_MODE);
	} 
} 

//****TC0 configuration ****//
/*
	Example of this program：
	MODE1:8bit-Timer(no AutoLoad)
	MODE2:16bit-Timer(no AutoLoad)
	MODE3:BUZ(AutoLoad)
	MODE4:PWM(PWM1 can choose PB1 or PB5),(PWM2 can choose PB0 or PB4),(PWM0 can choose PB0 or PB2);
	MODE5:TC0-internal Low_Mode
*/
void TC0_Init(unsigned char mode) 
{ 
	if(mode == TC0_Mode_8bit) 
	{
		/*
		8bit Timer interrupt：1ms
		Config：Fcpu = 4Mhz 4'
		*/
		//;TC0 init value
	 	TC0L = 58;	//TC0 Low_8bit
	 	//;TC0H = 0x00;	//TC0 High_8bit	//PWM0 duty
	 	//;TC0D1 = 0x00;				//PWM1 duty
	 	//;TC0D2 = 0x00;				//PWM2 duty
	 	TC0R = 58;	//AutoLoad-ineffective 	
	 
	 	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
	 
	 	TC0M = 0x48;	//0111 1000;//Fosc 1' Fosc=8MHz;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 使能位
		
		FTC0IF = 0;		//TC0 overflow flag		 
		FTC0IE = 1;  	//TC0 overflow enable bit(1=EN,0=DIS)	
	}
	else if(mode == TC0_Mode_16bit)
	{
		/*
		16-bit Timer interrupt：10ms
		Config：Fcpu = 4Mhz 4'
		*/
		//;TC0 init value
	 	TC0L = (0xff-1000)%256;	//TC0 Low_8bit
	 	TC0H = (0xff-1000)/256;	//TC0 High_8bit
	 	//;TC0D1 = 0x00;	//PWM1 duty
	 	//;TC0D2 = 0x00;	//PWM2 duty
	 	//;TC0R = 0x00;	//AutoLoad-ineffective	
	 
	 	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
	  
	 	TC0M = 0x74;	//0111 0100;//Fcpu 2'；16bit
	 	
		FTC0IF = 0;		//TC0 overflow flag		    
		FTC0IE = 1;   	//TC0 overflow enable bit(1=EN,0=DIS)	
	}
	else if(mode == TC0_Mode_BUZ)
	{
		/*BUZ mode：single pulse：100us 
		Config：Fcpu = 4Mhz 4'
		*/
		//;TC0 init value
	 	TC0L = 56;	//TC0 Low_8bit
	 	//;TC0H = 0x00;	//TC0 High_8bit	//PWM0 duty
	 	//;TC0D1 = 0x00;				//PWM1 duty
	 	//;TC0D2 = 0x00;				//PWM2 duty
	 	TC0R = 56;	//AutoLoad-ineffective		
	 
	 	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
	 
	 	TC0M = 0x7a;	//0111 1010;//Fosc 1' Fosc=8MHz；8bit；BUZ
	 	
		FTC0IF = 0;		//TC0 overflow flag		  
		TC0IE = 1;  	//TC0 overflow enable bit(1=EN,0=DIS)
	}
	else if(mode == TC0_Mode_PWM)
	{
		/*
		PWM mode ：3PWM-out
		Config：Fcpu=4Mhz 4' 
		*/
		//;TC0 init value 1ms
	 	TC0L = 0x00;	//TC0 Low_8bit
	 	
	 	TC0H = 0x30;	//TC0 High_8bit/PWM0 duty
	 	TC0D1= 0x80;	//PWM1 duty
	 	TC0D2= 0xc0;	//PWM2 duty 
	 	TC0R = 0x00;	//AutoLoad-ineffective			
	 
	 	PWMCON = 0x03;	//0000 0011;//choose PWM out PIN；pwm1-PB1；pwm2-PB0	 
	 					//;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
	 
	 	TC0M = 0x71;	//0111 1001;//Fosc 1'；pwm0-PB2
	 	
		FTC0IF = 0;		//TC0 overflow flag		 
		FTC0IE = 1; 	//TC0 overflow enable bit(1=EN,0=DIS)
	}
	if(mode == TC0_Mode_LOW)
	{
		/*
		8bit Timer interrupt：24ms
		Config：Fcpu = 4Mhz 4'
		*/
		//;TC0 init value
	 	TC0L = 0x156;	//TC0 Low_8bit
	 	//;TC0H = 0x00;	//TC0 High_8bit/PWM0 duty
	 	//;TC0D1 = 0x00;	//PWM1 duty
	 	//;TC0D2 = 0x00;	//PWM2 duty
	 	//;TC0R = 0x00;	//AutoLoad-ineffective 	
	 
	 	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
	 
	 	TC0M = 0x70;	//0111 0000;//Fcpu 2';8bit
		
		FTC0IF = 0;		//TC0 overflow flag		 
		FTC0IE = 1;   	//TC0 overflow enable bit(1=EN,0=DIS)	
		
		OSCM = 0x10;	//-001 0000 ;TC0时钟源选低速
	}
	
	FTC0TR = 1; //;TC0 Start bit	
	FGIE  = 1;	//【INTEN.bit7】GIE:global inturrupt 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--);    
} 