/****************************************************************************
i2c8.c (optimized version to minimize code size)
v1.0 (22/04/2003)
i2c protocol with 8 bits address memory acces
Library for HI-TECH PIC C - master mode only.
Optimized version to reduce code size
Supported divices: 24xx00, 24xx01, 24xx02, 24xx04, 24xx08, 24xx16, ...
This library use i2c library for low level I/O.
Written by Philippe Corbes <philippe.corbes@laposte.net>
This code is free for personal use.
You need my agreement for a commercial use.
****************************************************************************/
#include <pic.h>
#include "delay.h"
#include "i2c.h"
#include "i2c8.h"
//Global struct for I2C link
struct I2C8 i2c8 ;
/*
* Start a transaction, select a component and init Address
*
* Input: - i2c8.component
* - i2c8.address
* Output: update i2c8.error
* - I2C_BUSY on Line busy by an other node
* - I2C_ERROR on bus error
* - I2C_ACK_TIMEOUT if no ack received eq no ack
*/
void
i2c8_start(void)
{
if ((i2c8.error = i2c_start()) == I2C_OK)
if ((i2c8.error = i2c_write(i2c8.component)) == I2C_OK)
i2c8.error = i2c_write(i2c8.address);
}
/*
* Read a byte from the slave and acknowledges the transfer
*
* Input: - i2c8.component
* - i2c8.address
* Output: update i2c8.error
* - the byte if no error
* - I2C_BUSY on Line busy by an other node
* - I2C_ERROR on bus error
* - I2C_ACK_TIMEOUT on ack timeout
*/
void
i2c8_read(void)
{
i2c8_start();
if (i2c8.error == I2C_OK) {
if ((i2c8.error = i2c_repStart()) == I2C_OK) {
if ((i2c8.error = i2c_write(i2c8.component + 1)) == I2C_OK) {
i2c8.error = i2c_read(I2C_LAST);
}
}
i2c_stop();
}
}
/*
* Write specified data byte in i2c device
*
* Input: - i2c8.component
* - i2c8.address
* Output: update i2c8.error
* - I2C_OK if ack received from slave
* - I2C_BUSY on Line busy by an other node
* - I2C_ERROR on bus error
* - I2C_ACK_TIMEOUT on ack timeout
*/
void
i2c8_write( unsigned char abyte )
{
i2c8_start();
if (i2c8.error == I2C_OK) {
i2c8.error = i2c_write(abyte);
i2c_stop();
DelayMs(I2C_EEPROM_UPDATE);
}
}
/*
* Read a numbrer of bytes and strore them at '*data'
* The number of bytes to read is specified by 'length'
*
* Input: - i2c8.component
* - i2c8.address
* Output: update i2c8.error
* - the lastbyte if no error
* - I2C_ERROR on bus error
* - I2C_BUSY on Line busy by an other node
* - I2C_ACK_TIMEOUT if no ack received eq no ack
*/
void
i2c8_read_seq( unsigned char length,
unsigned char *abyte)
{
i2c8_start();
if (i2c8.error == I2C_OK) {
if ((i2c8.error = i2c_repStart()) == I2C_OK) {
i2c8.error = i2c_write(i2c8.component+1);
// read with acnowledge to signal we desire additionnal data
length -=1;
while(((length--) > 0) && (i2c8.error >= I2C_OK)) {
if ((i2c8.error = i2c_read(I2C_MORE)) >= I2C_OK) {
*abyte++ = i2c8.error;
}
}
if (i2c8.error >= I2C_OK) {
// read with no ack to signal this is the last data
if ((i2c8.error = i2c_read(I2C_LAST)) >= I2C_OK) {
*abyte = i2c8.error;
}
}
}
i2c_stop();
}
}
/*
* Write a numbrer of bytes from '*data' to the i2c component
* The number of bytes to write is specified by 'length'
*
* Input: - i2c8.component
* - i2c8.address
* Output: update i2c8.error
* - I2C_OK if ack received from slave
* - I2C_BUSY on Line busy by an other node
* - I2C_ERROR on bus error
* - I2C_ACK_TIMEOUT on ack timeout
*/
void
i2c8_write_seq( unsigned char length,
unsigned char *abyte)
{
i2c8_start();
while(((length--) > 0) && (i2c8.error >= I2C_OK))
i2c8.error = i2c_write(*abyte++);
i2c_stop();
DelayMs(I2C_EEPROM_UPDATE);
}