/******************************************************************************/
/* i2c.c */
/* 2012 Francisco Zayas */
/* */
/* Librería módulo i2c */
/******************************************************************************/
#include "i2c.h"
/*----------------------------------------------------------------------------*/
/* i2c_init */
/*----------------------------------------------------------------------------*/
void i2c_init(u32 freq)
{
I2CBRG = ((FCY/freq)-(FCY/10000000UL))-1;
I2CCON = 0x0000;
I2CSTAT = 0x0000;
I2CCON.I2CEN = 1;
}
/*----------------------------------------------------------------------------*/
/* i2c_start */
/*----------------------------------------------------------------------------*/
void i2c_start(void)
{
i2c_idle(); //Comprobar actividad del bus
I2CCONbits.SEN = 1; //Condición Start
while(I2CCONbits.SEN = 1); //Esperar Fin de condición Start
}
/*----------------------------------------------------------------------------*/
/* i2c_stop */
/*----------------------------------------------------------------------------*/
void i2c_stop(void)
{
I2CCONbits.PEN = 1; //Condición Stop
while(I2CCONbits.PEN = 1); //Esperar Fin de condición Stop
}
/*----------------------------------------------------------------------------*/
/* i2c_read */
/*----------------------------------------------------------------------------*/
u8 i2c_read(void)
{
I2C1CONbits.RCEN = 1; //Habilitar recepción de byte
while(I2C1CONbits.RCEN); //Esperar recepción
I2C1STATbits.I2COV = 0; //Limpiar bit de overflow
while(!I2C1STATbits.RBF); //Esperar Datos en registro
return(I2C1RCV); //Leer registro
}
/*----------------------------------------------------------------------------*/
/* i2c_write */
/*----------------------------------------------------------------------------*/
u8 i2c_write(u8 data)
{
I2CTRN = data; //Carga dato en registro
if(I2CSTATbits.IWCOL) //Colisión?
return 0; //Sí -> Error!!
while(I2CSTATbits.TRSTAT); //Secuencia Escritura Completa?
return !I2CSTATbits.ACKSTAT; //ACK/NACK del Slave
}
/*----------------------------------------------------------------------------*/
/* i2c_ack_nack */
/*----------------------------------------------------------------------------*/
void i2c_ack_nack(u8 ackbit)
{
I2CCONbits.ACKDT = ackbit; //Envío de ACK/NACK (0/1)
I2CCONbits.ACKEN = 1; //Habilitar envío
while(I2CCONbits.ACKEN); //Esperar fin de ACK/NACK
}
/*----------------------------------------------------------------------------*/
/* i2c_idle */
/*----------------------------------------------------------------------------*/
void i2c_idle(void)
{
//Espera mientras el Bus tiene actividad o está ocupado
while(I2CCONbits.SEN || I2CCONbits.RSEN || I2CCONbits.PEN ||
I2CCONbits.RCEN ||I2CCONbits.ACKEN || I2CSTATbits.TRSTAT);
}