The following is used with a RTC chip. Feel free to adapt.:
/****************************************************************************
*
* NAME: vI2C_Read
*
* DESCRIPTION: I2C read function
*
* PARAMETERS: Name RW Usage
* u8 Address R Address of desired byte in the RTC
* pau8ReadBuffer R pointer to data buffer
* ui8Length R number of bytes to read
*
* RETURNS: Nothing
* None.
*
* NOTES:
* None.
****************************************************************************/
PUBLIC uint8 vI2C_Read(uint8 u8SlaveAddress, uint8 u8RegisterAddress,
uint8 *u8ReadBuffer, uint8 ui8Length)
{
uint8 i=0;
// DBG_vPrintf(TRACE_I2C, "I2C_Read::Start - I2C: %x, Reg: %d, Len: %d\n",
// u8SlaveAddress, u8RegisterAddress, ui8Length);
// set slave address
vAHI_SiMasterWriteSlaveAddr(u8SlaveAddress >> 1, FALSE);
vAHI_SiMasterSetCmdReg(E_AHI_SI_START_BIT,
E_AHI_SI_NO_STOP_BIT,
E_AHI_SI_NO_SLAVE_READ,
E_AHI_SI_SLAVE_WRITE,
E_AHI_SI_SEND_ACK,
E_AHI_SI_NO_IRQ_ACK);
while(bAHI_SiMasterPollTransferInProgress()); // wait while busy
// DBG_vPrintf(TRACE_I2C, "I2C_Read:: Setting register address\n");
vAHI_SiMasterWriteData8(u8RegisterAddress); // RTC address to read from
vAHI_SiMasterSetCmdReg(E_AHI_SI_NO_START_BIT,
E_AHI_SI_NO_STOP_BIT,
E_AHI_SI_NO_SLAVE_READ,
E_AHI_SI_SLAVE_WRITE,
E_AHI_SI_SEND_ACK,
E_AHI_SI_NO_IRQ_ACK);
while(bAHI_SiMasterPollTransferInProgress()); // wait while busy
/* check to see if we get an ACK back*/
if(bAHI_SiMasterCheckRxNack())
{
return (1);
}
/* check to see if anyone else has taken the bus */
if(bAHI_SiMasterPollArbitrationLost())
{
return (2);
}
vAHI_SiMasterWriteSlaveAddr(u8SlaveAddress >> 1,TRUE);
vAHI_SiMasterSetCmdReg(E_AHI_SI_START_BIT,
E_AHI_SI_NO_STOP_BIT,
E_AHI_SI_NO_SLAVE_READ,
E_AHI_SI_SLAVE_WRITE,
E_AHI_SI_SEND_ACK,
E_AHI_SI_NO_IRQ_ACK);
while(bAHI_SiMasterPollTransferInProgress()); // wait while busy
// DBG_vPrintf(TRACE_I2C, "I2C_Read:: Reading data\n");
// now we read data from the RTC
while(ui8Length > 0x00)
{
if(ui8Length < 0x02) /* is it the last byte */
{
vAHI_SiMasterSetCmdReg(E_AHI_SI_NO_START_BIT,
E_AHI_SI_STOP_BIT,
E_AHI_SI_SLAVE_READ,
E_AHI_SI_NO_SLAVE_WRITE,
E_AHI_SI_SEND_NACK,
E_AHI_SI_NO_IRQ_ACK);
}
else
{
vAHI_SiMasterSetCmdReg(E_AHI_SI_NO_START_BIT,
E_AHI_SI_NO_STOP_BIT,
E_AHI_SI_SLAVE_READ,
E_AHI_SI_NO_SLAVE_WRITE,
E_AHI_SI_SEND_ACK,
E_AHI_SI_NO_IRQ_ACK);
}
while(bAHI_SiMasterPollTransferInProgress()); // wait while busy
u8ReadBuffer[i++] = u8AHI_SiMasterReadData8();
ui8Length--;
}
return (0);
}
/****************************************************************************
*
* NAME: vI2C_Write
*
* DESCRIPTION:
*
* PARAMETERS: Name RW Usage
* None.
*
* RETURNS:
* None.
*
* NOTES:
* None.
****************************************************************************/
PUBLIC uint8 vI2C_Write(uint8 u8SlaveAddress, uint8 u8RegisterAddress,
uint8 *u8WriteBuffer, uint8 ui8Length)
{
uint8 i=0;
// set slave address
vAHI_SiMasterWriteSlaveAddr(u8SlaveAddress >> 1,FALSE);
vAHI_SiMasterSetCmdReg(E_AHI_SI_START_BIT,
E_AHI_SI_NO_STOP_BIT,
E_AHI_SI_NO_SLAVE_READ,
E_AHI_SI_SLAVE_WRITE,
E_AHI_SI_SEND_ACK,
E_AHI_SI_NO_IRQ_ACK);
while(bAHI_SiMasterPollTransferInProgress()); // wait while busy
/* check to see if we get an ACK back*/
if(bAHI_SiMasterCheckRxNack())
{
return (1);
}
/* check to see if anyone else has taken the bus */
if(bAHI_SiMasterPollArbitrationLost())
{
return (2);
}
vAHI_SiMasterWriteData8(u8RegisterAddress); // address to write
vAHI_SiMasterSetCmdReg(E_AHI_SI_NO_START_BIT,
E_AHI_SI_NO_STOP_BIT,
E_AHI_SI_NO_SLAVE_READ,
E_AHI_SI_SLAVE_WRITE,
E_AHI_SI_SEND_ACK,
E_AHI_SI_NO_IRQ_ACK);
while(bAHI_SiMasterPollTransferInProgress()); // wait while busy
/* check to see if we get an ACK back*/
if(bAHI_SiMasterCheckRxNack())
{
return (3);
}
/* check to see if anyone else has taken the bus */
if(bAHI_SiMasterPollArbitrationLost())
{
return (4);
}
// now we write data to the RTC
while(ui8Length > 0x00)
{
/* data to write */
vAHI_SiWriteData8(u8WriteBuffer[i++]);
if(ui8Length < 2) /* is it the last byte */
{
vAHI_SiMasterSetCmdReg(E_AHI_SI_NO_START_BIT,
E_AHI_SI_STOP_BIT,
E_AHI_SI_NO_SLAVE_READ,
E_AHI_SI_SLAVE_WRITE,
E_AHI_SI_SEND_NACK,
E_AHI_SI_NO_IRQ_ACK);
}
else
{
vAHI_SiMasterSetCmdReg(E_AHI_SI_NO_START_BIT,
E_AHI_SI_NO_STOP_BIT,
E_AHI_SI_NO_SLAVE_READ,
E_AHI_SI_SLAVE_WRITE,
E_AHI_SI_SEND_ACK,
E_AHI_SI_NO_IRQ_ACK);
}
ui8Length--;
while(bAHI_SiMasterPollTransferInProgress()); /* wait while busy */
/* check to see if we get an ACK back*/
if(bAHI_SiMasterCheckRxNack())
{
return(5);
}
/* check to see if anyone else has taken the bus */
if(bAHI_SiMasterPollArbitrationLost())
{
return(6);
}
}
return (0);
}