wince +6410 IIC 驅動問題
最近調試6410的IIC驅動,要求上層將資料寫入eeprom永久儲存,開始由於bsp包裡的camera驅動裡,有操作IIC的樣本,自然就參考camera驅動裡依葫蘆畫瓢就行了,
// Initialize IIC1
hI2C = CreateFile(_T("IIC0:"), GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
if(INVALID_HANDLE_VALUE == hI2C)
{
MessageBox(L"無法開啟I2C");
dwErr = GetLastError();
return FALSE;
}
if (!DeviceIoControl(hI2C,
IOCTL_IIC_SET_CLOCK,
&IICClock, sizeof(UINT32),
NULL, 0,
&bytes, NULL) )
{
dwErr = GetLastError();
MessageBox(L"無法設定I2C clock");
return FALSE;
}
uiIICDelay = 0;
if ( !DeviceIoControl(hI2C,
IOCTL_IIC_SET_DELAY,
&uiIICDelay, sizeof(UINT32),
NULL, 0,
&bytes, NULL) )
{
dwErr = GetLastError();
MessageBox(L"無法設定I2C delay");
return FALSE;
}
開啟iic 沒有問題,設定時鐘 和延時時間就出問題了,iic壓根就沒反應,後開啟調試資訊,發現進入IIC_IOControl 後,到
if (GetDirectCallerProcessId() != GetCurrentProcessId()){
RETAILMSG(1, (TEXT(" mao IIC_IOControl 1: \r\n"))); //add mao
return ERROR_ACCESS_DENIED;
}
就沒往下走了,
後來網上查資料才知道本身驅動不支援應用程式調用,是給其他驅動程式調用的。因為在IIC_IOControl前面添加了個判斷
if (GetDirectCallerProcessId() != GetCurrentProcessId()){
RETAILMSG(1, (TEXT(" mao IIC_IOControl 1: \r\n"))); //add mao
return ERROR_ACCESS_DENIED;
}
應用程式調用時需要將上面的判斷注釋掉,注釋掉後,可以讀寫了,可有好幾次 連續讀資料時就報錯,
Exception 'Data Abort' (4): Thread-Id=01970006(pth=8617c2ec), Proc-Id=00400002(pprc=82ab9308) 'NK.EXE', VM-active=058b0006(pprc=84954618) 'explorer.exe'
PC=c0e32b98(s3c6410_iic.dll+0x00002b98) RA=c0e32b10(s3c6410_iic.dll+0x00002b10) SP=d285fe64, BVA=001aeee8
一直納悶,查原始碼沒找出根本原因,無意中看到一文章,說可能是IIC_IO_DESC這個參數裡麵包括指標,需要進行指標的映射,如下:
BOOL HW_Read (PHW_OPEN_INFO pOpenContext, PIIC_IO_DESC pInData ,PIIC_IO_DESC pOutData)
{
HRESULT hr; //add mao for iic
BOOL retVal = TRUE; // Initialize to success
PBYTE MappedEmbedded;
PBYTE Marshalled;
DEBUGMSG (ZONE_FUNCTION,
(TEXT("+HW_Read(0x%X)\r\n"),
pOpenContext));
HW_SetRegister(pOpenContext);
HW_Write(pOpenContext, pInData);
ResetEvent(g_hTransferDone);
// Wait until IIC bus is free.
if(!WaitForReg((PVOID)&(g_pIICReg->IICSTAT), (1<<5), 0x0, TIMEOUT_MS_RX))
{
DEBUGMSG(ZONE_ERROR,(TEXT("[IIC ERROR]IIS BUS is busy.\r\n")));
retVal = FALSE;
goto CleanUp;
}
// 核心地址映射
hr = CeOpenCallerBuffer((PVOID*) &MappedEmbedded, pOutData->Data, pOutData->Count, ARG_O_PTR, FALSE);
hr = CeAllocAsynchronousBuffer((PVOID*) &Marshalled, MappedEmbedded, pOutData->Count, ARG_O_PTR);
g_pcIIC_BUFFER = Marshalled;//pOutData->Data;
g_uIIC_PT = 0;
g_uIIC_DATALEN = pOutData->Count;
g_pIICReg->IICCON |= (1<<7); // Ack generation Enable
g_pIICReg->IICDS = pInData->SlaveAddress;
g_pIICReg->IICSTAT = MRX_START;
// RETAILMSG(1,(TEXT("mao g_pIICReg->IICDS Slave Address is 0x%02X\n"),pInData->SlaveAddress)); //add mao
if(WaitForSingleObject(g_hTransferDone, TIMEOUT_MS_RX) == WAIT_TIMEOUT)
{
DEBUGMSG(ZONE_ERROR,(TEXT("[IIC ERROR]RX Time out.\r\n")));
retVal = FALSE;
}
// 核心地址釋放
hr = CeFreeAsynchronousBuffer((PVOID)Marshalled, MappedEmbedded, pOutData->Count, ARG_O_PTR);
hr = CeCloseCallerBuffer((PVOID) MappedEmbedded, pOutData->Data, pOutData->Count, ARG_O_PTR);
CleanUp:
DEBUGMSG (ZONE_FUNCTION,
(TEXT("+HW_Read(0x%X)\r\n"),
pOpenContext));
return retVal;
}
BOOL HW_Write (PHW_OPEN_INFO pOpenContext, PIIC_IO_DESC pInData)
{
BOOL retVal = TRUE; // Initialize to success
PBYTE MappedEmbedded;
PBYTE Marshalled;
HRESULT hr; //add mao for iic
DEBUGMSG (ZONE_FUNCTION,
(TEXT("+HW_Write(0x%X)\r\n"),
pOpenContext));
HW_SetRegister(pOpenContext);
ResetEvent(g_hTransferDone);
// Wait until IIC bus is free.
if(!WaitForReg((PVOID)&(g_pIICReg->IICSTAT), (1<<5), 0x0, TIMEOUT_MS_TX))
{
DEBUGMSG(ZONE_ERROR,(TEXT("[IIC ERROR]IIC BUS is busy.\r\n")));
return FALSE;
}
// add mao
hr = CeOpenCallerBuffer((PVOID*) &MappedEmbedded, pInData->Data, pInData->Count, ARG_I_PTR, FALSE);
hr = CeAllocAsynchronousBuffer((PVOID*) &Marshalled, MappedEmbedded, pInData->Count, ARG_I_PTR);
g_pcIIC_BUFFER = Marshalled;;//pInData->Data;
g_uIIC_PT = 0;
g_uIIC_DATALEN = pInData->Count;
g_pIICReg->IICCON |= (1<<7); // Ack generation Enable
g_pIICReg->IICDS = pInData->SlaveAddress;
// RETAILMSG(1,(TEXT("mao [IIC TX]Slave Address is 0x%02X\n"),pInData->SlaveAddress)); //add mao
DEBUGMSG(ZONE_INFO,(TEXT("[IIC TX]Slave Address is 0x%02X\n"),pInData->SlaveAddress));
g_pIICReg->IICSTAT = MTX_START;
if(WaitForSingleObject(g_hTransferDone, 500) == WAIT_TIMEOUT)
{
DEBUGMSG(ZONE_ERROR,(TEXT("[IIC ERROR]TX Time out.\r\n")));
retVal = FALSE;
}
hr = CeFreeAsynchronousBuffer((PVOID)Marshalled, MappedEmbedded, pInData->Count, ARG_I_PTR);
hr = CeCloseCallerBuffer((PVOID) MappedEmbedded, pInData->Data, pInData->Count, ARG_I_PTR);
DEBUGMSG (ZONE_FUNCTION,
(TEXT("-HW_Write(0x%X)\r\n"),
pOpenContext));
return retVal;
}
重新編譯後,讀寫正常了。
參考文章:http://bbs.csdn.net/topics/310115283
http://blog.csdn.net/knock/article/details/4770325
http://jazka.blog.51cto.com/809003/702584
http://blog.csdn.net/fgwntg/article/details/6798420