/*********************************************/
/* Example Program For ET-BASE Z51F6412 V1.0 */
/* MCU      : Zilog MCS51 / Z51F6412         */
/*          : Run Internal RC (8.00 MHz)     */
/* Compiler : Keil C51 (V9.50a)              */
/* Editor   : uVision V4.53.0.6              */
/* Write By : Eakachai Makarn(ETT CO.,LTD.)  */
/* Function : Demo PWM-2,3,4,5 Control Servo */
/*          : PWM2 Pin = P5[4] = 20mS PWM    */
/*          : PWM3 Pin = P5[5] = 20mS PWM    */
/*          : PWM4 Pin = P5[6] = 20mS PWM    */
/*          : PWM5 Pin = P5[7] = 20mS PWM    */
/* Update   : 18 August 2012                 */
/*********************************************/
// ET-BASE Z51F6412 Hardware Statdard I/O
// SW1    = P8[0] GPIO Input
// LED    = P8[1] GPIO Output
// BUZZER = P5[0] Buzzer Drive
// UART0  = P0[2]:TX0,P0[3]:RX0
// UART1  = P3[2]:TX1,P3[3]:RX1
//
#include <z51f6412.h>																							// Z8051 : Z51F6412

//Timer5 PWM SFR 
#define PWM5HDR     T5H																						// PWM5HDR Same Address SFR T5H
#define PWM5LDR 		T5L																						// PWM5LDR Same Address SFR T5L
#define PWM5HPR			T5DRH																					// PWM5HPR Same Address SFR T5DRH
#define PWM5LPR    	T5DRL																					// PWM5LPR Same Address SFR T5DRL

/******************************************/
/* ET-BASE Z51F6412 Hardware System Clock */
/******************************************/
#define FREQ_32KHZ    			(32768ul)															// 32.768 KHz
#define FREQ_125KHZ					(125000ul)														// 125 KHz
#define FREQ_1MHZ						(1000000ul)														// 1.00 MHZ
#define FREQ_2MHZ						(2000000ul)														// 2.00 MHz
#define FREQ_4MHZ						(4000000ul)   												// 4.00 MHz
#define FREQ_8MHZ						(8000000ul)   												// 8.00 MHz
#define FREQ_10MHZ					(10000000ul)   												// 10.00 MHz
#define FREQ_12MHZ					(12000000ul)  												// 12.00 MHz
#define FREQ_16MHZ					(16000000ul)  												// 16.00 MHz
#define FREQ_PLL	    			(14745600ul)  												// 14.7456MHz
#define MY_FREQ							FREQ_8MHZ

/*******************************************/
/* ET-BASE Z51F6412 Hardware UART Baudrate */
/*******************************************/
#define BAUD_1200     			(1200ul)															// 1200
#define BAUD_2400     			(2400ul)															// 2400
#define BAUD_4800     			(4800ul)															// 4800
#define BAUD_9600     			(9600ul)															// 9600
#define BAUD_19200    			(19200ul)															// 19200
#define BAUD_38400    			(38400ul)															// 38400
#define BAUD_57600    			(57600ul)															// 57600
#define BAUD_115200   			(115200ul)														// 115200
#define MY_BAUD							BAUD_9600					
	
/************************************/
/* ET-BASE Z51F6412 Hardware SW Pin */
/************************************/
#define SW_PIN							(1 << 0)															// P8[0] = SW
#define SW_PORT_DIR					P8IO																	// Port Direction
#define SW_PORT_DATA				P8																		// Port Data
#define SW_PORT_PULLUP			P8PU																	// Port Pull-Up
#define SW_PORT_DEBOUNCE		P8DB																	// Port Debounce
#define SW_PORT_INIT() 			SW_PORT_DIR      	&= ~(SW_PIN)				// SW = Input 
#define SW_LOGIC_INIT()     SW_PORT_DATA     	|=  (SW_PIN)				// SW Defualt Logic = "1"
#define SW_PULLUP_INIT()		SW_PORT_PULLUP   	|=  (SW_PIN)				// Enable Pull-Up SW Pin
#define SW_DEBOUNCE_INIT()  SW_PORT_DEBOUNCE 	|=  (SW_PIN)				// Enable Debounce SW Pin

/*************************************/
/* ET-BASE Z51F6412 Hardware LED Pin */
/*************************************/
#define LED_PIN							(1 << 1)															// P8[1] = LED
#define LED_PORT_DIR				P8IO
#define LED_PORT_DATA 			P8
#define LED_PORT_INIT()    	LED_PORT_DIR 			|=  (LED_PIN)				// LED = Output
#define LED_OFF()						LED_PORT_DATA			&= ~(LED_PIN) 			// LED Pin = 0
#define LED_ON()  					LED_PORT_DATA			|=  (LED_PIN) 			// LED Pin = 1
#define LED_TOGGLE()  			LED_PORT_DATA			^=  (LED_PIN) 			// LED Pin = Toggle

/*************************************/
/* ET-BASE Z51F6412 Hardware SPI Pin */
/*************************************/
#define SPI0_CS_PIN	  			(1 << 4)															// P3[4] = CS0#
#define SPI0_PORT_DIR				P3IO
#define SPI0_PORT_DATA			P3
#define SPI0_CS_INIT()  		SPI0_PORT_DIR 		|=  (SPI0_CS_PIN)
#define SPI0_CS_LOW()				SPI0_PORT_DATA  	&= ~(SPI0_CS_PIN)
#define SPI0_CS_HIGH()  		SPI0_PORT_DATA  	|=  (SPI0_CS_PIN)

#define SPI1_CS_PIN	  			(1 << 4)															// P4[4] = CS1#
#define SPI1_PORT_DIR				P4IO
#define SPI1_PORT_DATA			P4
#define SPI1_CS_INIT()  		SPI1_PORT_DIR 		|=  (SPI1_CS_PIN)
#define SPI1_CS_LOW()				SPI1_PORT_DATA  	&= ~(SPI1_CS_PIN)
#define SPI1_CS_HIGH()  		SPI1_PORT_DATA  	|=  (SPI1_CS_PIN)

/***********************
 * Function Prototypes *
 ***********************/
void init_pwm2_timer2(void);
void init_pwm3_timer3(void);
void init_pwm4_timer4(void);
void init_pwm5_timer5(void);

/********************
 * Function: main() *
 ********************/
void main(void)
{	  
	/* Config System Clock = Internal RC 8.00 MHz */
	//PLLCR = 0,0,0,00,00,0
	// 0xxxxxxx : PLL Output Status
	// x0xxxxxx : PLL Output Bypass
	// xx0xxxxx : Power PLL = Default
	// xxx00xxx : FBDiv = Default
	// xxxxx00x : PLL M = Default
	// xxxxxxx0 : PLL Disable
	PLLCR = 0x00;																										// Disable PLL
	
	// SCCR = 0,01,0,0,1,00
	// 0xxxxxxx : Stop Mode = Mode 2
	// x01xxxxx : INTRC Clock Divide = INTRC(16MHz)/2 = 8MHz
	// xxx0xxxx : Clock Change By Hardware
	// xxxx0xxx : RC Oscillator Enable
	// xxxxx1xx : XTAL Oscillator Disable
	// xxxxxx00 : System Clock Source = INTRC(16MHz)
	SCCR = 0x24;  																									// INT-RC 8MHz	
	/* Now System Clock = 8.00MHz */
	
	//Initial PWM-2,3,4,5
	init_pwm2_timer2();   																					// P5[4] = 16Bit PWM (50Hz)
	init_pwm3_timer3();   																					// P5[5] = 16Bit PWM (50Hz)
	init_pwm4_timer4();   																					// P5[6] = 16Bit PWM (50Hz)
	init_pwm5_timer5();   																					// P5[7] = 16Bit PWM (50Hz)
	
	// 1Cycle = 0.5uS
	// Duty Cycle = nTime/0.5uS
  // 16Bit PWM Duty Cycle Max = 65535 Cycle
	// For Servo = 20mS Period PWM
	//           = 40,000 Cycle
	// Duty = 1...39999 Cycle
	// For Servo = 1..2mS
	// Adjust Duty Cycle = 2000..4000 For Control Position Servo
	
	// PWM2 = 16Bit PWM Control Servo
	// Set PWM2(P5.4) Duty Cycle = 1mS
	// Example 1.0mS Duty = 2000 Cycle  
	// 2000 = 0x07D0
	PWM2HDR	   =  0x07;																							// MSB Duty[15..8]
	PWM2LDR	   =  0xD0;																							// LSB Duty[7..0]
	
	// PWM3 = 16Bit PWM Control Servo
	// Set PWM3(P5.5) Duty Cycle = 3mS(Max=8.191mS)
	// Example 1.4mS Duty = 2800 Cycle 
	// 2800 = 0x0AF0
	PWM3HDR	   =  0x0A;																							// MSB Duty[15..8]
	PWM3LDR	   =  0xF0;																							// LSB Duty[7..0]
	
	// PWM4 = 16Bit PWM Control Servo
	// Set PWM4(P5.6) Duty Cycle = 4mS
	// Example 1.6mS Duty = 3200 Cycle 
	// 3200 = 0x0C80
	PWM4HDR	   =  0x0C;																							// MSB Duty[15..8]
	PWM4LDR	   =  0x80;																							// LSB Duty[7..0]
	
	// PWM5 = 16Bit PWM Control Servo
	// Set PWM5(P5.7) Duty Cycle = 5mS
	// Example 2.0mS Duty = 4000 Cycle 
	// 4000 = 0x0FA0
	PWM5HDR	   =  0x0F;																							// MSB Duty[15..8]
	PWM5LDR	   =  0xA0;																							// LSB Duty[7..0]
	
	// Indicator MCU Running By LED ON 
	LED_PORT_INIT();					
	LED_ON();
	
	//Main Loop 
	while(1);
}

/*
 * Function    : init_pwm2_timer2
 * Description : initialize timer[2] = PWM 16Bit Mode
 *             : Config PWM Period 20mS For Control Servo
 */
void init_pwm2_timer2(void)
{
	// Timer2,3,4,5 = 16Bit PWM Mode
	// fx = 8MHz
	// f-Timer  = fx/4= 2MHz
	// 1Cycle   = 0.5uS
	// PWM Freq = 50 Hz
	// Period   = 40000x0.5uS
	//          = 20mS
	// Freq     = 1/20mS
	//          = 50 Hz
	// Duty Cycle = 1...39,9999
	
	// Initial TxCR = 1,1,,0,001,1,1 
  // 1xxxxxxx : Timer2 Enable
  // x1xxxxxx : PWM Enable
  // xx0xxxxx : Timer/Counter Mode
	// xxx001xx : Clock Source = Fx/4
  // xxxxxx1x : Continue Count
  // xxxxxxx1	: Clear Counter & Start
	T2CR = 0xC7;
	
	// Initial TxCR1 = 00000,0,1,1 
  // 00000xxx : Default for Reserve Bit
	// xxxxx0xx : External Clock Disable
  // xxxxxx1x : Timer Output Enable(P5.4=PWM2)
  // xxxxxxx1	: PWM Polarity High
	T2CR1 = 0x03;
	
  // Period = PWMxHPR+PWMxLPR
	// 20mS Period of 0.5uS = 40,000 Cycle
	//                    = 0x9C40
	PWM2HPR = 0x9C;																									// MSB Period[15..8]
  PWM2LPR = 0x40;																									// LSB Period[7..0]
	
  // Duty = PWMxHDR+PWMxLDR
	// Default PWM Dyty = 1.5mS(Center)
	//         = 3000 Cycle
	//         = 0x0BB8
	PWM2HDR	   =  0x0B;																							// MSB Duty[15..8]
	PWM2LDR	   =  0xB8;																							// LSB Duty[7..0]
	
  // xxxxx0xx :	Disable Timer2 Interrupt									
	IE2 &= ~0x04;																										// Disable Timer2 Interrupt
}

/*
 * Function    : init_pwm3_timer3
 * Description : initialize timer[3] = PWM 16Bit Mode
 *             : Config PWM Period 20mS For Control Servo
 */
void init_pwm3_timer3(void)
{
	// Timer2,3,4,5 = 16Bit PWM Mode
	// fx = 8MHz
	// f-Timer  = fx/4= 2MHz
	// 1Cycle   = 0.5uS
	// PWM Freq = 50 Hz
	// Period   = 40000x0.5uS
	//          = 20mS
	// Freq     = 1/20mS
	//          = 50 Hz
	// Duty Cycle = 1...39,9999
	
	// Initial TxCR = 1,1,,0,001,1,1 
  // 1xxxxxxx : Timer2 Enable
  // x1xxxxxx : PWM Enable
  // xx0xxxxx : Timer/Counter Mode
	// xxx001xx : Clock Source = Fx/4
  // xxxxxx1x : Continue Count
  // xxxxxxx1	: Clear Counter & Start
	T3CR = 0xC7;
	
	// Initial TxCR1 = 00000,0,1,1 
  // 00000xxx : Default for Reserve Bit
	// xxxxx0xx : External Clock Disable
  // xxxxxx1x : Timer Output Enable(P5.5=PWM3)
  // xxxxxxx1	: PWM Polarity High
	T3CR1 = 0x03;
	
  // Period = PWMxHPR+PWMxLPR
	// 20mS Period of 0.5uS = 40,000 Cycle
	//                    = 0x9C40
	PWM3HPR = 0x9C;																									// MSB Period[15..8]
  PWM3LPR = 0x40;																									// LSB Period[7..0]
	
  // Duty = PWMxHDR+PWMxLDR
	// Default PWM Dyty = 1.5mS(Center)
	//         = 3000 Cycle
	//         = 0x0BB8
	PWM3HDR	   =  0x0B;																							// MSB Duty[15..8]
	PWM3LDR	   =  0xB8;																							// LSB Duty[7..0]
	
	// xxxx0xxx :	Disable Timer3 Interrupt									
	IE2 &= ~0x08;																										// Disable Timer3 Interrupt
}

/*
 * Function    : init_pwm4_timer4
 * Description : initialize timer[4] = PWM 16Bit Mode
 *             : Config PWM Period 20mS For Control Servo
 */
void init_pwm4_timer4(void)
{
	// Timer2,3,4,5 = 16Bit PWM Mode
	// fx = 8MHz
	// f-Timer  = fx/4= 2MHz
	// 1Cycle   = 0.5uS
	// PWM Freq = 50 Hz
	// Period   = 40000x0.5uS
	//          = 20mS
	// Freq     = 1/20mS
	//          = 50 Hz
	// Duty Cycle = 1...39,9999
	
	// Initial TxCR = 1,1,,0,001,1,1 
  // 1xxxxxxx : Timer2 Enable
  // x1xxxxxx : PWM Enable
  // xx0xxxxx : Timer/Counter Mode
	// xxx001xx : Clock Source = Fx/4
  // xxxxxx1x : Continue Count
  // xxxxxxx1	: Clear Counter & Start
	T4CR = 0xC7;
	
	// Initial TxCR1 = 00000,0,1,1 
  // 00000xxx : Default for Reserve Bit
	// xxxxx0xx : External Clock Disable
  // xxxxxx1x : Timer Output Enable(P5.6=PWM4)
  // xxxxxxx1	: PWM Polarity High
	T4CR1 = 0x03;
	
  // Period = PWMxHPR+PWMxLPR
	// 20mS Period of 0.5uS = 40,000 Cycle
	//                    = 0x9C40
	PWM4HPR = 0x9C;																									// MSB Period[15..8]
  PWM4LPR = 0x40;																									// LSB Period[7..0]
	
  // Duty = PWMxHDR+PWMxLDR
	// Default PWM Dyty = 1.5mS(Center)
	//         = 3000 Cycle
	//         = 0x0BB8
	PWM4HDR	   =  0x0B;																							// MSB Duty[15..8]
	PWM4LDR	   =  0xB8;																							// LSB Duty[7..0]
	
	// xxx0xxxx :	Disable Timer4 Interrupt									
	IE2 &= ~0x10;																										// Disable Timer4 Interrupt
}

/*
 * Function    : init_pwm5_timer5
 * Description : initialize timer[5] = PWM 16Bit Mode
 *             : Config PWM Period 20mS For Control Servo
 */
void init_pwm5_timer5(void)
{
	// Timer2,3,4,5 = 16Bit PWM Mode
	// fx = 8MHz
	// f-Timer  = fx/4= 2MHz
	// 1Cycle   = 0.5uS
	// PWM Freq = 50 Hz
	// Period   = 40000x0.5uS
	//          = 20mS
	// Freq     = 1/20mS
	//          = 50 Hz
	// Duty Cycle = 1...39,9999
	
	// Initial TxCR = 1,1,,0,001,1,1 
  // 1xxxxxxx : Timer2 Enable
  // x1xxxxxx : PWM Enable
  // xx0xxxxx : Timer/Counter Mode
	// xxx001xx : Clock Source = Fx/4
  // xxxxxx1x : Continue Count
  // xxxxxxx1	: Clear Counter & Start
	T5CR = 0xC7;
	
	// Initial TxCR1 = 00000,0,1,1 
  // 00000xxx : Default for Reserve Bit
	// xxxxx0xx : External Clock Disable
  // xxxxxx1x : Timer Output Enable(P5.7=PWM5)
  // xxxxxxx1	: PWM Polarity High
	T5CR1 = 0x03;
	
  // Period = PWMxHPR+PWMxLPR
	// 20mS Period of 0.5uS = 40,000 Cycle
	//                    = 0x9C40
	PWM5HPR = 0x9C;																									// MSB Period[15..8]
  PWM5LPR = 0x40;																									// LSB Period[7..0]
	
  // Duty = PWMxHDR+PWMxLDR
	// Default PWM Dyty = 1.5mS(Center)
	//         = 3000 Cycle
	//         = 0x0BB8
	PWM5HDR	   =  0x0B;																							// MSB Duty[15..8]
	PWM5LDR	   =  0xB8;																							// LSB Duty[7..0]
	
	// xx0xxxxx :	Disable Timer5 Interrupt									
	IE2 &= ~0x20;																										// Disable Timer5 Interrupt
}

