📄 cspsocspi.c
字号:
return FALSE;
}
RETAILMSG (DEBUGPRINT, (TEXT("+Spi READ+ Waited hFrmendEvent\r\n") ));
#else //!SPI_INTR
bRet = SPI_POLLING_FRMEND(pDevHdl);
#endif //!SPI_INTR
//Step7 END
RETAILMSG (DEBUGPRINT, (TEXT("+Spi + RX FIFO status:0x%x\r\n"),READ_REGISTER_ULONG(&((((PSPI_SOC_REGS)(pDevHdl->pSpiSocRegs))->v_pSpiSocRegs)->spirxfifostat)) ));
pDevHdl->StatusReg[1] = READ_REGISTER_ULONG(&((((PSPI_SOC_REGS)(pDevHdl->pSpiSocRegs))->v_pSpiSocRegs)->spirxfifostat));
//Step8: getdata (memcpy or read buffer)
if(bRet)
{
//RETAILMSG(1, (TEXT("+Spi SocReadData+ IoMod %d, DataLength %d \r\n"), pDevHdl->SpiDevInfo.IoMod, pDevHdl->SpiDevInfo.DataLength));
if(pDevHdl->SpiDevInfo.IoMod != SPI_INFO_IO_MODE)
{
WRITE_REGISTER_ULONG (&((((PSPI_SOC_REGS)(pDevHdl->pSpiSocRegs))->v_pSpiSocRegs)->spirxmode), SPI_INFO_DMA_RX_FLUSH_MODE);
RETAILMSG (DEBUGPRINT, (TEXT("+Spi + RX FIFO status:0x%x\r\n"),READ_REGISTER_ULONG(&((((PSPI_SOC_REGS)(pDevHdl->pSpiSocRegs))->v_pSpiSocRegs)->spirxfifostat)) ));
//iDMA_DATA_LEN has been set a right value before
memcpy(pMisoBuf, pDevHdl->m_pRawBufR, iDMA_DATA_LEN);
}
else
{
int dNum = 0;
switch (pDevHdl->SpiDevInfo.DataFmt)
{
case SPI_INFO_TRAN_DATA_FORMAT_8BIT:
dNum = 8*(pDevHdl->SpiDevInfo.DataLength+1);
break;
case SPI_INFO_TRAN_DATA_FORMAT_12BIT:
case SPI_INFO_TRAN_DATA_FORMAT_16BIT:
dNum = 16*(pDevHdl->SpiDevInfo.DataLength+1);
break;
case SPI_INFO_TRAN_DATA_FORMAT_32BIT:
dNum = 32*(pDevHdl->SpiDevInfo.DataLength+1);
break;
default:
RETAILMSG(1, (TEXT("+Spi SocWriteData+ WRONG data format: (%d)\r\n"), pDevHdl->SpiDevInfo.DataFmt));
SPI_RELEASEMUTEX(pDevHdl);
bRet = FALSE;
}
//CHECK: read back data from FIFO
do
{
if(dNum >= 32)
{
*((PDWORD)pMisoBuf) = (DWORD)READ_REGISTER_ULONG(&((((PSPI_SOC_REGS)(pDevHdl->pSpiSocRegs))->v_pSpiSocRegs)->spirxfifodata));
++(PDWORD)pMisoBuf;
dNum -= 32;
}
else
{
if(dNum)
{
if(dNum == 16)
{
*((PWORD)pMisoBuf) = (WORD)READ_REGISTER_ULONG(&((((PSPI_SOC_REGS)(pDevHdl->pSpiSocRegs))->v_pSpiSocRegs)->spirxfifodata));
dNum -= 16;
}
else
{
*((PBYTE)pMisoBuf) = (BYTE)READ_REGISTER_ULONG(&((((PSPI_SOC_REGS)(pDevHdl->pSpiSocRegs))->v_pSpiSocRegs)->spirxfifodata));
dNum -= 8;
}
}
}
} while(dNum>0);
}
}
//Step8 END
pDevHdl->StatusReg[2] = READ_REGISTER_ULONG(&((((PSPI_SOC_REGS)(pDevHdl->pSpiSocRegs))->v_pSpiSocRegs)->spirxfifostat));
//Step9: Disable interrupts
WRITE_REGISTER_ULONG(&((((PSPI_SOC_REGS)(pDevHdl->pSpiSocRegs))->v_pSpiSocRegs)->spiinten), 0);
WRITE_REGISTER_ULONG(&((((PSPI_SOC_REGS)(pDevHdl->pSpiSocRegs))->v_pSpiSocRegs)->spitxrxen), 0);
//Step9 END
//SpiDumpReg(pDevHdl);
SPI_RELEASEMUTEX(pDevHdl);
RETAILMSG (DEBUGPRINT,(TEXT("-Spi SocReadData- end port(%d)\r\n"),pDevHdl->uiHwPort ));
return bRet;
}
BOOL SpiSocWriteData(PVOID pSpiHandle, LPVOID pMosiBuf, DWORD uiMosiBufLen, LPVOID pMisoBuf, DWORD uiMisoBufLen)
{
//Do in one Func
PSPI_DEV_HANDLE pDevHdl = (PSPI_DEV_HANDLE)pSpiHandle;
BOOL bRet = TRUE;
int i=0, iDMA_DATA_LEN, iDMA_XLEN;
DWORD dwReg=0;
//RETAILMSG(1, (TEXT("+Spi SocWriteData+ pMosiBuf 0x%x\r\n"), *(PBYTE)pMosiBuf));
RETAILMSG (DEBUGPRINT,(TEXT("+Spi SocWriteData+ entered port(%d)\r\n"), pDevHdl->uiHwPort ));
//Parameter validation
if(pMosiBuf == NULL && pMisoBuf == NULL || !pDevHdl->bSpiOpen)
{
RETAILMSG (1,(TEXT("+Spi SocWriteData+ Parameter Error or spi not open\r\n") ));
return FALSE;
}
if (SPI_INFO_IO_MODE == pDevHdl->SpiDevInfo.IoMod)
{
if(!SPI_ParametCheck(pDevHdl,FIFO_LENGTH))
{
RETAILMSG (1,(TEXT("+Spi SocWriteData+ Parameter Error\r\n") ));
return FALSE;
}
}
else
{
if(!SPI_ParametCheck(pDevHdl,DMA_LENGTH))
{
RETAILMSG (1,(TEXT("+Spi SocWriteData+ Parameter Error\r\n") ));
return FALSE;
}
}
//Step1: Get Dev Info
if(!SPI_GRABMUTEX(pDevHdl))
{
RETAILMSG (1,(TEXT("+Spi SocWriteData+ GRABMUTEX failed\r\n") ));
return FALSE;
}
//Step1 END
//Config CmdByteNum,MulDataMod and whether have command bit for this write operation.
if (SPI_INFO_NO_COMMAND_DATA == pDevHdl->SpiDevInfo.HaveCmdInFrm)
{
dwReg = READ_REGISTER_ULONG(&((((PSPI_SOC_REGS)(pDevHdl->pSpiSocRegs))->v_pSpiSocRegs)->spictrl));
dwReg &= ~(0x1 << 17);
dwReg = dwReg
| pDevHdl->SpiDevInfo.CmdByteNum
| pDevHdl->SpiDevInfo.MulDataMod;
}
else
{
dwReg = READ_REGISTER_ULONG(&((((PSPI_SOC_REGS)(pDevHdl->pSpiSocRegs))->v_pSpiSocRegs)->spictrl));
dwReg |= ((0x1 << 17)
| pDevHdl->SpiDevInfo.CmdByteNum
| pDevHdl->SpiDevInfo.MulDataMod);
}
WRITE_REGISTER_ULONG (&((((PSPI_SOC_REGS)(pDevHdl->pSpiSocRegs))->v_pSpiSocRegs)->spictrl), dwReg);
//Set write data length
WRITE_REGISTER_ULONG (&((((PSPI_SOC_REGS)(pDevHdl->pSpiSocRegs))->v_pSpiSocRegs)->spitxdatalen), pDevHdl->SpiDevInfo.DataLength);
//Step2: clear and enable interrupts
//clear interrupts
WRITE_REGISTER_ULONG (&((((PSPI_SOC_REGS)(pDevHdl->pSpiSocRegs))->v_pSpiSocRegs)->spiintstatus), SPI_INT_MASK_ALL);
// Enable the interrupt
WRITE_REGISTER_ULONG (&((((PSPI_SOC_REGS)(pDevHdl->pSpiSocRegs))->v_pSpiSocRegs)->spiinten), SPI_INT_FRM_END_MASK);
//Step2 END
////Step3: TXFIFO RESET/START for DMA mode -- will do in step6
WRITE_REGISTER_ULONG (&((((PSPI_SOC_REGS)(pDevHdl->pSpiSocRegs))->v_pSpiSocRegs)->spitxfifoop), SPI_FIFO_RESET);
WRITE_REGISTER_ULONG (&((((PSPI_SOC_REGS)(pDevHdl->pSpiSocRegs))->v_pSpiSocRegs)->spitxfifoop), SPI_FIFO_START);
////Step3 END
//Step4: prepare Spicommand if need,
//TODO: always write command by pMosiBuf -- need modify app also
if (SPI_INFO_ONLY_COMMAND_DATA == pDevHdl->SpiDevInfo.HaveCmdInFrm)
{
return SpiWriteCmdOnly(pDevHdl,pMosiBuf);
}
else if (SPI_INFO_HAVE_COMMAND_DATA == pDevHdl->SpiDevInfo.HaveCmdInFrm)
{
switch (pDevHdl->SpiDevInfo.CmdByteNum)
{
case SPI_INFO_CMD_BYTE_NUM_1:
WRITE_REGISTER_ULONG(&((((PSPI_SOC_REGS)(pDevHdl->pSpiSocRegs))->v_pSpiSocRegs)->spicommand), *(PBYTE)pMisoBuf);
break;
case SPI_INFO_CMD_BYTE_NUM_2:
WRITE_REGISTER_ULONG(&((((PSPI_SOC_REGS)(pDevHdl->pSpiSocRegs))->v_pSpiSocRegs)->spicommand), *(PWORD)pMisoBuf);
break;
case SPI_INFO_CMD_BYTE_NUM_3:
WRITE_REGISTER_ULONG(&((((PSPI_SOC_REGS)(pDevHdl->pSpiSocRegs))->v_pSpiSocRegs)->spicommand), *(PDWORD)pMisoBuf & 0xffffff);
break;
case SPI_INFO_CMD_BYTE_NUM_4:
WRITE_REGISTER_ULONG(&((((PSPI_SOC_REGS)(pDevHdl->pSpiSocRegs))->v_pSpiSocRegs)->spicommand), *(PDWORD)pMisoBuf);
break;
default:
RETAILMSG(1, (TEXT("+Spi SocWriteData+ WRONG command byte number: (%d)\r\n"), pDevHdl->SpiDevInfo.CmdByteNum));
bRet = FALSE;
break;
}
}
//Step4 END
//Step5: write txfifo if not command only and not DMA
if (SPI_INFO_IO_MODE == pDevHdl->SpiDevInfo.IoMod)
{
int dNum = 0;
switch (pDevHdl->SpiDevInfo.DataFmt)
{
case SPI_INFO_TRAN_DATA_FORMAT_8BIT:
dNum = pDevHdl->SpiDevInfo.DataLength+1;
break;
case SPI_INFO_TRAN_DATA_FORMAT_12BIT:
case SPI_INFO_TRAN_DATA_FORMAT_16BIT:
dNum = 2*(pDevHdl->SpiDevInfo.DataLength+1);
break;
case SPI_INFO_TRAN_DATA_FORMAT_32BIT:
dNum = 4*(pDevHdl->SpiDevInfo.DataLength+1);
break;
default:
RETAILMSG(1, (TEXT("+Spi SocWriteData+ WRONG data format: (%d)\r\n"), pDevHdl->SpiDevInfo.DataFmt));
bRet = FALSE;
break;
}
//CHECK: write one DWORD into fifo
do {
WRITE_REGISTER_ULONG(&((((PSPI_SOC_REGS)(pDevHdl->pSpiSocRegs))->v_pSpiSocRegs)->spitxfifodata), *((PDWORD)pMosiBuf));
++(PDWORD)pMosiBuf;
dNum -= 4;
//RETAILMSG(1, (TEXT("+Spi SocWriteData+ do writing pMosiBuf 0x%x\r\n"), *(PBYTE)pMosiBuf));
} while(dNum>0);
}
//Step5 END
//Step6: Is DMA Mode
else
{
//get parameter and prepare data
pDevHdl->m_pRawBufW = (BYTE *)(pDevHdl->dwVirtAddrW); //pointer to read memory
if (NULL == pDevHdl->m_pRawBufW)
{
RETAILMSG(1, (TEXT("+Spi SocWriteData+ m_pRawBufW is NULL.\r\n")));
SPI_RELEASEMUTEX(pDevHdl);
return FALSE;
}
iDMA_DATA_LEN = pDevHdl->SpiDevInfo.DataLength+1;
switch (pDevHdl->SpiDevInfo.DataFmt)
{
case SPI_INFO_TRAN_DATA_FORMAT_8BIT:
break;
case SPI_INFO_TRAN_DATA_FORMAT_12BIT:
case SPI_INFO_TRAN_DATA_FORMAT_16BIT:
iDMA_DATA_LEN = 2*iDMA_DATA_LEN;
break;
case SPI_INFO_TRAN_DATA_FORMAT_32BIT:
iDMA_DATA_LEN = 4*iDMA_DATA_LEN;
break;
default:
RETAILMSG(1, (TEXT("+Spi SocWriteData+ WRONG data format: (%d)\r\n"), pDevHdl->SpiDevInfo.DataFmt));
bRet = FALSE;
break;
}
//copy data to DMA buffer
memcpy(pDevHdl->m_pRawBufW, pMosiBuf, iDMA_DATA_LEN);
// configure DMA
iDMA_XLEN = (iDMA_DATA_LEN>>2)+((iDMA_DATA_LEN%4==0)?0:1); //count what? byte->word?
switch (pDevHdl->uiHwPort)
{
case SEPARATE_SPI0:
WRITE_BITFIELD(struct RSCDmaMuxBits, &((v_pRscRegs)->rscDmaMux), ch13, 1); //SPI set to 1
v_pDMAReg->dmaWidth[USP_TRS_DMA_WIDTH_ID] = iDMA_XLEN; //for 2D-DMA, it should be greater than or equal to xlReg
//for 1D-DMA, it no special requirement
WRITE_REGISTER_ULONG(&(v_pDMAReg->dmaChn[13].xlReg), iDMA_XLEN);
WRITE_REGISTER_ULONG(&(v_pDMAReg->dmaChn[13].ylReg), 0); //ylReg = 0, means 1D-DMA
RETAILMSG (0, (TEXT("+Spi SocWriteData+ v_pDMAReg->dmaWidth[USP_TRS_DMA_WIDTH_ID] (0x%x)\r\n"), v_pDMAReg->dmaWidth[USP_TRS_DMA_WIDTH_ID]));
WRITE_BITFIELD(struct dmaCtrlBits, &((v_pDMAReg)->dmaChn[13].ctrlReg), ws, USP_TRS_DMA_WIDTH_ID);
WRITE_BITFIELD(struct dmaCtrlBits, &((v_pDMAReg)->dmaChn[13].ctrlReg), dir, 1); //from sdram
WRITE_BITFIELD(struct dmaCtrlBits, &((v_pDMAReg)->dmaChn[13].ctrlReg), burst, 0); //no burst
//Enable DMA
WRITE_REGISTER_ULONG(&((v_pDMAReg)->dmaChn[13].addrReg), (DWORD)((pDevHdl->dwPhyAddrW)/4));
break;
case SEPARATE_SPI1:
WRITE_BITFIELD(struct RSCDmaMuxBits, &((v_pRscRegs)->rscDmaMux), ch15, 1); //SPI set to 1
WRITE_REGISTER_ULONG(&(v_pDMAReg->dmaChn[15].xlReg), iDMA_XLEN);
WRITE_REGISTER_ULONG(&(v_pDMAReg->dmaChn[15].ylReg), 0); //ylReg = 0, means 1D-DMA
WRITE_BITFIELD(struct dmaCtrlBits, &((v_pDMAReg)->dmaChn[15].ctrlReg), ws, USP_TRS_DMA_WIDTH_ID);
WRITE_BITFIELD(struct dmaCtrlBits, &((v_pDMAReg)->dmaChn[15].ctrlReg), dir, 1);
WRITE_BITFIELD(struct dmaCtrlBits, &((v_pDMAReg)->dmaChn[15].ctrlReg), burst, 0);
//Enable DMA
WRITE_REGISTER_ULONG(&((v_pDMAReg)->dmaChn[15].addrReg), (DWORD)((pDevHdl->dwPhyAddrW)/4));
break;
default:
RETAILMSG (1, (TEXT("+Spi SocWriteData+ WRONG spi port num. (%d)\r\n"), pDevHdl->uiHwPort));
bRet = FALSE;
break;
}
}
//Step6 END
//Step7: TX_EN
WRITE_REGISTER_ULONG(&((((PSPI_SOC_REGS)(pDevHdl->pSpiSocRegs))->v_pSpiSocRegs)->spitxrxen), SPI_TX_EN);
//Step7 END
#if SPI_INTR
RETAILMSG (DEBUGPRINT, (TEXT("+Spi Write+ Waiting hFrmendEvent\r\n") ));
switch (pDevHdl->uiHwPort)
{
case SEPARATE_SPI0:
WaitForSingleObject((HANDLE)v_pDriverGlobals->misc.spiDev[0].hFrmendEvent, INFINITE);
break;
case SEPARATE_SPI1:
WaitForSingleObject((HANDLE)v_pDriverGlobals->misc.spiDev[1].hFrmendEvent, INFINITE);
break;
default:
RETAILMSG (1, (TEXT("+Spi + WRONG spi port num. (%d)\r\n"), pDevHdl->uiHwPort));
SPI_RELEASEMUTEX(pDevHdl);
return FALSE;
}
RETAILMSG (DEBUGPRINT, (TEXT("+Spi Write+ Waited hFrmendEvent\r\n") ));
#else //!SPI_INTR
bRet = SPI_POLLING_FRMEND(pDevHdl);
#endif //!SPI_INTR
//Step8 END
//Step9: Disable interrupts
WRITE_REGISTER_ULONG(&((((PSPI_SOC_REGS)(pDevHdl->pSpiSocRegs))->v_pSpiSocRegs)->spiinten), 0);
WRITE_REGISTER_ULONG(&((((PSPI_SOC_REGS)(pDevHdl->pSpiSocRegs))->v_pSpiSocRegs)->spitxrxen), 0);
//Step9 END
SPI_RELEASEMUTEX(pDevHdl);
RETAILMSG (DEBUGPRINT,(TEXT("-Spi SocWriteData- end port(%d)\r\n"), pDevHdl->uiHwPort ));
return bRet;
}
static void DumpSPIDevInfo(PVOID pSpiHandle)
{
PSPI_DEV_HANDLE pDevHdl = (PSPI_DEV_HANDLE)pSpiHandle;
RETAILMSG(1, (TEXT("++++++++++++++++++++++++++++++++++++\r\n") ));
RETAILMSG(1, (TEXT("+Dump SPIDevInfo+ Start:\r\n") ));
//RETAILMSG(1, (TEXT(" ClkDiv 0x%x\r\n"), pDevHdl->SpiDevInfo.ClkDiv));
RETAILMSG(1, (TEXT(" dwSPIFreq 0x%x\r\n"), pDevHdl->SpiDevInfo.dwSPIFreq));
RETAILMSG(1, (TEXT(" SlaveMod 0x%x\r\n"), pDevHdl->SpiDevInfo.SlaveMod));
RETAILMSG(1, (TEXT(" HaveCmdInFrm 0x%x\r\n"), pDevHdl->SpiDevInfo.HaveCmdInFrm));
RETAILMSG(1, (TEXT(" CsIoOutHigh 0x%x\r\n"), pDevHdl->SpiDevInfo.CsIoOutHigh));
RETAILMSG(1, (TEXT(" CsIoCtlMod 0x%x\r\n"), pDevHdl->SpiDevInfo.CsIoCtlMod));
RETAILMSG(1, (TEXT(" ClkIdleStatHigh 0x%x\r\n"), pDevHdl->SpiDevInfo.ClkIdleStatHigh));
RETAILMSG(1, (TEXT(" CsIdleStatHigh 0x%x\r\n"), pDevHdl->SpiDevInfo.CsIdleStatHigh));
RETAILMSG(1, (TEXT(" TransModeMsb 0x%x\r\n"), pDevHdl->SpiDevInfo.TransModeMsb));
RETAILMSG(1, (TEXT(" DrvRsingEdge 0x%x\r\n"), pDevHdl->SpiDevInfo.DrvRsingEdge));
RETAILMSG(1, (TEXT(" CsHold2Clk 0x%x\r\n"), pDevHdl->SpiDevInfo.CsHold2Clk));
RETAILMSG(1, (TEXT(" Clk3SampleFilterGlitch 0x%x\r\n"), pDevHdl->SpiDevInfo.Clk3SampleFilterGlitch));
RETAILMSG(1, (TEXT(" DataFmt 0x%x\r\n"), pDevHdl->SpiDevInfo.DataFmt));
RETAILMSG(1, (TEXT(" CmdByteNum 0x%x\r\n"), pDevHdl->SpiDevInfo.CmdByteNum));
RETAILMSG(1, (TEXT(" AutoClearTXEn 0x%x\r\n"), pDevHdl->SpiDevInfo.AutoClearTXEn));
RETAILMSG(1, (TEXT(" MulDataMod 0x%x\r\n"), pDevHdl->SpiDevInfo.MulDataMod));
RETAILMSG(1, (TEXT(" IoMod 0x%x\r\n"), pDevHdl->SpiDevInfo.IoMod));
RETAILMSG(1, (TEXT(" DataLength 0x%x\r\n"), pDevHdl->SpiDevInfo.DataLength));
RETAILMSG(1, (TEXT("+Dump SPIDevInfo+ End\r\n") ));
RETAILMSG(1, (TEXT("++++++++++++++++++++++++++++++++++++\r\n") ));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -