?? iic_drv.cpp
字號:
/*************************************************************************************************
Copyright(c) 2006, XXXX
All rights reserved.
FileName: TalkDev.cpp
Description: implement talk
Current Version: 1.0
Author: Jinping Wang
Date: 2006-12-01
History:
*************************************************************************************************/
#include "IIC_Drv.h"
#pragma comment(lib,"ceddk.lib")
volatile IICreg *v_pIICReg = NULL;
volatile IOPreg *v_pIOPReg = NULL;
HANDLE g_hIICInterrupt = NULL;
HANDLE g_hIICIST = NULL;
unsigned long g_dwIICPosition = 0;
static volatile unsigned long g_dwI2CMode = 0;
static volatile int g_iI2CDataCount = 0;
static unsigned char g_ucI2CBuff[I2CBUFSIZE] = {0};
static unsigned char g_ucI2CPt = 0;
static volatile int g_iI2CStatus = 0;
BOOL WINAPI DllEntryPoint(HANDLE hinstDLL,
DWORD dwReason,
LPVOID lpvReserved)
{
switch( dwReason )
{
case DLL_PROCESS_ATTACH:
RETAILMSG(1, (TEXT("IIC:DLL_PROCESS_ATTACH\n\r")) );
return TRUE;
case DLL_THREAD_ATTACH:
RETAILMSG(1, (TEXT("IIC:DLL_THREAD_ATTACH\n\r")) );
break;
case DLL_THREAD_DETACH:
RETAILMSG(1, (TEXT("IIC:DLL_THREAD_DETACH\n\r")) );
break;
case DLL_PROCESS_DETACH:
RETAILMSG(1, (TEXT("IIC:DLL_PROCESS_DETACH\n\r")) );
break;
case DLL_PROCESS_EXITING:
RETAILMSG(1, (TEXT("IIC:DLL_PROCESS_EXITING\n\r")) );
break;
case DLL_SYSTEM_STARTED:
RETAILMSG(1, (TEXT("IIC:DLL_SYSTEM_STARTED\n\r")) );
break;
}
return TRUE;
}
DWORD IIC_Init(HANDLE hDeviceContext)
{
RETAILMSG(1, (TEXT("IIC_Init()\n")) );
//Init IIC driver
v_pIICReg = (volatile IICreg *)VirtualAlloc(0, sizeof(IICreg), MEM_RESERVE, PAGE_NOACCESS);
if( v_pIICReg == NULL )
{
RETAILMSG(1,(TEXT("[IIC] v_pIICReg : VirtualAlloc failed!\r\n")));
goto ERROR_EXIT1;
}
if( !VirtualCopy( (PVOID)v_pIICReg, (PVOID)(IIC_BASE), sizeof(IICreg), PAGE_READWRITE|PAGE_NOCACHE ) )
{
RETAILMSG(1,(TEXT("[IIC] v_pIICReg : VirtualCopy failed!\r\n")));
goto ERROR_EXIT1;
}
v_pIOPReg = (volatile IOPreg *)VirtualAlloc(0, sizeof(IOPreg), MEM_RESERVE, PAGE_NOACCESS);
if( v_pIOPReg == NULL )
{
RETAILMSG(1,(TEXT("[IIC] v_pIOPregs : VirtualAlloc failed!\r\n")));
goto ERROR_EXIT1;
}
if( !VirtualCopy( (PVOID)v_pIOPReg, (PVOID)(IOP_BASE), sizeof(IOPreg), PAGE_READWRITE|PAGE_NOCACHE ) )
{
RETAILMSG(1,(TEXT("[KBD] v_pIOPregs : VirtualCopy failed!\r\n")));
goto ERROR_EXIT1;
}
//Init GPE15 --> IIC SDA GPE14 -->IIC SCL
v_pIOPReg->rGPEUP |= 0xc000; //Pull-up disable
v_pIOPReg->rGPECON &= ~0xf0000000;
v_pIOPReg->rGPECON |= 0xa0000000; //GPE15:IICSDA , GPE14:IICSCL
//Init IIC register
v_pIICReg->rIICCON = (1 << 7) | (1 << 6) | (1 << 5) | 0x00;
v_pIICReg->rIICADD = 0x10; //2410 slave address = [7:1]
v_pIICReg->rIICSTAT = 0x10; //IIC bus data output enable(Rx/Tx)
VirtualFree((PVOID)v_pIOPReg, 0, MEM_RELEASE);
v_pIOPReg = NULL;
#if 0
if( IIC_StartThread() )
{
return TRUE;
}
#endif
return (TRUE);
ERROR_EXIT1:
if ( v_pIOPReg )
VirtualFree((PVOID)v_pIOPReg, 0, MEM_RELEASE);
if ( v_pIICReg )
VirtualFree((PVOID)v_pIICReg, 0, MEM_RELEASE);
v_pIOPReg = NULL;
v_pIICReg = NULL;
RETAILMSG(1,(TEXT("IIC_Init()[FAILED!!!]\r\n")));
return FALSE;
}
DWORD IIC_Deinit(HANDLE hDeviceContext)
{
if ( v_pIOPReg )
{
VirtualFree((PVOID)v_pIOPReg, 0, MEM_RELEASE);
v_pIOPReg = NULL;
}
if ( v_pIICReg )
{
VirtualFree((PVOID)v_pIICReg, 0, MEM_RELEASE);
v_pIICReg = NULL;
}
return TRUE;
}
DWORD IIC_Open(HANDLE hDeviceContext,
DWORD AccessCode,
DWORD ShareMode )
{
g_dwIICPosition = 0;
return (TRUE);
}
BOOL IIC_Close(HANDLE hDeviceContext)
{
g_dwIICPosition = 0;
return (TRUE);
}
DWORD IIC_Read(HANDLE hDeviceContext,LPVOID pBuffer,DWORD dwCount)
{
unsigned long dwLoop;
unsigned char *pucData;
if( dwCount >= AT24C01_MEM_SIZE )
{
dwCount = AT24C01_MEM_SIZE;
}
pucData = (unsigned char*)pBuffer;
for( dwLoop = 0; dwLoop < dwCount; dwLoop++)
{
if( TRUE != IIC_ReadByte( (unsigned short)dwLoop,(pucData+dwLoop) ) )
{
return dwLoop;
}
}
return dwCount;
}
DWORD IIC_Write(HANDLE hDeviceContext,LPVOID pSrcData,DWORD dwCount)
{
unsigned long dwLoop;
if( dwCount >= AT24C01_MEM_SIZE )
{
dwCount = AT24C01_MEM_SIZE;
}
pucBuff = (unsigned char*)pSrcData;
for( dwLoop = 0; dwLoop < dwCount; dwLoop++)
{
if( TRUE != IIC_WriteByte( (unsigned short)dwLoop,*(pucBuff+dwLoop) ) )
{
return dwLoop;
}
}
return dwCount;
}
BOOL IIC_OIControl( HANDLE hDeviceContext,
DWORD dwCode,
PBYTE pBufIn,
DWORD dwLenIn,
PBYTE pBufOut,
DWORD dwLenOut,
PDWORD pdwActualOut)
{
return(TRUE);
}
void IIC_PowerUp(HANDLE hDeviceContext)
{
return;
}
void IIC_PowerDown(HANDLE hDeviceContext)
{
return;
}
DWORD IIC_Seek(HANDLE hDeviceContext,long Offset,DWORD dwType)
{
DWORD dwRet = 0;
g_dwIICPosition = (g_dwIICPosition + Offset) % AT24C01_MEM_SIZE;
return dwRet;
}
#if 0
BOOL IIC_StartThread(void)
{
HANDLE hIICThreadHandle;
hIICThreadHandle = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)IIC_ThreadEntry,0,0,NULL);
CloseHandle( hIICThreadHandle );
return (TRUE);
}
BOOL IIC_ThreadEntry(void)
{
int iI2CStatus,i,iDelay;
RETAILMSG(1,(TEXT("IIC:IIC_StartThread!\r\n")));
////////////////Initialize Event/////////////////
g_hIICInterrupt = CreateEvent( NULL, FALSE, FALSE, NULL );//create event
if( g_hIICInterrupt == NULL )
{
RETAILMSG(1,(TEXT("IIC Event creation failed!\r\n")));
return (FALSE);
}
//注冊中斷
if( !InterruptInitialize( SYSINTR_IC_CARD, g_hIICInterrupt, NULL, 0 ) )
{
RETAILMSG(1,(TEXT("IIC InterruptInitialize failed!\r\n")));
return (FALSE);
}
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
while( TRUE )
{
if (WaitForSingleObject(g_hIICInterrupt, INFINITE) == WAIT_OBJECT_0)
{
RETAILMSG(1,(TEXT("IIC occur interrupt!\r\n")));
/* occur interrupt */
iI2CStatus = v_pIICReg->rIICSTAT;
//When bus arbitration is failed.
if( iI2CStatus & 0x8 )
{
}
//When a slave address is matched with IICADD
if( iI2CStatus & 0x4 )
{
}
//When a slave address is 0000000b
if( iI2CStatus & 0x2 )
{
}
//When ACK isn't received
if( iI2CStatus & 0x1 )
{
}
switch( g_dwI2CMode )
{
case EN_I2C_POLLACK:
RETAILMSG(1,(TEXT("IIC occur interrupt -> EN_I2C_POLLACK!\r\n")));
g_iI2CStatus = iI2CStatus;
break;
case EN_I2C_RDDATA:
RETAILMSG(1,(TEXT("IIC occur interrupt -> EN_I2C_RDDATA!\r\n")));
if( (g_iI2CDataCount--) == 0 ) /* 這里先判斷條件再做"-1"操作 */
{
g_ucI2CBuff[g_ucI2CPt++] = v_pIICReg->rIICDS;
v_pIICReg->rIICSTAT = 0x90; //Stop MasRx condition
v_pIICReg->rIICCON = 0xe0; //0xaf; Resumes IIC operation.
Delay(1); //Wait until stop condtion is in effect.
//Too long time...
//The pending bit will not be set after issuing stop condition.
break;
}
g_ucI2CBuff[g_ucI2CPt++] = v_pIICReg->rIICDS; //The last data has to be read with no ack.
if( g_iI2CDataCount == 0 )
v_pIICReg->rIICCON = 0x60;//0x2f; //Resumes IIC operation with NOACK.
else
v_pIICReg->rIICCON = 0xe0;//0xaf; //Resumes IIC operation with ACKs
break;
case EN_I2C_WRDATA:
RETAILMSG(1,(TEXT("IIC occur interrupt -> EN_I2C_WRDATA !\r\n")));
if( (g_iI2CDataCount--) == 0 )
{
v_pIICReg->rIICSTAT = 0xd0; //Stop MasTx condition
v_pIICReg->rIICCON = 0xe0; //0xaf; Resumes IIC operation.
Delay(1); //Wait until stop condtion is in effect.
//The pending bit will not be set after issuing stop condition.
break;
}
v_pIICReg->rIICDS = g_ucI2CBuff[g_ucI2CPt++]; //_iicData[0] has dummy.
for( i=0; i<10; i++) //for setup time until rising edge of IICSCL
{
iDelay++;
}
v_pIICReg->rIICCON = 0xe0; //0xaf; resumes IIC operation.
break;
case EN_I2C_SETRDADDR:
RETAILMSG(1,(TEXT("IIC occur interrupt -> EN_I2C_SETRDADDR !\r\n")));
if( (g_iI2CDataCount--) == 0 )
break; //IIC operation is stopped because of IICCON[4]
v_pIICReg->rIICDS = g_ucI2CBuff[g_ucI2CPt++];
for( i=0; i<10; i++ ) //For setup time until rising edge of IICSCL
{
iDelay++;
}
v_pIICReg->rIICCON = 0xe0; //0xaf; Resumes IIC operation.
break;
default:
break;
}
RETAILMSG(1,(TEXT("IIC occur interrupt -> InterruptDone !\r\n")));
/* Notify system interrupt done */
InterruptDone(SYSINTR_IC_CARD);
}
}
return (TRUE);
}
#endif
static void Delay(int time)
{
int i;
for(; time > 0; time-- )
{
for( i = 0; i < (S2410FCLK/10000/10); i++ );
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -