📄 i2c_driver.cpp
字号:
dwType = REG_SZ;
dwStatus = RegQueryValueEx(hkI2C, TEXT("Key"), NULL, &dwType,
(LPBYTE) regkeyname, &dwSize);
if (dwStatus != ERROR_SUCCESS) {
RETAILMSG(ZONE_ERROR, (_T("IIC_Init: Error getting device key name\r\n")));
RegCloseKey(hkI2C);
goto cleanup;
}
// Open the registry key and read the index value
dwStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE, regkeyname, 0, 0, &hkI2C);
if (dwStatus != ERROR_SUCCESS) {
RETAILMSG(ZONE_ERROR, (_T("IIC_Init: Error opening device registry!\r\n")));
goto cleanup;
}
// Get I2C index value
dwSize = sizeof(indx);
dwType = REG_DWORD;
dwStatus = RegQueryValueEx(hkI2C, TEXT("Index"), NULL, &dwType,
(LPBYTE) &indx, &dwSize);
if (dwStatus != ERROR_SUCCESS) {
RETAILMSG(ZONE_ERROR, (_T("IIC_Init: Error getting Index\r\n")));
}
index = (int) indx;
RegCloseKey(hkI2C);
DEBUGMSG(ZONE_INIT, (_T("IIC_Init: Using index %d\r\n"), index));
// Get IRQ mapped to this I2C channel
if (index == 0)
{
irqt = OAL_INTR_IRQ_I2C_1;
}
else
{
irqt = OAL_INTR_IRQ_I2C_2;
}
pDev = &i2cDrv [index];
// Setup defaults
pDev->pI2CRegs = NULL;
pDev->I2CsysIntr = SYSINTR_UNDEFINED;
pDev->pClkPwrRegs = NULL;
pDev->i2cEvent = NULL;
pDev->i2cLock = NULL;
pDev->i2cNum = index;
// Allocate registers for I2C and clock and power
pa.HighPart = 0;
pa.LowPart = CLK_PM_BASE;
pDev->pClkPwrRegs = (CLKPWR_REGS_T *) MmMapIoSpace(pa,
sizeof (CLKPWR_REGS_T), FALSE);
pa.HighPart = 0;
if (index == 0)
{
pa.LowPart = I2C1_BASE;
}
else
{
pa.LowPart = I2C2_BASE;
}
pDev->pI2CRegs = (I2C_REGS_T *) MmMapIoSpace(pa,
sizeof (I2C_REGS_T), FALSE);
if ((pDev->pClkPwrRegs == NULL) ||
(pDev->pI2CRegs == NULL))
{
RETAILMSG(ZONE_ERROR,
(TEXT("ERROR: I2C: Failed to map registers\r\n")));
goto cleanup;
}
// Enable I2C clocking and power for init
I2CPeriphUp((DWORD) pDev);
// Allocate I2C and initialize I2C interface
pDev->pI2CClass = new bspI2C(pDev->pI2CRegs);
if (pDev->pI2CClass == NULL)
{
RETAILMSG(ZONE_ERROR,
(TEXT("ERROR: I2C: Failed to allocate I2C driver class\r\n")));
goto cleanup;
}
// Get sysintr value
if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &irqt, sizeof(irqt),
&pDev->I2CsysIntr, sizeof(pDev->I2CsysIntr),
NULL))
{
RETAILMSG(ZONE_ERROR,
(TEXT("ERROR: I2C: Failed to request the I2C sysintr.\r\n")));
pDev->I2CsysIntr = SYSINTR_UNDEFINED;
goto cleanup;
}
// Create event handle
pDev->i2cEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (pDev->i2cEvent == NULL)
{
RETAILMSG(ZONE_ERROR,
(TEXT("ERROR: I2C: Failed to create handler event.\r\n")));
goto cleanup;
}
// Initialize the I2C interrupt
if (InterruptInitialize(pDev->I2CsysIntr, pDev->i2cEvent,
NULL, 0) == FALSE) {
// Cannot initialize interrupt
RETAILMSG(ZONE_ERROR,
(TEXT("ERROR: I2C: Cannot initialize I2C interrupt\r\n")));
goto cleanup;
}
InterruptDone(pDev->I2CsysIntr);
// Create access mutex for I2C registers
pDev->i2cLock = CreateMutex(NULL, FALSE, NULL);
if (pDev->i2cLock == NULL) {
RETAILMSG(ZONE_ERROR,
(TEXT("ERROR: I2C: Error creating control mutex\r\n")));
goto cleanup;
}
// Get base clock for I2C
if (KernelIoControl(IOCTL_LPC32XX_GETHCLK, NULL, 0, &clk,
sizeof (clk), (LPDWORD) &bytesret) == FALSE)
{
// Cannot get clock
RETAILMSG(ZONE_ERROR,
(TEXT("ERROR: I2C: Error getting I2C base clock rate.\r\n")));
goto cleanup;
}
pDev->pI2CClass->bspi2cSetClock(clk, 400000, FALSE);
sts = (DWORD) pDev;
// Disable I2C clock until it is needed
I2CPeriphDown((DWORD) pDev);
cleanup:
return sts;
}
//------------------------------------------------------------------------------
//
// IIC_IOControl
//
// I2C driver general IOCTL handler function
//
extern "C" BOOL IIC_IOControl(DWORD hOpenContext, DWORD dwCode, PBYTE pBufIn,
DWORD dwLenIn, PBYTE pBufOut, DWORD dwLenOut,
PDWORD pdwActualOut) {
UINT32 bytesret, clk;
I2C_XFER_SETUP_T *pi2cSetup;
I2C_DRVCTL_T *pDev = (I2C_DRVCTL_T *) hOpenContext;
switch (dwCode)
{
case IOCTL_APP_I2CREQ:
// Attempt transfer
if ((pBufIn != NULL) && (pBufOut != NULL) &&
(dwLenIn == sizeof(I2C_OUT_XFER_T)) &&
(dwLenOut == sizeof(I2C_IN_XFER_T)))
{
*pdwActualOut = sizeof(I2C_IN_XFER_T);
return I2C_Transfer(pDev, (I2C_OUT_XFER_T *) pBufIn,
(I2C_IN_XFER_T *) pBufOut);
}
break;
case IOCTL_APP_I2CSETUP:
// Attempt setup
if ((pBufIn != NULL) && (dwLenIn == sizeof(I2C_XFER_SETUP_T)))
{
// Get base clock for I2C
if (KernelIoControl(IOCTL_LPC32XX_GETHCLK, NULL, 0, &clk,
sizeof (clk), (LPDWORD) &bytesret) != FALSE)
{
pi2cSetup = (I2C_XFER_SETUP_T *) pBufIn;
I2C_Lock(pDev->i2cLock);
pDev->pI2CClass->bspi2cSetClock(clk, pi2cSetup->clock,
pi2cSetup->assym);
I2C_Unlock(pDev->i2cLock);
return TRUE;
}
}
break;
default:
break;
}
return FALSE;
}
//------------------------------------------------------------------------------
//
// IIC_Close
//
// I2C driver close function
//
extern "C" BOOL IIC_Close(DWORD hOpenContext) {
I2C_DRVCTL_T *pDev = (I2C_DRVCTL_T *) hOpenContext;
i2cInstances[pDev->i2cNum]--;
if (i2cInstances[pDev->i2cNum] == 0)
{
// Disable clocks, no more I2C channels open
I2CPeriphDown(hOpenContext);
}
return TRUE;
}
//------------------------------------------------------------------------------
//
// IIC_Open
//
// I2C driver open function
//
extern "C" DWORD IIC_Open(DWORD hDeviceContext, DWORD AccessCode,
DWORD ShareMode) {
I2C_DRVCTL_T *pDev = (I2C_DRVCTL_T *) hDeviceContext;
(void) AccessCode;
(void) ShareMode;
i2cInstances[pDev->i2cNum]++;
if (i2cInstances[pDev->i2cNum] == 1)
{
// Enable clocks
I2CPeriphUp(hDeviceContext);
}
// Return the device context, this will be used as the open
// context to identify which I2C channel is used for operations
return hDeviceContext;
}
//------------------------------------------------------------------------------
//
// IIC_Read
//
// I2C driver read stub function
//
extern "C" DWORD IIC_Read(DWORD hOpenContext, LPVOID pBuffer, DWORD Count) {
(void) hOpenContext;
(void) pBuffer;
(void) Count;
/* Read not allowed */
return 0;
}
//------------------------------------------------------------------------------
//
// IIC_Write
//
// I2C driver write stub function
//
extern "C" DWORD IIC_Write(DWORD hOpenContext, LPCVOID pBuffer, DWORD Count) {
(void) hOpenContext;
(void) pBuffer;
(void) Count;
/* Write not allowed */
return 0;
}
//------------------------------------------------------------------------------
//
// IIC_Seek
//
// I2C driver seek stub function
//
extern "C" DWORD IIC_Seek(DWORD hOpenContext, long Amount, WORD Type) {
(void) hOpenContext;
(void) Amount;
(void) Type;
/* Seek not allowed */
return 0;
}
//------------------------------------------------------------------------------
//
// IIC_DLLEntry
//
// DLL entry point
//
extern "C" BOOL __stdcall IIC_DLLEntry (
HANDLE hinstDLL, // [in] : Instance pointer
DWORD Op, // [in] : Reason routine is called
LPVOID lpvReserved // [in] : system parameter
)
{
switch(Op) {
case DLL_PROCESS_ATTACH :
DisableThreadLibraryCalls((HMODULE) hinstDLL);
break;
case DLL_PROCESS_DETACH :
break;
case DLL_THREAD_DETACH :
case DLL_THREAD_ATTACH :
break;
default :
break;
}
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -