

#include "mcf5213.h"

void init_AN_bit0(void);
void init_pto_AS(void);
void inicializa_i2c(void);
void 	re_start_i2c(void);
void start_i2c(void);
void stop_i2c(void);
void escribe_i2c(unsigned char d);
unsigned char lee_i2c(unsigned char a);
unsigned char lee_i2c(unsigned char a);
void escribe_reloj(unsigned char d, unsigned char v);
unsigned char lee_reloj(unsigned char d);
void init_pto_ua(void);
void inicia_UART0(void);
unsigned char input_s();
void output_s(unsigned char caracter);

/*
	Programa principal
*/

int main (void) {

	unsigned char valor;
	unsigned char direccion;
	unsigned char x;
	unsigned char y;

	init_AN_bit0();
	inicia_UART0();


	inicializa_i2c();
	



	while(1)
	{	
		direccion = input_s();		//via serie se envia la direccion
		valor = input_s();		//via serie se le envia el valor 

		escribe_reloj(direccion,valor);

		x=0;
		while (x<19)			// Leer todos los registros (18) del reloj DS3231
		{	
			y = lee_reloj(x);
			output_s(y);		// Enviar cada registro por el puerto serie
			x++;
		}
	}
	return 0;
}



/*
	Inicia Puerto An para Trigger
*/


void init_AN_bit0(void)
	{
		MCF_GPIO_DDRAN = MCF_GPIO_DDRAN_DDRAN0;
    		MCF_GPIO_PANPAR = 0;
	}

/*
	Procedimiento que inicializa puerto para I2C
*/

void init_pto_AS(void)
	{
    		MCF_GPIO_PASPAR = MCF_GPIO_PASPAR_PASPAR1(0x1) |    // I2C serial data
                      		MCF_GPIO_PASPAR_PASPAR0(0x1);     // I2C serial clock

					    
		MCF_GPIO_DDRAS = 0;
   		MCF_GPIO_PASPAR = MCF_GPIO_PASPAR_PASPAR1(0x1) |
                      	MCF_GPIO_PASPAR_PASPAR0(0x1);

	}



/*
	Procedimiento que inicializa el bus i2c
*/
void inicializa_i2c(void) {
	unsigned char dummy;


	init_pto_AS();

	MCF_I2C_I2CR =	0;		
	MCF_I2C_I2CR =	0xA0;		

	dummy = MCF_I2C_I2DR ;

	MCF_I2C_I2CR =	0;
	MCF_I2C_I2SR =	0;	


	MCF_CLOCK_SYNCR = 0;  		// La CPU usa el clock externo  (Cristal)  

	MCF_I2C_I2FDR = 0x07;		//divide el serial bit clock entre 20 según cuadro
						//para un clock frequency de 100 KHz

	MCF_I2C_I2AR = 0xC0;		//dirección cuando funciona como esclavo
 

 	MCF_I2C_I2CR = 	MCF_I2C_I2CR_IEN; 		// habilita I2C		
	
}



	

/*
	Procedimiento que transmite un re-start condition
*/
void 	re_start_i2c(void) {
	

	MCF_I2C_I2CR |= 	MCF_I2C_I2CR_RSTA;	// Genera Rstart
	 
	
}




/*
	Procedimiento que transmite un start condition
*/
void start_i2c(void) {

	 
	if ((MCF_I2C_I2SR & MCF_I2C_I2SR_IBB)!=0)
		{				
		while((MCF_I2C_I2SR & MCF_I2C_I2SR_IBB)!=0)	//Espera a que el bus este libre
			{}
		}

	
	MCF_I2C_I2CR |=	MCF_I2C_I2CR_MTX;		// Modo Transmisión
	MCF_I2C_I2CR |= 	MCF_I2C_I2CR_MSTA;	// Modo maestro - genera start
 
	
}


/*
	Procedimiento que transmite un stop condition
*/
void stop_i2c(void) {	

	MCF_I2C_I2CR &=	~MCF_I2C_I2CR_MSTA;	// Slave mode - genera stop  

}


/*
	Procedimiento que envia un dato al esclavo
*/
void escribe_i2c(unsigned char d) {
	unsigned char IIF;
	
	
	MCF_I2C_I2SR &= ~MCF_I2C_I2SR_IIF;			// Limpia bandera de recep/trans

	MCF_I2C_I2DR = d;						// Envia el dato a escribir

	IIF = MCF_I2C_I2SR & MCF_I2C_I2SR_IIF;		// Espero por Flag Recepcion
	while (IIF == 0)
		{
			IIF = MCF_I2C_I2SR & MCF_I2C_I2SR_IIF;
		}
	MCF_I2C_I2SR &= ~MCF_I2C_I2SR_IIF;			// Limpia bandera de recep/trans
}


/*
	Función que lee un dato del esclavo,
	Hay que indicar si el bit de control de
	flujo debe ser ACK o NACK.
*/
unsigned char lee_i2c(unsigned char a) {
	unsigned char dato;
	unsigned char IIF;
	unsigned char dummy;

	MCF_I2C_I2CR &= ~MCF_I2C_I2CR_MTX;			// Modo recepción
	if (a ==1)
		MCF_I2C_I2CR |=  MCF_I2C_I2CR_TXAK;		// Responde NACK = 1			
	else
		MCF_I2C_I2CR &= ~MCF_I2C_I2CR_TXAK;		// Responde  ACK = 0

	while ((MCF_I2C_I2SR & ~MCF_I2C_I2SR_IBB)==0) 	

	MCF_I2C_I2SR &= ~MCF_I2C_I2SR_IIF;			// Limpia bandera de recep/trans
	
	dummy = MCF_I2C_I2DR;					// Lee el dato

	IIF = MCF_I2C_I2SR & MCF_I2C_I2SR_IIF;		// Espero por Flag Recepcion
	while (IIF == 0)
		{
			IIF = MCF_I2C_I2SR & MCF_I2C_I2SR_IIF;
		}
	MCF_I2C_I2SR &= ~MCF_I2C_I2SR_IIF;			// Limpia bandera de recep/trans

	dato = MCF_I2C_I2DR;					// Lee el dato

	IIF = MCF_I2C_I2SR & MCF_I2C_I2SR_IIF;		// Espero por Flag Recepcion
	while (IIF == 0)
		{
			IIF = MCF_I2C_I2SR & MCF_I2C_I2SR_IIF;
		}
	MCF_I2C_I2SR &= ~MCF_I2C_I2SR_IIF;			// Limpia bandera de recep/tran

	return dato;
}

/*********************************************************************************/


/*
	Procedimiento que asigna el valor v al
	registro número d del reloj en tiempo real
*/
void escribe_reloj(unsigned char d, unsigned char v) {


	start_i2c();

	escribe_i2c(0xD0);

	escribe_i2c(d);	

	escribe_i2c(v);

	stop_i2c();

}


/*
	Función que devuelve el contenido del registro
	d del reloj en tiempo real
*/
unsigned char lee_reloj(unsigned char d) {
	unsigned char resultado;
	
	start_i2c();
	escribe_i2c(0xD0);
	escribe_i2c(d);
	re_start_i2c();
	escribe_i2c(0xD1);
	resultado=lee_i2c(1);
	stop_i2c();
	return resultado;
}





void init_pto_ua(void)
	{
    		MCF_GPIO_DDRUA  = 0;
		MCF_GPIO_PUAPAR = MCF_GPIO_PUAPAR_PUAPAR1(0x1) |
            			MCF_GPIO_PUAPAR_PUAPAR0(0x1);
 	}


void init_uart_0(void)
	{
    		// Configure UART 0 (first UART channel)
    		// Baud Rate = 9600
    		// 8 data bits, 1 stop bit, No parity
    		// /CTS input has no effect on the transmitter
    		// /RTS output is not affected by receiver or transmitter
    		// UART 0: Reset transmitter, receiver and mode register pointer

    		
		MCF_UART0_UCR = 	MCF_UART_UCR_MISC(0x3);		//Reset Transmisión
    		MCF_UART0_UCR = 	MCF_UART_UCR_MISC(0x2);		//Reset Recepción
    		MCF_UART0_UCR = 	MCF_UART_UCR_MISC(0x1);		//Apunta a UMR1
    		MCF_UART0_UMR = 	MCF_UART_UMR_PM(0x2) |		//UMR1 Modo no paridad
                    		MCF_UART_UMR_BC(0x3);		//UMR1 Bits por caracter = 8
    		MCF_UART0_UMR = 	MCF_UART_UMR_SB(0x7);		//UMR2 Bit de Stop = 1
    		MCF_UART0_UCSR =	MCF_UART_UCSR_RCS(0xd) |	//Clock de Recepcion = interno
                     		MCF_UART_UCSR_TCS(0xd);		//Clock de Transmision = interno
    		MCF_UART0_UBG2 = 	0x17;					//Baudios = 9600    		
    		MCF_UART0_UCR = 	MCF_UART_UCR_TXC(0x1);		//Habilita transmisión
    		MCF_UART0_UCR = 	MCF_UART_UCR_RXC(0x1);		//Habilita recepción

	}




void output_s(unsigned char caracter) 
	{				
		char val_TXRDY;
		char val_TXEMP;			
		MCF_UART0_USR = MCF_UART_USR(0);						
		val_TXRDY = (MCF_UART0_USR & MCF_UART_USR_TXRDY);
		val_TXEMP = (MCF_UART0_USR & MCF_UART_USR_TXEMP);					
		while (val_TXRDY ==0 && val_TXEMP ==0)	
			{
				MCF_UART0_USR = MCF_UART_USR(0);						
				val_TXRDY = (MCF_UART0_USR & MCF_UART_USR_TXRDY  );
				val_TXEMP = (MCF_UART0_USR & MCF_UART_USR_TXEMP  );
			}	
		MCF_UART0_UTB = caracter;
	}


unsigned char input_s()
	{	
		char val_RXRDY;
		char val_FFULL;

		MCF_UART0_USR = MCF_UART_USR(0);						
		val_RXRDY = (MCF_UART0_USR & MCF_UART_USR_RXRDY);		
		val_FFULL = (MCF_UART0_USR & MCF_UART_USR_FFULL);				
		while ( val_RXRDY == 0 && val_FFULL == 0 ) 		
			{
				MCF_UART0_USR = MCF_UART_USR(0);						
				val_RXRDY = (MCF_UART0_USR & MCF_UART_USR_RXRDY);
				val_FFULL = (MCF_UART0_USR & MCF_UART_USR_FFULL);			
			}		
		return MCF_UART0_URB;
	}


void inicia_UART0(void)
	{		
		
		init_pto_ua();
		init_uart_0();	
	}

