//**************************************************************************
// COPYRIGNT 2008.10.17
// ALL RIGHT REAERVE
// DESCRIPTION: upd78f0513 POWER METER
// FILE: STORAGE.C
// AUTHOR: WYP
// VERSION: 1.0
//**************************************************************************
#include "includes.h"
#define SlaveAddr 0xA0
#define p_size 16
#define p_size_hex 15
void I2cStart(void)
{
IIC_SDA_OUT;
IIC_SDA = 1;
DelayUs(2);
IIC_SCL_OUT;
IIC_SCL = 1;
DelayUs(2);
IIC_SDA = 0;
DelayUs(4);
IIC_SCL = 0;
DelayUs(4);
}
void I2cStop(void)
{
uint8_t t = 10;
IIC_SDA_OUT;
IIC_SDA = 0;
DelayUs(4);
IIC_SCL = 1;
DelayUs(4);
IIC_SDA = 1;
while(--t != 0);
}
uint8_t I2cGetAck(void)
{
uint8_t ACK;
IIC_SDA_IN;
IIC_SCL = 1;
DelayUs(4);
if(IIC_SDA)
{
ACK = 1;
}
else
{
ACK = 0;
}
IIC_SCL = 0;
DelayUs(4);
return(ACK);
}
void I2cPutAck(void)
{
IIC_SDA_OUT;
IIC_SDA = 1;
IIC_SCL = 1;
DelayUs(4);
IIC_SCL = 0;
DelayUs(4);
}
void I2cPutNoAck(void)
{
IIC_SDA_OUT;
IIC_SDA = 0;
IIC_SCL = 1;
DelayUs(4);
IIC_SCL = 0;
DelayUs(4);
}
void SendOneByte(uint8_t dat)
{
uint8_t i;
IIC_SDA_OUT;
for(i=0;i<8;i++)
{
if(dat & 0x80)
{
IIC_SDA = 1;
}
else
{
IIC_SDA = 0;
}
dat <<= 1;
IIC_SCL = 1;
DelayUs(4);
IIC_SCL = 0;
DelayUs(4);
}
}
uint8_t RecvOneByte(void)
{
uint8_t i;
uint8_t dat = 0;
IIC_SDA_IN;
for(i=0;i<8;i++)
{
IIC_SCL = 1;
DelayUs(4);
dat <<= 1;
if(IIC_SDA)
{
dat++;
}
IIC_SCL = 0;
DelayUs(4);
}
return(dat);
}
bool I2cOneByteWrite(uint16_t SubAddr,uint8_t dat)
{
I2cStart();
SendOneByte ((SlaveAddr | (((uint8_t)(SubAddr>>8))<<1)));
if(I2cGetAck())
{
I2cStop();
return 1;
}
SendOneByte((uint8_t)SubAddr);
if(I2cGetAck ())
{
I2cStop();
return 1;
}
SendOneByte(dat);
if(I2cGetAck())
{
I2cStop();
return 1;
}
I2cStop();
DelayMs(10);
return 0;
}
bool I2cSequenceWrite(uint16_t SubAddr,uint8_t Size,uint8_t *dat)
{
uint8_t i,PageCnt,SizeCnt;
ClrWtd();
DI();
IICWPENOUT0;
if(Size == 0)
return 1;
PageCnt = (Size+(0x000F&(uint8_t)(SubAddr))-1)/p_size + 1;
ClrWtd();
do
{
I2cStart();
SendOneByte ((SlaveAddr | (((uint8_t)(SubAddr>>8))<<1)));
if(I2cGetAck ())
{
I2cStop();
return 1;
}
SendOneByte((uint8_t)SubAddr);
if(I2cGetAck())
{
I2cStop();
return 1;
}
if (SubAddr&p_size_hex)
{
if((Size+((uint8_t)(SubAddr)&p_size_hex))>p_size)
SizeCnt = p_size-((uint8_t)(SubAddr)&p_size_hex);
else
SizeCnt = Size;
SubAddr=(SubAddr/16)<<4;
}
else
{
if (Size<p_size)
SizeCnt = Size;
else
SizeCnt = p_size;
}
Size -= SizeCnt;
for(i=0;i<SizeCnt;i++)
{
SendOneByte(*dat++);
if(I2cGetAck())
{
I2cStop();
return 1;
}
}
I2cStop();
DelayMs(10);
SubAddr >>= 4;
SubAddr++;
SubAddr <<= 4;
PageCnt--;
}while(PageCnt>0);
IICWPENOUT1;
EI();
return 0;
}
bool I2cSequenceRead(uint16_t SubAddr,uint8_t Size,uint8_t *dat)
{
ClrWtd();
if(Size == 0)
return 1;
I2cStart();
SendOneByte ((SlaveAddr | (((uint8_t)(SubAddr>>8))<<1)));
if(I2cGetAck ())
{
I2cStop();
return 1;
}
SendOneByte ((uint8_t)SubAddr);
if(I2cGetAck ())
{
I2cStop();
return 1;
}
I2cStart();
SendOneByte ((SlaveAddr | (((uint8_t)(SubAddr>>8))<<1)) | 0x01);
if(I2cGetAck ())
{
I2cStop();
return 1;
}
for(;;)
{
*dat++ = RecvOneByte ();
if(--Size == 0)
{
I2cPutAck ();
break;
}
I2cPutNoAck ();
}
I2cStop();
return 0;
}