//-------------------------------------------------------------------------------------------------------------------------// Copyright (c) Samsung Electronics Co., Ltd. All rights reserved.//-------------------------------------------------------------------------------------------------------------------------//// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,// INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.//// Module Name : SPI.C//// Abstract : SPI Interface Routines for Samsung S5PV210 CPU//// Environment : Samsung S5PV210 / WincCE6.0//// 2010/02/10 asdf Added Full duplex mode (Ver 1.01)// Define SPI_FULL_DUPLEX in sources file to use full duplex// 2009/07/10 asdf Modified for supporting multi-channel////-------------------------------------------------------------------------------------------------------------------------/***************************************************************************** * Includes *****************************************************************************/ #include <windows.h>#include <nkintr.h>#include <ceddk.h> #include <memory.h>#include <types.h>#include <ddkreg.h>#include <bsp.h>#include <oal_intr.h>#include <drvmsg.h>#include <dma_controller.h>#include <spi_reg.h>#include "spi_priv.h"#include <pmplatform.h>#ifdef SPI_COMM_STREAM_IF//#include <serpriv.h>#endif /***************************************************************************** * Definitions *****************************************************************************/ //#define SLAVE_READY 0//#define TEST_MODE// MSG#define SPI_MSG SPI_USR1#define SPI_INIT SPI_INFO#define SPI_DEBUGSPI_DBG#define VERSION_INFO"SPI"#define DateInformation"1.03"#define SPI_CLOCKMPLL_CLOCK //EPLL_CLOCK//MPLL_CLOCK#define CLKSEL (0x1 << 9) //SCLK/***************************************************************************** * Functions *****************************************************************************/ DWORD HW_Init(PSPI_PUBLIC_CONTEXT pPublicSpi);DWORD ThreadForTx(PSPI_PUBLIC_CONTEXT pPublicSpi);DWORD ThreadForRx(PSPI_PUBLIC_CONTEXT pPublicSpi);DWORD ThreadForSpi(PSPI_PUBLIC_CONTEXT pPublicSpi);#ifdef SPI_EX_GPIO_CALLBACKextern BOOL HSPCALLBACK_SetSlaveReady(PSPI_PRIVATE_CONTEXT pSpiPrivate); // SLAVE SIDEextern BOOL HSPCALLBACK_ClrSlaveReady(PSPI_PRIVATE_CONTEXT pSpiPrivate);extern BOOL HSPCALLBACK_GetSlaveReady(PSPI_PRIVATE_CONTEXT pSpiPrivate);extern BOOL HSPCALLBACK_Init(PSPI_PRIVATE_CONTEXT pSpiPrivate);extern BOOL HSPCALLBACK_Deinit(PSPI_PRIVATE_CONTEXT pSpiPrivate);#endif #ifdef SPI_FULL_DUPLEXBOOL SPI_FullDuplex(PSPI_PRIVATE_CONTEXT pSpiPrivate, PBYTE pRxBuf, PBYTE pTxBuf, DWORD dwCount);#endif void SPI_SFR_DUMP(PSPI_PUBLIC_CONTEXT pPublicSpi){#if 0 volatile SPI_REG *pSPIregs = pPublicSpi->pSPIregs; DBGMSG(SPI_INFO,(TEXT("**** SPI SFR CH%d*****\r\n"), pPublicSpi->chnum)); DBGMSG(SPI_INFO,(TEXT(" CH_CFG : 0x%x \r\n"), pSPIregs->CH_CFG)); DBGMSG(SPI_INFO,(TEXT(" CLK_CFG : 0x%x \r\n"), pSPIregs->CLK_CFG)); DBGMSG(SPI_INFO,(TEXT(" MODE_CFG : 0x%x \r\n"), pSPIregs->MODE_CFG)); DBGMSG(SPI_INFO,(TEXT(" SPI_INT_EN : 0x%x \r\n"), pSPIregs->SPI_INT_EN)); DBGMSG(SPI_INFO,(TEXT(" STATUS : 0x%x \r\n"), pSPIregs->SPI_STATUS)); DBGMSG(SPI_INFO,(TEXT(" FB CLK DELAY : 0x%x \r\n"), pSPIregs->FB_CLK_SEL));#endif }BOOLDllEntry(HINSTANCE hinstDll,DWORD dwReason,LPVOID lpReserved){if ( dwReason == DLL_PROCESS_ATTACH ){DBGMSG (SPI_DEBUG, (TEXT("[SPI] Process Attach\r\n")));}if ( dwReason == DLL_PROCESS_DETACH ){DBGMSG (SPI_DEBUG, (TEXT("[SPI] Process Detach\r\n")));}return(TRUE);}DWORDHW_Init(PSPI_PUBLIC_CONTEXT pPublicSpi ){BOOL bResult = TRUE;PHYSICAL_ADDRESS ioPhysicalBase = {0, 0};if ( !pPublicSpi ){bResult = FALSE;goto CleanUp;}// GPIO Virtual allocioPhysicalBase.LowPart = BASE_REG_PA_GPIO;pPublicSpi->pGPIOregs = (PGPIO_REG)MmMapIoSpace(ioPhysicalBase, sizeof(GPIO_REG), FALSE);if (pPublicSpi->pGPIOregs == NULL){ERRMSG((TEXT("[SPI] For pGPIOregs: MmMapIoSpace failed!\r\n")));bResult = FALSE;goto CleanUp;}// Syscon Virtual allocioPhysicalBase.LowPart = BASE_REG_PA_CMU_CLK;pPublicSpi->pSYSCONregs = (PCMU_CLK_REG)MmMapIoSpace(ioPhysicalBase, sizeof(CMU_CLK_REG), FALSE);if (pPublicSpi->pSYSCONregs == NULL){ERRMSG((TEXT("[SPI] For pSYSCONregs: MmMapIoSpace failed!\r\n")));bResult = FALSE;goto CleanUp;}// MDMAC Virtual allocioPhysicalBase.LowPart = BASE_REG_PA_MDMA;pPublicSpi->pDMACregs = (PDMAC_REG)MmMapIoSpace(ioPhysicalBase, sizeof(DMAC_REG), FALSE);if (pPublicSpi->pDMACregs == NULL){ERRMSG((TEXT("[SPI] For pDMACregs: MmMapIoSpace failed!\r\n")));bResult = FALSE;goto CleanUp;}// DMAC0 Virtual allocioPhysicalBase.LowPart = BASE_REG_PA_PDMA0;pPublicSpi->pDMAC0regs = (PDMAC_REG)MmMapIoSpace(ioPhysicalBase, sizeof(DMAC_REG), FALSE);if (pPublicSpi->pDMAC0regs == NULL){ERRMSG((TEXT("[SPI] For pDMAC0regs: MmMapIoSpace failed!\r\n")));bResult = FALSE;goto CleanUp;}// DMAC1 Virtual allocioPhysicalBase.LowPart = BASE_REG_PA_PDMA1;pPublicSpi->pDMAC1regs = (PDMAC_REG)MmMapIoSpace(ioPhysicalBase, sizeof(DMAC_REG), FALSE);if (pPublicSpi->pDMAC1regs == NULL){ERRMSG((TEXT("[SPI] For pDMAC1regs: MmMapIoSpace failed!\r\n")));bResult = FALSE;goto CleanUp;}// HS-SPI Virtual allocioPhysicalBase.LowPart = BASE_REG_PA_SPI0+(pPublicSpi->chnum * BASE_REG_SPI_OFFSET);pPublicSpi->pSPIregs = (PSPI_REG)MmMapIoSpace(ioPhysicalBase, sizeof(SPI_REG), FALSE);if (pPublicSpi->pSPIregs == NULL){ERRMSG((TEXT("[SPI] For pSPIregs: MmMapIoSpace failed!\r\n")));bResult = FALSE;goto CleanUp;}if(pPublicSpi->chnum==SPI0) {DBGMSG(SPI_INFO,(TEXT("[SPI] CH0 HW_init\r\n")));//Configure SPI Port Drive StrengthpPublicSpi->pGPIOregs->GPB.GP_DRV_SR = (pPublicSpi->pGPIOregs->GPB.GP_DRV_SR & ~(0xFF<<0)) | (0x55<<0);//Set GPIO for MISO, MOSI, SPICLK, SSSet_PinFunction(pPublicSpi->pGPIOregs, SPI0_CLK);Set_PinFunction(pPublicSpi->pGPIOregs, SPI0_nSS);Set_PinFunction(pPublicSpi->pGPIOregs, SPI0_MISO);Set_PinFunction(pPublicSpi->pGPIOregs, SPI0_MOSI); Set_PinPullUD(pPublicSpi->pGPIOregs, SPI0_CLK, sgip_PULL_DISABLE); Set_PinPullUD(pPublicSpi->pGPIOregs, SPI0_nSS, sgip_PULL_DISABLE); Set_PinPullUD(pPublicSpi->pGPIOregs, SPI0_MISO, sgip_PULL_DISABLE); Set_PinPullUD(pPublicSpi->pGPIOregs, SPI0_MOSI, sgip_PULL_DISABLE); DBGMSG(SPI_INFO,(TEXT("++[SPI] SPI_GPIO GPB_DRV_SR =%x, GPB_PUD = %x, GPB_CON = %x\r\n"), pPublicSpi->pGPIOregs->GPB.GP_DRV_SR, pPublicSpi->pGPIOregs->GPB.GP_PUD, pPublicSpi->pGPIOregs->GPB.GP_CON)); // Clock On#if (SPI_CLOCK == EPLL_CLOCK)pPublicSpi->pSYSCONregs->CLK_SRC.CLK_SRC5 = (pPublicSpi->pSYSCONregs->CLK_SRC.CLK_SRC5 & ~(0xF << 0)) | (0x7 << 0);pPublicSpi->pSYSCONregs->CLK_SRC.CLK_SRC_MASK0 = (pPublicSpi->pSYSCONregs->CLK_SRC.CLK_SRC_MASK0 | (1 << 16));pPublicSpi->pSYSCONregs->CLK_DIV.CLK_DIV5 = (pPublicSpi->pSYSCONregs->CLK_DIV.CLK_DIV5 & ~(0xF << 0));#elif (SPI_CLOCK == MPLL_CLOCK)pPublicSpi->pSYSCONregs->CLK_SRC.CLK_SRC5 = (pPublicSpi->pSYSCONregs->CLK_SRC.CLK_SRC5 & ~(0xF << 0)) | (0x6 << 0); pPublicSpi->pSYSCONregs->CLK_SRC.CLK_SRC_MASK0 = (pPublicSpi->pSYSCONregs->CLK_SRC.CLK_SRC_MASK0 | (1 << 16));pPublicSpi->pSYSCONregs->CLK_DIV.CLK_DIV5 = (pPublicSpi->pSYSCONregs->CLK_DIV.CLK_DIV5 & ~(0xF << 0)) | (7 << 0);#endifpPublicSpi->pSYSCONregs->CLK_GATE.CLK_GATE_IP3 = (pPublicSpi->pSYSCONregs->CLK_GATE.CLK_GATE_IP3 & ~(0x1 << 12)) | (0x1 << 12);}else if(pPublicSpi->chnum==SPI1){DBGMSG(SPI_INFO,(TEXT("[SPI] CH1 HW_init\r\n")));//Configure SPI Port Drive StrengthpPublicSpi->pGPIOregs->GPB.GP_DRV_SR = (pPublicSpi->pGPIOregs->GPB.GP_DRV_SR & ~(0xFF<<8)) | (0xFF<<8);//Set GPIO for MISO, MOSI, SPICLK, SSSet_PinFunction(pPublicSpi->pGPIOregs, SPI1_CLK);Set_PinFunction(pPublicSpi->pGPIOregs, SPI1_nSS);Set_PinFunction(pPublicSpi->pGPIOregs, SPI1_MISO);Set_PinFunction(pPublicSpi->pGPIOregs, SPI1_MOSI); Set_PinPullUD(pPublicSpi->pGPIOregs, SPI1_CLK, sgip_PULL_DISABLE); Set_PinPullUD(pPublicSpi->pGPIOregs, SPI1_nSS, sgip_PULL_DISABLE); Set_PinPullUD(pPublicSpi->pGPIOregs, SPI1_MISO, sgip_PULL_DISABLE); Set_PinPullUD(pPublicSpi->pGPIOregs, SPI1_MOSI, sgip_PULL_DISABLE); DBGMSG(SPI_INFO,(TEXT("++[SPI] SPI_GPIO GPB_DRV_SR =%x, GPB_PUD = %x, GPB_CON = %x\r\n"), pPublicSpi->pGPIOregs->GPB.GP_DRV_SR, pPublicSpi->pGPIOregs->GPB.GP_PUD, pPublicSpi->pGPIOregs->GPB.GP_CON)); // Clock On#if (SPI_CLOCK == EPLL_CLOCK)pPublicSpi->pSYSCONregs->CLK_SRC.CLK_SRC5 = (pPublicSpi->pSYSCONregs->CLK_SRC.CLK_SRC5 & ~(0xF << 4)) | (0x7 << 4); pPublicSpi->pSYSCONregs->CLK_SRC.CLK_SRC_MASK0 = (pPublicSpi->pSYSCONregs->CLK_SRC.CLK_SRC_MASK0 | (1 << 17));//pPublicSpi->pSYSCONregs->CLK_DIV.CLK_DIV5 = (pPublicSpi->pSYSCONregs->CLK_DIV.CLK_DIV5 & ~(0xF << 4));pPublicSpi->pSYSCONregs->CLK_DIV.CLK_DIV5 = (pPublicSpi->pSYSCONregs->CLK_DIV.CLK_DIV5 & ~(0xF << 4))| (2 << 4);//asdf #elif (SPI_CLOCK == MPLL_CLOCK)pPublicSpi->pSYSCONregs->CLK_SRC.CLK_SRC5 = (pPublicSpi->pSYSCONregs->CLK_SRC.CLK_SRC5 & ~(0xF << 4)) | (0x6 << 4); pPublicSpi->pSYSCONregs->CLK_SRC.CLK_SRC_MASK0 = (pPublicSpi->pSYSCONregs->CLK_SRC.CLK_SRC_MASK0 | (1 << 17));//pPublicSpi->pSYSCONregs->CLK_DIV.CLK_DIV5 = (pPublicSpi->pSYSCONregs->CLK_DIV.CLK_DIV5 & ~(0xF << 4)) | (12 << 4);pPublicSpi->pSYSCONregs->CLK_DIV.CLK_DIV5 = (pPublicSpi->pSYSCONregs->CLK_DIV.CLK_DIV5 & ~(0xF << 4)) | (19 << 4);//asdf test#endifpPublicSpi->pSYSCONregs->CLK_GATE.CLK_GATE_IP3 = (pPublicSpi->pSYSCONregs->CLK_GATE.CLK_GATE_IP3 & ~(0x1 << 13)) | (0x1 << 13);}else if(pPublicSpi->chnum==SPI2){DBGMSG(SPI_INFO,(TEXT("[SPI] CH2 HW_init\r\n")));//Configure SPI Port Drive StrengthpPublicSpi->pGPIOregs->GPG2.GP_DRV_SR = (pPublicSpi->pGPIOregs->GPG2.GP_DRV_SR & ~(0xFF<<0)) | (0x55<<0);//Set GPIO for MISO, MOSI, SPICLK, SSpPublicSpi->pGPIOregs->GPG2.GP_PUD= (pPublicSpi->pGPIOregs->GPG2.GP_PUD & ~(0xFF<<0));pPublicSpi->pGPIOregs->GPG2.GP_CON = (pPublicSpi->pGPIOregs->GPG2.GP_CON & ~(0xFFFF<<0)) | (0x3333<<0);// Clock On#if (SPI_CLOCK == EPLL_CLOCK)pPublicSpi->pSYSCONregs->CLK_SRC.CLK_SRC5 = (pPublicSpi->pSYSCONregs->CLK_SRC.CLK_SRC5 & ~(0xF << 8)) | (0x7 << 8);pPublicSpi->pSYSCONregs->CLK_SRC.CLK_SRC_MASK0 = (pPublicSpi->pSYSCONregs->CLK_SRC.CLK_SRC_MASK0 | (1 << 18));pPublicSpi->pSYSCONregs->CLK_DIV.CLK_DIV5 = (pPublicSpi->pSYSCONregs->CLK_DIV.CLK_DIV5 & ~(0xF<<8)); #elif (SPI_CLOCK == MPLL_CLOCK)pPublicSpi->pSYSCONregs->CLK_SRC.CLK_SRC5 = (pPublicSpi->pSYSCONregs->CLK_SRC.CLK_SRC5 & ~(0xF << 8)) | (0x6 << 8); pPublicSpi->pSYSCONregs->CLK_SRC.CLK_SRC_MASK0 = (pPublicSpi->pSYSCONregs->CLK_SRC.CLK_SRC_MASK0 | (1 << 18));pPublicSpi->pSYSCONregs->CLK_DIV.CLK_DIV5 = (pPublicSpi->pSYSCONregs->CLK_DIV.CLK_DIV5 & ~(0xF << 8)) | (13 << 8);#endifpPublicSpi->pSYSCONregs->CLK_GATE.CLK_GATE_IP3 = (pPublicSpi->pSYSCONregs->CLK_GATE.CLK_GATE_IP3 & ~(0x1 << 14)) | (0x1 << 14);}else{ERRMSG((TEXT("[SPI] Invalid channel \r\n"))); }DMA_initialize_register_address((void *)pPublicSpi->pDMAC0regs,(void *)pPublicSpi->pDMAC1regs,(void *)pPublicSpi->pDMACregs,(void *)pPublicSpi->pSYSCONregs);CleanUp:if (!bResult){if (pPublicSpi != NULL){if (pPublicSpi->pGPIOregs){MmUnmapIoSpace((PVOID)pPublicSpi->pGPIOregs, sizeof(GPIO_REG));pPublicSpi->pGPIOregs = NULL;}if (pPublicSpi->pSPIregs){MmUnmapIoSpace((PVOID)pPublicSpi->pSPIregs, sizeof(SPI_REG));pPublicSpi->pSPIregs = NULL;}if (pPublicSpi->pDMACregs){MmUnmapIoSpace((PVOID)pPublicSpi->pDMACregs, sizeof(DMAC_REG));pPublicSpi->pDMACregs = NULL;}if (pPublicSpi->pDMAC0regs){MmUnmapIoSpace((PVOID)pPublicSpi->pDMAC0regs, sizeof(DMAC_REG));pPublicSpi->pDMAC0regs = NULL;}if (pPublicSpi->pDMAC1regs){MmUnmapIoSpace((PVOID)pPublicSpi->pDMAC1regs, sizeof(DMAC_REG));pPublicSpi->pDMAC1regs = NULL;}if (pPublicSpi->pSYSCONregs){MmUnmapIoSpace((PVOID)pPublicSpi->pSYSCONregs, sizeof(CMU_CLK_REG));pPublicSpi->pSYSCONregs = NULL;}}bResult = FALSE;}return bResult;}BOOL InitializeDMABuffer(PSPI_PUBLIC_CONTEXT pPublicSpi){BOOL bResult = TRUE;DMA_ADAPTER_OBJECT Adapter1, Adapter2;DBGMSG(SPI_FUNC,(TEXT("+[SPI] InitializeBuffer\n")));if ( !pPublicSpi ){bResult = FALSE;goto CleanUp;}memset(&Adapter1, 0, sizeof(DMA_ADAPTER_OBJECT));Adapter1.InterfaceType = Internal;Adapter1.ObjectSize = sizeof(DMA_ADAPTER_OBJECT);memset(&Adapter2, 0, sizeof(DMA_ADAPTER_OBJECT));Adapter2.InterfaceType = Internal;Adapter2.ObjectSize = sizeof(DMA_ADAPTER_OBJECT);// Allocate a block of virtual memory (physically contiguous) for the DMA buffers.//pPublicSpi->SPIDMAInfo.pVirtDmaDstBufferAddr = (PBYTE)HalAllocateCommonBuffer(&Adapter1, SPI_DMA_BUF_SIZE, &pPublicSpi->SPIDMAInfo.PhysDmaDstBufferAddr, FALSE);DBGMSG(FALSE, (TEXT("[SPIDD] InitializeBuffer() - pVirtDmaDstBufferAddr %x\r\n"),pPublicSpi->SPIDMAInfo.pVirtDmaDstBufferAddr));if (pPublicSpi->SPIDMAInfo.pVirtDmaDstBufferAddr == NULL){ERRMSG( (TEXT("[SPI] InitializeBuffer() - Failed to allocate DMA buffer for SPI.\r\n")));HalFreeCommonBuffer(0, 0, pPublicSpi->SPIDMAInfo.PhysDmaDstBufferAddr, pPublicSpi->SPIDMAInfo.pVirtDmaDstBufferAddr, FALSE);bResult = FALSE;goto CleanUp;}pPublicSpi->SPIDMAInfo.pVirtDmaSrcBufferAddr = (PBYTE)HalAllocateCommonBuffer(&Adapter2, SPI_DMA_BUF_SIZE, &pPublicSpi->SPIDMAInfo.PhysDmaSrcBufferAddr, FALSE);DBGMSG(FALSE, (TEXT("[SPIDD] InitializeBuffer() - pVirtDmaSrcBufferAddr %x\r\n"),pPublicSpi->SPIDMAInfo.pVirtDmaSrcBufferAddr));if (pPublicSpi->SPIDMAInfo.pVirtDmaSrcBufferAddr == NULL){ERRMSG( (TEXT("[SPI] InitializeBuffer() - Failed to allocate DMA buffer for SPI.\r\n")));HalFreeCommonBuffer(0, 0, pPublicSpi->SPIDMAInfo.PhysDmaSrcBufferAddr, pPublicSpi->SPIDMAInfo.pVirtDmaSrcBufferAddr, FALSE);bResult = FALSE;goto CleanUp;}//DMA AddresspPublicSpi->SPIDMAInfo.DmaDstAddress = (UINT)(pPublicSpi->SPIDMAInfo.PhysDmaDstBufferAddr.LowPart);pPublicSpi->SPIDMAInfo.DmaSrcAddress = (UINT)(pPublicSpi->SPIDMAInfo.PhysDmaSrcBufferAddr.LowPart);DBGMSG(SPI_INFO, (TEXT("[SPI] pVirtDmaSrcBufferAddr 0x%x DmaSrcAddress 0x%x \r\n"),pPublicSpi->SPIDMAInfo.pVirtDmaSrcBufferAddr, pPublicSpi->SPIDMAInfo.DmaSrcAddress));DBGMSG(SPI_INFO, (TEXT("[SPI] pVirtDmaDstBufferAddr 0x%x DmaDstAddress 0x%x \r\n"),pPublicSpi->SPIDMAInfo.pVirtDmaDstBufferAddr, pPublicSpi->SPIDMAInfo.DmaDstAddress));DBGMSG(SPI_FUNC,(TEXT("-[SPI] InitializeBuffer\n")));CleanUp:return bResult;}PSPI_PUBLIC_CONTEXT SPI_Init(PVOID Context){PSPI_PUBLIC_CONTEXT pPublicSpi = NULL;LPTSTR ActivePath = (LPTSTR) Context;BOOL bResult = TRUE;DWORD dwHwIntr=0;HKEY hKey = NULL;DDKISRINFO isri;DWORD dwDataSize=4;DBGMSG(SPI_INFO,(TEXT("*************************************************\r\n")));DBGMSG(SPI_INFO,(TEXT("* %a_%a : %s\r\n"),VERSION_INFO,DateInformation, ActivePath));DBGMSG(SPI_INFO,(TEXT("*************************************************\r\n"))); DBGMSG(SPI_FUNC,(TEXT("[SPI] ++HSP_Init \r\n")));if ( !(pPublicSpi = (PSPI_PUBLIC_CONTEXT)LocalAlloc( LPTR, sizeof(SPI_PUBLIC_CONTEXT) )) ){ERRMSG((TEXT("[SPI] Can't not allocate for SPI Context\n")));bResult = FALSE;goto CleanUp;}pPublicSpi->hSpiEvent = CreateEvent(NULL, FALSE, FALSE, NULL);pPublicSpi->dwSpiSysIntr = SYSINTR_NOP;hKey = OpenDeviceKey((LPCTSTR)Context);if (hKey == NULL ) {ERRMSG((TEXT("[SPI] Failed to open device key\r\n")));bResult = FALSE;goto CleanUp; } // Read ISR informationisri.cbSize = sizeof(isri);if (DDKReg_GetIsrInfo(hKey, &isri) != ERROR_SUCCESS) {ERRMSG((TEXT("[SPI] Error getting ISR information\r\n")));bResult = FALSE;goto CleanUp;}DBGMSG(SPI_INFO,(TEXT("[SPI] IRQ(%d)\r\n"), isri.dwIrq));if (isri.dwSysintr == SYSINTR_NOP) {if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &(isri.dwIrq), sizeof(DWORD), &pPublicSpi->dwSpiSysIntr, sizeof(DWORD), NULL)){ERRMSG((TEXT("[SPI] Error KernelIoControl\r\n")));bResult = FALSE;goto CleanUp;}}// Get Device Index. if(RegQueryValueEx(hKey, PC_REG_SPI_DEVICE_INDEX, NULL, NULL,(LPBYTE)(&pPublicSpi->chnum),&dwDataSize)!=ERROR_SUCCESS){ERRMSG((TEXT("[SPI] Error RegQueryValueEx\r\n")));pPublicSpi->chnum=0;bResult = FALSE;goto CleanUp; }DBGMSG(SPI_DEBUG,(TEXT("[SPI] chnum=%d\r\n"), pPublicSpi->chnum));if (!InterruptInitialize(pPublicSpi->dwSpiSysIntr, pPublicSpi->hSpiEvent, NULL, 0)){ERRMSG((TEXT("[SPI] SPI Interrupt Initialization failed!!!\n")));bResult = FALSE;goto CleanUp;}if(!HW_Init(pPublicSpi)){ERRMSG((TEXT("[SPI] HW_Init is failed\n")));bResult = FALSE;goto CleanUp;}if(!InitializeDMABuffer(pPublicSpi)){ERRMSG((TEXT("[SPI] InitializeBuffer is failed\n")));bResult = FALSE;goto CleanUp;}if(pPublicSpi->chnum==SPI0){DBGMSG(SPI_INFO,(TEXT("[SPI] CH0 DMA \n")));pPublicSpi->dw_spi_dma_tx_ch = DMAsrc_SPI_0_TX;pPublicSpi->dw_spi_dma_rx_ch = DMAsrc_SPI_0_RX; }else if(pPublicSpi->chnum==SPI1){DBGMSG(SPI_INFO,(TEXT("[SPI] CH1 DMA \n")));pPublicSpi->dw_spi_dma_tx_ch = DMAsrc_SPI_1_TX;pPublicSpi->dw_spi_dma_rx_ch = DMAsrc_SPI_1_RX; }else if(pPublicSpi->chnum==SPI2){DBGMSG(SPI_INFO,(TEXT("[SPI] CH2 DMA \n"))); pPublicSpi->dw_spi_dma_tx_ch = DMAsrc_SPI_2_TX;pPublicSpi->dw_spi_dma_rx_ch = DMAsrc_SPI_2_RX; } else{ERRMSG((TEXT("[SPI] Invalid channel \n")));}if( DMA_request_channel(&pPublicSpi->SPIDMAInfo.g_OutputDMA, pPublicSpi->dw_spi_dma_tx_ch) != TRUE ){ERRMSG((TEXT("[SPI] DMA SPI TX channel request is failed\n")));bResult = FALSE;goto CleanUp;}if( DMA_request_channel(&pPublicSpi->SPIDMAInfo.g_InputDMA, pPublicSpi->dw_spi_dma_rx_ch) != TRUE ){ERRMSG((TEXT("[SPI] DMA SPI RX channel request is failed\n")));bResult = FALSE;goto CleanUp;} do{InitializeCriticalSection(&(pPublicSpi->CsRxAccess));InitializeCriticalSection(&(pPublicSpi->CsTxAccess));//Rx ThreadpPublicSpi->hRxEvent = CreateEvent(NULL, FALSE, FALSE, NULL);if (pPublicSpi->hRxEvent == NULL){ERRMSG((TEXT("[SPI] SPI Rx Event creation error!!!\n")));bResult = FALSE;break;}pPublicSpi->hRxThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)ThreadForRx, (LPVOID)pPublicSpi, 0, (LPDWORD)&pPublicSpi->dwRxThreadId);if (pPublicSpi->hRxThread == NULL){ERRMSG((TEXT("[SPI] SPI Rx Thread creation error!!!\n")));bResult = FALSE;break;}pPublicSpi->hRxDoneEvent = CreateEvent(NULL, FALSE, FALSE, NULL);if (pPublicSpi->hRxDoneEvent == NULL){ERRMSG( (TEXT("[SPI] SPI Rx Done Event creation error!!!\n")));bResult = FALSE;break;}pPublicSpi->hRxIntrDoneEvent = CreateEvent(NULL, FALSE, FALSE, NULL);if (pPublicSpi->hRxIntrDoneEvent == NULL){ERRMSG( (TEXT("[SPI] SPI Rx Interrupt Event creation error!!!\n")));bResult = FALSE;break;}//Tx ThreadpPublicSpi->hTxEvent = CreateEvent(NULL, FALSE, FALSE, NULL);if (pPublicSpi->hTxEvent == NULL){ERRMSG((TEXT("[SPI] SPI Tx Event creation error!!!\n")));bResult = FALSE;break;}pPublicSpi->hTxThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)ThreadForTx, (LPVOID)pPublicSpi, 0, (LPDWORD)&pPublicSpi->dwTxThreadId);if (pPublicSpi->hTxThread == NULL){ERRMSG((TEXT("[SPI] SPI Tx Thread creation error!!!\n")));bResult = FALSE;break;}pPublicSpi->hTxDoneEvent = CreateEvent(NULL, FALSE, FALSE, NULL);if (pPublicSpi->hTxDoneEvent == NULL){ERRMSG( (TEXT("[SPI] SPI Tx Done Event creation error!!!\n")));bResult = FALSE;break;}pPublicSpi->hTxIntrDoneEvent = CreateEvent(NULL, FALSE, FALSE, NULL);if (pPublicSpi->hTxIntrDoneEvent == NULL){ERRMSG( (TEXT("[SPI] SPI Tx Interrupt Event creation error!!!\n")));bResult = FALSE;break;}pPublicSpi->hSpiThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)ThreadForSpi, (LPVOID)pPublicSpi, 0, (LPDWORD)&pPublicSpi->dwSpiThreadId);if (pPublicSpi->hSpiThread == NULL){ERRMSG((TEXT("[SPI] SPI ISR Thread creation error!!!\n")));bResult = FALSE;break;}//Tx DMA Done ISRpPublicSpi->dwTxDmaDoneSysIntr = SYSINTR_NOP;dwHwIntr = pPublicSpi->SPIDMAInfo.g_OutputDMA.dwIRQ;pPublicSpi->hTxDmaDoneEvent = CreateEvent(NULL, FALSE, FALSE, NULL);if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &dwHwIntr, sizeof(DWORD), &pPublicSpi->dwTxDmaDoneSysIntr, sizeof(DWORD), NULL)){ERRMSG((TEXT("[SPI] Failed to request the SPI_DMA sysintr.\n")));pPublicSpi->dwTxDmaDoneSysIntr = SYSINTR_UNDEFINED;bResult = FALSE;break;}if (!InterruptInitialize(pPublicSpi->dwTxDmaDoneSysIntr, pPublicSpi->hTxDmaDoneEvent, NULL, 0)){ERRMSG((TEXT("[SPI] DMA Interrupt Initialization failed!!!\n")));bResult = FALSE;break;}//Rx DMA Done ISRpPublicSpi->dwRxDmaDoneSysIntr = SYSINTR_NOP;dwHwIntr = pPublicSpi->SPIDMAInfo.g_InputDMA.dwIRQ;pPublicSpi->hRxDmaDoneEvent = CreateEvent(NULL, FALSE, FALSE, NULL);if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &dwHwIntr, sizeof(DWORD), &pPublicSpi->dwRxDmaDoneSysIntr, sizeof(DWORD), NULL)){ERRMSG((TEXT("[SPI] Failed to request the SPI_DMA sysintr.\n")));pPublicSpi->dwRxDmaDoneSysIntr = SYSINTR_UNDEFINED;bResult = FALSE;break;}if (!InterruptInitialize(pPublicSpi->dwRxDmaDoneSysIntr, pPublicSpi->hRxDmaDoneEvent, NULL, 0)){ERRMSG((TEXT("[SPI] DMA Interrupt Initialization failed!!!\n")));bResult = FALSE;break;}pPublicSpi->m_hPowerCon = CreateFile( L"PWC0:", GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);if(pPublicSpi->m_hPowerCon == INVALID_HANDLE_VALUE){ERRMSG((L"[SPI:ERR] Initialize() : CreateFile() m_hPowerCon Open is failed\n\r"));bResult = FALSE;break;}DMA_initialize_channel(&pPublicSpi->SPIDMAInfo.g_OutputDMA, TRUE);DMA_initialize_channel(&pPublicSpi->SPIDMAInfo.g_InputDMA, TRUE);} while (0);CleanUp:DBGMSG(SPI_INIT,(TEXT("--[SPI] HSP_Init Function\r\n")));if(bResult){return pPublicSpi;}else{return NULL;}}DWORDSPI_Open(DWORD pContext,DWORD AccessCode,DWORD ShareMode){PSPI_PUBLIC_CONTEXT pSpiPublic = NULL;PSPI_PRIVATE_CONTEXT pSpiPrivate = NULL;BOOL bResult = TRUE;DBGMSG(SPI_FUNC,(TEXT("++[SPI] SPI_Open CH\r\n"))); if(pContext != 0){pSpiPublic = (PSPI_PUBLIC_CONTEXT) pContext;}else{bResult = FALSE;goto CleanUp;}if ( !(pSpiPrivate = (PSPI_PRIVATE_CONTEXT)LocalAlloc( LPTR, sizeof(SPI_PRIVATE_CONTEXT) )) ){ERRMSG((TEXT("[SPI] Can't not allocate for SPI Context\n")));bResult = FALSE;goto CleanUp;}pSpiPrivate->State = STATE_INIT;pSpiPrivate->pSpiPublic = pSpiPublic; // Display driver use GPB4,5,6,7(SPI1) as output mode // To test SPI1, reconfiguration // Apply this at Display driver /*if(pSpiPublic->chnum==SPI1) {Set_PinFunction(pSpiPublic->pGPIOregs, SPI1_CLK);Set_PinFunction(pSpiPublic->pGPIOregs, SPI1_nSS);Set_PinFunction(pSpiPublic->pGPIOregs, SPI1_MISO);Set_PinFunction(pSpiPublic->pGPIOregs, SPI1_MOSI); Set_PinPullUD(pSpiPublic->pGPIOregs, SPI1_CLK, sgip_PULL_DISABLE); Set_PinPullUD(pSpiPublic->pGPIOregs, SPI1_nSS, sgip_PULL_DISABLE); Set_PinPullUD(pSpiPublic->pGPIOregs, SPI1_MISO, sgip_PULL_DISABLE); Set_PinPullUD(pSpiPublic->pGPIOregs, SPI1_MOSI, sgip_PULL_DISABLE); }*/ DBGMSG(SPI_INFO,(TEXT("[SPI_CH%d] GPB_CON = %x\r\n"),pSpiPublic->chnum ,pSpiPublic->pGPIOregs->GPB.GP_CON));pSpiPrivate->bUseRxDMA = FALSE;pSpiPrivate->bUseRxIntr = FALSE;pSpiPrivate->bUseTxDMA = FALSE;pSpiPrivate->bUseTxIntr = FALSE;pSpiPrivate->spi_tx_data_addr = BASE_REG_PA_SPI0+(pSpiPublic->chnum*BASE_REG_SPI_OFFSET)+0x18;pSpiPrivate->spi_rx_data_addr = BASE_REG_PA_SPI0+(pSpiPublic->chnum*BASE_REG_SPI_OFFSET)+0x1C; CleanUp:DBGMSG(SPI_FUNC,(TEXT("--[SPI] SPI_Open\r\n")));if(bResult){return (DWORD) pSpiPrivate;}else{return (DWORD) NULL;}}DWORDSPI_Read(DWORD hOpenContext,LPVOID pBuffer,DWORD Count){PSPI_PRIVATE_CONTEXT pSpiPrivate = (PSPI_PRIVATE_CONTEXT)hOpenContext;PSPI_PUBLIC_CONTEXT pSpiPublic = pSpiPrivate->pSpiPublic;BOOL bResult = TRUE;ULONG BytesRead = 0;UINT i;DBGMSG(SPI_FUNC,(TEXT("++[SPI] SPI_Read \r\n")));DBGMSG(SPI_INFO,(TEXT("++[SPI] SPI_GPIO GPB_DRV_SR =%x, GPB_PUD = %x, GPB_CON = %x\r\n"), pSpiPublic->pGPIOregs->GPB.GP_DRV_SR, pSpiPublic->pGPIOregs->GPB.GP_PUD, pSpiPublic->pGPIOregs->GPB.GP_CON)); DBGMSG(SPI_INFO,(TEXT("++[SPI] SPI_GPIO GPG2_DRV_SR =%x, GPG2_PUD = %x, GPG2_CON = %x\r\n"), pSpiPublic->pGPIOregs->GPG2.GP_DRV_SR, pSpiPublic->pGPIOregs->GPG2.GP_PUD, pSpiPublic->pGPIOregs->GPG2.GP_CON)); if((PSPI_PRIVATE_CONTEXT)hOpenContext == NULL){bResult = FALSE;goto CleanUp;}//param checkif(pSpiPrivate->State != STATE_IDLE){ERRMSG((TEXT("[SPI] READ ERROR : STATE IS NOT IDLE\n")));bResult = FALSE;goto CleanUp;}DBGMSG(SPI_INFO,(TEXT("[SPI] pRxBuffer : 0x%X, Count : %d\n"), pBuffer, Count));if(SPI_DEBUG){memset(pSpiPublic->SPIDMAInfo.pVirtDmaDstBufferAddr, 0, SPI_DMA_BUF_SIZE);for (i = 0; i < Count; i++){DBGMSG(SPI_USR2,(TEXT("%d "),pSpiPublic->SPIDMAInfo.pVirtDmaDstBufferAddr[i]));}}if(pSpiPrivate->bUseRxDMA){pSpiPrivate->pRxBuffer = pSpiPublic->SPIDMAInfo.pVirtDmaDstBufferAddr;pSpiPrivate->pRxDMABuffer = (LPVOID)pSpiPublic->SPIDMAInfo.DmaDstAddress;}else{pSpiPrivate->pRxBuffer = pBuffer;}pSpiPrivate->dwRxCount = Count;pSpiPublic->pSpiPrivate = pSpiPrivate;#ifdef SLAVE_READYif(pSpiPrivate->dwMode == SPI_SLAVE_MODE && pSpiPrivate->ClrSlaveReady) {pSpiPrivate->ClrSlaveReady(pSpiPrivate);}#endifSetEvent(pSpiPublic->hRxEvent);//Thread callWaitForSingleObject(pSpiPublic->hRxDoneEvent, INFINITE);pSpiPrivate->State = STATE_IDLE;if(pSpiPrivate->bUseRxDMA){memcpy(pBuffer, pSpiPublic->SPIDMAInfo.pVirtDmaDstBufferAddr,Count);}else if(SPI_DEBUG){memcpy(pSpiPublic->SPIDMAInfo.pVirtDmaDstBufferAddr, pBuffer,Count);} CleanUp:BytesRead = Count - pSpiPrivate->dwRxCount;DBGMSG(SPI_MSG,(TEXT("[SPI] SPI_Read : Return Value : %d\n\n"), BytesRead));if(SPI_DEBUG){for (i = 0; i < Count; i++){DBGMSG(SPI_USR4,(TEXT("%d "),pSpiPublic->SPIDMAInfo.pVirtDmaDstBufferAddr[i]));}}DBGMSG(SPI_FUNC,(TEXT("--[SPI] SPI_Read\r\n")));if(bResult){return BytesRead;}else{return -1;}}DWORDSPI_Write(DWORD hOpenContext,LPVOID pBuffer,DWORD Count){PSPI_PRIVATE_CONTEXT pSpiPrivate = (PSPI_PRIVATE_CONTEXT)hOpenContext;PSPI_PUBLIC_CONTEXT pSpiPublic = pSpiPrivate->pSpiPublic;BOOL bResult = TRUE;ULONG BytesWritten = 0;UINT i;DBGMSG(SPI_FUNC,(TEXT("++[SPI] SPI_Write chnum = %d\r\n"),pSpiPublic->chnum));DBGMSG(SPI_INFO,(TEXT("++[SPI] SPI_GPIO GP_DRV_SR =%x, GP_PUD = %x, GP_CON = %x\r\n"), pSpiPublic->pGPIOregs->GPB.GP_DRV_SR, pSpiPublic->pGPIOregs->GPB.GP_PUD, pSpiPublic->pGPIOregs->GPB.GP_CON)); if((PSPI_PRIVATE_CONTEXT)hOpenContext == NULL){bResult = FALSE;goto CleanUp;}//param checkif(pSpiPrivate->State != STATE_IDLE){ERRMSG((TEXT("[SPI] WRITE ERROR : STATE IS NOT IDLE\n")));bResult = FALSE;goto CleanUp;}DBGMSG(SPI_MSG,(TEXT("[SPI] pBuffer : 0x%X, Count : %d\n"), pBuffer, Count));if(pSpiPrivate->bUseTxDMA){memcpy(pSpiPublic->SPIDMAInfo.pVirtDmaSrcBufferAddr,pBuffer, Count);pSpiPrivate->pTxBuffer = pSpiPublic->SPIDMAInfo.pVirtDmaSrcBufferAddr;pSpiPrivate->pTxDMABuffer = (LPVOID)pSpiPublic->SPIDMAInfo.DmaSrcAddress;}else if(SPI_DEBUG){memcpy(pSpiPublic->SPIDMAInfo.pVirtDmaSrcBufferAddr,pBuffer, Count); pSpiPrivate->pTxBuffer = (LPVOID)pBuffer;}if(SPI_DEBUG){for (i = 0; i < Count; i++){DBGMSG(SPI_USR1,(TEXT("%d "),pSpiPublic->SPIDMAInfo.pVirtDmaSrcBufferAddr[i]));}}pSpiPrivate->dwTxCount = Count;pSpiPublic->pSpiPrivate = pSpiPrivate;#ifdef SLAVE_READYif(pSpiPrivate->dwMode == SPI_MASTER_MODE && pSpiPrivate->GetSlaveReady) {while(!(pSpiPrivate->GetSlaveReady(pSpiPrivate))){Sleep(1); //Do nothing }}#endifSetEvent(pSpiPublic->hTxEvent);//Thread callWaitForSingleObject(pSpiPublic->hTxDoneEvent, INFINITE);pSpiPrivate->State = STATE_IDLE;CleanUp:BytesWritten = Count - pSpiPrivate->dwTxCount;DBGMSG(SPI_INFO,(TEXT("[SPI] SPI_Write : Return Value : %d\n"), BytesWritten));if(SPI_DEBUG){for (i = 0; i < Count; i++){DBGMSG(SPI_USR3,(TEXT("%d "),pSpiPublic->SPIDMAInfo.pVirtDmaSrcBufferAddr[i]));}}DBGMSG(SPI_FUNC,(TEXT("--[SPI] SPI_Write\r\n")));if(bResult){return BytesWritten;}else{return -1;}}BOOLSPI_IOControl(DWORD dwInst,DWORD dwIoControlCode,PBYTE lpInBuf,DWORD nInBufSize,PBYTE lpOutBuf,DWORD nOutBufSize,LPDWORD lpBytesRetruned){PSPI_PRIVATE_CONTEXT pSpiPrivate = (PSPI_PRIVATE_CONTEXT)dwInst;PSPI_PUBLIC_CONTEXT pSpiPublic = pSpiPrivate->pSpiPublic;volatile SPI_REG *pSPIregs = pSpiPublic->pSPIregs;volatile SPI_REG *pRxSPIregs = &pSpiPrivate->RxSPIregs;volatile SPI_REG *pTxSPIregs = &pSpiPrivate->TxSPIregs;PSPI_SET_CONFIG pSetConfig;BOOL bResult = TRUE;#ifdef BSP_USEDVFS DWORD Profile;DWORD dwBytes;#endif #ifdef SPI_FULL_DUPLEXDWORD dwCount=0;#endif if((PSPI_PRIVATE_CONTEXT)dwInst == NULL){bResult = FALSE;goto CleanUp;}switch(dwIoControlCode){case SPI_IOCTL_SET_CONFIG:DBGMSG(SPI_INFO,(TEXT("[SPI] SPI STATE : SPI_IOCTL_SET_CONFIG\n")));if( nInBufSize != sizeof(SPI_SET_CONFIG) ){bResult = FALSE;break;}pSetConfig = (PSPI_SET_CONFIG) lpInBuf;pSpiPrivate->dwTimeOutVal = pSetConfig->dwTimeOutVal;pSpiPrivate->dwMode = pSetConfig->dwMode;pSpiPrivate->dwPrescaler = pSetConfig->dwPrescaler;pSpiPrivate->bUseRxDMA = pSetConfig->bUseRxDMA;pSpiPrivate->bUseRxIntr = pSetConfig->bUseRxIntr;pSpiPrivate->bUseTxDMA = pSetConfig->bUseTxDMA;pSpiPrivate->bUseTxIntr = pSetConfig->bUseTxIntr;DBGMSG(SPI_USR2,(TEXT("[SPI%d] pSetConfig->dwTimeOutVal = %d \n"),pSpiPublic->chnum, pSetConfig->dwTimeOutVal));DBGMSG(SPI_USR2,(TEXT("[SPI%d] pSetConfig->dwMode = %d \n"),pSpiPublic->chnum, pSetConfig->dwMode));DBGMSG(SPI_USR2,(TEXT("[SPI%d] pSetConfig->dwPrescaler = %d (%d) \n"),pSpiPublic->chnum, pSetConfig->dwPrescaler, pSpiPrivate->dwPrescaler ));DBGMSG(SPI_USR2,(TEXT("[SPI%d] pSetConfig->bUseRxDMA = %d \n"),pSpiPublic->chnum, pSetConfig->bUseRxDMA));DBGMSG(SPI_USR2,(TEXT("[SPI%d] pSetConfig->bUseRxIntr = %d \n"),pSpiPublic->chnum, pSetConfig->bUseRxIntr));DBGMSG(SPI_USR2,(TEXT("[SPI%d] pSetConfig->bUseTxDMA = %d \n"),pSpiPublic->chnum, pSetConfig->bUseTxDMA));DBGMSG(SPI_USR2,(TEXT("[SPI%d] pSetConfig->bUseTxIntr = %d \n"),pSpiPublic->chnum, pSetConfig->bUseTxIntr));DBGMSG(SPI_USR2,(TEXT("[SPI%d] pSetConfig->Format = %d \n"),pSpiPublic->chnum, pSetConfig->Format));if (pSetConfig->Format == SPI_FORMAT_0){ pRxSPIregs->CH_CFG = CPOL_RISING|CPHA_FORMAT_A;}else if (pSetConfig->Format == SPI_FORMAT_1){ pRxSPIregs->CH_CFG = CPOL_RISING | CPHA_FORMAT_B;}else if (pSetConfig->Format == SPI_FORMAT_2){ pRxSPIregs->CH_CFG = CPOL_FALLING | CPHA_FORMAT_A;}else if (pSetConfig->Format == SPI_FORMAT_3){ pRxSPIregs->CH_CFG = CPOL_FALLING | CPHA_FORMAT_B;}else{ ERRMSG((TEXT("[SPI] This SPI_FORMAT is not supported\n")));}//Slave TX output time controlpRxSPIregs->CH_CFG &= ~(HIGH_SPEED_MASK);if (pSpiPrivate->dwPrescaler == 0){pRxSPIregs->CH_CFG |= (HIGH_SPEED_EN);}pRxSPIregs->FB_CLK_SEL = pSetConfig->dwFBClkSel;pRxSPIregs->CLK_CFG = CLKSEL|(pSpiPrivate->dwPrescaler);pRxSPIregs->MODE_CFG = MODE_DEFAULT;DBGMSG(SPI_USR2,(TEXT("[SPI%d] pRxSPIregs->CH_CFG = %d \n"), pSpiPublic->chnum, pRxSPIregs->CH_CFG));DBGMSG(SPI_USR2,(TEXT("[SPI%d] pRxSPIregs->FB_CLK_SEL = %d \n"), pSpiPublic->chnum, pRxSPIregs->FB_CLK_SEL));DBGMSG(SPI_USR2,(TEXT("[SPI%d] pRxSPIregs->CLK_CFG = %d \n"), pSpiPublic->chnum, pRxSPIregs->CLK_CFG));DBGMSG(SPI_USR2,(TEXT("[SPI%d] pRxSPIregs->MODE_CFG = %d \n"), pSpiPublic->chnum, pRxSPIregs->MODE_CFG));pTxSPIregs->CH_CFG &= ~(HIGH_SPEED_MASK);pTxSPIregs->CH_CFG = pRxSPIregs->CH_CFG;pTxSPIregs->FB_CLK_SEL = pSetConfig->dwFBClkSel; pTxSPIregs->CLK_CFG = pRxSPIregs->CLK_CFG;pTxSPIregs->MODE_CFG = pRxSPIregs->MODE_CFG;DBGMSG(SPI_USR2,(TEXT("[SPI%d] pTxSPIregs->CH_CFG = %d \n"), pSpiPublic->chnum, pTxSPIregs->CH_CFG));DBGMSG(SPI_USR2,(TEXT("[SPI%d] pTxSPIregs->FB_CLK_SEL = %d \n"), pSpiPublic->chnum, pTxSPIregs->FB_CLK_SEL));DBGMSG(SPI_USR2,(TEXT("[SPI%d] pTxSPIregs->CLK_CFG = %d \n"), pSpiPublic->chnum, pTxSPIregs->CLK_CFG));DBGMSG(SPI_USR2,(TEXT("[SPI%d] pTxSPIregs->MODE_CFG = %d \n"), pSpiPublic->chnum, pTxSPIregs->MODE_CFG)); //SPI_SFR_DUMP(pSpiPublic); if (pSetConfig->dwLineStrength == 0){ DBGMSG(SPI_USR2,(TEXT("[SPI%d] DRV Strength 1x \n"), pSpiPublic->chnum));if (pSpiPublic->chnum == SPI0){pSpiPublic->pGPIOregs->GPB.GP_DRV_SR = (pSpiPublic->pGPIOregs->GPB.GP_DRV_SR & ~(0xFF<<0)) | (0x0<<0); } else if (pSpiPublic->chnum == SPI1){pSpiPublic->pGPIOregs->GPB.GP_DRV_SR = (pSpiPublic->pGPIOregs->GPB.GP_DRV_SR & ~(0xFF<<8)) | (0x0<<8); } else if (pSpiPublic->chnum == SPI2){pSpiPublic->pGPIOregs->GPG2.GP_DRV_SR = (pSpiPublic->pGPIOregs->GPG2.GP_DRV_SR & ~(0xFF<<0)) | (0x0<<0); }else{ERRMSG((TEXT("[SPI%d] It's not supported MODE\n"), pSpiPublic->chnum));}}else if (pSetConfig->dwLineStrength == 1){ DBGMSG(SPI_USR2,(TEXT("[SPI%d] DRV Strength 2x \n"), pSpiPublic->chnum));if (pSpiPublic->chnum == SPI0){pSpiPublic->pGPIOregs->GPB.GP_DRV_SR = (pSpiPublic->pGPIOregs->GPB.GP_DRV_SR & ~(0xFF<<0)) | (0xAA<<0); } else if (pSpiPublic->chnum == SPI1){pSpiPublic->pGPIOregs->GPB.GP_DRV_SR = (pSpiPublic->pGPIOregs->GPB.GP_DRV_SR & ~(0xFF<<8)) | (0xAA<<8); } else if (pSpiPublic->chnum == SPI2){pSpiPublic->pGPIOregs->GPG2.GP_DRV_SR = (pSpiPublic->pGPIOregs->GPG2.GP_DRV_SR & ~(0xFF<<0)) | (0xAA<<0); }else{ERRMSG((TEXT("[SPI%d] It's not supported MODE\n"), pSpiPublic->chnum));}}else if (pSetConfig->dwLineStrength == 2){ DBGMSG(SPI_USR2,(TEXT("[SPI%d] DRV Strength 3x \n"), pSpiPublic->chnum));if (pSpiPublic->chnum == SPI0){pSpiPublic->pGPIOregs->GPB.GP_DRV_SR = (pSpiPublic->pGPIOregs->GPB.GP_DRV_SR & ~(0xFF<<0)) | (0x55<<0); } else if (pSpiPublic->chnum == SPI1){pSpiPublic->pGPIOregs->GPB.GP_DRV_SR = (pSpiPublic->pGPIOregs->GPB.GP_DRV_SR & ~(0xFF<<8)) | (0x55<<8); } else if (pSpiPublic->chnum == SPI2){pSpiPublic->pGPIOregs->GPG2.GP_DRV_SR = (pSpiPublic->pGPIOregs->GPG2.GP_DRV_SR & ~(0xFF<<0)) | (0x55<<0); }else{ERRMSG((TEXT("[SPI%d] It's not supported MODE\n"), pSpiPublic->chnum));}}else if (pSetConfig->dwLineStrength == 3){ DBGMSG(SPI_USR2,(TEXT("[SPI%d] DRV Strength 4x \n"), pSpiPublic->chnum));if (pSpiPublic->chnum == SPI0){pSpiPublic->pGPIOregs->GPB.GP_DRV_SR = (pSpiPublic->pGPIOregs->GPB.GP_DRV_SR & ~(0xFF<<0)) | (0xFF<<0); } else if (pSpiPublic->chnum == SPI1){pSpiPublic->pGPIOregs->GPB.GP_DRV_SR = (pSpiPublic->pGPIOregs->GPB.GP_DRV_SR & ~(0xFF<<8)) | (0xFF<<8); } else if (pSpiPublic->chnum == SPI2){pSpiPublic->pGPIOregs->GPG2.GP_DRV_SR = (pSpiPublic->pGPIOregs->GPG2.GP_DRV_SR & ~(0xFF<<0)) | (0xFF<<0); }else{ERRMSG((TEXT("[SPI%d] LineStrength for this channel not supported \n"), pSpiPublic->chnum));}}else{ERRMSG((TEXT("[SPI%d] This LineStrength value is not supported\n"), pSpiPublic->chnum));}if(pSpiPrivate->dwMode == SPI_MASTER_MODE){pRxSPIregs->CH_CFG |= SPI_MASTER;pRxSPIregs->CLK_CFG |= ENCLK_ENABLE;pTxSPIregs->CH_CFG |= SPI_MASTER;pTxSPIregs->CLK_CFG |= ENCLK_ENABLE;}else if(pSpiPrivate->dwMode == SPI_SLAVE_MODE){pRxSPIregs->CH_CFG |= SPI_SLAVE;pRxSPIregs->CLK_CFG |= ENCLK_DISABLE;pTxSPIregs->CH_CFG |= SPI_SLAVE;pTxSPIregs->CLK_CFG |= ENCLK_DISABLE;}else{ERRMSG((TEXT("[SPI%d] It's not supported MODE\n"), pSpiPublic->chnum));pSpiPrivate->State = STATE_ERROR;}#ifdef BSP_USEDVFSif(!pSpiPublic->m_bDVFSFixed){Profile = HIGH_PERF;if(!DeviceIoControl(pSpiPublic->m_hPowerCon, IOCTL_DVFS_SET_PROFILE, &Profile, sizeof(DWORD), NULL, 0, &dwBytes, NULL)){ERRMSG((L"[WAV] ERROR : It's failed to fix DVFS into HIGH_PERF\r\n"));}elsepSpiPublic->m_bDVFSFixed = TRUE;} #endif #ifdef SPI_EX_GPIO_CALLBACKHSPCALLBACK_Init(pSpiPrivate); #endif break;case SPI_IOCTL_START:DBGMSG(SPI_INFO,(TEXT("[SPI%d] SPI STATE : SPI_IOCTL_START\n"), pSpiPublic->chnum));if(pSpiPrivate->State == STATE_ERROR){ERRMSG((TEXT("[SPI%d] SPI_IOCTL_START ERROR\n"), pSpiPublic->chnum));bResult = FALSE;break;}pSpiPrivate->State = STATE_IDLE;break;case SPI_IOCTL_STOP:DBGMSG(SPI_INFO,(TEXT("[SPI%d] SPI STATE : SPI_IOCTL_STOP\n"), pSpiPublic->chnum));#ifdef BSP_USEDVFSif(pSpiPublic->m_bDVFSFixed){Profile = HIGH_PERF;if(!DeviceIoControl(pSpiPublic->m_hPowerCon, IOCTL_DVFS_CLEAR_PROFILE, &Profile, sizeof(DWORD), NULL, 0, &dwBytes, NULL)){ERRMSG((L"[WAV] ERROR : It's failed to clear fixed DVFS value\r\n"));} elsepSpiPublic->m_bDVFSFixed = FALSE;} #endif break; #ifdef SPI_EX_GPIO_CALLBACKcase SPI_IOCTL_SET_CALLBACK:DBGMSG(SPI_INFO,(TEXT("[SPI%d] SPI STATE : SPI_IOCTL_SET_CALLBACK\n"), pSpiPublic->chnum));HSPCALLBACK_Init(pSpiPrivate);break;case SPI_IOCTL_CLR_CALLBACK:DBGMSG(SPI_INFO,(TEXT("[SPI%d] SPI STATE : SPI_IOCTL_CLR_CALLBACK\n"), pSpiPublic->chnum)); HSPCALLBACK_Deinit(pSpiPrivate);break; case SPI_IOCTL_IS_SLAVE_READY:DBGMSG(SPI_INFO,(TEXT("[SPI%d] SPI STATE : SPI_IOCTL_IS_SLAVE_READY\n"), pSpiPublic->chnum)); *(BOOL *)lpOutBuf = pSpiPrivate->GetSlaveReady(pSpiPrivate);break;#endif#ifdef SPI_COMM_STREAM_IFcase SPI_IOCTL_SERIAL_GET_WAIT_MASK:DBGMSG (SPI_INFO,(TEXT("[SPI%d] IOCTL_SERIAL_GET_WAIT_MASK\r\n"), pSpiPublic->chnum));if ( (nOutBufSize < sizeof(DWORD)) || (NULL == lpOutBuf) ||(NULL == lpBytesRetruned) ) {SetLastError (ERROR_INVALID_PARAMETER);bResult = FALSE;ERRMSG((TEXT("[SPI%d] SPI_IOCTL_SERIAL_GET_WAIT_MASK: Invalid parameter\r\n"), pSpiPublic->chnum));break;}// Set The Wait Mask*(DWORD *)lpOutBuf = pSpiPrivate->dwEventMask;// Return the size*lpBytesRetruned = sizeof(DWORD); break;case SPI_IOCTL_SERIAL_SET_WAIT_MASK:DBGMSG (SPI_INFO,(TEXT("[SPI%d] SPI_IOCTL_SERIAL_SET_WAIT_MASK\r\n"), pSpiPublic->chnum)); if ( (nInBufSize < sizeof(DWORD)) || (NULL == lpInBuf) ) {SetLastError (ERROR_INVALID_PARAMETER);bResult = FALSE;ERRMSG((TEXT("[SPI%d] SPI_IOCTL_SERIAL_SET_WAIT_MASK: Invalid parameter\r\n"), pSpiPublic->chnum));break;}else {DWORD dwFlagEventMask = 0;dwFlagEventMask = *(DWORD *)lpInBuf;pSpiPrivate->dwEventMask = dwFlagEventMask;SetEvent(pSpiPrivate->hCommEvent);} break;case SPI_IOCTL_SERIAL_WAIT_ON_MASK:DBGMSG (SPI_INFO,(TEXT("[SPI%d] SPI_IOCTL_SERIAL_WAIT_ON_MASK\r\n"), pSpiPublic->chnum)); if ( (nOutBufSize < sizeof(DWORD)) || (NULL == lpOutBuf) ||(NULL == lpBytesRetruned) ) {SetLastError (ERROR_INVALID_PARAMETER);bResult = FALSE;ERRMSG((TEXT("[SPI%d] SPI_IOCTL_SERIAL_WAIT_ON_MASK: Invalid parameter\r\n"), pSpiPublic->chnum));break;}if(pSpiPrivate->dwEventMask==0){return (FALSE);}WaitForSingleObject(pSpiPrivate->hCommEvent, (ULONG)-1);*(DWORD *)lpOutBuf = pSpiPrivate->dwEventMask;*lpBytesRetruned = sizeof(DWORD); bResult=TRUE; break;#endif //SPI_COMM_STREAM_IF#ifdef SPI_FULL_DUPLEX case SPI_IOCTL_FULL_DUPLEX:DBGMSG (SPI_INFO,(TEXT("[SPI%d] SPI_IOCTL_FULL_DUPLEX\r\n"), pSpiPublic->chnum)); if ( (nInBufSize < sizeof(DWORD)) || (NULL == lpInBuf) ) {SetLastError (ERROR_INVALID_PARAMETER);bResult = FALSE;ERRMSG((TEXT("[SPI%d] SPI_IOCTL_FULL_DUPLEX: Invalid parameter\r\n"), pSpiPublic->chnum));break;}else { dwCount=(nInBufSize>nOutBufSize)? (nInBufSize):(nOutBufSize); *lpBytesRetruned = dwCount; if(!SPI_FullDuplex(pSpiPrivate, lpInBuf, lpOutBuf, dwCount)) bResult = FALSE;} break;#endif default:pSpiPrivate->Error = UNDEFINED_ERROR;goto CleanUp;}CleanUp:return bResult;}DWORD ThreadForTx(PSPI_PUBLIC_CONTEXT pSpiPublic){volatile SPI_REG *pSPIregs = pSpiPublic->pSPIregs;PSPI_PRIVATE_CONTEXT pSpiPrivate;DWORD dwTxCount;PBYTE pTxBuffer;DWORD dwOldPerm;PBYTE pTestBuffer;DWORD dwTestCount;ULONG TimeOut;ULONG TotalTimeOut;ULONG WaitReturn;INT TimeOutCount;do{WaitForSingleObject(pSpiPublic->hTxEvent, INFINITE);pSpiPrivate = (PSPI_PRIVATE_CONTEXT) pSpiPublic->pSpiPrivate;if(pSpiPrivate->dwTxCount != 0){dwTestCount = dwTxCount = pSpiPrivate->dwTxCount;}dwOldPerm = SetProcPermissions((DWORD)-1);pTestBuffer = pTxBuffer = (PBYTE) MapPtrToProcess(pSpiPrivate->pTxBuffer, (HANDLE) GetCurrentProcessId());DBGMSG(SPI_USR2,(TEXT("[SPI] pTxBuffer : 0x%X, dwTxCount : %d \r\n"), pTxBuffer, dwTxCount));//ResetpSPIregs->CH_CFG |= SW_RST;while(!(pSPIregs->CH_CFG & SW_RST));DBGMSG(SPI_USR2,(TEXT("[SPI] HS SPI reset\n")));pSPIregs->CH_CFG &= ~SW_RST;if(pSpiPrivate->bUseTxIntr)// INT + TX{DBGMSG(SPI_USR2,(TEXT("[SPI] Thread for TX : USE INT \r\n")));pSpiPrivate->State = STATE_TXINTR;pSPIregs->CH_CFG = pSpiPrivate->TxSPIregs.CH_CFG;pSPIregs->FB_CLK_SEL = pSpiPrivate->TxSPIregs.FB_CLK_SEL; pSPIregs->CLK_CFG = pSpiPrivate->TxSPIregs.CLK_CFG;pSPIregs->MODE_CFG = pSpiPrivate->TxSPIregs.MODE_CFG|(GetTxTriggerLevel(pSpiPublic->chnum) <<5);DBGMSG(SPI_USR2,(TEXT("[SPI] pSPIregs->FB_CLK_SEL = %d \n"),pSPIregs->FB_CLK_SEL));pSPIregs->SPI_INT_EN = TX_FIFORDY;pSPIregs->PENDING_CLR_REG = TX_UNDERRUN_CLR|TX_OVERRUN_CLR|RX_UNDERRUN_CLR|RX_OVERRUN_CLR|TRAILING_CLR;pSPIregs->CH_CFG |= TX_CH_ON;if(pSpiPrivate->dwMode == SPI_MASTER_MODE){DBGMSG(SPI_USR2,(TEXT("[SPI] Thread for TX : MASTER MODE \r\n")));MASTER_CS_ENABLE;}else{DBGMSG(SPI_USR2,(TEXT("[SPI] Thread for TX : SLAVE MODE \r\n")));}//Timeout value settingTotalTimeOut = WRITE_TIME_OUT_CONSTANT + (WRITE_TIME_OUT_MULTIPLIER/1000)*dwTxCount;TimeOut = TotalTimeOut;WaitReturn = WaitForSingleObject(pSpiPublic->hTxIntrDoneEvent, TimeOut);if ( WAIT_TIMEOUT == WaitReturn ){// TimeoutERRMSG ((TEXT("Write timeout!!!\r\n")));goto LEAVEWRITE;}TimeOutCount = 1000;while((((pSPIregs ->SPI_STATUS>>6) & 0x1ff) && !(pSPIregs ->SPI_STATUS & TX_DONE))|| (TimeOutCount>0)){TimeOutCount--;}}else if(pSpiPrivate->bUseTxDMA)// DMA + TX{DWORD dwDmaLen = dwTxCount & 0xFFFFF;DBGMSG(SPI_USR2,(TEXT("[SPI] Thread for TX : USE DMA (TxCount : %d) \r\n"),dwDmaLen));pSpiPrivate->State = STATE_TXDMA;if(pSpiPrivate->dwMode == SPI_MASTER_MODE){pSPIregs->CH_CFG = pSpiPrivate->TxSPIregs.CH_CFG;pSPIregs->FB_CLK_SEL = pSpiPrivate->TxSPIregs.FB_CLK_SEL; pSPIregs->CLK_CFG = pSpiPrivate->TxSPIregs.CLK_CFG;pSPIregs->MODE_CFG = pSpiPrivate->TxSPIregs.MODE_CFG;}else{pSPIregs->CH_CFG = pSpiPrivate->TxSPIregs.CH_CFG;pSPIregs->FB_CLK_SEL = pSpiPrivate->TxSPIregs.FB_CLK_SEL; pSPIregs->CLK_CFG = pSpiPrivate->TxSPIregs.CLK_CFG;pSPIregs->MODE_CFG = pSpiPrivate->TxSPIregs.MODE_CFG;} if(dwDmaLen > 0){pSPIregs->MODE_CFG |= TX_DMA_ON|DMA_SINGLE;pSPIregs->CH_CFG |= TX_CH_ON;{DBGMSG(SPI_USR2,(TEXT("[SPI] pSpiPrivate->pTxDMABuffer : 0x%X \r\n"), pSpiPrivate->pTxDMABuffer));DMA_set_channel_source(&pSpiPublic->SPIDMAInfo.g_OutputDMA, (UINT)pSpiPrivate->pTxDMABuffer, BYTE_UNIT, BURST_1, INCREASE);DMA_set_channel_destination(&pSpiPublic->SPIDMAInfo.g_OutputDMA, pSpiPrivate->spi_tx_data_addr, BYTE_UNIT, BURST_1, FIXED);DMA_set_channel_transfer_size(&pSpiPublic->SPIDMAInfo.g_OutputDMA, dwDmaLen);DMA_initialize_LLI(&pSpiPublic->SPIDMAInfo.g_OutputDMA, 1);DMA_set_LLI_entry(&pSpiPublic->SPIDMAInfo.g_OutputDMA, 0, LLI_FIRST_ENTRY, (UINT)pSpiPrivate->pTxDMABuffer,pSpiPrivate->spi_tx_data_addr, dwDmaLen);}if(pSpiPrivate->dwMode == SPI_MASTER_MODE){DBGMSG(SPI_USR2,(TEXT("[SPI] Thread for TX : MASTER MODE \r\n")));MASTER_CS_ENABLE;}else{DBGMSG(SPI_USR2,(TEXT("[SPI] Thread for TX : SLAVE MODE \r\n")));}#ifdef SLAVE_READYif(pSpiPrivate->dwMode == SPI_MASTER_MODE && pSpiPrivate->GetSlaveReady) {while(!(pSpiPrivate->GetSlaveReady(pSpiPrivate))){Sleep(1) ; //Do nothing }}#endif //SPI_SFR_DUMP(pSpiPublic);DMA_channel_start(&pSpiPublic->SPIDMAInfo.g_OutputDMA);#ifdef SLAVE_READYif(pSpiPrivate->dwMode == SPI_SLAVE_MODE && pSpiPrivate->SetSlaveReady) {// while((pSPIregs->SPI_STATUS & (0x1FF >> 6)) < (GetFifoSize(pSpiPublic->chnum))){; //Do nothing }pSpiPrivate->SetSlaveReady(pSpiPrivate);}#endif//Timeout value settingTotalTimeOut = WRITE_TIME_OUT_CONSTANT + (WRITE_TIME_OUT_MULTIPLIER/1000)*dwTxCount;TimeOut = TotalTimeOut;WaitReturn = WaitForSingleObject(pSpiPublic->hTxDmaDoneEvent, TimeOut);#ifdef SLAVE_READYif(pSpiPrivate->dwMode == SPI_SLAVE_MODE && pSpiPrivate->ClrSlaveReady) {pSpiPrivate->ClrSlaveReady(pSpiPrivate);}#endifif ( WAIT_TIMEOUT == WaitReturn ){// TimeoutDBGMSG (TRUE, (TEXT("Write timeout!!!\r\n")));// Stop output DMADMA_channel_stop(&pSpiPublic->SPIDMAInfo.g_OutputDMA);goto LEAVEWRITE;} DMA_clear_interrupt_pending(&pSpiPublic->SPIDMAInfo.g_OutputDMA); DMA_set_interrupt_mask(&pSpiPublic->SPIDMAInfo.g_OutputDMA); InterruptDone(pSpiPublic->dwTxDmaDoneSysIntr); DMA_clear_interrupt_mask(&pSpiPublic->SPIDMAInfo.g_OutputDMA); pSpiPrivate->dwTxCount -= dwDmaLen;pSpiPrivate->pTxBuffer = (((PUINT) pSpiPrivate->pTxBuffer) + dwDmaLen);}TimeOutCount = 1000;while((((pSPIregs ->SPI_STATUS>>6) & 0x1ff) && !(pSPIregs ->SPI_STATUS & TX_DONE))|| (TimeOutCount>0)){TimeOutCount--;}}else// POLLING + TX{ULONG Count;DBGMSG(SPI_USR2,(TEXT("[SPI] Thread for TX : USE Polling (TxCount : %d) \r\n"), dwTxCount));pSPIregs->CH_CFG = pSpiPrivate->TxSPIregs.CH_CFG;pSPIregs->CLK_CFG = pSpiPrivate->TxSPIregs.CLK_CFG;pSPIregs->MODE_CFG = pSpiPrivate->TxSPIregs.MODE_CFG;pSPIregs->CH_CFG |= TX_CH_ON;if(pSpiPrivate->dwMode == SPI_MASTER_MODE){DBGMSG(SPI_USR2,(TEXT("[SPI] Thread for TX : MASTER MODE \r\n")));MASTER_CS_ENABLE;}else{DBGMSG(SPI_USR2,(TEXT("[SPI] Thread for TX : SLAVE MODE \r\n")));}TotalTimeOut = WRITE_TIME_OUT_CONSTANT*100*50 + (WRITE_TIME_OUT_MULTIPLIER)*dwTxCount;Count = 0;do{while(((pSPIregs ->SPI_STATUS>>6) & 0x1ff)== GetFifoSize(pSpiPublic->chnum)) //FIFO_FULL{Count++;if(TotalTimeOut == Count){// TimeoutERRMSG ((TEXT("Write timeout!!!\r\n")));goto LEAVEWRITE;}}pSPIregs->SPI_TX_DATA = *(PBYTE)pSpiPrivate->pTxBuffer;} while(--pSpiPrivate->dwTxCount > 0 && ++(PBYTE)pSpiPrivate->pTxBuffer);TimeOutCount = 1000;while((((pSPIregs ->SPI_STATUS>>6) & 0x1ff) && !(pSPIregs ->SPI_STATUS & TX_DONE))|| (TimeOutCount>0)){TimeOutCount--;}}LEAVEWRITE:#ifdef TEST_MODEdo{DBGMSG(SPI_USR2,(TEXT("[SPI] WRITE BYTE : %02X(dwTxCount : %d)\n"), *pTestBuffer, dwTestCount));} while( (--dwTestCount > 0) && ++pTestBuffer);#endifDBGMSG(FALSE,(TEXT("[SPI] TX_CH_OFF \n")));pSPIregs->CH_CFG &= ~TX_CH_ON;if(pSpiPrivate->dwMode == SPI_MASTER_MODE){MASTER_CS_DISABLE;}UnMapPtr(pTxBuffer);SetProcPermissions(dwOldPerm);SetEvent(pSpiPublic->hTxDoneEvent);} while(TRUE);return 0;}DWORD ThreadForRx(PSPI_PUBLIC_CONTEXT pSpiPublic){volatile SPI_REG *pSPIregs = pSpiPublic->pSPIregs;PSPI_PRIVATE_CONTEXT pSpiPrivate;DWORD dwRxCount;PBYTE pRxBuffer;DWORD dwOldPerm;PBYTE pTestBuffer;DWORD dwTestCount;ULONG TimeOut;ULONG TotalTimeOut;ULONG WaitReturn;do{WaitForSingleObject(pSpiPublic->hRxEvent, INFINITE);pSpiPrivate = (PSPI_PRIVATE_CONTEXT) pSpiPublic->pSpiPrivate;if(pSpiPrivate->dwRxCount != 0){dwTestCount = dwRxCount = pSpiPrivate->dwRxCount;}dwOldPerm = SetProcPermissions((DWORD)-1);pTestBuffer = pRxBuffer = (PBYTE) MapPtrToProcess(pSpiPrivate->pRxBuffer, (HANDLE) GetCurrentProcessId());DBGMSG(SPI_USR2,(TEXT("[SPI] pRxBuffer : 0x%X, dwRxCount : %d \r\n"), pRxBuffer, dwRxCount));//ResetpSPIregs->CH_CFG |= SW_RST;while(!(pSPIregs->CH_CFG & SW_RST));DBGMSG(SPI_USR2,(TEXT("[SPI] HS SPI reset\n")));pSPIregs->CH_CFG &= ~SW_RST;if(pSpiPrivate->bUseRxIntr)//INT Mode + RX{DBGMSG(SPI_USR2,(TEXT("[SPI] Thread for RX : USE INT \r\n")));pSpiPrivate->State = STATE_RXINTR;if(pSpiPrivate->dwMode == SPI_MASTER_MODE){pSPIregs->CH_CFG = pSpiPrivate->RxSPIregs.CH_CFG;pSPIregs->FB_CLK_SEL = pSpiPrivate->RxSPIregs.FB_CLK_SEL; pSPIregs->CLK_CFG = pSpiPrivate->RxSPIregs.CLK_CFG;pSPIregs->MODE_CFG = pSpiPrivate->RxSPIregs.MODE_CFG|TRAIL_CNT(0x3FF)|(RX_TRIG_LEVEL<<11);pSPIregs->PACKET_CNT_REG = PACKET_CNT_EN | (pSpiPrivate->dwRxCount) ;}else{pSPIregs->CH_CFG = pSpiPrivate->RxSPIregs.CH_CFG;pSPIregs->FB_CLK_SEL = pSpiPrivate->RxSPIregs.FB_CLK_SEL; pSPIregs->CLK_CFG = pSpiPrivate->RxSPIregs.CLK_CFG;pSPIregs->MODE_CFG = pSpiPrivate->RxSPIregs.MODE_CFG|TRAIL_CNT(0x3FF)|(RX_TRIG_LEVEL<<11);pSPIregs->PACKET_CNT_REG = PACKET_CNT_EN | (pSpiPrivate->dwRxCount) ;}DBGMSG(SPI_USR2,(TEXT("[SPI] pSPIregs->FB_CLK_SEL = %d \n"),pSPIregs->FB_CLK_SEL));pSPIregs->SPI_INT_EN = RX_FIFORDY;pSPIregs->PENDING_CLR_REG = TX_UNDERRUN_CLR|TX_OVERRUN_CLR|RX_UNDERRUN_CLR|RX_OVERRUN_CLR|TRAILING_CLR;pSPIregs->CH_CFG |= RX_CH_ON;if(pSpiPrivate->dwMode == SPI_MASTER_MODE){DBGMSG(SPI_USR2,(TEXT("[SPI] Thread for RX : MASTER MODE \r\n")));MASTER_CS_ENABLE;}else{DBGMSG(SPI_USR2,(TEXT("[SPI] Thread for RX : SLAVE MODE \r\n")));}//Timeout value settingTotalTimeOut = READ_TIME_OUT_CONSTANT + (READ_TIME_OUT_MULTIPLIER/1000)*dwRxCount;TimeOut = TotalTimeOut;WaitReturn = WaitForSingleObject(pSpiPublic->hRxIntrDoneEvent, TimeOut);if ( WAIT_TIMEOUT == WaitReturn ){// TimeoutERRMSG ((TEXT("Read timeout!!!\r\n")));goto LEAVEREAD;}}else if(pSpiPrivate->bUseRxDMA)//DMA Mode + Rx{DWORD dwDmaLen = (pSpiPrivate->dwRxCount & 0xFFFFF);DBGMSG(SPI_USR2,(TEXT("[SPI] Thread for RX : USE DMA \r\n")));pSpiPrivate->State = STATE_RXDMA;//Resetif(pSpiPrivate->dwMode == SPI_MASTER_MODE){pSPIregs->CH_CFG = pSpiPrivate->RxSPIregs.CH_CFG;pSPIregs->FB_CLK_SEL = pSpiPrivate->RxSPIregs.FB_CLK_SEL; pSPIregs->CLK_CFG = pSpiPrivate->RxSPIregs.CLK_CFG;pSPIregs->MODE_CFG = pSpiPrivate->RxSPIregs.MODE_CFG;pSPIregs->PACKET_CNT_REG = PACKET_CNT_EN | (pSpiPrivate->dwRxCount);}else{pSPIregs->CH_CFG = pSpiPrivate->RxSPIregs.CH_CFG;pSPIregs->FB_CLK_SEL = pSpiPrivate->RxSPIregs.FB_CLK_SEL; pSPIregs->CLK_CFG = pSpiPrivate->RxSPIregs.CLK_CFG;pSPIregs->MODE_CFG = pSpiPrivate->RxSPIregs.MODE_CFG;pSPIregs->PACKET_CNT_REG = PACKET_CNT_EN | (pSpiPrivate->dwRxCount);} if(dwDmaLen > 0){pSPIregs->MODE_CFG |= RX_DMA_ON|DMA_SINGLE;pSPIregs->CH_CFG |= RX_CH_ON;{DMA_set_channel_source(&pSpiPublic->SPIDMAInfo.g_InputDMA, pSpiPrivate->spi_rx_data_addr, BYTE_UNIT, BURST_1, FIXED);DMA_set_channel_destination(&pSpiPublic->SPIDMAInfo.g_InputDMA, (UINT)pSpiPrivate->pRxDMABuffer, BYTE_UNIT, BURST_1, INCREASE);DMA_set_channel_transfer_size(&pSpiPublic->SPIDMAInfo.g_InputDMA, dwDmaLen);DMA_initialize_LLI(&pSpiPublic->SPIDMAInfo.g_InputDMA, 1);DMA_set_LLI_entry(&pSpiPublic->SPIDMAInfo.g_InputDMA, 0, LLI_FIRST_ENTRY, pSpiPrivate->spi_rx_data_addr,(UINT)pSpiPrivate->pRxDMABuffer, dwDmaLen);}if(pSpiPrivate->dwMode == SPI_MASTER_MODE){DBGMSG(SPI_USR2,(TEXT("[SPI] Thread for RX : MASTER MODE \r\n")));MASTER_CS_ENABLE;}else{DBGMSG(SPI_USR2,(TEXT("[SPI] Thread for RX : SLAVE MODE \r\n")));} //SPI_SFR_DUMP(pSpiPublic);DMA_channel_start(&pSpiPublic->SPIDMAInfo.g_InputDMA);#ifdef SLAVE_READYif(pSpiPrivate->dwMode == SPI_SLAVE_MODE && pSpiPrivate->SetSlaveReady) {pSpiPrivate->SetSlaveReady(pSpiPrivate);}#endif//Timeout value settingTotalTimeOut = READ_TIME_OUT_CONSTANT + (READ_TIME_OUT_MULTIPLIER/1000)*dwRxCount;TimeOut = TotalTimeOut;WaitReturn = WaitForSingleObject(pSpiPublic->hRxDmaDoneEvent, TimeOut);#ifdef SLAVE_READYif(pSpiPrivate->dwMode == SPI_SLAVE_MODE && pSpiPrivate->ClrSlaveReady) {pSpiPrivate->ClrSlaveReady(pSpiPrivate);}#endifif ( WAIT_TIMEOUT == WaitReturn ){// TimeoutERRMSG ((TEXT("Read timeout!!!\r\n")));// Stop input DMADMA_channel_stop(&pSpiPublic->SPIDMAInfo.g_InputDMA);goto LEAVEREAD;} DMA_clear_interrupt_pending(&pSpiPublic->SPIDMAInfo.g_InputDMA); DMA_set_interrupt_mask(&pSpiPublic->SPIDMAInfo.g_InputDMA); InterruptDone(pSpiPublic->dwRxDmaDoneSysIntr); DMA_clear_interrupt_mask(&pSpiPublic->SPIDMAInfo.g_InputDMA); pSpiPrivate->dwRxCount -= dwDmaLen;pSpiPrivate->pRxBuffer = (PBYTE) (((PUINT) pSpiPrivate->pRxBuffer) + dwDmaLen);}}else{//POLLING Mode + RXULONG Count;DBGMSG(SPI_USR2,(TEXT("[SPI] Thread for RX : USE Polling (RxCount : %d) \r\n"), dwRxCount));if(pSpiPrivate->dwMode == SPI_MASTER_MODE){pSPIregs->CH_CFG = pSpiPrivate->RxSPIregs.CH_CFG;pSPIregs->CLK_CFG = pSpiPrivate->RxSPIregs.CLK_CFG;pSPIregs->MODE_CFG = pSpiPrivate->RxSPIregs.MODE_CFG;pSPIregs->PACKET_CNT_REG = PACKET_CNT_EN | (pSpiPrivate->dwRxCount);}else{pSPIregs->CH_CFG = pSpiPrivate->RxSPIregs.CH_CFG;pSPIregs->CLK_CFG = pSpiPrivate->RxSPIregs.CLK_CFG;pSPIregs->MODE_CFG = pSpiPrivate->RxSPIregs.MODE_CFG;}pSPIregs->CH_CFG |= RX_CH_ON;if(pSpiPrivate->dwMode == SPI_MASTER_MODE){DBGMSG(SPI_USR2,(TEXT("[SPI] Thread for RX : MASTER MODE \r\n")));MASTER_CS_ENABLE;}else{DBGMSG(SPI_USR2,(TEXT("[SPI] Thread for RX : SLAVE MODE \r\n")));}TotalTimeOut = READ_TIME_OUT_CONSTANT*100*50 + (READ_TIME_OUT_MULTIPLIER)*dwRxCount;Count = 0;do{while (((pSPIregs ->SPI_STATUS >> 15) & 0x1ff) == FIFO_EMPTY){Count++;if(TotalTimeOut == Count){// TimeoutERRMSG ((TEXT("Read timeout!!!\r\n")));goto LEAVEREAD;}}*(PBYTE)pSpiPrivate->pRxBuffer = pSPIregs->SPI_RX_DATA;} while(--pSpiPrivate->dwRxCount > 0 && ++(PBYTE)pSpiPrivate->pRxBuffer);}LEAVEREAD:#ifdef TEST_MODEdo{DBGMSG(SPI_USR2,(TEXT("[SPI] READ BYTE : %02X(dwRxCount %d)\n"), *pTestBuffer, dwTestCount));} while((--dwTestCount > 0) && ++pTestBuffer);#endifDBGMSG(FALSE,(TEXT("[SPI] RX_CH_OFF \n")));pSPIregs->CH_CFG &= ~RX_CH_ON;if(pSpiPrivate->dwMode == SPI_MASTER_MODE){MASTER_CS_DISABLE;}UnMapPtr(pRxBuffer);SetProcPermissions(dwOldPerm);SetEvent(pSpiPublic->hRxDoneEvent);#ifdef SPI_COMM_STREAM_IF pSpiPrivate->dwEventMask |= EV_RXCHAR;SetEvent(pSpiPrivate->hCommEvent);#endif } while(TRUE);return 0;}DWORD ThreadForSpi(PSPI_PUBLIC_CONTEXT pSpiPublic){volatile SPI_REG *pSPIregs = pSpiPublic->pSPIregs; // for HS-SPIPSPI_PRIVATE_CONTEXT pSpiPrivate;UINT dwRxCount = 0;UINT dwTxCount = 0;DWORD dwOldPerm = 0;DBGMSG(SPI_USR3,(TEXT("[SPI] ThreadForSpi thread is created \r\n")));do{WaitForSingleObject(pSpiPublic->hSpiEvent, INFINITE);pSpiPrivate = (PSPI_PRIVATE_CONTEXT) pSpiPublic->pSpiPrivate;dwOldPerm = SetProcPermissions((DWORD)-1);if(pSpiPrivate->State == STATE_RXINTR){if(pSpiPrivate->dwMode == SPI_MASTER_MODE){dwRxCount = ((pSPIregs ->SPI_STATUS>>15) & 0x1ff) ;DBGMSG(SPI_USR3,(TEXT("MR %d, %d\r\n"),pSpiPrivate->dwRxCount, dwRxCount)); if (dwRxCount != 0){do{// while (((pSPIregs ->SPI_STATUS>>15)&0x1ff)==FIFO_EMPTY);*(PBYTE)pSpiPrivate->pRxBuffer = pSPIregs->SPI_RX_DATA;DBGMSG(SPI_USR4,(TEXT("MR %d, %d\r\n"),pSpiPrivate->dwRxCount, dwRxCount));} while(--pSpiPrivate->dwRxCount > 0 && ++(PBYTE)pSpiPrivate->pRxBuffer && --dwRxCount > 0);} else{ERRMSG((TEXT("dwRxCount is zero %d\r\n"))); }if(pSpiPrivate->dwRxCount ==0){pSPIregs->SPI_INT_EN &= ~(RX_FIFORDY|TX_FIFORDY);SetEvent(pSpiPublic->hRxIntrDoneEvent);}DBGMSG(SPI_USR3,(TEXT("[SPI]MR %d, %d\r\n"),pSpiPrivate->dwRxCount, dwRxCount));}else{dwRxCount = ((pSPIregs ->SPI_STATUS>>15) & 0x1ff) ;DBGMSG(SPI_USR3,(TEXT("SR %d, %d\r\n"),pSpiPrivate->dwRxCount, dwRxCount)); if (dwRxCount != 0){do{*(PBYTE)pSpiPrivate->pRxBuffer = pSPIregs->SPI_RX_DATA;DBGMSG(SPI_USR4,(TEXT("SR %d, %d\r\n"),pSpiPrivate->dwRxCount, dwRxCount)); } while(--pSpiPrivate->dwRxCount > 0 && ++(PBYTE)pSpiPrivate->pRxBuffer && --dwRxCount > 0);}else{ERRMSG((TEXT("dwRxCount is zero %d\r\n"))); // SetEvent(pSpiPublic->hRxIntrDoneEvent);}if(pSpiPrivate->dwRxCount ==0){pSPIregs->SPI_INT_EN &= ~(RX_FIFORDY|TX_FIFORDY);SetEvent(pSpiPublic->hRxIntrDoneEvent);}DBGMSG(SPI_USR3,(TEXT("[SPI]SR %d, %d\r\n"),pSpiPrivate->dwRxCount, dwRxCount));}}else if(pSpiPrivate->State == STATE_TXINTR){if(pSpiPrivate->dwMode == SPI_MASTER_MODE){dwTxCount = GetFifoSize(pSpiPublic->chnum)-((pSPIregs ->SPI_STATUS>>6) & 0x1ff) ;if (dwTxCount != 0){do{pSPIregs->SPI_TX_DATA = *(PBYTE)pSpiPrivate->pTxBuffer;DBGMSG(SPI_USR4,(TEXT("MT %d, %d\r\n"),pSpiPrivate->dwTxCount, dwTxCount)); } while(--pSpiPrivate->dwTxCount > 0 && ++(PBYTE)pSpiPrivate->pTxBuffer && --dwTxCount > 0);}else{ERRMSG((TEXT("dwTxCount is zero %d\r\n"))); // SetEvent(pSpiPublic->hTxIntrDoneEvent);}if(pSpiPrivate->dwTxCount ==0){pSPIregs->SPI_INT_EN &= ~(RX_FIFORDY|TX_FIFORDY);SetEvent(pSpiPublic->hTxIntrDoneEvent);}DBGMSG(SPI_USR3,(TEXT("[SPI]MT %d, %d\r\n"),pSpiPrivate->dwTxCount, dwTxCount)); }else{dwTxCount = GetFifoSize(pSpiPublic->chnum) -((pSPIregs ->SPI_STATUS>>6) & 0x1ff) ;if (dwTxCount != 0){do{pSPIregs->SPI_TX_DATA = *(PBYTE)pSpiPrivate->pTxBuffer;DBGMSG(SPI_USR4,(TEXT("ST %d, %d\r\n"),pSpiPrivate->dwTxCount, dwTxCount)); } while(--pSpiPrivate->dwTxCount > 0 && ++(PBYTE)pSpiPrivate->pTxBuffer && --dwTxCount > 0);}else{ERRMSG((TEXT("dwTxCount is zero %d\r\n"))); // SetEvent(pSpiPublic->hTxIntrDoneEvent);}if(pSpiPrivate->dwTxCount ==0){pSPIregs->SPI_INT_EN &= ~(RX_FIFORDY|TX_FIFORDY);SetEvent(pSpiPublic->hTxIntrDoneEvent);}DBGMSG(SPI_USR3,(TEXT("[SPI]ST %d, %d\r\n"),pSpiPrivate->dwTxCount, dwTxCount)); }}else{ERRMSG((TEXT("[SPI] UNSOLVED OPERATION\n")));}//END_POINT:SetProcPermissions(dwOldPerm);InterruptDone(pSpiPublic->dwSpiSysIntr);} while(TRUE);return 0;}void SPI_PowerDown (PSPI_PUBLIC_CONTEXT pPublicSpi){DBGMSG(SPI_MSG,(TEXT("[SPI] ++PowerDown()\n\r")));if((PSPI_PUBLIC_CONTEXT)pPublicSpi == NULL){goto CleanUp;}DBGMSG(SPI_MSG,(TEXT("[SPI] --PowerDown()\n\r")));CleanUp:return;}void SPI_Deinit (PSPI_PUBLIC_CONTEXT pPublicSpi){DBGMSG(SPI_INIT,(TEXT("++[SPI] SPI_Deinit\r\n")));if((PSPI_PUBLIC_CONTEXT)pPublicSpi == NULL){goto CleanUp;}// Delete CSDeleteCriticalSection(&(pPublicSpi->CsRxAccess));DeleteCriticalSection(&(pPublicSpi->CsTxAccess));// Deinitialize BufferHalFreeCommonBuffer(0, 0, pPublicSpi->SPIDMAInfo.PhysDmaDstBufferAddr, pPublicSpi->SPIDMAInfo.pVirtDmaDstBufferAddr, FALSE);HalFreeCommonBuffer(0, 0, pPublicSpi->SPIDMAInfo.PhysDmaSrcBufferAddr, pPublicSpi->SPIDMAInfo.pVirtDmaSrcBufferAddr, FALSE);// Clear value assigned to DMA physical AddresspPublicSpi->SPIDMAInfo.DmaDstAddress = 0;pPublicSpi->SPIDMAInfo.DmaSrcAddress = 0;// DMA Channel StopDMA_channel_stop(&pPublicSpi->SPIDMAInfo.g_OutputDMA);DMA_channel_stop(&pPublicSpi->SPIDMAInfo.g_InputDMA);DMA_release_channel(&pPublicSpi->SPIDMAInfo.g_OutputDMA);DMA_release_channel(&pPublicSpi->SPIDMAInfo.g_InputDMA);// Assign SYSINTR_NOP valuepPublicSpi->dwSpiSysIntr = SYSINTR_NOP;// Close Handleif (pPublicSpi->hRxEvent != NULL){CloseHandle(pPublicSpi->hRxEvent);}if (pPublicSpi->hRxDoneEvent != NULL){CloseHandle(pPublicSpi->hRxDoneEvent);}if (pPublicSpi->hRxIntrDoneEvent != NULL){CloseHandle(pPublicSpi->hRxIntrDoneEvent);}if (pPublicSpi->hTxEvent != NULL){CloseHandle(pPublicSpi->hTxEvent);}if (pPublicSpi->hTxDoneEvent != NULL){CloseHandle(pPublicSpi->hTxDoneEvent);}if (pPublicSpi->hTxIntrDoneEvent != NULL){CloseHandle(pPublicSpi->hTxIntrDoneEvent);}if (pPublicSpi->hSpiEvent != NULL){CloseHandle(pPublicSpi->hSpiEvent);}if (pPublicSpi->hTxDmaDoneEvent != NULL){CloseHandle(pPublicSpi->hTxDmaDoneEvent);}if (pPublicSpi->hRxDmaDoneEvent != NULL){CloseHandle(pPublicSpi->hRxDmaDoneEvent);}if (pPublicSpi->hRxThread != NULL){CloseHandle(pPublicSpi->hRxThread);}if (pPublicSpi->hTxThread != NULL){CloseHandle(pPublicSpi->hTxThread);}if (pPublicSpi->hSpiThread != NULL){CloseHandle(pPublicSpi->hSpiThread);}if (pPublicSpi->hTxDmaDoneThread != NULL){CloseHandle(pPublicSpi->hTxDmaDoneThread);}if (pPublicSpi->hRxDmaDoneThread != NULL){CloseHandle(pPublicSpi->hRxDmaDoneThread);}// VirtualFreeif (pPublicSpi->pGPIOregs){MmUnmapIoSpace((PVOID)pPublicSpi->pGPIOregs, sizeof(GPIO_REG));pPublicSpi->pGPIOregs = NULL;}if (pPublicSpi->pSPIregs){MmUnmapIoSpace((PVOID)pPublicSpi->pSPIregs, sizeof(SPI_REG));pPublicSpi->pSPIregs = NULL;}if (pPublicSpi->pDMAC0regs){MmUnmapIoSpace((PVOID)pPublicSpi->pDMAC0regs, sizeof(DMAC_REG));pPublicSpi->pDMAC0regs = NULL;}if (pPublicSpi->pDMAC1regs){MmUnmapIoSpace((PVOID)pPublicSpi->pDMAC1regs, sizeof(DMAC_REG));pPublicSpi->pDMAC1regs = NULL;}if (pPublicSpi->pSYSCONregs){MmUnmapIoSpace((PVOID)pPublicSpi->pSYSCONregs, sizeof(CMU_CLK_REG));pPublicSpi->pSYSCONregs = NULL;}// Local FreeLocalFree(pPublicSpi);CleanUp:DBGMSG(SPI_INIT,(TEXT("--[SPI] SPI_Deinit\r\n")));return;}void SPI_PowerUp (PSPI_PUBLIC_CONTEXT pPublicSpi){DBGMSG(SPI_PM,(TEXT("[SPI] ++PowerUp()\n\r")));if((PSPI_PUBLIC_CONTEXT)pPublicSpi == NULL){goto CleanUp;}DBGMSG(SPI_MSG,(TEXT("[SPI] --PowerUp()\n\r")));CleanUp:return;}BOOL SPI_Close (DWORD dwOpen){PSPI_PUBLIC_CONTEXT pSpiPublic = NULL;BOOL bResult = TRUE;DBGMSG(SPI_INIT,(TEXT("++[SPI] SPI_Close\r\n")));if(dwOpen != 0){pSpiPublic = (PSPI_PUBLIC_CONTEXT) dwOpen;}else{bResult = FALSE;goto CleanUp;}// Free all data allocated in openLocalFree( pSpiPublic );CleanUp:DBGMSG(SPI_INIT,(TEXT("--[SPI] SPI_Close\r\n")));return bResult;}DWORD SPI_Seek(DWORD Handle, long lDistance, DWORD dwMoveMethod){return 0;}UINT GetFifoSize(DWORD chnum){UINT dwFifoSize = 0;DBGMSG(SPI_INIT,(TEXT(" ++[SPI] GetFifoSize chnum = %d\r\n"),chnum)); if (chnum == SPI0){dwFifoSize = 64;}else if (chnum == SPI1){dwFifoSize = 16;}else if (chnum == SPI2){dwFifoSize = 16;}else{ERRMSG((TEXT(" GetFifoSize Invalid SPI Channel \r\n"))); dwFifoSize = 0;}DBGMSG(SPI_INIT,(TEXT(" --[SPI] GetFifoSize\r\n"))); return dwFifoSize;}DWORD GetTxTriggerLevel(DWORD chnum){DWORD dwTxTriggerLevel = 0;DBGMSG(SPI_INIT,(TEXT(" ++[SPI] GetTxTriggerLevel chnum = %d\r\n"),chnum)); if (chnum == SPI0){dwTxTriggerLevel = 10;}else if (chnum == SPI1){dwTxTriggerLevel = 15;}else if (chnum == SPI2){dwTxTriggerLevel = 15;}else{ERRMSG((TEXT(" GetTxTriggerLevel Invalid SPI Channel \r\n"))); dwTxTriggerLevel = 0;}DBGMSG(SPI_INIT,(TEXT(" --[SPI] GetTxTriggerLevel\r\n"))); return dwTxTriggerLevel;}#ifdef SPI_FULL_DUPLEXBOOL SPI_FullDuplex(PSPI_PRIVATE_CONTEXT pSpiIOPrivate, PBYTE pRxBuf, PBYTE pTxBuf, DWORD dwCount){ PSPI_PRIVATE_CONTEXT pSpiPrivate = (PSPI_PRIVATE_CONTEXT)pSpiIOPrivate; PSPI_PUBLIC_CONTEXT pSpiPublic = pSpiPrivate->pSpiPublic; volatile SPI_REG *pSPIregs = pSpiPublic->pSPIregs; ULONG WaitReturn; // Check status if(pSpiPrivate->State != STATE_IDLE) { DBGMSG(1,(TEXT(" [SPI] E : STATE IS NOT IDLE (%d)\r\n"), pSpiPrivate->State)); return FALSE; } if((NULL == pTxBuf)||(NULL == pRxBuf)) { DBGMSG(1,(TEXT(" [SPI] E : In OR Out Buf is NULL \r\n"))); return FALSE; } pSpiPrivate->State = STATE_FULLDUPLEX; // Copy TX buf to DMA buf memcpy(pSpiPublic->SPIDMAInfo.pVirtDmaSrcBufferAddr,(PBYTE)pTxBuf, dwCount); // Mapping Rx/Tx buf to DMA buf pSpiPrivate->pTxBuffer = pSpiPublic->SPIDMAInfo.pVirtDmaSrcBufferAddr; pSpiPrivate->pTxDMABuffer = (LPVOID)pSpiPublic->SPIDMAInfo.DmaSrcAddress; pSpiPrivate->pRxBuffer = pSpiPublic->SPIDMAInfo.pVirtDmaDstBufferAddr; pSpiPrivate->pRxDMABuffer = (LPVOID)pSpiPublic->SPIDMAInfo.DmaDstAddress; //SPI RESET pSPIregs->CH_CFG |= SW_RST; while(!(pSPIregs->CH_CFG & SW_RST)); DBGMSG(SPI_USR2,(TEXT("[SPI] HS SPI reset\n"))); pSPIregs->CH_CFG &= ~SW_RST; if(dwCount>0) { // SPI register configuration pSPIregs->CH_CFG = pSpiPrivate->RxSPIregs.CH_CFG; pSPIregs->CLK_CFG = pSpiPrivate->RxSPIregs.CLK_CFG; pSPIregs->MODE_CFG = pSpiPrivate->RxSPIregs.MODE_CFG; pSPIregs->MODE_CFG |= TX_DMA_ON|DMA_SINGLE|RX_DMA_ON; pSPIregs->CH_CFG |= TX_CH_ON|RX_CH_ON; // RX DMA start DMA_set_channel_source(&pSpiPublic->SPIDMAInfo.g_InputDMA, pSpiPrivate->spi_rx_data_addr, BYTE_UNIT, BURST_1, FIXED); DMA_set_channel_destination(&pSpiPublic->SPIDMAInfo.g_InputDMA, (UINT)pSpiPrivate->pRxDMABuffer, BYTE_UNIT, BURST_1, INCREASE); DMA_set_channel_transfer_size(&pSpiPublic->SPIDMAInfo.g_InputDMA, dwCount); DMA_initialize_LLI(&pSpiPublic->SPIDMAInfo.g_InputDMA, 1); DMA_set_LLI_entry(&pSpiPublic->SPIDMAInfo.g_InputDMA, 0, LLI_FIRST_ENTRY, pSpiPrivate->spi_rx_data_addr,(UINT)pSpiPrivate->pRxDMABuffer, dwCount); DMA_channel_start(&pSpiPublic->SPIDMAInfo.g_InputDMA); // TX DMA start DMA_set_channel_source(&pSpiPublic->SPIDMAInfo.g_OutputDMA, (UINT)pSpiPrivate->pTxDMABuffer, BYTE_UNIT, BURST_1, INCREASE); DMA_set_channel_destination(&pSpiPublic->SPIDMAInfo.g_OutputDMA, pSpiPrivate->spi_tx_data_addr, BYTE_UNIT, BURST_1, FIXED); DMA_set_channel_transfer_size(&pSpiPublic->SPIDMAInfo.g_OutputDMA, dwCount); DMA_initialize_LLI(&pSpiPublic->SPIDMAInfo.g_OutputDMA, 1); DMA_set_LLI_entry(&pSpiPublic->SPIDMAInfo.g_OutputDMA, 0, LLI_FIRST_ENTRY, (UINT)pSpiPrivate->pTxDMABuffer,pSpiPrivate->spi_tx_data_addr, dwCount); DMA_channel_start(&pSpiPublic->SPIDMAInfo.g_OutputDMA); if(pSpiPrivate->dwMode == SPI_MASTER_MODE) { DBGMSG(SPI_USR2,(TEXT("[SPI] Thread for FD : MASTER MODE \r\n"))); MASTER_CS_ENABLE; } //Wait DMA done Interrupt // Waiting for RX DMA done interrupt is enough WaitReturn=WaitForSingleObject(pSpiPublic->hRxDmaDoneEvent, READ_TIME_OUT_CONSTANT); if(WAIT_TIMEOUT == WaitReturn) { DBGMSG(1,(TEXT("[SPI] E : RX DMA TIMEOUT\r\n"))); } DMA_clear_interrupt_pending(&pSpiPublic->SPIDMAInfo.g_InputDMA); DMA_set_interrupt_mask(&pSpiPublic->SPIDMAInfo.g_InputDMA); InterruptDone(pSpiPublic->dwRxDmaDoneSysIntr); DMA_clear_interrupt_mask(&pSpiPublic->SPIDMAInfo.g_InputDMA); while(!(pSPIregs ->SPI_STATUS & TX_DONE)); if(pSpiPrivate->dwMode == SPI_MASTER_MODE) { DBGMSG(SPI_USR2,(TEXT("[SPI] Thread for FD : MASTER MODE \r\n"))); MASTER_CS_DISABLE; } // Copy RX DMA Buf to RX Buf memcpy(pRxBuf, pSpiPublic->SPIDMAInfo.pVirtDmaDstBufferAddr, dwCount); } else { return FALSE; } pSpiPrivate->State = STATE_IDLE; return TRUE; }#endif