📄 cspiclass.cpp
字号:
INSREG32BF(&pCspiReg->CONTROLREG, CSPI_CONTROLREG_SPIEN, CSPI_CONTROLREG_SPIEN_DISABLE);
#ifdef DEBUG
for(i = 0; i < NumOfWords; i++)
DEBUGMSG(ZONE_INFO, (TEXT("rxBuf[%d]:(0x%08x)\r\n"), i, pRxBuf[i]));
#endif
DEBUGMSG(ZONE_FUNCTION, (TEXT("Exchange-\r\n")));
return NumOfWords;
}
//------------------------------------------------------------------------------
//
// FUNCTION: SetSwap
//
// DESCRIPTION: This is the function to enable or disbale byte swapping of
// Tx FIFO and RxFIFO data.
//
// PARAMETERS:
// bSwap -
// To enable or disable byte swapping
//
// RETURNS:
// TRUE -
// set swap success
//
// FALSE -
// Not get the cspi resource lock, set swap fail
//------------------------------------------------------------------------------
BOOL CspiClass::SetSwap(BOOL bSwap)
{
if (!IsGetLock)
return FALSE;
if (bSwap)
INSREG32BF(&pCspiReg->CONTROLREG, CSPI_CONTROLREG_SWAP, CSPI_CONTROLREG_SWAP_SWAPDATA);
else
INSREG32BF(&pCspiReg->CONTROLREG, CSPI_CONTROLREG_SWAP, CSPI_CONTROLREG_SWAP_NOSWAP);
return TRUE;
}
//------------------------------------------------------------------------------
//
// FUNCTION: StartDMAExchange
//
// DESCRIPTION: This is the function to start the SPI-DMA exchange.
//
// PARAMETERS:
// // bit-mask of the following
// 1 -
// TxFIFO Empty DMA Request Enable
//
// 2 -
// RxFIFO Full DMA Request Enable
//
// 3 -
// TxFIFO Half DMA Request Enable
//
// 4 -
// RxFIFO Half DMA Request Enable
//
// RETURNS:
// TRUE -
// start DMA exchange success
//
// FALSE -
// Not get the cspi resource lock, start DMA exchange fail
//------------------------------------------------------------------------------
BOOL CspiClass::StartDMAExchange(UINT8 mode)
{
if (!IsGetLock)
return FALSE;
// make sure not doing exchange
INSREG32BF(&pCspiReg->CONTROLREG, CSPI_CONTROLREG_XCH, CSPI_CONTROLREG_XCH_IDLE);
// enable cspi
INSREG32BF(&pCspiReg->CONTROLREG, CSPI_CONTROLREG_SPIEN, CSPI_CONTROLREG_SPIEN_ENABLE);
if (mode & 0x01) // TxFIFO Empty DMA Request Enable
INSREG32BF(&pCspiReg->DMA, CSPI_DMA_TEDEN, CSPI_DMA_TEDEN_ENABLE);
if (mode & 0x02) // RxFIFO Full DMA Request Enable
INSREG32BF(&pCspiReg->DMA, CSPI_DMA_RFDEN, CSPI_DMA_RFDEN_ENABLE);
if (mode & 0x04) // TxFIFO Half DMA Request Enable
INSREG32BF(&pCspiReg->DMA, CSPI_DMA_THDEN, CSPI_DMA_THDEN_ENABLE);
if (mode & 0x08) // RxFIFO Half DMA Request Enable
INSREG32BF(&pCspiReg->DMA, CSPI_DMA_RHDEN, CSPI_DMA_RHDEN_ENABLE);
// start exchange
INSREG32BF(&pCspiReg->CONTROLREG, CSPI_CONTROLREG_XCH, CSPI_CONTROLREG_XCH_EN);
return TRUE;
}
//------------------------------------------------------------------------------
//
// FUNCTION: StopDMAExchange
//
// DESCRIPTION: This is the function to stop the SPI-DMA exchange.
//
// // bit-mask of the following
// 1 -
// TxFIFO Empty DMA Request Disable
//
// 2 -
// RxFIFO Full DMA Request Disable
//
// 3 -
// TxFIFO Half DMA Request Disable
//
// 4 -
// RxFIFO Half DMA Request Disable
//
// RETURNS:
// TRUE -
// stop DMA exchange success
//
// FALSE -
// Not get the cspi resource lock, stop DMA exchange fail
//------------------------------------------------------------------------------
BOOL CspiClass::StopDMAExchange(UINT8 mode)
{
if (!IsGetLock)
return FALSE;
// wait until the exchange is finsihed
while ((pCspiReg->CONTROLREG & CSP_BITFMASK(CSPI_CONTROLREG_XCH)) != CSPI_CONTROLREG_XCH_IDLE)
Sleep(0);
if (mode & 0x01) // TxFIFO Empty DMA Request Disable
INSREG32BF(&pCspiReg->DMA, CSPI_DMA_TEDEN, CSPI_DMA_TEDEN_DISABLE);
if (mode & 0x02) // RxFIFO Full DMA Request Disable
INSREG32BF(&pCspiReg->DMA, CSPI_DMA_RFDEN, CSPI_DMA_RFDEN_DISABLE);
if (mode & 0x04) // TxFIFO Half DMA Request Disable
INSREG32BF(&pCspiReg->DMA, CSPI_DMA_THDEN, CSPI_DMA_THDEN_DISABLE);
if (mode & 0x08) // RxFIFO Half DMA Request Disable
INSREG32BF(&pCspiReg->DMA, CSPI_DMA_RHDEN, CSPI_DMA_RHDEN_DISABLE);
// disable cspi
INSREG32BF(&pCspiReg->CONTROLREG, CSPI_CONTROLREG_SPIEN, CSPI_CONTROLREG_SPIEN_DISABLE);
return FALSE;
}
//------------------------------------------------------------------------------
//
// FUNCTION: ReadRxFifo
//
// DESCRIPTION: This is the function to read the top of the 8 × 32 RxFIFO
// received from external CSPI device during data transaction.
//
// PARAMETERS:
// None
//
// RETURNS:
// The data on top of the RXFIFO
//------------------------------------------------------------------------------
UINT32 CspiClass::ReadRxFifo(void)
{
// assume that the caller that obtained the lock
// NOTE: It is not a valid value if the RR bit in the Interrupt
// control/status register is cleared.
return (UINT32)(pCspiReg->RXDATA);
}
//------------------------------------------------------------------------------
//
// FUNCTION: IsRxFifoDataReady
//
// DESCRIPTION: This is the function to check the Data Ready Status of
// the Rx Fifo.
//
// PARAMETERS:
// None
//
// RETURNS:
// TRUE -
// At least one data word is ready in Rx FIFO.
//
// FALSE -
// RxFIFO is empty.
//------------------------------------------------------------------------------
BOOL CspiClass::IsRxFifoDataReady(void)
{
// assume that the caller that obtained the lock
if ((pCspiReg->INT & CSP_BITFMASK(CSPI_INT_RR)) == CSPI_INT_RR_EMPTY)
return FALSE;
return TRUE;
}
//------------------------------------------------------------------------------
//
// FUNCTION: IsExchangeOngoing
//
// DESCRIPTION: This is the function to check the exchange is still ongoing.
//
// PARAMETERS:
// None
//
// RETURNS:
// TRUE -
// Exchange of data is over.
//
// FALSE -
// Exchange of data is still ongoing.
//------------------------------------------------------------------------------
BOOL CspiClass::IsExchangeOngoing(void)
{
// assume that the caller that obtained the lock
if ((pCspiReg->CONTROLREG & CSP_BITFMASK(CSPI_CONTROLREG_XCH)) == CSPI_CONTROLREG_XCH_IDLE)
return FALSE;
return TRUE;
}
//------------------------------------------------------------------------------
// PRIVATE FUNCTIONS
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//
// FUNCTION: Initialize
//
// DESCRIPTION: This function is used to do some initialization.
// It will only be called once for each cspi set
//
// PARAMETERS:
// None
//
// RETURNS:
// None
//
//------------------------------------------------------------------------------
BOOL CspiClass::Initialize(void)
{
DWORD dwTransferred;
DWORD irq;
HWCLOCK_ID clockId;
GPIO_IOCTL_CFG cfg;
DRV_FUNCTION_ENTRY();
// Enable CSPI module pins and hw clocks
if(Id == CSPI1)
{
GPIO_SET_IOCTL_STRUCT(cfg, CSPI1);
clockId = HWCLOCK_ID_CSPI1;
irq = IRQ_CSPI1;
}
else
{
GPIO_SET_IOCTL_STRUCT(cfg, CSPI2);
clockId = HWCLOCK_ID_CSPI2;
irq = IRQ_CSPI2;
}
if(!KernelIoControl(IOCTL_HAL_ENABLE_GPIO, &cfg, sizeof(cfg), NULL, 0, &dwTransferred))
{
DEBUGMSG(ZONE_ERROR, (TEXT("CspiClass: Failed to configure GPIO pins for CSPI%d.\r\n"), Id+1));
return FALSE;
}
if(!KernelIoControl(IOCTL_HAL_POWER_HW_CLK, &clockId, sizeof(clockId), NULL, 0, &dwTransferred))
{
DEBUGMSG(ZONE_ERROR, (TEXT("CspiClass: Failed to enable clock for CSPI%d.\r\n"), Id+1));
return FALSE;
}
// Request sysintr
if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &irq, sizeof(DWORD),
&CspiSystemInterrupt[Id], sizeof(DWORD), NULL))
{
DEBUGMSG(ZONE_ERROR, (TEXT("CspiClass: Failed to obtain sysintr value.\r\n")));
return FALSE;
}
if(InterruptInitialize(CspiSystemInterrupt[Id], csEvent[Id], NULL, 0) == FALSE)
{
DEBUGMSG(ZONE_ERROR, (TEXT("CspiClass: Failed to initialize interrupt sysintr %d (irq %d).\r\n"),
CspiSystemInterrupt[Id], irq));
return FALSE;
}
// Soft reset CSPI module
INSREG32BF(&pCspiReg->RESET, CSPI_RESET_START, CSPI_RESET_START_SWRESET);
// Wait for reset done.
while(pCspiReg->RESET & CSP_BITFVAL(CSPI_RESET_START, CSPI_RESET_START_SWRESET))
Sleep(0);
DEBUGMSG(ZONE_FUNCTION, (TEXT("Initialize-: csMutex[%d](0x%x)\r\n"), Id, csMutex[Id]));
return TRUE;
}
//------------------------------------------------------------------------------
//
// FUNCTION: CalculateDivRate
//
// DESCRIPTION: This is a private function to calculate the data
// rate divider from input frequency.
//
// PARAMETERS:
// dwFrequency -
// It is the frequency requested.
//
// RETURNS:
// dwDivisor -
// It's the data rate divisor
//------------------------------------------------------------------------------
UINT32 CspiClass::CalculateDivRate(UINT32 dwFrequency)
{
DWORD dwtmpRate; // the actual data rate
DWORD dwDivisor; // the data rate divisor
DEBUGMSG(ZONE_FUNCTION, (TEXT("CalculateDivRate+:dwFrequency(%d)\r\n"), dwFrequency));
dwtmpRate = BSPDrvlibGetPERCLK2() / dwFrequency;
if (dwtmpRate > CSPI_CONTROLREG_DATARATE_DIV_MAX)
dwtmpRate = CSPI_CONTROLREG_DATARATE_DIV_MAX;
else if (dwtmpRate < CSPI_CONTROLREG_DATARATE_DIV_MIN)
dwtmpRate = CSPI_CONTROLREG_DATARATE_DIV_MIN;
if(dwtmpRate == 3) {
dwDivisor = 1;
}
else {
for (dwDivisor=0; dwDivisor <= 0x10; dwDivisor++) {
// For even: 2x2^(n/2), For odd: 3x2^((n-1)/2))
if((dwDivisor%2) == 0) {
if( (DWORD)(2 << ((dwDivisor/2))) >= dwtmpRate)
break;
}
else {
if( (DWORD)(3*(2 << (((dwDivisor-1)/2)-1))) >= dwtmpRate)
break;
}
}
}
DEBUGMSG(ZONE_FUNCTION, (TEXT("CalculateDivRate-:dwDivisor(%d) \r\n"), dwDivisor));
return dwDivisor;
}
//------------------------------------------------------------------------------
//
// FUNCTION: ConfigureSSPins
//
// DESCRIPTION: This function is used to configure required SS pins
// for a CSPI module.
//
// PARAMETERS:
// PortId -
// It is the port id.
// enable -
// Enable pins if TRUE
//
// RETURNS:
// TRUE -
// configuration success
//
// FALSE -
// configure chip select pin fail
// invalid chip select
//
//------------------------------------------------------------------------------
BOOL CspiClass::ConfigureSSPin(CSPISSPORTID_C PortId, BOOL enable)
{
GPIO_IOCTL_CFG cfg;
DWORD dwTransferred;
BOOL status;
DEBUGMSG(ZONE_FUNCTION, (TEXT("ConfigureSSPin+\r\n")));
if(PortId > CSPISSMAX)
return FALSE;
switch(Id)
{
case CSPI1:
switch(PortId)
{
case CSPISS0:
GPIO_SET_IOCTL_STRUCT(cfg, CSPI1_SS0);
break;
case CSPISS1:
GPIO_SET_IOCTL_STRUCT(cfg, CSPI1_SS1);
break;
case CSPISS2:
GPIO_SET_IOCTL_STRUCT(cfg, CSPI1_SS2);
break;
default:
DEBUGMSG(ZONE_ERROR, (TEXT("ConfigureSSPin: should not reach here!\r\n")));
return FALSE;
}
break;
case CSPI2:
switch(PortId)
{
case CSPISS0:
GPIO_SET_IOCTL_STRUCT(cfg, CSPI2_SS0);
break;
case CSPISS1:
GPIO_SET_IOCTL_STRUCT(cfg, CSPI2_SS1);
break;
case CSPISS2:
GPIO_SET_IOCTL_STRUCT(cfg, CSPI2_SS2);
break;
default:
DEBUGMSG(ZONE_ERROR, (TEXT("ConfigureSSPin: should not reach here!\r\n")));
return FALSE;
}
break;
default:
DEBUGMSG(ZONE_ERROR, (TEXT("ConfigureSSPin: should not reach here!\r\n")));
return FALSE;
}
if(enable)
status = KernelIoControl(IOCTL_HAL_ENABLE_GPIO, &cfg, sizeof(cfg), NULL, 0, &dwTransferred);
else
status = KernelIoControl(IOCTL_HAL_DISABLE_GPIO, &cfg, sizeof(cfg), NULL, 0, &dwTransferred);
if(status != TRUE)
DEBUGMSG(ZONE_ERROR, (TEXT("ConfigureSSPin: failed!\r\n")));
else
DEBUGMSG(ZONE_INFO, (TEXT("ConfigureSSPin success!\r\n")));
DEBUGMSG(ZONE_FUNCTION, (TEXT("ConfigureSSPin-\r\n")));
return status;
}
//------------------------------------------------------------------------------
// END OF FILE
//------------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -