📄 i2c.c
字号:
//
// Copyright(C) Renesas Technology Corp. 2002-2003. All rights reserved.
//
// I2C driver for ITS-DS7
//
// FILE : I2C.C
// CREATED : 2002.06.26
// MODIFIED : 2003.06.20
// AUTHOR : Renesas Technology Corp.
// HARDWARE : RENESAS ITS-DS7
// HISTORY :
// 2003.06.20
// - Created release code.
// (based on I2C driver for ITS-DS4 Ver.1.2.0 for WCE4.2)
//
#define WINCEMACRO 1
#include <windows.h>
#include <types.h>
#include <tchar.h>
#include <devload.h>
#include <memory.h>
#include <oalintr.h>
#include <excpt.h>
#include "platform.h"
#include "sh7770.h"
#include "I2C.H"
#include "I2CDBG.H"
#include "drv_glob.h"
#include "ioctl_its_ds7.h"
DWORD AdjustMicroSecondsToLoopCount( DWORD dwMicroSeconds );
DWORD BusyWait( DWORD dwLoopCount );
BOOL __stdcall
DllEntry(
HINSTANCE hInstDll, // @parm Instance pointer
DWORD dwReason, // @parm Reason routine is called
LPVOID lpReserved // @parm system parameter
)
{
switch( dwReason ){
case DLL_PROCESS_ATTACH :
DEBUGREGISTER( hInstDll );
break;
case DLL_PROCESS_DETACH :
break;
case DLL_THREAD_ATTACH :
break;
case DLL_THREAD_DETACH :
break;
default :
break;
}
return TRUE;
}
// @func HANDLE | I2C_Init | device initialization routine
// @parm DWORD | dwIndex | info passed to RegisterDevice
// @rdesc Returns a HANDLE which will be passed to Open & Deinit or NULL if
// unable to initialize to driver.
HANDLE
I2C_Init(
DWORD dwIndex
)
{
PI2C_DRIVER_INFO pI2c;
pI2c = VirtualAlloc(NULL, sizeof(I2C_DRIVER_INFO), MEM_COMMIT, PAGE_READWRITE);
if ( pI2c == NULL ){
return NULL;
}
memset( pI2c, 0, sizeof(I2C_DRIVER_INFO) );
pI2c -> hIntEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if ( pI2c -> hIntEvent == NULL ){
VirtualFree(pI2c, sizeof(I2C_DRIVER_INFO), MEM_DECOMMIT);
return NULL;
}
pI2c -> pvBaseAddress = VirtualAlloc(0, I2C_REGSIZE, MEM_RESERVE, PAGE_NOACCESS);
if ( pI2c -> pvBaseAddress == NULL ){
VirtualFree(pI2c, sizeof(I2C_DRIVER_INFO), MEM_DECOMMIT);
CloseHandle( pI2c -> hIntEvent );
return NULL;
}
if ( !VirtualCopy((PVOID)pI2c -> pvBaseAddress, (PVOID)(I2C_REGBASE),
I2C_REGSIZE, PAGE_READWRITE | PAGE_NOCACHE) ){
VirtualFree(pI2c, sizeof(I2C_DRIVER_INFO), MEM_DECOMMIT);
CloseHandle( pI2c -> hIntEvent );
VirtualFree( (PVOID)pI2c -> pvBaseAddress, 0, MEM_RELEASE );
return NULL;
}
pI2c -> data = (PI2C_WORK)VirtualAlloc(0, I2C_BUFFER_SIZE, MEM_RESERVE, PAGE_NOACCESS);
if ( pI2c -> data != NULL ){
if ( !VirtualCopy((PVOID)pI2c -> data, (PVOID)(I2C_BUFFER_BASE|UNCACHED_BASE),
I2C_BUFFER_SIZE, PAGE_READWRITE | PAGE_NOCACHE) ){
}
}
if ( !InterruptInitialize(SYSINTR_I2C, pI2c -> hIntEvent, NULL, 0) ){
VirtualFree(pI2c, sizeof(I2C_DRIVER_INFO), MEM_DECOMMIT);
CloseHandle( pI2c -> hIntEvent );
VirtualFree((PVOID)pI2c -> pvBaseAddress, 0, MEM_RELEASE );
VirtualFree((PVOID)pI2c -> data, 0, MEM_RELEASE);
return NULL;
}
InitializeCriticalSection( &(pI2c -> csI2C) );
pI2c -> SCR = pI2c -> pvBaseAddress;
pI2c -> MCR = pI2c -> SCR + I2C_MCR_OFFSET;
pI2c -> SSR = pI2c -> SCR + I2C_SSR_OFFSET;
pI2c -> MSR = pI2c -> SCR + I2C_MSR_OFFSET;
pI2c -> SIER = pI2c -> SCR + I2C_SIER_OFFSET;
pI2c -> MIER = pI2c -> SCR + I2C_MIER_OFFSET;
pI2c -> CCR = pI2c -> SCR + I2C_CCR_OFFSET;
pI2c -> SAR = pI2c -> SCR + I2C_SAR_OFFSET;
pI2c -> MAR = pI2c -> SCR + I2C_MAR_OFFSET;
pI2c -> RXD = pI2c -> SCR + I2C_RXD_OFFSET;
pI2c -> TXD = pI2c -> SCR + I2C_TXD_OFFSET;
DEBUGMSG(ZONE_TRACE, (TEXT("Revision %08x \r\n"), (ULONG)READ_REGISTER_ULONG(pI2c -> SCR) ));
DEBUGMSG(ZONE_TRACE, (TEXT("%08x \r\n"), (ULONG)READ_REGISTER_ULONG(pI2c -> MCR) ));
DEBUGMSG(ZONE_TRACE, (TEXT("%08x \r\n"), (ULONG)READ_REGISTER_ULONG(pI2c -> SSR) ));
DEBUGMSG(ZONE_TRACE, (TEXT("%08x \r\n"), (ULONG)READ_REGISTER_ULONG(pI2c -> MSR) ));
DEBUGMSG(ZONE_TRACE, (TEXT("%08x \r\n"), (ULONG)READ_REGISTER_ULONG(pI2c -> SIER) ));
DEBUGMSG(ZONE_TRACE, (TEXT("%08x \r\n"), (ULONG)READ_REGISTER_ULONG(pI2c -> MIER) ));
DEBUGMSG(ZONE_TRACE, (TEXT("%08x \r\n"), (ULONG)READ_REGISTER_ULONG(pI2c -> CCR) ));
DEBUGMSG(ZONE_TRACE, (TEXT("%08x \r\n"), (ULONG)READ_REGISTER_ULONG(pI2c -> SAR) ));
DEBUGMSG(ZONE_TRACE, (TEXT("%08x \r\n"), (ULONG)READ_REGISTER_ULONG(pI2c -> MAR) ));
DEBUGMSG(ZONE_TRACE, (TEXT("%08x \r\n"), (ULONG)READ_REGISTER_ULONG(pI2c -> RXD) ));
DEBUGMSG(ZONE_TRACE, (TEXT("%08x \r\n"), (ULONG)READ_REGISTER_ULONG(pI2c -> TXD) ));
DEBUGMSG(ZONE_TRACE, (TEXT("0xffc00000 : %08x \r\n"), (ULONG)READ_REGISTER_ULONG(0xffc00000) ));
return (HANDLE)pI2c;
}
// @func BOOL | I2C_Deinit | device deinitialization routine
// @parm ??
// @rdesc Returns TRUE for success, FALSE for failure
BOOL
I2C_Deinit(
PI2C_DRIVER_INFO pI2c
)
{
SetEvent( pI2c -> hIntEvent );
Sleep( 100 );
VirtualFree( (PVOID)pI2c -> pvBaseAddress, 0, MEM_RELEASE);
VirtualFree((PVOID)pI2c -> data, 0, MEM_RELEASE);
CloseHandle( pI2c -> hIntEvent );
VirtualFree(pI2c, sizeof(I2C_DRIVER_INFO), MEM_DECOMMIT);
return TRUE;
}
// @func HANDLE | I2C_Open | device open routine
// @parm DWORD | dwData | value returned from I2C_Init call
// @parm DWORD | dwAccess | requested access (combination of GENERIC_READ
// and GENERIC_WRITE)
// @parm DWORD | dwShareMode | requested share mode (combination of
// FILE_SHARE_READ and FILE_SHARE_WRITE)
// @rdesc Returns a HANDLE which will be passed to Read, Write, etc or NULL if
// unable to open device.
HANDLE
I2C_Open(
DWORD dwData,
DWORD dwAccess,
DWORD dwShareMode
)
{
PI2C_OPEN_INFO pOpen;
pOpen = LocalAlloc(LPTR, sizeof(I2C_OPEN_INFO));
if ( pOpen == NULL ){
return NULL;
}
pOpen -> dwAccess = dwAccess;
pOpen -> dwShareMode = dwShareMode;
pOpen -> pI2CHandle = (PI2C_DRIVER_INFO)dwData;
pOpen -> dwMaster = I2C_MASTER_MODE;
pOpen -> bSingleStage = TRUE;
pOpen -> dwBaudrate = 0;
return (HANDLE)pOpen;
}
// @func BOOL | I2C_Close | device close routine
// @parm ???
// @rdesc Returns TRUE for success, FALSE for failure
BOOL
I2C_Close(
PI2C_OPEN_INFO pOpen
)
{
LocalFree( pOpen );
return TRUE;
}
// @func DWORD | I2C_Read | device read routine
// @parm DWORD | dwData | value returned from I2C_Open call
// @parm LPVOID | pBuf | buffer to receive data
// @parm DWORD | dwLen | maximum length to read
// @rdesc Returns 0 for end of file, -1 for error, otherwise the number of
// bytes read.
DWORD
I2C_Read(
DWORD dwData,
LPVOID pBuf,
DWORD dwLen
)
{
PI2C_OPEN_INFO pOpen = (PI2C_OPEN_INFO)dwData;
DWORD ReadLength = 0;
EnterCriticalSection( &(pOpen -> pI2CHandle -> csI2C) );
if ( pOpen -> dwMaster == I2C_MASTER_MODE ){
ReadLength = I2C_MasterRead(pOpen, pBuf, dwLen);
}else if ( pOpen -> dwMaster == I2C_SLAVE_MODE ){
ReadLength = I2C_SlaveRead(pOpen, pBuf, dwLen);
}
LeaveCriticalSection( &(pOpen -> pI2CHandle -> csI2C) );
return ReadLength;
}
// @func DWORD | I2C_Write | device write routine
// @parm DWORD | dwData | value returned from I2C_Open call
// @parm LPCVOID | pBuf | buffer containing data
// @parm DWORD | dwLen | data length to write
// @rdesc Returns -1 for error, otherwise the number of bytes written
DWORD
I2C_Write(
DWORD dwData,
LPCVOID pBuf,
DWORD dwLen
)
{
PI2C_OPEN_INFO pOpen = (PI2C_OPEN_INFO)dwData;
DWORD WriteLength = 0;
EnterCriticalSection( &(pOpen -> pI2CHandle -> csI2C) );
if ( pOpen -> dwMaster == I2C_MASTER_MODE ){
WriteLength = I2C_MasterWrite(pOpen, pBuf, dwLen);
}else if ( pOpen -> dwMaster == I2C_SLAVE_MODE ){
WriteLength = I2C_SlaveWrite(pOpen, pBuf, dwLen);
}
LeaveCriticalSection( &(pOpen -> pI2CHandle -> csI2C) );
return WriteLength;
}
// @func DWORD | I2C_Seek | device seek routine
// @parm DWORD | dwData | value returned from I2C_Open call
// @parm long | lPos | position to seek to
// @parm DWORD | dwType | FILE_BEGIN, FILE_CURRENT, or FILE_END
// @rdesc Returns current position relative to start of file, or -1 on error
DWORD
I2C_Seek(
DWORD dwData,
long lPos,
DWORD dwType
)
{
return -1;
}
// @func VOID | I2C_PowerUp | device powerup routine
// @comm Called power up device
VOID
I2C_PowerUp(
DWORD dwData
)
{
}
// @func VOID | I2C_PowrDown | device powerdwn routine
// @comm Called suspend device
VOID
I2C_PowerDown(
DWORD dwData
)
{
}
// @func BOOL | I2C_IOControl | Device IO control routine
// @parm DWORD | dwData | value returned from I2C_Open call
// @parm DWORD | dwCode | io control code to be performed
// @parm PVOID | pBufIn | input data to the device
// @parm DWORD | dwLenIn | number of bytes being passed in
// @parm PVOID | pBufOut | output data from the device
// @parm DWORD | dwLenOut | maximum number of bytes to receive from device
// @parm PDWORD | pdwActualOut | actual number of bytes received from device
// @rdesc Returns TRUE for success, FALSE for failure
BOOL
I2C_IOControl(
DWORD dwData,
DWORD dwCode,
PVOID pBufIn,
DWORD dwLenIn,
PVOID pBufOut,
DWORD dwLenOut,
PDWORD pdwActualOut
)
{
BOOL bRet = TRUE;
PI2C_OPEN_INFO pOpen = (PI2C_OPEN_INFO)dwData;
*pdwActualOut = 0;
switch( dwCode ){
case IOCTL_I2C_SET_BAUDRATE :
if ( pOpen -> dwMaster == I2C_MASTER_MODE ){
pOpen -> dwBaudrate = *((PDWORD)pBufIn);
}
break;
case IOCTL_I2C_SET_MODE :
if ( *((PDWORD)pBufIn) == I2C_MASTER_MODE ){
pOpen -> dwMaster = I2C_MASTER_MODE;
}else{
pOpen -> dwMaster = I2C_SLAVE_MODE;
}
break;
case IOCTL_I2C_SET_BUFFER_MODE :
if ( *((PDWORD)pBufIn) == I2C_SINGLE_STAGE ){
pOpen -> bSingleStage = TRUE;
}else{
pOpen -> bSingleStage = FALSE;
}
break;
default :
bRet = FALSE;
break;
}
return bRet;
}
BOOL
InitializeI2C(
PI2C_OPEN_INFO pi2c,
BOOL bMaster // Master is TRUE, Slave is FALSE
)
{
PI2C_DRIVER_INFO pI2c = pi2c -> pI2CHandle;
RegMCR mcr;
try {
mcr.AsDWORD = 0;
mcr.bits.FSB = 1;
WRITE_REGISTER_ULONG(pI2c -> SCR, 0x00000000);
WRITE_REGISTER_ULONG(pI2c -> MCR, READ_REGISTER_ULONG(pI2c -> MCR) & mcr.AsDWORD);
WRITE_REGISTER_ULONG(pI2c -> SSR, 0x00000000);
WRITE_REGISTER_ULONG(pI2c -> MSR, 0x00000000);
WRITE_REGISTER_ULONG(pI2c -> SIER, 0x00000000);
WRITE_REGISTER_ULONG(pI2c -> MIER, 0x00000000);
WRITE_REGISTER_ULONG(pI2c -> CCR, 0x00000000);
WRITE_REGISTER_ULONG(pI2c -> SAR, 0x00000000);
WRITE_REGISTER_ULONG(pI2c -> MAR, 0x00000000);
} except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
return FALSE;
}
return TRUE;
}
BOOL
SetCCR(
PI2C_OPEN_INFO pi2c
)
{
try {
WRITE_REGISTER_ULONG(pi2c -> pI2CHandle -> CCR, pi2c -> dwBaudrate);
} except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
return FALSE;
}
return TRUE;
}
// pBuf : [0] [1-n]
// Adr Data0 - Datan
// dwLen: n+1
DWORD
I2C_MasterWrite(
PI2C_OPEN_INFO pOpen,
LPVOID pBuf,
DWORD dwLen
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -