📄 cspiutil.c
字号:
// Write the packet to the TXFIFO
BSPPmicCSPIWriteTXFIFO(packet.data);
DEBUGMSG(ZONE_INFO, (_T("read addr = 0x%x\r\n"), addr));
return TRUE;
}
//-----------------------------------------------------------------------------
//
// Function: cspiDataExchange
//
// Initiate CSPI data exchange.
//
// Parameters:
// None.
//
// Returns:
// TRUE if data exchange is successful.
//
//-----------------------------------------------------------------------------
BOOL cspiDataExchange()
{
BSPPmicCSPIExchange();
#ifdef VPMX31
// wait until transaction is complete
BSPPmicCSPIWaitTransactionComplete();
#endif
return TRUE;
}
//-----------------------------------------------------------------------------
//
// Function: cspiReceiveData
//
// Read a packet from CSPI RXDATA.
//
// Parameters:
// data
// [out] data read from CSPI RXDATA
//
// Returns:
// TRUE if CSPI reading is successful.
//
//-----------------------------------------------------------------------------
BOOL cspiReceiveData(UINT32* data)
{
#ifdef VPMX31
*data = BSPPmicCSPIReadRXFIFO();
*data &= 0xFFFFFF;
DEBUGMSG(ZONE_INFO, (_T("Receive data = 0x%x\r\n"), *data));
return TRUE;
#else
BOOL rc = FALSE;
// If polled communication is requested
if (g_bUsePolling)
{
// Wait until transaction is complete
BSPPmicCSPIWaitReadReady();
}
// Else use interrupt-driven communication
else
{
// Set a global to indicate we are about to block on the CSPI
// transfer. This will be used during a suspend procedure
// to see if we need to wait until the transfer is complete
g_bSync = TRUE;
// NOTE: Can't use WaitForSingleObject directly on an event
// registered with InterruptInitialize as the kernel faults
// on priority inversion!
if (WaitForSingleObject(g_hCspiWaitEvent, CSPI_TIMEOUT) != WAIT_OBJECT_0)
{
ERRORMSG(TRUE, (_T("cspiReceiveData failed\r\n")));
*data = 0;
goto cleanUp;
}
}
*data = BSPPmicCSPIReadRXFIFO();
*data &= 0xFFFFFF;
DEBUGMSG(ZONE_INFO, (_T("Receive data = 0x%x\r\n"), *data));
rc = TRUE;
cleanUp:
g_bSync = FALSE;
InterruptDone(g_cspiSysIntr);
return rc;
#endif
}
//-----------------------------------------------------------------------------
//
// Function: cspiDiscardData
//
// Discard all data in CSPI RXDATA.
//
// Parameters:
// None.
//
// Returns:
// TRUE.
//
//-----------------------------------------------------------------------------
BOOL cspiDiscardData()
{
UINT data;
return cspiReceiveData(&data);
}
//-----------------------------------------------------------------------------
//
// Function: cspiPowerDown
//
// Power down the CSPI interface.
//
// Parameters:
// None.
//
// Returns:
// TRUE.
//
//-----------------------------------------------------------------------------
VOID cspiPowerDown(void)
{
}
//-----------------------------------------------------------------------------
//
// Function: cspiSync
//
// Waits for pending interrupt-driven SPI transfers to complete so that the
// system can properly suspend.
//
// Parameters:
// None.
//
// Returns:
// TRUE.
//
//-----------------------------------------------------------------------------
VOID cspiSync(void)
{
// Wait for pending interrupt-driven transfers to complete. The g_bSync
// global is set prior to blocking on the CSPI transfer and will be cleared
// by CspiIntrServThread or completion of cspiReceiveData
while (g_bSync)
; // Polling loop.
}
//-----------------------------------------------------------------------------
//
// Function: cspiLock
//
// Obtains a lock for the CSPI hardware so that the OAL and PMIC core driver
// can safely share access.
//
// Parameters:
// None.
//
// Returns:
// None.
//
//-----------------------------------------------------------------------------
void cspiLock(void)
{
// For WinCE 6.00, use an OEM IOCTL call to signal the OAL to grant
// exclusive access to the CSPI bus. We must use this approach because
// WinCE 6.00 does not support the use of named mutexes.
if (!KernelIoControl(IOCTL_PMIC_CSPI_LOCK, NULL, 0, NULL, 0, NULL))
{
ERRORMSG(TRUE, (TEXT("cspiLock(): KernelIoControl() returned FALSE ")
TEXT("(expected TRUE always)\r\n")));
}
BSPPmicSetSpiClockGating(TRUE);
BSPPmicCSPIEnable();
// Configure the CSPI for polled/interrupt-driven mode.
if (g_bUsePolling)
{
// Disable all CSPI interrupts
BSPPmicCSPIIRQDisable();
}
else
{
// Enable RX FIFO ready interrupt
BSPPmicCSPIRXIRQEnable();
}
}
//-----------------------------------------------------------------------------
//
// Function: cspiUnlock
//
// Release the lock previously obtained by cspiLock.
//
// Parameters:
// None.
//
// Returns:
// None.
//
//-----------------------------------------------------------------------------
void cspiUnlock(void)
{
BSPPmicCSPIDisable();
BSPPmicSetSpiClockGating(FALSE);
// Use an OEM IOCTL call to signal the OAL to release exclusive
// access to the CSPI bus. This should only be called by the thread
// that had previously called cspiLock(). Then we can guarantee that
// the KernelIoControl() call will never block and always be successful.
if (!KernelIoControl(IOCTL_PMIC_CSPI_UNLOCK, NULL, 0, NULL, 0, NULL))
{
ERRORMSG(TRUE, (TEXT("cspiUnlock(): KernelIoControl() returned FALSE ")
TEXT("(expected TRUE always)\r\n")));
}
}
//-----------------------------------------------------------------------------
//
// Function: CspiIntrServThread
//
// This is the interrupt service thread for CSPI interrupts.
//
// Parameters:
// lpParam
// [in] Thread data passed to the function using the
// lpParameter parameter of the CreateThread function. Not used.
//
// Returns:
// Returns thread exit code.
//
//-----------------------------------------------------------------------------
static DWORD WINAPI CspiIntrServThread (LPVOID lpParam)
{
DWORD rc = TRUE;
// Bump up our priority to the highest level available to CE drivers.
// This will make surewe have a chance to signal threads blocked on a
// CSPI transfer before starting the suspend procedure.
CeSetThreadPriority(GetCurrentThread(), 97);
while(TRUE)
{
if(WaitForSingleObject(g_hCspiIntrEvent, INFINITE) == WAIT_OBJECT_0)
{
// Disable CSPI interrupts, so we can call InterruptDone. The
// thread signaled with g_hCspiWaitEvent will perform the actual
// CSPI servicing.
BSPPmicCSPIIRQDisable();
g_bSync = FALSE;
InterruptDone(g_cspiSysIntr);
SetEvent(g_hCspiWaitEvent);
}
else
{
// Abnormal interrupt signal.
ERRORMSG(TRUE, (TEXT("CSPI interrupt handler exiting ")
TEXT("due to error!\r\n")));
rc = FALSE;
break;
}
}
return rc;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -