⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cspsocspi.c

📁 WINCE 架构下SPI驱动源码
💻 C
📖 第 1 页 / 共 4 页
字号:
			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 + -