📄 i2c.c
字号:
WD_MultiTransfer(hWD,trns,nbevents);
bit = (trns[nbevents-2].Data.Byte & SDABIT) ? 1 : 0;
#else
for (i=0 ;i<8 ;i++)
I2cWriteBit((data<<i) & 0x80);
I2cSetSDA(HIGH); /* Set SDA to HIGH for acknowledge test */
bit=I2cReadBit();
#endif
return !bit;
}
/*****************************************************
**FUNCTION :: I2cReadByte
**ACTION :: Read a byte from the slave
**PARAMS IN :: NONE
**PARAMS OUT:: NONE
**RETURN :: if error -1 else byte read
*****************************************************/
unsigned char I2cReadByte(int level)
{
char i,bit,valRet=0,nbevents=0;
#ifdef I2C_WINDRIVER
for(i=0 ;i<8 ;i++)
{
I2cGetBit(nbevents); /* set all 8 bits */
nbevents+=3;
}
I2cSetBit(nbevents,level); /* Set acknowledge bit */
nbevents+=3;
if(!level)
{
trns[nbevents].cmdTrans = WP_BYTE;
trns[nbevents].dwPort = SppDataPort;
trns[nbevents].Data.Byte = 0x00; /* if acknowledge reset SDA to HIGH level */
nbevents++;
}
WD_MultiTransfer(hWD,trns,nbevents);
for(i=7 ;i>=0 ;i--)
{
bit = (trns[(7-i)*3+1].Data.Byte & SDABIT) ? 1 : 0;
valRet = valRet | (bit<<i);
}
#else
/* Read 8 bits data */
for(i=7 ;i>=0 ;i--)
valRet = valRet | (I2cReadBit()<<i);
I2cWriteBit(level); /* Set acknowledge bit */
if(!level)
I2cSetSDA(HIGH); /* if acknowledge reset SDA to HIGH level */
#endif
return valRet;
}
/*****************************************************
**FUNCTION :: I2cStop
**ACTION :: Send a stop sequence on the I2C bus (Rising edge on SDAT while SCLK is HIGH)
**PARAMS IN :: NONE
**PARAMS OUT:: NONE
**RETURN :: bus status
*****************************************************/
I2C_RESULT I2cStop (void)
{
U8 scl,sda;
#ifdef I2C_WINDRIVER
trns[0].cmdTrans = WP_BYTE;
trns[0].dwPort = SppDataPort;
trns[0].Data.Byte = SDABIT; /* Set SDA to LOW */
trns[1].cmdTrans = WP_BYTE;
trns[1].dwPort = SppControlPort;
trns[1].Data.Byte = SCLBIT; /* Set SCL to HIGH */
trns[2].cmdTrans = WP_BYTE;
trns[2].dwPort = SppDataPort;
trns[2].Data.Byte = 0x00; /* Set SDA to HIGH */
trns[3].cmdTrans = RP_BYTE;
trns[3].dwPort = SppStatusPort; /* Get SDA & SCL level */
WD_MultiTransfer(hWD,trns,4);
sda = (trns[3].Data.Byte & SDABIT) ? 1 : 0;
scl = (trns[3].Data.Byte & SCLBIT) ? 1 : 0;
#else
I2cSetSDA(LOW);
I2cSetSCL(HIGH);
I2cSetSDA(HIGH);
sda = I2cGetSDA();
scl = I2cGetSCL();
#endif
return ((!scl)<<1) + (!sda);
}
#endif /* I2C_USB */
/*****************************************************
**FUNCTION :: I2cInit
**ACTION :: Init the variables needed for I2C communication
**PARAMS IN :: NONE
**PARAMS OUT:: NONE
**RETURN :: NONE
*****************************************************/
void I2cInit(U16 BaseAddress, U32 tempo)
{
#ifndef I2C_USB
#ifdef I2C_WINDRIVER
WD_VERSION verBuf;
WD_LICENSE lic;
DWORD dwStatus;
int i;
#endif
SppDataPort = BaseAddress;
SppStatusPort = BaseAddress + 1;
SppControlPort = BaseAddress + 2;
I2cBitTempoValue = tempo & 0xFF;
#ifdef I2C_WINDRIVER
hWD = INVALID_HANDLE_VALUE;
hWD = WD_Open();
if (hWD==INVALID_HANDLE_VALUE)
printf ("error opening WINDRVR\n");
strcpy(lic.cLicense, "6f1ea8b41bd21a55304a6673509dc122a32e6238b2adae.ST Microelectronics");
WD_License(hWD, &lic);
for(i=0;i<24;i++)
BZERO(trns[i]);
BZERO(verBuf);
WD_Version (hWD, &verBuf);
if (verBuf.dwVer<WD_VER)
{
printf ("error incorrect WINDRVR version. needs ver %d\n",WD_VER);
WD_Close(hWD);
}
BZERO(cardReg);
cardReg.Card.dwItems = 1;
cardReg.Card.Item[0].item = ITEM_IO;
cardReg.Card.Item[0].fNotSharable = TRUE;
cardReg.Card.Item[0].I.IO.dwAddr = BaseAddress;
cardReg.Card.Item[0].I.IO.dwBytes = 3;
cardReg.fCheckLockOnly = FALSE;
dwStatus = WD_CardRegister(hWD, &cardReg);
if (cardReg.hCard==0)
{
//printf("Failed locking device. Status 0x%x - %s\n",dwStatus, Stat2Str(dwStatus));
}
#endif
#else
hUsb=USB_Init((LPGUID) &CYUSBDRV_GUID,0); /* Get a handle to USB driver */
#endif
}
/*****************************************************
**FUNCTION :: I2cTerm
**ACTION :: Init the variables needed for I2C communication
**PARAMS IN :: NONE
**PARAMS OUT:: NONE
**RETURN :: NONE
*****************************************************/
void I2cTerm(void)
{
#ifdef I2C_WINDRIVER
WD_CardUnregister(hWD,&cardReg);
WD_Close(hWD);
#endif
#ifdef I2C_USB
hUsb=USB_Term(hUsb);
#endif
}
#ifndef I2C_USB
/*****************************************************
**FUNCTION :: I2cReadWrite
**ACTION :: Read/write data from/to the slave
**PARAMS IN :: mode -> READ or WRITE
** ChipAddress -> I2C address of the chip
** Data -> Buffer containing data to send
** NbData -> Number of data to write/read
**PARAMS OUT:: Data -> Buffer containing data received
**RETURN :: I2C_ACK if acknowledge, I2C_NOACK otherwise
*****************************************************/
I2C_RESULT I2cReadWrite(I2C_MODE mode,unsigned char ChipAddress,unsigned char *Data,int NbData)
{
char i=0,ack=0;
I2C_RESULT status;
status = I2cStart(); /* Start the I2C sequence */
if(status == I2C_OK)
{
ack=I2cWriteByte(ChipAddress+(mode == I2C_READ)); /* Send Slave chip address */
while((i<NbData) && ack)
{
if(mode == I2C_READ)
Data[i]=I2cReadByte(i==(NbData-1)); /* Read data from the slave */
else
ack=I2cWriteByte(Data[i]); /* Write data to the salve */
i++;
}
}
if(mode != I2C_WRITENOSTOP)
status |= I2cStop(); /* Stop the I2C sequence */
if((status == I2C_OK) && (!ack))
status = I2C_NOACK; /* bus OK but no acknowledge */
if((status != I2C_OK) && (mode == I2C_READ))
for(i=0;i<NbData;i++) /* Fill data bytes with 0xFF */
Data[i]=0xFF;
return status;
}
#else
/*****************************************************
**FUNCTION :: I2cReadWrite
**ACTION :: Read/write data from/to the slave
**PARAMS IN :: mode -> READ or WRITE
** ChipAddress -> I2C address of the chip
** Data -> Buffer containing data to send
** NbData -> Number of data to write/read
**PARAMS OUT:: Data -> Buffer containing data received
**RETURN :: I2C_ACK if acknowledge, I2C_NOACK otherwise
*****************************************************/
I2C_RESULT I2cReadWrite(I2C_MODE mode,unsigned char ChipAddress,unsigned char *Data,int NbData)
{
I2C_RESULT status = I2C_BUSERROR;
if(hUsb)
{
switch(mode)
{
case I2C_WRITE: /* write to slave */
req.Type = I2CREQ_WRITE;
req.Address = ChipAddress>>1;
req.NbWrData = NbData;
req.NbRdData = 0;
memcpy(req.Data,Data,req.NbWrData);
if(USB_WriteDataToEndPoint(hUsb,FX2LP_ENDPOINT2OUT,(unsigned char *)&req,4+req.NbWrData))
if(USB_ReadDataFromEndPoint(hUsb,FX2LP_ENDPOINT6IN,(unsigned char *)&ans,2+req.NbRdData))
{
if(ans.Error)
status = I2C_NOACK;
else
status = I2C_OK;
}
break;
case I2C_READ: /* Read from slave */
req.Type = I2CREQ_READ;
req.Address = ChipAddress>>1;
req.NbWrData = 0;
req.NbRdData = NbData;
if(USB_WriteDataToEndPoint(hUsb,FX2LP_ENDPOINT2OUT,(unsigned char *)&req,4+req.NbWrData))
if(USB_ReadDataFromEndPoint(hUsb,FX2LP_ENDPOINT6IN,(unsigned char *)&ans,2+req.NbRdData))
{
if(ans.Error)
status = I2C_NOACK;
else
{
status = I2C_OK;
memcpy(Data,ans.Data,req.NbRdData);
}
}
break;
case I2C_WRITENOSTOP:
status = I2C_NOACK;
break;
}
}
return status;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -