?? gspi_bus_2440.c
字號:
#if defined(IF_GSPI) && (defined(SC2442_SPI))
#include <Windows.h>
#include <Pkfuncs.h>
#include "s3c2440a.h"
#define SSPreg S3C2440A_SPI_REG
#define DMAreg S3C2440A_DMA_REG
#define IOPreg S3C2440A_IOPORT_REG
#define CLKreg S3C2440A_CLKPWR_REG
#define SSP_BASE S3C2440A_BASE_REG_PA_SPI
#define IOP_BASE S3C2440A_BASE_REG_PA_IOPORT
#define DMA_BASE S3C2440A_BASE_REG_PA_DMA
#define CLK_BASE S3C2440A_BASE_REG_PA_CLOCK_POWER
#define rGPDDAT GPDDAT
#define rGPDCON GPDCON
#define rGPDUP GPDUP
#define rGPEDAT GPEDAT
#define rGPECON GPECON
#define rGPEUP GPEUP
#define rGPFDAT GPFDAT
#define rGPFCON GPFCON
#define rGPFUP GPFUP
#define rGPGDAT GPGDAT
#define rGPGCON GPGCON
#define rGPGUP GPGUP
#define rGPHDAT GPHDAT
#define rGPHCON GPHCON
#define rGPHUP GPHUP
#define rSPCON0 SPCON0
#define rSPPRE0 SPPRE0
#define rSPPIN0 SPPIN0
#define rSPSTA0 SPSTA0
#define rSPTDAT0 SPTDAT0
#define rSPRDAT0 SPRDAT0
#define rMISCCR MISCCR
#define rEXTINT0 EXTINT0
#define rEXTINT1 EXTINT1
#define rDSTAT1 DSTAT1
#define rDISRC1 DISRC1
#define rDISRCC1 DISRCC1
#define rDIDST1 DIDST1
#define rDIDSTC1 DIDSTC1
#define rDIDSTC1 DIDSTC1
#define rDCON1 DCON1
#define rDSTAT3 DSTAT3
#define rDISRC3 DISRC3
#define rDISRCC3 DISRCC3
#define rDIDST3 DIDST3
#define rDIDSTC3 DIDSTC3
#define rDIDSTC3 DIDSTC3
#define rDCON3 DCON3
#define rDMASKTRIG3 DMASKTRIG3
#include "gspi_bus_2440.h"
typedef struct GspiBusDmaData
{
DWORD dwDmaIntID;
HANDLE hGspiDmaIntrEvent;
HANDLE hIstDmaThread;
HANDLE hGspiBusSem;
int IstPriority;
BOOLEAN gspi_dma_exit;
}
GSPI_DMA_DATA,*PGSPI_DMA_DATA;
static SYSTEM_INFO si = {0, 0, 0, 0};
#ifndef DEBUG
#define GSPI_BUS_DELAY(x) gspi_bus_delay(x)
#else
#define GSPI_BUS_DELAY(x)
#endif
//#define GSPI_WAIT_FOR_BUS_RDY() while(!(*spi_status_ptr & BIT0))
//#define GSPI_WAIT_FOR_BUS_RDY() while(!(*((volatile UINT32 *)(&(g_pHwInfo->pSPIRegs->rSPSTA0))) & BIT0))
#if 1
#ifndef DEBUG
#define GSPI_WAIT_FOR_BUS_RDY() gspi_wait_for_bus_rdy()
#else
#define GSPI_WAIT_FOR_BUS_RDY() while (!((volatile)(g_pHwInfo->pSPIRegs->rSPSTA0) & BIT0))
#endif
#endif
/* ----- Local function declaration -------- */
UINT32 spi_status = 0;
void* MapIOSpace(void* pPhysAddr,
DWORD dwSize,
DWORD dwFlags);
void UnmapIOSpace(void* pVirtAddr);
DWORD WINAPI GspiBusDmaIST(PVOID pContext);
int GspiBusCtrlInit();
int GspiBusGPIOInit();
int GspiBusDmaInit();
void GspiBusInitRxDMA();
void GspiBusInitTxDMA();
static __inline
void gspi_bus_delay(int times);
static __inline
void gspi_wait_for_bus_rdy();
static __inline
void gspi_xmt_data(UINT16* pData,UINT16 size);
static __inline
void gspi_recv_data(UINT16* pData,UINT16 size);
int gspi_read_data(UINT16 *data, UINT16 size);
int gspi_bus_write_data(UINT16 *data, UINT16 size);
int gspi_read_data_direct(UCHAR *data, UINT16 reg, UINT16 size);
int gspi_bus_write_data_direct(UCHAR *data, UINT16 reg, UINT16 size);
void gspi_delay(int loop);
unsigned long GspiBusGetBSPDMAIntID();
int GspiBusDmaDeinit();
int GspiBusDmaIntrInit(IN PGSPI_DMA_DATA pDriver);
int GspiBusDmaIntrDeinit(IN PGSPI_DMA_DATA pDriver);
/* ----------------------------------------- */
/* Use default clock rate of 20 Mhz for GSPI. So, clkdiv as 0 */
static int clkdiv = 0;
//extern int g_spi_dummy_clk_reg;
//extern int g_spi_dummy_clk_data;
int g_spi_dummy_clk_reg = 0x05; //JKU
int g_spi_dummy_clk_data = 0x0e; //JKU
volatile UINT32 *spi_status_ptr;
// Pointers to Hardware register base.
static GSPI_HW_INFO HwInfo;
pGSPI_HW_INFO g_pHwInfo = &HwInfo;
static GSPI_DMA_DATA g_GspiDmaData;
#ifdef BUILT_FOR_LGEVT
volatile BSP_ARGS* g_pBspArgs = NULL;
#endif
//__inline
void GspiBusDMADone()//PSPI_DMA_DATA pDrv);
{
ReleaseSemaphore(g_GspiDmaData.hGspiBusSem, 1, NULL);
}
//__inline
int GspiBusWaitForDMA()
{
WaitForSingleObject(g_GspiDmaData.hGspiBusSem, INFINITE);
return 1;
}
void gspi_set_read_delay(int reg,int io)
{
g_spi_dummy_clk_reg = reg;
g_spi_dummy_clk_data = io;
}
void GspiHostSetTst1High()
{
g_pHwInfo->pGPIORegs->rGPEDAT |= (0x1 << 10); //GPE10
}
void GspiHostSetTst1Low()
{
g_pHwInfo->pGPIORegs->rGPEDAT &= ~(0x1 << 10); //GPE10
}
void GspiHostSetTst2Low()
{
g_pHwInfo->pGPIORegs->rGPEDAT &= ~(0x1 << 9); //GPE9
}
void GspiHostSetTst2High()
{
g_pHwInfo->pGPIORegs->rGPEDAT |= (0x1 << 9); //GPE9
}
void GspiHostSetTst3High()
{
g_pHwInfo->pGPIORegs->rGPEDAT |= (0x1 << 8); //GPE8
}
void GspiHostSetTst3Low()
{
g_pHwInfo->pGPIORegs->rGPEDAT &= ~(0x1 << 8); //GPE8
}
void GspiHostSetSCSHigh()
{
//g_pHwInfo->pGPIORegs->rGPEDAT |= (0x1 << 9); //GPE9
g_pHwInfo->pGPIORegs->rGPGDAT |= (0x1 << 2); //nSS0
gspi_delay(10);
}
void GspiHostSetSCSLow()
{
//g_pHwInfo->pGPIORegs->rGPEDAT &= ~(0x1 << 9); //GPE9
g_pHwInfo->pGPIORegs->rGPGDAT &= ~(0x1 << 2); //nSS0
}
void GspiHostSetRSTHigh()
{
g_pHwInfo->pGPIORegs->rGPHDAT |= (0x1 << 10); //GPH10
}
void GspiHostSetRSTLow()
{
g_pHwInfo->pGPIORegs->rGPHDAT &= ~(0x1 << 10); //GPH10
}
void GspiHostSetPDHigh()
{
g_pHwInfo->pGPIORegs->rGPEDAT |= (0x1 << 9); //GPE9
}
void GspiHostSetPDLow()
{
g_pHwInfo->pGPIORegs->rGPEDAT &= ~(0x1 << 9); //GPE9
}
void GspiHostSetPwrEnHigh()
{
}
void GspiHostSetPwrEnLow()
{
}
static __inline
void prepare_for_spibus(UCHAR *data, UCHAR* source, UINT16 size)
{
register int ii, jj;
UINT16 *tmpval = (UINT16*)data;
for (ii = 0; ii < size; ii++)
{
jj = 2 * ii;
tmpval[ii] = (source[jj] << 8) | (source[jj+1] );
}
}
static __inline
void GspiBusSetTransmitter(void)
{
//DBG_PRINT(gDbgInfo,("before SPCON0 =0x%lX\n", (unsigned long)g_pHwInfo->pSPIRegs->rSPCON0));
g_pHwInfo->pSPIRegs->rSPCON0 = (0x0<<5) | 0x58; //TAGD=0,CPHA=0,CPOL=0,MSTR=1,ENSCK=1, SMOD=DMA
//DBG_PRINT(gDbgInfo,("after SPCON0 =0x%lX\n", (unsigned long)g_pHwInfo->pSPIRegs->rSPCON0));
}
static __inline
void GspiBusSetTransmitter_nodma(void)
{
//DBG_PRINT(gDbgInfo,("before SPCON0 =0x%lX\n", (unsigned long)g_pHwInfo->pSPIRegs->rSPCON0));
g_pHwInfo->pSPIRegs->rSPCON0 = (0x0<<5) | 0x18; //TAGD=0,CPHA=0,CPOL=0,MSTR=1,ENSCK=1, SMOD=polling
// g_pHwInfo->pSPIRegs->rSPCON0 = (0x0<<5) | 0x38; //TAGD=0,CPHA=0,CPOL=0,MSTR=1,ENSCK=1, SMOD=Interrupt
//DBG_PRINT(gDbgInfo,("after SPCON0 =0x%lX\n", (unsigned long)g_pHwInfo->pSPIRegs->rSPCON0));
}
static __inline
void GspiBusResetTransmitter(void)
{
g_pHwInfo->pSPIRegs->rSPCON0 = (0x0<<5) | 0x18; //TAGD=0,CPHA=0,CPOL=0,MSTR=1,ENSCK=1, SMOD=polling
}
static __inline
void GspiBusSetReceiver(void)
{
//DBG_PRINT(gDbgInfo,("before SPCON0 =0x%lX\n", (unsigned long)g_pHwInfo->pSPIRegs->rSPCON0));
g_pHwInfo->pSPIRegs->rSPCON0 = (0x0<<5) | 0x59; //TAGD=0,CPHA=0,CPOL=0,MSTR=1,ENSCK=1, SMOD=DMA
//DBG_PRINT(gDbgInfo,("after SPCON0 =0x%lX\n", (unsigned long)g_pHwInfo->pSPIRegs->rSPCON0));
}
static __inline
void GspiBusSetReceiver_nodma(void)
{
//DBG_PRINT(gDbgInfo,("before SPCON0 =0x%lX\n", (unsigned long)g_pHwInfo->pSPIRegs->rSPCON0));
g_pHwInfo->pSPIRegs->rSPCON0 = (0x0<<5) | 0x19; //TAGD=0,CPHA=0,CPOL=0,MSTR=1,ENSCK=1, SMOD=polling
// g_pHwInfo->pSPIRegs->rSPCON0 = (0x0<<5) | 0x39; //TAGD=0,CPHA=0,CPOL=0,MSTR=1,ENSCK=1, SMOD=interrupt
//DBG_PRINT(gDbgInfo,("after SPCON0 =0x%lX\n", (unsigned long)g_pHwInfo->pSPIRegs->rSPCON0));
}
static __inline
void GspiBusResetReceiver(void)
{
g_pHwInfo->pSPIRegs->rSPCON0 = (0x0<<5) | 0x18; //TAGD=0,CPHA=0,CPOL=0,MSTR=1,ENSCK=1, SMOD=polling
}
int GspiCardInit(void)
{
// take the card out of reset
GspiHostSetRSTHigh();
//NdisMSleep(1000);
Sleep(1);
GspiHostSetRSTLow();
//JKU: NdisMSleep(5000);
Sleep(5);
GspiHostSetRSTHigh();
//JKU: NdisMSleep(1000);
Sleep(1);
return GSPI_OK;
}
//
// Map H/W registers and DMA pages into the local address space.
//
int GspiMapMemories()
{
// Map SPI registers into driver address space
g_pHwInfo->pSPIRegs = (SSPreg*)MapIOSpace(
(void *)( SSP_BASE ),
sizeof(SSPreg),
( PAGE_READWRITE | PAGE_NOCACHE )
);
if (!g_pHwInfo->pSPIRegs)
{
ERRORMSG( TRUE, ( TEXT( "GSPI: ERROR mapping SPI registers.\n" ) ) );
return !GSPI_OK;
}
// DBG_PRINT(gDbgInfo,("SPI register virtual addr =0x%lX\n", (unsigned long)g_pHwInfo->pSPIRegs));
// Map gpio register space
g_pHwInfo->pGPIORegs = (IOPreg*)MapIOSpace(
(void*)( IOP_BASE ),
sizeof( IOPreg ),
PAGE_READWRITE | PAGE_NOCACHE );
if (!g_pHwInfo->pGPIORegs)
{
ERRORMSG( TRUE, ( TEXT( "GSPI: ERROR mapping GPIO registers.\n" ) ) );
return !GSPI_OK;
}
// DBG_PRINT(gDbgInfo,("GPIO register virtual addr =0x%lX\n", (unsigned long)g_pHwInfo->pGPIORegs));
// Map clock register space
g_pHwInfo->pCLKRegs = (CLKreg*)MapIOSpace(
(void*)( CLK_BASE ),
sizeof( CLKreg ),
PAGE_READWRITE | PAGE_NOCACHE );
if (!g_pHwInfo->pCLKRegs)
{
ERRORMSG( TRUE, ( TEXT( "GSPI: ERROR mapping CLK registers.\n" ) ) );
return !GSPI_OK;
}
// DBG_PRINT(gDbgInfo,("CLK register virtual addr =0x%lX\n", (unsigned long)g_pHwInfo->pCLKRegs));
// Map DMA registers into driver address space
g_pHwInfo->pDMARegs = (DMAreg*)MapIOSpace(
(void *)( DMA_BASE ),
sizeof(DMAreg),
( PAGE_READWRITE | PAGE_NOCACHE ) );
if (!g_pHwInfo->pDMARegs)
{
ERRORMSG( TRUE, ( TEXT( "GSPI: ERROR mapping DMA registers.\n" ) ) );
return !GSPI_OK;
}
// DBG_PRINT(gDbgInfo,("DMA register virtual addr =0x%lX\n", (unsigned long)g_pHwInfo->pDMARegs));
// Allocate a block of virtual memory big enough to hold the DMA buffers
g_pHwInfo->dmaTxBuf = AllocPhysMem(BSP_GSPI_DMA_TX_BUF_SIZE, ( PAGE_READWRITE | PAGE_NOCACHE ), 0, 0, &g_pHwInfo->dmaPhyTxBuf);
if (!g_pHwInfo->dmaTxBuf)
{
ERRORMSG( TRUE, ( TEXT( "GSPI: ERROR allocate Tx DMA memory.\n" ) ) );
return !GSPI_OK;
}
g_pHwInfo->dmaRxBuf = AllocPhysMem(BSP_GSPI_DMA_RX_BUF_SIZE, ( PAGE_READWRITE | PAGE_NOCACHE ), 0, 0, &g_pHwInfo->dmaPhyRxBuf);
if (!g_pHwInfo->dmaRxBuf)
{
ERRORMSG( TRUE, ( TEXT( "GSPI: ERROR allocate Rx memory.\n" ) ) );
return !GSPI_OK;
}
g_pHwInfo->dmaTxRxBuf = AllocPhysMem(BSP_GSPI_DMA_TX_RX_BUF_SIZE, ( PAGE_READWRITE | PAGE_NOCACHE ), 0, 0, &g_pHwInfo->dmaPhyTxRxBuf);
if (!g_pHwInfo->dmaTxRxBuf)
{
ERRORMSG( TRUE, ( TEXT( "GSPI: ERROR allocate TxRx memory.\n" ) ) );
return !GSPI_OK;
}
memset(g_pHwInfo->dmaTxRxBuf, 0xff, BSP_GSPI_DMA_TX_RX_BUF_SIZE);
// DBG_PRINT(gDbgInfo,("DMA tx buffer virtual addr =0x%lX, phy addr=0x%x\n", (unsigned long)g_pHwInfo->dmaTxBuf, g_pHwInfo->dmaPhyTxBuf));
// DBG_PRINT(gDbgInfo,("DMA rx buffer virtual addr =0x%lX, phy addr=0x%x\n", (unsigned long)g_pHwInfo->dmaRxBuf, g_pHwInfo->dmaPhyRxBuf));
// DBG_PRINT(gDbgInfo,("DMA txrx buffer virtual addr =0x%lX, phy addr=0x%x\n", (unsigned long)g_pHwInfo->dmaTxRxBuf, g_pHwInfo->dmaPhyTxRxBuf));
return GSPI_OK;
}
int GspiUnmapMemories()
{
// Unmap SPI registers into driver address space
if(g_pHwInfo->pSPIRegs)
UnmapIOSpace(g_pHwInfo->pSPIRegs);
// Unmap gpio register space
if(g_pHwInfo->pGPIORegs)
UnmapIOSpace(g_pHwInfo->pGPIORegs);
// Unmap clock register space
if(g_pHwInfo->pCLKRegs)
UnmapIOSpace(g_pHwInfo->pCLKRegs);
// Map DMA registers into driver address space
if(g_pHwInfo->pDMARegs)
UnmapIOSpace(g_pHwInfo->pDMARegs);
// Free the virtual memory allocated for DMA buffers
if (g_pHwInfo->dmaTxBuf)
FreePhysMem(g_pHwInfo->dmaTxBuf);
if(g_pHwInfo->dmaRxBuf)
FreePhysMem(g_pHwInfo->dmaRxBuf);
if(g_pHwInfo->dmaTxRxBuf)
FreePhysMem(g_pHwInfo->dmaTxRxBuf);
return GSPI_OK;
}
int GspiBusHwReset()
{
GspiHostSetPDHigh();
//JKU: NdisMSleep(5000);
Sleep(5);
// Initialize SPI controller here
if(GspiBusGPIOInit() != GSPI_OK)
return !GSPI_OK;
if(GspiBusCtrlInit() != GSPI_OK)
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -