?? gspi_bus_2440.c
字號(hào):
//JKU: NdisMSleep(5000);
Sleep(5);
GspiHostSetPDHigh();
//JKU: NdisMSleep(5000);
Sleep(5);
GspiHostSetPDLow();
if (GspiUnmapMemories() != GSPI_OK)
return !GSPI_OK;
return GSPI_OK;
}
void GspiBusRaiseBusClock(void)
{
g_pHwInfo->pSPIRegs->rSPPRE0 = 0;
}
void GspiBusLowerBusClock(void)
{
g_pHwInfo->pSPIRegs->rSPPRE0 = 1;
}
int GspiBusCtrlInit()
{
//SET UP Pclk
g_pHwInfo->pSPIRegs->rSPPRE0 = 1;
//set spi control register
// Baud rate
//g_pHwInfo->pSPIRegs->rSPCON0 = (0x0<<5) | 0x18; //TAGD=0,CPHA=0,CPOL=0,MSTR=1,ENSCK=1, SMOD=polling
g_pHwInfo->pSPIRegs->rSPPIN0 = 0x0; //KEEP=0, SPICS=0,ENMUL=0
//DBG_PRINT(gDbgInfo,("GPGCON=0x%x\n", (unsigned long)g_pHwInfo->pGPIORegs->rGPGCON));
// DBG_PRINT(gDbgInfo,("after SPCON0 =0x%lX\n", (unsigned long)g_pHwInfo->pSPIRegs->rSPCON0));
// DBG_PRINT(gDbgInfo,("after rSPPIN0 =0x%lX\n", (unsigned long)g_pHwInfo->pSPIRegs->rSPPIN0));
// DBG_PRINT(gDbgInfo,("after SPPRE0 =0x%lX\n", (unsigned long)g_pHwInfo->pSPIRegs->rSPPRE0));
// RETAILMSG(1, (TEXT("CLKDIVN =0x%lX\n\n"), g_pHwInfo->pCLKRegs->CLKDIVN));
return GSPI_OK;
}
int GspiBusGPIOInit()
{
/*
* Program gpio pins
* XSY: we use
* gpg3 : wlan interrupt
* nSS0 : SCSn signal
* gph10 : RSTn signal
*/
//gpg3 for input, gpe8 gpe9 and gpe10 as output
// g_pHwInfo->pGPIORegs->rGPEDAT |= (0x1 << 9); //GPE9
g_pHwInfo->pGPIORegs->rGPECON &= ~((0x03 << 20)|(0x03 << 18) | (0x03 << 16)); // clear
g_pHwInfo->pGPIORegs->rGPECON |= ((0x01 << 20)|(0x01 << 18) |(0x01 << 16) ); // set
g_pHwInfo->pGPIORegs->rGPECON &= ~((0x03 << 22) | (0x03 << 24) | (0x03 << 26)); // clear
g_pHwInfo->pGPIORegs->rGPECON |= (0x02 << 22) | (0x02 << 24) | (0x02 << 26); // set
// to config spi_cs as general io pin
g_pHwInfo->pGPIORegs->rGPGCON &= ~(0x03 << 4); // clear
g_pHwInfo->pGPIORegs->rGPGCON |= 0x01 << 4; // set
g_pHwInfo->pGPIORegs->rGPGUP |= (0x01 << 2);
//gph10 as output
g_pHwInfo->pGPIORegs->rGPHCON &= ~(0x03 << 20); // clear
g_pHwInfo->pGPIORegs->rGPHCON |= 0x01 << 20; // set
// Diable the pull up function for the output pins
g_pHwInfo->pGPIORegs->rGPEUP |= ((0x01 << 10)|(0x01 << 9) | (0x01 << 8));
g_pHwInfo->pGPIORegs->rGPEUP |= (0x01 << 11) | (0x01 << 12);
/*
// Configure the interrupt pin
g_pHwInfo->pGPIORegs->rGPGCON &= ~(3<<6);
g_pHwInfo->pGPIORegs->rGPGCON |= (2<<6);
g_pHwInfo->pGPIORegs->rGPGUP |= (1<<3);
g_pHwInfo->pGPIORegs->rEXTINT1 &= ~(0xf<<12);
g_pHwInfo->pGPIORegs->rEXTINT1 |= (0x2<<12); //falling edge trigger
*/
GspiHostSetSCSHigh();
return GSPI_OK;
}
int GspiBusIntGPIOInit()
{
DWORD ttt;
// Configure the interrupt pin
g_pHwInfo->pGPIORegs->rGPGCON &= ~(3<<6);
g_pHwInfo->pGPIORegs->rGPGCON |= (2<<6);
g_pHwInfo->pGPIORegs->rGPGUP |= (1<<3);
ttt = (g_pHwInfo->pGPIORegs->rEXTINT1 & (~(0xf<<12))) | (0x2<<12);
g_pHwInfo->pGPIORegs->rEXTINT1 = ttt;
return GSPI_OK;
}
int GspiIntStatus(void)
{
if(0 == (g_pHwInfo->pGPIORegs->rGPGDAT & 0x8))
return TRUE;
return FALSE;
}
int GspiBusReinit()
{
return GSPI_OK;
}
void GspiBusInitRxDMA()
{
return;
}
void GspiBusInitTxDMA()
{
return;
}
int GspiBusDmaInit()
{
//set up DMA iRQ
GspiBusDmaIntrInit(&g_GspiDmaData);
// Request dma for SPI Rx
// Setup rx dma
GspiBusInitRxDMA();
// Request dma for SPI Tx
// Setup tx dma
GspiBusInitTxDMA();
return GSPI_OK;
}
int GspiBusDmaDeinit()
{
//set up DMA iRQ
GspiBusDmaIntrDeinit(&g_GspiDmaData);
return GSPI_OK;
}
int GspiBusDmaIntrInit(IN PGSPI_DMA_DATA pDriver)
{
DWORD irq= IRQ_DMA1;;
pDriver->IstPriority = ISTPRIORITY;
// Create the event flag for the IST.
pDriver->hGspiDmaIntrEvent = CreateEvent(
NULL, //Ignored. Must be NULL.
FALSE, //FALSE, the system automatically resets
FALSE, //it is nonsignaled.
NULL); //NULL, the event object is created without a name.
// Hook the interrupt and start the associated thread.
// Initialize the interrupt to be associated with the hSerialEvent event.
// pDriver->dwDmaIntID = SYSINTR_UNDEFINED;
if( 0== KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &irq, sizeof(DWORD), &pDriver->dwDmaIntID, sizeof(DWORD), NULL))
{
GSPIMSG(1,(TEXT("IOCTL_HAL_REQUEST_SYSINTR failed\n")));
return (!GSPI_OK);
};
GSPIMSG(1,(TEXT("irq = %d sysint= %d\n"),irq, pDriver->dwDmaIntID));
//DBG_PRINT(gDbgInfo,("sysint= %d\n",pDriver->dwIntID));
if(0 == InterruptInitialize(
pDriver->dwDmaIntID, // Logical ID = SYSINTR_FIRMWARE (16)+Irq
pDriver->hGspiDmaIntrEvent, // Event used by OS to trigger thread
NULL, // Ptr passed to OEMInterruptEnable
0))
{
GSPIMSG(1,(TEXT("InterruptInitialize failed\n")));
return (!GSPI_OK);
};
// Create and start the IST thread
pDriver->hIstDmaThread = CreateThread(
NULL, // no security attributes
0, // use default stack size
GspiBusDmaIST, // thread function
pDriver, // argument to thread function
0, // use default creation flags
NULL); // returns the thread identifier
return (GSPI_OK);
}
// IST: The actual Interrupt Service Thread.
static DWORD WINAPI GspiBusDmaIST(PVOID pContext)
{
DWORD dwExitCode;
PGSPI_DMA_DATA pDrv = (PGSPI_DMA_DATA)pContext;
CeSetThreadPriority(GetCurrentThread(), pDrv->IstPriority);
while (1)
{
//DBG_PRINT(gDbgInfo,("DMA IST is running.\n"));
// Wait for the kernel to set the event flag.
WaitForSingleObject(pDrv->hGspiDmaIntrEvent, INFINITE);
if (pDrv->gspi_dma_exit)
{
GSPIMSG(1,(TEXT(" DMA IST shutting down!\n")));
break;
}
// Call an internal function to process the interrupt
//DBG_PRINT(gDbgInfo,("GSPIDrvHandler is called!\n"));
// Signal the end of interrupt processing
InterruptDone(pDrv->dwDmaIntID);
GspiBusDMADone();
}
//following are resource clean up
//InterruptDisable( pDrv->dwIntID ); //disable the hardware interrupt and to deregister the event registered.
//CloseHandle(pDrv->hGspiIntrEvent); //close event
GetExitCodeThread (pDrv->hIstDmaThread, &dwExitCode);
ExitThread(dwExitCode); //gracefully exit thread
//CloseHandle(pDrv->hIstThread); //close thread handle
return (0);
}
// Code adapted from \Public\Common\Oak\Drivers\Serial\MDD.c
// Intr_Init: Called when the driver is initialized.
int GspiBusDmaIntrDeinit(IN PGSPI_DMA_DATA pDriver)
{
// unregister the interrupt event
InterruptDisable(pDriver->dwDmaIntID);
KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR, &pDriver->dwDmaIntID, sizeof(DWORD), NULL, 0, NULL);
//JKU: NdisMSleep(1);
Sleep(0);
// to stop IST thread
pDriver->gspi_dma_exit = 1;
SetEvent(pDriver->hGspiDmaIntrEvent);
//NdisMSleep(1);
//YYU: wait for the IST
WaitForSingleObject(pDriver->hIstDmaThread, INFINITE);
GSPIMSG(1,(TEXT("Dma IST ended\n")));
// To release the event object
CloseHandle(pDriver->hGspiDmaIntrEvent);
CloseHandle(pDriver->hIstDmaThread); //close thread handle
return (GSPI_OK);
}
void GspiBusStartRxDMA(USHORT usDstOffset, USHORT usSizeInBytes)
{
//memset(g_pHwInfo->dmaRxBuf, 0, BSP_GSPI_DMA_RX_BUF_SIZE); // clear for debug output
while (g_pHwInfo->pDMARegs->rDSTAT1);
// source
g_pHwInfo->pDMARegs->rDISRC1 = (int)(PHY_RX_REG_BASE);
g_pHwInfo->pDMARegs->rDISRCC1 = (SOURCE_PERIPHERAL_BUS | FIXED_SOURCE_ADDRESS); // Src is periperal bus, fixed addr
// dest
g_pHwInfo->pDMARegs->rDIDST1 = (int)(g_pHwInfo->dmaPhyRxBuf + (DWORD)usDstOffset);
g_pHwInfo->pDMARegs->rDIDSTC1 &= ~(DESTINATION_PERIPHERAL_BUS | FIXED_DESTINATION_ADDRESS); // Dest is system bus, increment addr
// configure dma channel
g_pHwInfo->pDMARegs->rDCON1 = ( SPI_DMA1 | DMA_TRIGGERED_BY_HARDWARE
| NO_DMA_AUTO_RELOAD | TRANSFER_BYTE | usSizeInBytes );
g_pHwInfo->pDMARegs->rDMASKTRIG1 = ENABLE_DMA_CHANNEL;
}
void GspiBusStopRxDMA()
{
}
void GspiBusStartTxDMA(USHORT usSrcOffset, USHORT usSizeInBytes)
{
while (g_pHwInfo->pDMARegs->rDSTAT1);
// source
g_pHwInfo->pDMARegs->rDISRC1 = (int)(g_pHwInfo->dmaPhyTxBuf + (DWORD)usSrcOffset);
g_pHwInfo->pDMARegs->rDISRCC1 &= ~(SOURCE_PERIPHERAL_BUS | FIXED_SOURCE_ADDRESS); // Source is system bus, increment addr
// dest
g_pHwInfo->pDMARegs->rDIDST1 = (int)PHY_TX_REG_BASE;
g_pHwInfo->pDMARegs->rDIDSTC1 = (DESTINATION_PERIPHERAL_BUS | FIXED_DESTINATION_ADDRESS); // Dest is periperal bus, fixed addr
// configure dma channel
g_pHwInfo->pDMARegs->rDCON1 = ( SPI_DMA1 | DMA_TRIGGERED_BY_HARDWARE
| NO_DMA_AUTO_RELOAD | TRANSFER_BYTE | usSizeInBytes);
g_pHwInfo->pDMARegs->rDMASKTRIG1 = ENABLE_DMA_CHANNEL;
}
void GspiBusStartTxRxDMA(USHORT usSrcOffset, USHORT usSizeInBytes)
{
while (g_pHwInfo->pDMARegs->rDSTAT1);
// source
g_pHwInfo->pDMARegs->rDISRC1 = (int)(g_pHwInfo->dmaPhyTxRxBuf + (DWORD)usSrcOffset);
g_pHwInfo->pDMARegs->rDISRCC1 &= ~(SOURCE_PERIPHERAL_BUS | FIXED_SOURCE_ADDRESS); // Source is system bus, increment addr
// dest
g_pHwInfo->pDMARegs->rDIDST1 = (int)PHY_TX_REG_BASE;
g_pHwInfo->pDMARegs->rDIDSTC1 = (DESTINATION_PERIPHERAL_BUS | FIXED_DESTINATION_ADDRESS); // Dest is periperal bus, fixed addr
// configure dma channel
g_pHwInfo->pDMARegs->rDCON1 = ( SPI_DMA1 | DMA_TRIGGERED_BY_HARDWARE
| NO_DMA_AUTO_RELOAD | TRANSFER_BYTE | usSizeInBytes);
g_pHwInfo->pDMARegs->rDMASKTRIG1 = ENABLE_DMA_CHANNEL;
}
void GspiBusStopTxDMA()
{
}
void GspiBusWaitForTxDMA()
{
while (g_pHwInfo->pDMARegs->rDSTAT1);
}
void GspiBusWaitForRxDMA()
{
while (g_pHwInfo->pDMARegs->rDSTAT1);
}
#ifndef DEBUG
UINT32 spi_bus_delay = 0;
void gspi_bus_delay(int times)
{
int i;
for (i=0; i< times; i++)
spi_bus_delay = i;
}
__inline void gspi_wait_for_bus_rdy()
{
//while(!(*spi_status_ptr & BIT0));
while (!(spi_status & BIT0))
spi_status = (volatile)g_pHwInfo->pSPIRegs->rSPSTA0;
spi_status = 0;
}
#endif
void gspi_xmt_data(UINT16* pData,UINT16 size)
{
register int ii;
for (ii = 0; ii < size; ii++)
{
GSPI_WAIT_FOR_BUS_RDY();
//while (!((volatile)(g_pHwInfo->pSPIRegs->rSPSTA0) & BIT0));
*(UINT8*)(&g_pHwInfo->pSPIRegs->rSPTDAT0) = (UINT8)((*pData & 0xff00) >> 8);
//while (!((volatile)(g_pHwInfo->pSPIRegs->rSPSTA0) & BIT0));
GSPI_WAIT_FOR_BUS_RDY();
*(UINT8*)(&g_pHwInfo->pSPIRegs->rSPTDAT0) = (UINT8)(*pData & 0xff);
pData++;
}
GSPI_WAIT_FOR_BUS_RDY();
//while (!((volatile)(g_pHwInfo->pSPIRegs->rSPSTA0) & BIT0))
}
void gspi_recv_data(UINT16* pData,UINT16 size)
{
// UINT8 buf[100];
//UINT8 *pBuf = buf;
register int ii;
GspiBusSetReceiver_nodma();
//throw away the first byte
//DBG_PRINT(gDbgInfo,("gspi_recv_data=0x%x size =%d\n", *pData, size));
GSPI_WAIT_FOR_BUS_RDY();
//while (!((volatile)(g_pHwInfo->pSPIRegs->rSPSTA0) & BIT0));
pData[0] = (UINT8)(g_pHwInfo->pSPIRegs->rSPRDAT0);
//GSPI_BUS_DELAY(20);
GSPI_WAIT_FOR_BUS_RDY();
//while (!((volatile)(g_pHwInfo->pSPIRegs->rSPSTA0) & BIT0));
pData[0] = (UINT8)(g_pHwInfo->pSPIRegs->rSPRDAT0);
//GSPI_BUS_DELAY(20);
for (ii = 0; ii < size ; ii ++)
{
GSPI_WAIT_FOR_BUS_RDY();
//while (!((volatile)(g_pHwInfo->pSPIRegs->rSPSTA0) & BIT0));
pData[ii ] = (UINT8)(g_pHwInfo->pSPIRegs->rSPRDAT0) << 8;
GSPI_WAIT_FOR_BUS_RDY();
//while (!((volatile)(g_pHwInfo->pSPIRegs->rSPSTA0) & BIT0));
pData[ii ] |= (UINT8)g_pHwInfo->pSPIRegs->rSPRDAT0;
//GSPI_BUS_DELAY(20);
}
GSPI_WAIT_FOR_BUS_RDY();
GspiBusResetReceiver();
}
void gspi_write_for_read(UINT16 data, INT32 now)
{
register int ii;
UINT16 dummy = 0xffff;
gspi_xmt_data((UINT16*)&data,1);
for (ii = 0; ii < now - 1; ii++)
{
gspi_xmt_data((UINT16*)&dummy, 1);
}
}
int gspi_read_data_direct(UCHAR *data, UINT16 reg, UINT16 size)
{
GspiBusAcquireIO();
GspiHostSetSCSHigh();
GspiHostSetSCSLow();
GspiBusSetTransmitter_nodma();
gspi_write_for_read(reg, 1 + g_spi_dummy_clk_data);
GspiBusSetReceiver();
GspiBusStartRxDMA(0, size * 2 + 2);
GspiBusWaitForRxDMA();
GSPI_WAIT_FOR_BUS_RDY();
// GspiHostSetSCSHigh();
GspiBusResetReceiver();
//if (((volatile)(g_pHwInfo->pSPIRegs->rSPSTA0) & BIT0))
{ // read the last byte
g_pHwInfo->dmaRxBuf[size * 2] = g_pHwInfo->pSPIRegs->rSPRDAT0 & 0xff;
}
/*
DBG_PRINT(gDbgInfo,("rbuffer: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
g_pHwInfo->dmaRxBuf[0],
g_pHwInfo->dmaRxBuf[1],
g_pHwInfo->dmaRxBuf[2],
g_pHwInfo->dmaRxBuf[3],
g_pHwInfo->dmaRxBuf[4],
g_pHwInfo->dmaRxBuf[5],
g_pHwInfo->dmaRxBuf[6],
g_pHwInfo->dmaRxBuf[7],
g_pHwInfo->dmaRxBuf[8],
g_pHwInfo->dmaRxBuf[9],
g_pHwInfo->dmaRxBuf[10],
g_pHwInfo->dmaRxBuf[11],
g_pHwInfo->dmaRxBuf[12],
g_pHwInfo->dmaRxBuf[13],
g_pHwInfo->dmaRxBuf[14],
g_pHwInfo->dmaRxBuf[15],
g_pHwInfo->dmaRxBuf[16],
g_pHwInfo->dmaRxBuf[17],
g_pHwInfo->dmaRxBuf[18],
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -