📄 xllp.c
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR INDEMNITIES.
//
/******************************************************************************
**
** COPYRIGHT (C) 2000, 2001 Intel Corporation.
**
** Portions of the source code contained or described herein and all documents
** related to such source code (Material) are owned by Intel Corporation
** or its suppliers or licensors and is licensed by Microsoft Corporation for distribution.
** Title to the Material remains with Intel Corporation or its suppliers and licensors.
** Use of the Materials is subject to the terms of the Microsoft license agreement which accompanied the Materials.
** No other license under any patent, copyright, trade secret or other intellectual
** property right is granted to or conferred upon you by disclosure or
** delivery of the Materials, either expressly, by implication, inducement,
** estoppel or otherwise
** Some portion of the Materials may be copyrighted by Microsoft Corporation.
**
** FILENAME: xllp_i2c.c
**
** PURPOSE: Xllp i2c file
**
**
******************************************************************************/
#include <windows.h>
#include <windev.h>
#include <types.h>
#include <memory.h>
#include <string.h>
#include <ceddk.h>
#include <bulverde_base_regs.h>
#include <plato.h>
#include <xllp_intc.h>
#include <xllp_gpio.h>
#include <xllp_clkmgr.h>
#include <xllp_ost.h>
#include <xllp_i2c.h>
#include "pcf50606.h"
#include "pmdriver.h"
#ifndef SHIP_BUILD
extern DBGPARAM dpCurSettings;
#endif
static XLLP_BOOL_T
Xllp_I2CWrite(volatile P_XLLP_I2C_T I2C_regs,
volatile XLLP_OST_T *pOSTRegs,
XLLP_UINT8_T slaveAddr,
const XLLP_UINT8_T *bytesBuf,
XLLP_UINT32_T bytesCount,
XLLP_BOOL_T bSendStop);
static XLLP_BOOL_T
Xllp_I2CRead(volatile P_XLLP_I2C_T I2C_regs,
volatile XLLP_OST_T *pOSTRegs,
XLLP_UINT8_T slaveAddr,
XLLP_UINT8_T * bytesBuf,
XLLP_UINT32_T bytesCount,
XLLP_BOOL_T bSendStop);
/*
* Initialization to use I2C bus
*
* PARAMETERS:
* P_XLLP_I2C_T I2C_regs structure for i2c regs
* P_XLLP_CLKMGR_T clkaddr - address of clkmanager
* XLLP_UINT32_T dev_id - Default slave device id for Bulverde
*
* RETURNS: True - failure
* false - success
*/
/* Enable I2C Interface Unit -
*
* XLLP_ICR_GCD - Disable General Call (will be master)
* XLLP_ICR_UIE - Enable I2C unit
* XLLP_ICR_SCLEA - Enable I2C Clock Generator
*
*/
XLLP_BOOL_T XllpI2CInit(P_XLLP_I2C_T I2C_regs, P_XLLP_GPIO_T gpio, P_XLLP_CLKMGR_T clkMgr, XLLP_UINT32_T dev_id)
{
I2C_regs->ICR = 0;
clkMgr->cken |= XLLP_CLKEN_I2C;
gpio->GPDR3 |= (XLLP_GPIO_BIT_SCL | XLLP_GPIO_BIT_SDA);
gpio->GAFR3_U |= ( XLLP_GPIO_AF_BIT_SCL | XLLP_GPIO_AF_BIT_SDA);
/* Setup I2C slave address */
I2C_regs->ISAR = dev_id;
I2C_regs->ICR = XLLP_ICR_SCLEA;
I2C_regs->ICR |= XLLP_ICR_UIE;
return(XLLP_FALSE);
}
/*
* Initialization to use PWRI2C bus
*
* PARAMETERS:
* P_XLLP_I2C_T I2C_regs structure for i2c regs
* P_XLLP_CLKMGR_T clkaddr - address of clkmanager
* XLLP_UINT32_T dev_id - Default slave device id for Bulverde
*
* RETURNS: True - failure
* false - success
*/
/* Enable PWRI2C Interface Unit -
*
*
*/
XLLP_BOOL_T XllpPI2CInit(volatile P_XLLP_PI2C_T I2C_regs,
volatile P_XLLP_GPIO_T gpio,
volatile P_XLLP_CLKMGR_T clkMgr,
XLLP_UINT32_T dev_id)
{
clkMgr->cken |= XLLP_CLKEN_PWRI2C;
I2C_regs->PCFR |= 0x40;
I2C_regs->ICR = 0;
/* Setup I2C slave address */
I2C_regs->ISAR = dev_id;
I2C_regs->ICR = XLLP_ICR_SCLEA;
I2C_regs->ICR |= XLLP_ICR_UIE;
return(XLLP_FALSE);
}
/*
* Wait for Receive empty status
*
* RETURNS: 0 success
* 1 failure
*/
static XLLP_BOOL_T
XllpI2CRxFull(volatile P_XLLP_I2C_T I2C_regs,
volatile XLLP_OST_T *pOSTRegs,
XLLP_INT32_T timeout)
{
XLLP_UINT32_T temp;
while (timeout--)
{
temp = I2C_regs->ISR;
if ((temp & XLLP_ISR_IRF) == XLLP_ISR_IRF)
{
I2C_regs->ISR = temp | XLLP_ISR_IRF;
return XLLP_FALSE;
}
// delay 1 ms here
XllpOstDelayMilliSeconds((XLLP_OST_T *)pOSTRegs, 1);
}
return XLLP_TRUE;
}
/* Wait for transmit empty status
*
* RETURNS: 0 success
* 1 failure
*/
static XLLP_BOOL_T
XllpI2CTxEmpty(volatile P_XLLP_I2C_T I2C_regs,
volatile XLLP_OST_T *pOSTRegs,
XLLP_INT32_T timeout)
{
XLLP_UINT32_T temp;
while (timeout--)
{
temp = I2C_regs->ISR;
if((temp & XLLP_ISR_ITE) == XLLP_ISR_ITE)
{
I2C_regs->ISR = temp | XLLP_ISR_ITE;
if ((temp & XLLP_ISR_ALD) == XLLP_ISR_ALD)
{
I2C_regs->ISR |= XLLP_ISR_ALD;
}
return XLLP_FALSE;
}
// delay 1 ms here
XllpOstDelayMilliSeconds((XLLP_OST_T *)pOSTRegs, 1);
}
return XLLP_TRUE;
}
static XLLP_BOOL_T
Xllp_I2CWrite(volatile P_XLLP_I2C_T I2C_regs,
volatile XLLP_OST_T *pOSTRegs,
XLLP_UINT8_T slaveAddr,
const XLLP_UINT8_T * bytesBuf,
XLLP_UINT32_T bytesCount,
XLLP_BOOL_T bSendStop)
{
XLLP_UINT32_T reg;
int timer = 0;
I2C_regs->IDBR = slaveAddr & ~XLLP_IDBR_MODE;
reg = I2C_regs->ICR;
reg |= (XLLP_ICR_START | XLLP_ICR_TB);
reg &= ~(XLLP_ICR_STOP | XLLP_ICR_ALDIE);
I2C_regs->ICR = reg;
if (XllpI2CTxEmpty(I2C_regs, pOSTRegs,20) == XLLP_TRUE)
{
return XLLP_TRUE;
}
// Send all the bytes
while (bytesCount--)
{
I2C_regs->IDBR = (XLLP_UINT32_T)(*bytesBuf++);
reg = I2C_regs->ICR;
reg &= ~XLLP_ICR_START;
reg |= (XLLP_ICR_ALDIE | XLLP_ICR_TB);
if ((bytesCount == 0) && bSendStop)
reg |= XLLP_ICR_STOP;
else
reg &= ~XLLP_ICR_STOP;
I2C_regs->ICR = reg;
if (XllpI2CTxEmpty(I2C_regs, pOSTRegs, 250) == XLLP_TRUE)
{
return XLLP_TRUE;
}
}
// Clear the STOP bit always
I2C_regs->ICR &= ~XLLP_ICR_STOP;
return XLLP_FALSE;
}
static XLLP_BOOL_T
Xllp_I2CRead(volatile P_XLLP_I2C_T I2C_regs,
volatile XLLP_OST_T *pOSTRegs,
XLLP_UINT8_T slaveAddr,
XLLP_UINT8_T * bytesBuf,
XLLP_UINT32_T bytesCount,
XLLP_BOOL_T bSendStop)
{
XLLP_UINT32_T reg;
// Send device address with write bit
I2C_regs->IDBR = slaveAddr & ~XLLP_IDBR_MODE;
reg = I2C_regs->ICR;
reg |= (XLLP_ICR_START | XLLP_ICR_TB);
reg &= ~(XLLP_ICR_STOP | XLLP_ICR_ALDIE);
I2C_regs->ICR = reg;
if (XllpI2CTxEmpty(I2C_regs, pOSTRegs,20) == XLLP_TRUE)
{
return XLLP_TRUE;
}
// Write register address
I2C_regs->IDBR = (XLLP_UINT32_T)(*bytesBuf++);
reg = I2C_regs->ICR;
reg &= ~(XLLP_ICR_START | XLLP_ICR_STOP);
reg |= (XLLP_ICR_ALDIE | XLLP_ICR_TB);
I2C_regs->ICR = reg;
if (XllpI2CTxEmpty(I2C_regs, pOSTRegs, 250) == XLLP_TRUE)
{
return XLLP_TRUE;
}
// Switch to read
I2C_regs->IDBR = slaveAddr | XLLP_IDBR_MODE;
// Send device address with read bit
reg = I2C_regs->ICR;
reg |= (XLLP_ICR_START | XLLP_ICR_TB);
reg &= ~(XLLP_ICR_STOP | XLLP_ICR_ALDIE);
I2C_regs->ICR = reg;
if (XllpI2CTxEmpty(I2C_regs, pOSTRegs,20) == XLLP_TRUE)
{
return XLLP_TRUE;
}
// Read consecutive device registers
while (bytesCount--)
{
reg = I2C_regs->ICR;
reg &= ~XLLP_ICR_START;
reg |= XLLP_ICR_ALDIE | XLLP_ICR_TB;
if (bytesCount == 0)
{
reg |= XLLP_ICR_ACKNACK;
if (bSendStop)
reg |= XLLP_ICR_STOP;
else
reg &= ~XLLP_ICR_STOP;
} else
{
reg &= ~XLLP_ICR_ACKNACK;
}
I2C_regs->ICR = reg;
if (XllpI2CRxFull(I2C_regs, pOSTRegs, 60) == XLLP_TRUE)
{
return XLLP_TRUE;
}
reg = I2C_regs->IDBR & 0xFF;
*bytesBuf++ = (XLLP_UINT8_T)reg;
}
I2C_regs->ICR &= ~(XLLP_ICR_STOP | XLLP_ICR_ACKNACK);
return XLLP_FALSE;
}
DWORD
PDD_I2CWrite(LPCRITICAL_SECTION lpcsI2CAccess,
volatile XLLP_I2C_T *v_pI2CRegs,
volatile XLLP_OST_T *v_pOSTRegs,
UCHAR cRegisterAddress,
PUCHAR pBuffer,
DWORD Count)
{
UCHAR cDataBuffer[65];
// Add register address to top of buffer
cDataBuffer[0] = cRegisterAddress;
memcpy (&cDataBuffer[1], pBuffer, Count);
Count++;
EnterCriticalSection(lpcsI2CAccess);
if (Xllp_I2CWrite((XLLP_I2C_T *)v_pI2CRegs,
(XLLP_OST_T *) v_pOSTRegs,
(XLLP_UINT8_T)PCF50606_I2C_ID,
(const XLLP_UINT8_T *)cDataBuffer,
Count,
TRUE))
Count = 0;
LeaveCriticalSection(lpcsI2CAccess);
return Count-1;
}
DWORD
PDD_I2CRead(LPCRITICAL_SECTION lpcsI2CAccess,
volatile XLLP_I2C_T *v_pI2CRegs,
volatile XLLP_OST_T *v_pOSTRegs,
UCHAR cRegisterAddress,
PUCHAR pBuffer,
DWORD Count)
{
UCHAR cDataBuffer[65];
// Add register address to top of buffer
cDataBuffer[0] = cRegisterAddress;
EnterCriticalSection(lpcsI2CAccess);
if (Xllp_I2CRead((XLLP_I2C_T *)v_pI2CRegs,
(XLLP_OST_T *)v_pOSTRegs,
(XLLP_UINT8_T)PCF50606_I2C_ID,
cDataBuffer,
Count,
TRUE))
Count = 0;
else
// Put data in register cache
memcpy (pBuffer, &cDataBuffer[1], Count);
LeaveCriticalSection(lpcsI2CAccess);
return Count;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -