📄 cspsocspi.c
字号:
if((HANDLE)v_pDriverGlobals->misc.spiDev[1].hFrmendEvent)
CloseHandle((HANDLE)v_pDriverGlobals->misc.spiDev[1].hFrmendEvent);
if((HANDLE)v_pDriverGlobals->misc.spiDev[1].hSPIEvent)
CloseHandle((HANDLE)v_pDriverGlobals->misc.spiDev[1].hSPIEvent);
InterruptDisable(g_oalSysInfo.spiInfo[1].dwSysIntr);
break;
default:
RETAILMSG (1, (TEXT("+SPI StopDispatchThread+ WRONG spi port num. (%d)\r\n"), pDevHdl->uiHwPort));
return FALSE;
}
return TRUE;
}
#endif //SPI_INTR
//////////////////////////////////////////////////////////////////////////
BOOL SpiSocInit(PVOID pSpiHandle)
{
BOOL bRet = TRUE;
PSPI_DEV_HANDLE pDevHdl = (PSPI_DEV_HANDLE)pSpiHandle;
//check inited or not
switch (pDevHdl->uiHwPort)
{
case SEPARATE_SPI0:
if (!v_pDriverGlobals->misc.spiDev[0].bSpiInited)
{
if(NULL == pDevHdl->v_hSpiMutex)
{
RETAILMSG(DEBUGPRINT, (TEXT("CreateMutex SPI0_MUTEX_NAME\r\n")));
pDevHdl->v_hSpiMutex=CreateMutex(NULL,FALSE,SPI0_MUTEX_NAME);
}
// Reset SPI0 interface - bit17
WRITE_BITFIELD(struct ResetSWRBits, &(v_pRstRegs->resetswrReg), spi0, 1); //PR2X0A_RST.h -- confirmed -- riverlj 06/03/06
usWait (1);
WRITE_BITFIELD(struct ResetSWRBits, &(v_pRstRegs->resetswrReg), spi0, 0); //PR2X0A_RST.h -- confirmed -- riverlj 06/03/06
usWait (1);
// SPI pin mux;
PadEnableSpi0();
pDevHdl->pSpiSocRegs = (PVOID)&g_spi0_soc_regs;
((PSPI_SOC_REGS)(pDevHdl->pSpiSocRegs))->v_pSpiSocRegs = (volatile struct SpiReg *)v_pSpi0Regs;
v_pDriverGlobals->misc.spiDev[0].bSpiInited = TRUE;
}
else
{
RETAILMSG(1, (TEXT("Spi Init Error Port(0) has been initialized\r\n")));
return FALSE;
}
break;
case SEPARATE_SPI1:
if (!v_pDriverGlobals->misc.spiDev[1].bSpiInited)
{
if(NULL == pDevHdl->v_hSpiMutex)
{
RETAILMSG(DEBUGPRINT, (TEXT("CreateMutex SPI1_MUTEX_NAME\r\n")));
pDevHdl->v_hSpiMutex=CreateMutex(NULL,FALSE,SPI1_MUTEX_NAME);
}
// Reset SPI0 interface - bit17
WRITE_BITFIELD(struct ResetSWRBits, &(v_pRstRegs->resetswrReg), spi1, 1); //PR2X0A_RST.h -- confirmed -- riverlj 06/03/06
usWait (1);
WRITE_BITFIELD(struct ResetSWRBits, &(v_pRstRegs->resetswrReg), spi1, 0); //PR2X0A_RST.h -- confirmed -- riverlj 06/03/06
usWait (1);
WRITE_BITFIELD (struct RSCPinMuxBits, &(v_pRscRegs->rscPinMux), spi1, 1);// spi1 enable, muxed, xh add
// SPI pin mux;
PadEnableSpi1();
pDevHdl->pSpiSocRegs = (PVOID)&g_spi1_soc_regs;
((PSPI_SOC_REGS)(pDevHdl->pSpiSocRegs))->v_pSpiSocRegs = (volatile struct SpiReg *)v_pSpi1Regs;
v_pDriverGlobals->misc.spiDev[1].bSpiInited = TRUE;
}
else
{
RETAILMSG(1, (TEXT("Spi Init Error Port(0) has been initialized\r\n")));
return FALSE;
}
break;
default:
RETAILMSG (1, (TEXT("+Spi SocInit+ WRONG spi port num. (%d)\r\n"), pDevHdl->uiHwPort));
return FALSE;
}
//add by riverlj for DMA -- 06/04/26
pDevHdl->dwSizeR = DMA_LENGTH; //32k byte mem for dma read
pDevHdl->dwVirtAddrR = (DWORD) AllocPhysMem ( pDevHdl->dwSizeR,
PAGE_READWRITE | PAGE_NOCACHE,
0xffff, //64k Byte Alignment
0,
&(pDevHdl->dwPhyAddrR) );
if (NULL == (LPVOID)pDevHdl->dwVirtAddrR )
{
RETAILMSG(1, (TEXT("+Spi SocInit+ failed! dwVirtAddrR is NULL.\r\n")));
return FALSE;
}
pDevHdl->dwSizeW = DMA_LENGTH; //32k byte mem for dma write
pDevHdl->dwVirtAddrW = (DWORD) AllocPhysMem ( pDevHdl->dwSizeW,
PAGE_READWRITE | PAGE_NOCACHE,
0xffff, //64k Byte Alignment
0,
&(pDevHdl->dwPhyAddrW) );
if (NULL == (LPVOID)pDevHdl->dwVirtAddrW )
{
RETAILMSG(1, (TEXT("+Spi SocInit+ failed! dwVirtAddrW is NULL.\r\n")));
return FALSE;
}
//endof
#if SPI_INTR
if (v_pDriverGlobals->misc.spiDev[0].bSpiInited || v_pDriverGlobals->misc.spiDev[1].bSpiInited)
{
if(!KernelIoControl(IOCTL_HAL_GET_OALSYSINFO,
NULL,
0,
&g_oalSysInfo,
sizeof(OALSYSINFO),
NULL))
{
RETAILMSG(1, (TEXT("+Spi SocInit+ GET OALSYSINFO ERROR!\r\n")));
return FALSE;
}
// init interrupt part, must be only single time
if (!StartDispatchThread(pDevHdl))
{
// Failed on InterruptInitialize or CreateThread.
RETAILMSG(1, (TEXT("+Spi SocInit+ fail to StartDispatchThread!\r\n")));
SetLastError(ERROR_OPEN_FAILED);
return FALSE;
}
}
#endif //SPI_INTR
pDevHdl->bSpiOpen = FALSE;
return bRet;
}
BOOL SpiSocOpen(PVOID pSpiHandle)
{
PSPI_DEV_HANDLE pDevHdl = (PSPI_DEV_HANDLE)pSpiHandle;
BOOL bRet = TRUE;
SYSTEMCLOCKINFO systemClocks;
DWORD dwSysIoClock;
INT SPI_CLK_DIVISOR;
INT txfifo_ctrl,rxfifo_ctrl;
INT tmp;
//DumpSPIDevInfo(pDevHdl);
RETAILMSG (DEBUGPRINT, (TEXT("+Spi SocOpen Port(%d)\r\n"), pDevHdl->uiHwPort));
if(!SPI_GRABMUTEX(pDevHdl))
{
RETAILMSG (1, (TEXT("+SpiSocOpen+ GRABMUTEX failed!\r\n") ));
return FALSE;
}
switch (pDevHdl->uiHwPort)
{
case SEPARATE_SPI0:
if(!v_pDriverGlobals->misc.spiDev[0].bSpiOpened)
{
WRITE_BITFIELD(struct pwrclkenable, &(v_pPowerRegs->pmr_clkenable), io, 1);
WRITE_BITFIELD(struct pwrclkenable, &(v_pPowerRegs->pmr_clkenable), spi0, 1);
v_pDriverGlobals->misc.spiDev[0].bSpiOpened = TRUE;
}
else
{
RETAILMSG (1, (TEXT(" Port(0) has been opened\r\n")));
SPI_RELEASEMUTEX(pDevHdl);
return FALSE;
}
break;
case SEPARATE_SPI1:
if(!v_pDriverGlobals->misc.spiDev[1].bSpiOpened)
{
WRITE_BITFIELD(struct pwrclkenable, &(v_pPowerRegs->pmr_clkenable), io, 1);
WRITE_BITFIELD(struct pwrclkenable, &(v_pPowerRegs->pmr_clkenable), spi1, 1);
v_pDriverGlobals->misc.spiDev[1].bSpiOpened = TRUE;
}
else
{
RETAILMSG (1, (TEXT(" Port(1) has been opened\r\n")));
SPI_RELEASEMUTEX(pDevHdl);
return FALSE;
}
break;
default:
RETAILMSG (1, (TEXT("+SpiSocOpen+ WRONG spi port num. (%d)\r\n"), pDevHdl->uiHwPort));
bRet = FALSE;
break;
}
if (pDevHdl->SpiDevInfo.IoMod != SPI_INFO_IO_MODE)
{
WRITE_BITFIELD(struct pwrclkenable, &(v_pPowerRegs->pmr_clkenable), dma, 1);
}
//*************Config SPI according SpiDevInfo *****************//
//step 1: calculate clock divisor
//SPI_CLK_DIVISOR = pDevHdl->SpiDevInfo.ClkDiv; //TODO: calc div base freq?
//get io clk
if (!KernelIoControl(IOCTL_HAL_GET_SYS_CLOCK_INFO,
NULL,
0,
&systemClocks,
sizeof(SYSTEMCLOCKINFO),
NULL))
{
RETAILMSG(1,(L"+Spi SocOpen+ failed! Cannot get system clock info.\r\n"));
SPI_CLK_DIVISOR = 150; //Set Default Value
}
else
{
dwSysIoClock = systemClocks.dwIoClock;
//RETAILMSG(1,(TEXT("system clk=%d\r\n"),dwSysIoClock));
SPI_CLK_DIVISOR = dwSysIoClock/(pDevHdl->SpiDevInfo.dwSPIFreq*2)-1; //Set the working freq
if (0 == SPI_CLK_DIVISOR)
{
SPI_CLK_DIVISOR = 0x01;
}
}
//RETAILMSG(DEBUGPRINT,(TEXT("SPI_CLK_DIVISOR=0x%x\r\n"),SPI_CLK_DIVISOR));
//step 2: config SPI Control register (SPI_CTRL)
if (SPI_INFO_ONLY_COMMAND_DATA == pDevHdl->SpiDevInfo.HaveCmdInFrm)
{
tmp = SPI_CLK_DIVISOR //iWorkingFreqKhz --> SPI_CLK_DIVISOR
| pDevHdl->SpiDevInfo.SlaveMod
| (0x1 << 17)
| pDevHdl->SpiDevInfo.CsIoOutHigh
| pDevHdl->SpiDevInfo.CsIoCtlMod
| pDevHdl->SpiDevInfo.ClkIdleStatHigh
| pDevHdl->SpiDevInfo.CsIdleStatHigh
| pDevHdl->SpiDevInfo.TransModeMsb
| pDevHdl->SpiDevInfo.DrvRsingEdge
| pDevHdl->SpiDevInfo.CsHold2Clk
| pDevHdl->SpiDevInfo.Clk3SampleFilterGlitch
| pDevHdl->SpiDevInfo.DataFmt
| pDevHdl->SpiDevInfo.CmdByteNum
| pDevHdl->SpiDevInfo.AutoClearTXEn
| pDevHdl->SpiDevInfo.MulDataMod;
}
else
{
tmp = SPI_CLK_DIVISOR //iWorkingFreqKhz --> SPI_CLK_DIVISOR
| pDevHdl->SpiDevInfo.SlaveMod
| pDevHdl->SpiDevInfo.HaveCmdInFrm
| pDevHdl->SpiDevInfo.CsIoOutHigh
| pDevHdl->SpiDevInfo.CsIoCtlMod
| pDevHdl->SpiDevInfo.ClkIdleStatHigh
| pDevHdl->SpiDevInfo.CsIdleStatHigh
| pDevHdl->SpiDevInfo.TransModeMsb
| pDevHdl->SpiDevInfo.DrvRsingEdge
| pDevHdl->SpiDevInfo.CsHold2Clk
| pDevHdl->SpiDevInfo.Clk3SampleFilterGlitch
| pDevHdl->SpiDevInfo.DataFmt
| pDevHdl->SpiDevInfo.CmdByteNum
| pDevHdl->SpiDevInfo.AutoClearTXEn
| pDevHdl->SpiDevInfo.MulDataMod;
}
WRITE_REGISTER_ULONG (&((((PSPI_SOC_REGS)(pDevHdl->pSpiSocRegs))->v_pSpiSocRegs)->spictrl), tmp);
//step 3: io or dma mode
WRITE_REGISTER_ULONG (&((((PSPI_SOC_REGS)(pDevHdl->pSpiSocRegs))->v_pSpiSocRegs)->spitxmode), pDevHdl->SpiDevInfo.IoMod);
WRITE_REGISTER_ULONG (&((((PSPI_SOC_REGS)(pDevHdl->pSpiSocRegs))->v_pSpiSocRegs)->spirxmode), pDevHdl->SpiDevInfo.IoMod);
// Initialize FIFO level check registers
WRITE_REGISTER_ULONG(&((((PSPI_SOC_REGS)(pDevHdl->pSpiSocRegs))->v_pSpiSocRegs)->spitxfifolevel), (0x06 | (0x04 << 10) | (0x02 << 20)) );
WRITE_REGISTER_ULONG(&((((PSPI_SOC_REGS)(pDevHdl->pSpiSocRegs))->v_pSpiSocRegs)->spirxfifolevel), (0x02 | (0x04 << 10) | (0x06 << 20)) );
// Set FIFO threshold and FIFO WIDTH
//for IO mode with cmd -- fifo_ctrl -- TODO CHECK
//if ((SPI_INFO_IO_MODE == pDevHdl->SpiDevInfo.IoMod) && (SPI_INFO_HAVE_COMMAND_DATA == pDevHdl->SpiDevInfo.HaveCmdInFrm))
if (SPI_INFO_IO_MODE == pDevHdl->SpiDevInfo.IoMod)
{
txfifo_ctrl = (0x08 << 2) | 0x2;
rxfifo_ctrl = (0x18 << 2) | 0x2;
}
else
{
switch (pDevHdl->SpiDevInfo.DataFmt)
{
case SPI_INFO_TRAN_DATA_FORMAT_8BIT:
txfifo_ctrl = (0x08 << 2) & 0x7c;
rxfifo_ctrl = (0x18 << 2) & 0x7c;
break;
case SPI_INFO_TRAN_DATA_FORMAT_12BIT:
case SPI_INFO_TRAN_DATA_FORMAT_16BIT:
txfifo_ctrl = (0x08 << 2) | 0x1;
rxfifo_ctrl = (0x18 << 2) | 0x1;
break;
case SPI_INFO_TRAN_DATA_FORMAT_32BIT:
txfifo_ctrl = (0x08 << 2) | 0x2;
rxfifo_ctrl = (0x18 << 2) | 0x2;
break;
default:
RETAILMSG (1,(TEXT("+Spi SocOpen+ Data Frame Error\r\n")));
bRet = FALSE;
break;
}
}
WRITE_REGISTER_ULONG(&((((PSPI_SOC_REGS)(pDevHdl->pSpiSocRegs))->v_pSpiSocRegs)->spitxfifoctrl), txfifo_ctrl);
WRITE_REGISTER_ULONG(&((((PSPI_SOC_REGS)(pDevHdl->pSpiSocRegs))->v_pSpiSocRegs)->spirxfifoctrl), rxfifo_ctrl);
//********************* end of config ****************************//
// FIFO Reset
WRITE_REGISTER_ULONG (&((((PSPI_SOC_REGS)(pDevHdl->pSpiSocRegs))->v_pSpiSocRegs)->spitxfifoop), SPI_FIFO_RESET);
WRITE_REGISTER_ULONG (&((((PSPI_SOC_REGS)(pDevHdl->pSpiSocRegs))->v_pSpiSocRegs)->spirxfifoop), SPI_FIFO_RESET);
// FIFO start
WRITE_REGISTER_ULONG (&((((PSPI_SOC_REGS)(pDevHdl->pSpiSocRegs))->v_pSpiSocRegs)->spitxfifoop), SPI_FIFO_START);
WRITE_REGISTER_ULONG (&((((PSPI_SOC_REGS)(pDevHdl->pSpiSocRegs))->v_pSpiSocRegs)->spirxfifoop), SPI_FIFO_START);
// Disable inturrpts
WRITE_REGISTER_ULONG (&((((PSPI_SOC_REGS)(pDevHdl->pSpiSocRegs))->v_pSpiSocRegs)->spiinten), 0);
// Clear All Interrupt Status
WRITE_REGISTER_ULONG (&((((PSPI_SOC_REGS)(pDevHdl->pSpiSocRegs))->v_pSpiSocRegs)->spiintstatus), SPI_INT_MASK_ALL);
WRITE_BITFIELD(struct pendingBits, &v_pIntRegs->riscmask, spi0, 1);
WRITE_BITFIELD(struct pendingBits, &v_pIntRegs->riscmask, spi1, 1);
switch (pDevHdl->uiHwPort)
{
case SEPARATE_SPI0:
if ( pDevHdl->SpiDevInfo.IoMod != SPI_INFO_IO_MODE )
{
WRITE_BITFIELD(struct dmaIntEnBits, &v_pDMAReg->intEnable, chn12, 0);
WRITE_BITFIELD(struct dmaIntEnBits, &v_pDMAReg->intStatus, chn12, 1);
WRITE_BITFIELD(struct dmaIntEnBits, &v_pDMAReg->intEnable, chn13, 0);
WRITE_BITFIELD(struct dmaIntEnBits, &v_pDMAReg->intStatus, chn13, 1);
v_pDriverGlobals->sharedrc.dmaStatus &= ~0x3000;
}
break;
case SEPARATE_SPI1:
if ( pDevHdl->SpiDevInfo.IoMod != SPI_INFO_IO_MODE )
{
WRITE_BITFIELD(struct dmaIntEnBits, &v_pDMAReg->intEnable, chn14, 0);
WRITE_BITFIELD(struct dmaIntEnBits, &v_pDMAReg->intStatus, chn14, 1);
WRITE_BITFIELD(struct dmaIntEnBits, &v_pDMAReg->intEnable, chn15, 0);
WRITE_BITFIELD(struct dmaIntEnBits, &v_pDMAReg->intStatus, chn15, 1);
v_pDriverGlobals->sharedrc.dmaStatus &= ~0xc000;
}
break;
default:
RETAILMSG (1,(TEXT("+Spi SocOpen+ WRONG spi port num. (%d)\r\n"), pDevHdl->uiHwPort));
bRet = FALSE;
break;
}
pDevHdl->bSpiOpen = TRUE;
SPI_RELEASEMUTEX(pDevHdl);
RETAILMSG (DEBUGPRINT, (TEXT("-Spi SocOpen Port(%d)\r\n"), pDevHdl->uiHwPort));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -