Example #1
0
/**
  * @brief  This function send device address and register address to I2C slave.
  * @param  DeviceAddr: I2C slave address
  * @param  RegAddr: slave device's register address, usually before read/write slave device's register,
  *         i2c master should first send it.
  * @return
  *     @arg TRUE: success
  *     @arg FALSE:fail
  */
bool I2cSendAddr(void* I2cMasterHandle, uint8_t SlaveAddr, uint8_t RegAddr, uint8_t RwFlag)
{
	I2cStart(I2cMasterHandle);
	if(!I2cWriteByte(I2cMasterHandle, SlaveAddr))
	{
		/* Retry */
		I2cStart(I2cMasterHandle);
		if(!I2cWriteByte(I2cMasterHandle, SlaveAddr))
		{
			I2cStop(I2cMasterHandle);
			return FALSE;
		}
	}

	if(!I2cWriteByte(I2cMasterHandle, RegAddr))
	{
		I2cStop(I2cMasterHandle);
		return FALSE;
	}

	if(RwFlag == IIC_READ)
	{
		I2cStart(I2cMasterHandle);
		if(!I2cWriteByte(I2cMasterHandle, SlaveAddr | IIC_READ))
		{
			I2cStop(I2cMasterHandle);
			return FALSE;
		}
	}

	return TRUE;
}
Example #2
0
/**
  * @brief  This function send multiple bytes to I2C slave.
  * @param  Buf: Buffer pointer to the data to be send
  * @param  Len: Data Length to be send in byte uint
  * @return
  *     @arg TRUE:  success
  *     @arg FALSE: fail
  */
bool I2cWriteBytes(void* I2cMasterHandle, uint8_t* Buf, uint8_t Len)
{
	while(Len--)
	{
		if(!I2cWriteByte(I2cMasterHandle, *(Buf++)))
		{
			DBG("write data err\n");
			return FALSE;
		}
	}

	return TRUE;
}
Example #3
0
/*检测I2C设备是否忙*/
BYTE I2cDeviceBusy(BYTE bySlave)
{
	BYTE byBusy = 1;
	int i = 0;
	while((byBusy != 0) && (i < 100))
	{
		i2cStart();
		I2cWriteByte(bySlave);
		byBusy=I2cReadBit();
		if(byBusy)
			I2cStop();
		i++;
	}
#ifdef I2C_DEBUG    
	if(byBusy == 1)
		printf("\nThe device is busy\n");
	else
		printf("\nThe device is free\n");
#endif /* I2C_DEBUG */

	return byBusy;	
}
Example #4
0
/**
  Reads single byte data from TPM specified by I2C register address.

  Due to stability issues when using I2C combined write/read transfers (with
  RESTART) to TPM (specifically read from status register), a single write is
  performed followed by single read (with STOP condition in between).

  @param[in] TpmAddress  Address of register  to read.

  @return  The value register read.

**/
UINT8
TpmReadByte (
    IN UINTN  TpmAddress
)
{
    UINT8                   Data[1];
    UINT8                   ReadData;
    UINT8                   ReadCount;

    EFI_I2C_DEVICE_ADDRESS  I2CDeviceAddr;
    EFI_I2C_ADDR_MODE       I2CAddrMode;

    EFI_STATUS              Status;

    Status = EFI_SUCCESS;
    ReadData  = 0xFF;
    ReadCount = 0;

    //
    // Locate I2C protocol for TPM I2C access.
    //
    I2CDeviceAddr.I2CDeviceAddress = TPM_I2C_SLAVE_DEVICE_ADDRESS;
    I2CAddrMode = EfiI2CSevenBitAddrMode;

    //
    // As recommended by Infineon (SLB9645 I2C Communication protocol application
    // note revision 1.0) retry up to 3 times if TPM status, access or burst count
    // registers return 0xFF.
    //
    while ((ReadData == 0xFF) && (ReadCount < READ_RETRY)) {
        //
        // As recommended by Infineon (SLB9645 I2C Communication protocol application
        // note revision 1.0) wait 250 microseconds between a read and a write transfer.
        //
        if (mI2CPrevReadTransfer) {
            MicroSecondDelay (GUARD_TIME);
        }

        //
        // Write address to TPM.
        //
        Data[0] = (UINT8)TpmAddress;
        Status = I2cWriteByte (
                     I2CDeviceAddr,
                     I2CAddrMode,
                     &Data
                 );

        if (EFI_ERROR(Status)) {
            DEBUG ((EFI_D_INFO, "TpmReadByte(): write to TPM address %0x failed (%r)\n", TpmAddress, Status));
        }

        mI2CPrevReadTransfer = FALSE;

        //
        // Read data from TPM.
        //
        Data[0] = (UINT8)TpmAddress;
        Status = I2cReadByte (
                     I2CDeviceAddr,
                     I2CAddrMode,
                     &Data
                 );

        if (EFI_ERROR(Status)) {
            DEBUG ((EFI_D_INFO, "TpmReadByte(): read from TPM address %0x failed (%r)\n", TpmAddress, Status));
            ReadData = 0xFF;
        } else {
            ReadData = Data[0];
        }

        //
        // Only need to retry 3 times for TPM status, access, and burst count registers.
        // If read transfer is to TPM Data FIFO, do not retry, exit loop.
        //
        if (TpmAddress == INFINEON_TPM_DATA_FIFO_0_ADDRESS_DEFAULT) {
            ReadCount = READ_RETRY;
        } else {
            ReadCount++;
        }

        mI2CPrevReadTransfer = TRUE;
    }

    if (EFI_ERROR(Status)) {
        //
        //  Only reads to access register allowed to fail.
        //
        if (TpmAddress != INFINEON_TPM_ACCESS_0_ADDRESS_DEFAULT) {
            DEBUG ((EFI_D_ERROR, "TpmReadByte(): read from TPM address %0x failed\n", TpmAddress));
            ASSERT_EFI_ERROR (Status);
        }
    }
    return ReadData;
}
Example #5
0
SDWORD I2cReadTest(BYTE byIicPort, BYTE bySlave, DWORD dwAddr)
{
	BYTE byData = 0;
    volatile BYTE i2c_bw_ctrl; /* I2C write control */
    volatile BYTE i2c_br_ctrl; /* I2C read control */
    volatile BYTE i2c_addr_00; /* I2C address (0) */

    STATUS semStatus;                           /*i2c同步信号量*/

    semStatus = semTake(semI2cLock, WAIT_FOREVER); /*获得信号量*/
    
    if(ERROR == semStatus)
    {
        logMsg("i2c semTake ERROR\n", 0, 0, 0, 0, 0, 0);
        return;
    }
    
    if(0 == byIicPort)
    {
        sCurI2cPort.byClkPin = IICCLK0;
        sCurI2cPort.byDataPin = IICDATA0;
    }
    else if(1 == byIicPort)
    {
        sCurI2cPort.byClkPin = IICCLK1;
        sCurI2cPort.byDataPin = IICDATA1;
    }

#ifdef I2C_DEBUG    
	printf("\n i2cRead() slave address is 0x%08x, addr: 0x%08x", bySlave, dwAddr);
#endif /* I2C_DEBUG */
	i2c_ack_stat=0x0;
    i2c_bw_ctrl = bySlave | I2C_WRITE;
    i2c_br_ctrl = bySlave | I2C_READ;
    /*i2c_addr_01 = I2C_W1_ADDR(addr);*/
    i2c_addr_00 = I2C_W0_ADDR(dwAddr);

	if(1)
    {
		i2cStart();
		I2cWriteByte(i2c_bw_ctrl);
		ack1=I2cReadBit(); /*read ack from slave*/
		if(ack1!=0)
			i2c_ack_stat |= 0x1; 
        I2C_DELAY(CLOCK_LOW_TIME*3);
		/*I2cWriteByte(i2c_addr_01);*/
		/*ack1=I2cReadBit();*/ /*read ack from slave*/
		/*if(ack1!=0)
			i2c_ack_stat |= 0x2; */
		I2cWriteByte(i2c_addr_00);
		ack1=I2cReadBit(); /*read ack from slave*/
		if(ack1!=0)
			i2c_ack_stat |= 0x2; 
		i2cStart();
        I2C_DELAY(CLOCK_LOW_TIME*3);
		I2cWriteByte(i2c_br_ctrl);
		ack1=I2cReadBit(); /*read ack from slave*/
		if(ack1!=0)
			i2c_ack_stat |= 0x3; 
        I2C_DELAY(CLOCK_LOW_TIME*3);
		byData = I2cReadByte();

		I2cStop();
    }

#ifdef I2C_DEBUG 
	if(i2c_ack_stat!=0)
		printf("\nError in read, ack not recd, i2c_ack_stat=0x%x\n",i2c_ack_stat);
#endif
	printf("byData: %x \n", byData);
    semGive(semI2cLock);    /*释放信号量*/

    if(0 != i2c_ack_stat)
    {
	    return SYS_ERROR;
    }
    return SYS_OK;
}
Example #6
0
SDWORD TestCpld(void)
{
    BYTE byData[5] = {0};
    BYTE bySlave = 0xca;
    BYTE i2c_br_ctrl = 0; /* I2C read control */
    BYTE byIicPort = 0;
    
    STATUS semStatus;                           /*i2c同步信号量*/

	if (0==I2Cisinit)
	{
		dev_I2cInit( );
	}
    semStatus = semTake(semI2cLock, WAIT_FOREVER); /*获得信号量*/
    
    if(ERROR == semStatus)
    {
        logMsg("i2c semTake ERROR\n", 0, 0, 0, 0, 0, 0);
        return;
    }
    
    if(0 == byIicPort)
    {
        sCurI2cPort.byClkPin = IICCLK0;
        sCurI2cPort.byDataPin = IICDATA0;
    }
    else if(1 == byIicPort)
    {
        sCurI2cPort.byClkPin = IICCLK1;
        sCurI2cPort.byDataPin = IICDATA1;
    }

#ifdef I2C_DEBUG    
/*	printf("\n i2cRead() slave address is 0x%08x, addr: 0x%08x", bySlave, dwAddr);*/
#endif /* I2C_DEBUG */
	i2c_ack_stat=0x0;
    i2c_br_ctrl = bySlave | I2C_READ;
 
	if(1)/*0 == I2cDeviceBusy(bySlave))*/
    {
		i2cStart();
		I2cWriteByte(i2c_br_ctrl);
		ack1=I2cReadBit(); /*read ack from slave*/
		if(ack1!=0)
			i2c_ack_stat |= 0x3; 
        I2C_DELAY(CLOCK_LOW_TIME*3);
		byData[0] = I2cReadByte();
        I2cWriteBit(0x0); /*send ack*/
        I2cData(HIGH);
        byData[1] = I2cReadByte();
        I2cWriteBit(0x0); /*send ack*/
        I2cData(HIGH);
        byData[2] = I2cReadByte();
        I2cWriteBit(0x00); /*send ack*/
        I2cData(HIGH);
        byData[3] = I2cReadByte();
        I2cWriteBit(0x00); /*send ack*/
        I2cData(HIGH);
        byData[4] = I2cReadByte();
        I2cWriteBit(0x80); /*send ack*/
        I2cData(HIGH);
		I2cStop();
    }

#ifdef I2C_DEBUG 
	if(i2c_ack_stat!=0)
		printf("\nError in read, ack not recd, i2c_ack_stat=0x%x\n",i2c_ack_stat);
#endif
    printf("\Data[0] = 0x%2x, Data[1] = 0x%2x, Data[2] = 0x%2d, Data[3] = 0x%2d, Data[4] = 0x%2d\n", byData[0], byData[1], byData[2], byData[3], byData[4]);

    semGive(semI2cLock);    /*释放信号量*/

    if(0 != i2c_ack_stat)
    {
	    return SYS_ERROR;
    }
    return SYS_OK;
}
Example #7
0
SDWORD I2cReadCpld(BYTE *pbyData, BYTE byDataNum)
{
    BYTE bySlave = I2C_CPLDID;
    BYTE i2c_br_ctrl = 0; /* I2C read control */
    BYTE byIicPort = I2C_CPLDPORT;

    static BYTE *pCpldData = (BYTE *)0x20000020;
    
    STATUS semStatus;                           /*i2c同步信号量*/
	if (0==I2Cisinit)
	{
		dev_I2cInit( );
	}

    semStatus = semTake(semI2cLock, WAIT_FOREVER); /*获得信号量*/
    
    if(ERROR == semStatus)
    {
        logMsg("i2c semTake ERROR\n", 0, 0, 0, 0, 0, 0);
        return;
    }
    
    if(0 == byIicPort)
    {
        sCurI2cPort.byClkPin = IICCLK0;
        sCurI2cPort.byDataPin = IICDATA0;
    }
    else if(1 == byIicPort)
    {
        sCurI2cPort.byClkPin = IICCLK1;
        sCurI2cPort.byDataPin = IICDATA1;
    }

#ifdef I2C_DEBUG    
/*	printf("\n i2cRead() slave address is 0x%08x, addr: 0x%08x", bySlave, dwAddr);*/
#endif /* I2C_DEBUG */
	i2c_ack_stat=0x0;
    i2c_br_ctrl = bySlave | I2C_READ;
 
	if(1)
    {
		i2cStart();
		I2cWriteByte(i2c_br_ctrl);
		ack1=I2cReadBit(); /*read ack from slave*/
		if(ack1!=0)
			i2c_ack_stat |= 0x3; 
        I2C_DELAY(CLOCK_LOW_TIME*3);
		pbyData[0] = I2cReadByte();
        I2cWriteBit(0x0); /*send ack*/
        I2cData(HIGH);
        pbyData[1] = I2cReadByte();
        I2cWriteBit(0x0); /*send ack*/
        I2cData(HIGH);
        pbyData[2] = I2cReadByte();
        I2cWriteBit(0x80); /*send ack*/
        I2cData(HIGH);
		I2cStop();
    }

#ifdef I2C_DEBUG 
	if(i2c_ack_stat!=0)
		printf("\nError in read, ack not recd, i2c_ack_stat=0x%x\n",i2c_ack_stat);
#endif
/*    printf("\nbyData[0] =%d, byData[1] =%d,byData[2] =%d\n",pbyData[0], pbyData[1], pbyData[2]);*/

    if (0x20000030 > pCpldData)
    {        
        *pCpldData++ = pbyData[0];
        *pCpldData++ = pbyData[1];
        *pCpldData++ = pbyData[2];
    }
    
    semGive(semI2cLock);    /*释放信号量*/

    if(0 != i2c_ack_stat)
    {
	    return SYS_ERROR;
    }
    return SYS_OK;
}
Example #8
0
/*return:  SYS_OK
           SYS_ERR
*/
SDWORD I2cWritePage(BYTE byIicPort, BYTE bySlave, DWORD dwAddr, BYTE *pbyData, DWORD dwCount)
{
	int i;
    volatile BYTE i2c_bw_ctrl; /* I2C write control */
    volatile BYTE i2c_addr_00; /* I2C address (0) */

    STATUS semStatus;                            /*i2c同步信号量*/

    semStatus = semTake(semI2cLock, WAIT_FOREVER);  /*获得信号量*/

    if(ERROR == semStatus)
    {
        logMsg("i2c semTake ERROR\n", 0, 0, 0, 0, 0, 0);
        return;
    }

    if(0 == byIicPort)
    {
        sCurI2cPort.byClkPin = IICCLK0;
        sCurI2cPort.byDataPin = IICDATA0;
    }
    else if(1 == byIicPort)
    {
        sCurI2cPort.byClkPin = IICCLK1;
        sCurI2cPort.byDataPin = IICDATA1;
    }

	i2c_ack_stat=0x0;
    i2c_bw_ctrl = bySlave | I2C_WRITE;
    /*i2c_addr_01 = I2C_W1_ADDR(dwAddr);*/
    i2c_addr_00 = I2C_W0_ADDR(dwAddr);

    for(i=0;i<dwCount;i++)
	if(dwCount>16)
			dwCount=16;

	if(0 == I2cDeviceBusy(bySlave))
	{
		i2cStart();
		I2cWriteByte(i2c_bw_ctrl);
		ack1=I2cReadBit(); 
		if(ack1!=0)
			i2c_ack_stat |= 0x2;
		/*I2cWriteByte(i2c_addr_01);
		ack1=I2cReadBit();
		if(ack1!=0)
			i2c_ack_stat |= 0x2;*/
		I2cWriteByte(i2c_addr_00);
		ack1=I2cReadBit();
		if(ack1!=0)
			i2c_ack_stat |= 0x2;
		for(i=0;i<dwCount;i++)
		{
			I2cWriteByte(pbyData[i]);
			ack2=I2cReadBit();
			if(ack2!=0)
				i2c_ack_stat |= 0x8;
		}
		I2cStop();
	}
    
    semGive(semI2cLock);       /*释放信号量*/
    
    if(0 != i2c_ack_stat)
    {
	    return SYS_ERROR;
    }
    return SYS_OK;
}
Example #9
0
SDWORD I2cWrite(BYTE byIicPort, BYTE bySlave, DWORD dwAddr, BYTE byData)
{
	
    volatile BYTE i2c_bw_ctrl; /* I2C write control */
    volatile BYTE i2c_addr_00; /* I2C address (0) */

    STATUS semStatus;                           /*i2c同步信号量*/

    semStatus = semTake(semI2cLock, WAIT_FOREVER); /*获得信号量*/

    if(ERROR == semStatus)
    {
        logMsg("i2c semTake ERROR\n", 0, 0, 0, 0, 0, 0);
        return;
    }

    if(0 == byIicPort)
    {
        sCurI2cPort.byClkPin = IICCLK0;
        sCurI2cPort.byDataPin = IICDATA0;
    }
    else if(1 == byIicPort)
    {
        sCurI2cPort.byClkPin = IICCLK1;
        sCurI2cPort.byDataPin = IICDATA1;
    }

	i2c_ack_stat=0x0;
    i2c_bw_ctrl = bySlave | I2C_WRITE;
    /*i2c_addr_01 = I2C_W1_ADDR(dwAddr);*/
    i2c_addr_00 = I2C_W0_ADDR(dwAddr);

	if(1)/*0 == I2cDeviceBusy(bySlave))*/
	{
		i2cStart();
		I2cWriteByte(i2c_bw_ctrl);
		ack1=I2cReadBit();
		if(ack1!=0)
			i2c_ack_stat |= 0x2;
        I2C_DELAY(CLOCK_LOW_TIME*3);
		/*I2cWriteByte(i2c_addr_01);
		ack1=I2cReadBit();
		if(ack1!=0)
			i2c_ack_stat |= 0x2;*/
		I2cWriteByte(i2c_addr_00);
		ack1=I2cReadBit();
		if(ack1!=0)
			i2c_ack_stat |= 0x2;

        I2C_DELAY(CLOCK_LOW_TIME*3);

		I2cWriteByte(byData);
		ack2=I2cReadBit();
		if(ack2!=0)
			i2c_ack_stat |= 0x8;
        
        I2C_DELAY(CLOCK_LOW_TIME*3);
        
		I2cStop();
	}
    
    semGive(semI2cLock);       /*释放信号量*/

    if(0 != i2c_ack_stat)
    {
        printf("\nError in write, ack not recd, i2c_ack_stat=0x%x\n",i2c_ack_stat);
	    return SYS_ERROR;
    }
    return SYS_OK;
}
Example #10
0
/*I2C读字符串   功能暂时不提供
//input :  byIicPort     I2C端口号为 0 ~ 1
//         bySlave       设备号
//         dwAddr        命令地址
//         dwCount       命令长度
//output:  pbyData       命令值
  return:  SYS_OK
           SYS_ERR
*/
SDWORD I2cReadSeq(BYTE byIicPort, BYTE bySlave, DWORD dwAddr, BYTE *pbyData, DWORD dwCount)
{
    volatile BYTE i2c_bw_ctrl; /* I2C write control */
    volatile BYTE i2c_br_ctrl; /* I2C read control */
    volatile BYTE i2c_addr_00; /* I2C address (0) */
	int i;

    STATUS semStatus;                           /*i2c同步信号量*/

    if (0 == dwCount)
    {
        return SYS_ERROR;
    }
    
    semStatus = semTake(semI2cLock, WAIT_FOREVER); /*获得信号量*/

    if(ERROR == semStatus)
    {
        logMsg("i2c semTake ERROR\n", 0, 0, 0, 0, 0, 0);
        return;
    }

    if(0 == byIicPort)
    {
        sCurI2cPort.byClkPin = IICCLK0;
        sCurI2cPort.byDataPin = IICDATA0;
    }
    else if(1 == byIicPort)
    {
        sCurI2cPort.byClkPin = IICCLK1;
        sCurI2cPort.byDataPin = IICDATA1;
    }
    
#ifdef I2C_DEBUG    
	printf("\n i2cReadSeq() slave address is 0x%x", bySlave);
#endif /* I2C_DEBUG */
	i2c_ack_stat=0x0;
    i2c_bw_ctrl = bySlave | I2C_WRITE;
    i2c_br_ctrl = bySlave | I2C_READ;
    /*i2c_addr_01 = I2C_W1_ADDR(dwAddr);*/
    i2c_addr_00 = I2C_W0_ADDR(dwAddr);

	if(1)
	{
        i2cStart();
        I2cWriteByte(i2c_bw_ctrl);
        ack1=I2cReadBit(); /*read ack from slave*/
        if(ack1!=0)
            i2c_ack_stat |= 0x1; 
       
        I2cWriteByte(i2c_addr_00);
        ack1=I2cReadBit(); /*read ack from slave*/
        if(ack1!=0)
            i2c_ack_stat |= 0x2; 
        i2cStart();
        
        I2cWriteByte(i2c_br_ctrl);
        ack1=I2cReadBit(); /*read ack from slave*/
        if(ack1!=0)
            i2c_ack_stat |= 0x3; 
        for(i=0;i<dwCount;i++)
        {
            pbyData[i] = I2cReadByte();
            if(i != (dwCount-1))
                I2cWriteBit(0x0); /*send ack*/
            else
                I2cWriteBit(0x80); /*send nack after reading the last byte*/
            I2cData(HIGH);
        }
        
        I2cStop();
    }

	if(i2c_ack_stat!=0)
		printf("\nError in read, ack not recd, i2c_ack_stat=0x%x\n",i2c_ack_stat);

    semGive(semI2cLock);       /*释放信号量*/

    if(0 != i2c_ack_stat)
    {
	    return SYS_ERROR;
    }
    return SYS_OK;
}