⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 i2c.c

📁 WinCE5.0BSP for Renesas SH7770
💻 C
📖 第 1 页 / 共 2 页
字号:
//
// 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 + -