📄 ser2440_hw.c
字号:
s2440IOP->rGPBCON &= ~(0x3<<0);//2); // clear GPBCON for GPB1 (nIRDAEN)
s2440IOP->rGPBCON |= (0x1<<0);//2); // set GPBCON for GPB1 output
s2440IOP->rGPBUP |= (0x1<<0);//1); // set GPB1 pullup disable (external pullup)
s2440IOP->rGPBDAT &= ~(0x1<<0);//1); // set GPB1 signal low
s2440IOP->rGPHCON &= ~(0x3<<12 | 0x3<<14); // clear uart 2 - rx, tx
s2440IOP->rGPHCON |= (0x2<<12 | 0x2<<14);
s2440IOP->rGPHUP |= 0xc0;
#endif
LeaveCriticalSection(&(pHWHead->RegCritSec));
}
S2440_SetSerialIOP(
PVOID pHead // @parm points to device head
)
{
PS2440_UART_INFO pHWHead = (PS2440_UART_INFO)pHead;
PSER_INFO pHWHead1 = (PSER_INFO)pHead;
RETAILMSG(DEBUGMODE, (TEXT("S2440_SetSerialIOP \r\n")));
if(pHWHead1->dwIOBase == 0x50000000) // add by perry
{
#if USEVIRTUAL
EnterCriticalSection(&(pHWHead->RegCritSec));
//2006-7-20 wsf
v_pIOPregs->rGPHCON &= ~(0x3<<0 | 0x3<<2 | 0x3<<4 | 0x3<<6 );//clear uart0 all pins
v_pIOPregs->rGPHCON |= (0x2<<4 | 0x2<<6 );//enable uart0 TXD0,RXD0
v_pIOPregs->rGPHCON |= (0x2<<0 | 0x2<<2 );//enable uart0 CTS0,RTS0
v_pIOPregs->rGPHUP |= 0xC3;//cts0 rts0 pull up,txd0 rxd0 no pull up
/* pHWHead->rDTRport = (volatile unsigned int *)&(v_pIOPregs->rGPHDAT);
pHWHead->rDSRport = (volatile unsigned int *)&(v_pIOPregs->rGPHDAT);
pHWHead->DtrPortNum = 6;
pHWHead->DsrPortNum = 7;*/
#else
volatile IOPreg *s2440IOP;
s2440IOP = (volatile IOPreg *)IOP_BASE;
EnterCriticalSection(&(pHWHead->RegCritSec));
s2440IOP->rGPHCON &= ~(0x3<<0 | 0x3<<2 | 0x3<<4 | 0x3<<6 );
s2440IOP->rGPHCON |= (0x2<<4 | 0x2<<6 );
s2440IOP->rGPHCON |= (0x2<<0 | 0x2<<2 );
s2440IOP->rGPHUP |= 0xC3;
/* pHWHead->rDTRport = (volatile unsigned int *)(IOP_BASE+0x74); //s2440IOP->rGPHDAT
pHWHead->rDSRport = (volatile unsigned int *)(IOP_BASE+0x74);
pHWHead->DtrPortNum = 6;
pHWHead->DsrPortNum = 7;*/
#endif
}
else if(pHWHead1->dwIOBase == 0x50004000)
{
#if USEVIRTUAL
EnterCriticalSection(&(pHWHead->RegCritSec));
//2006-7-20 wsf
v_pIOPregs->rGPHCON &= ~(0x3<<8 | 0x3<<10 );//clear uart1 rxd1 txd1
v_pIOPregs->rGPHCON |= (0x2<<8 | 0x2<<10 );//enabled rxd1 txd1,no used cts1 rts1
v_pIOPregs->rGPHUP |= 0xc0;//no need pull up
/* pHWHead->rDTRport = (volatile unsigned int *)&(v_pIOPregs->rGPHDAT);
pHWHead->rDSRport = (volatile unsigned int *)&(v_pIOPregs->rGPHDAT);
pHWHead->DtrPortNum = 6;
pHWHead->DsrPortNum = 7;*/
#else
volatile IOPreg *s2440IOP;
s2440IOP = (volatile IOPreg *)IOP_BASE;
EnterCriticalSection(&(pHWHead->RegCritSec));
s2440IOP->rGPHCON &= ~(0x3<<8 | 0x3<<10 );
s2440IOP->rGPHCON |= (0x2<<8 | 0x2<<10 );
s2440IOP->rGPHUP |= 0xc0;
/* pHWHead->rDTRport = (volatile unsigned int *)(IOP_BASE+0x74); //s2440IOP->rGPHDAT
pHWHead->rDSRport = (volatile unsigned int *)(IOP_BASE+0x74);
pHWHead->DtrPortNum = 6;
pHWHead->DsrPortNum = 7;*/
#endif
}
else if(pHWHead1->dwIOBase == 0x50008000)
{
#if USEVIRTUAL
EnterCriticalSection(&(pHWHead->RegCritSec));
//2006-7-20 wsf
v_pIOPregs->rGPHCON &= ~(0x3<<12 | 0x3<<14 );//clear rxd2 txd2
v_pIOPregs->rGPHCON |= (0x2<<12 | 0x2<<14 );//enabled rxd2 txd2
v_pIOPregs->rGPHUP |= 0xc0;
/* pHWHead->rDTRport = (volatile unsigned int *)&(v_pIOPregs->rGPHDAT);
pHWHead->rDSRport = (volatile unsigned int *)&(v_pIOPregs->rGPHDAT);
pHWHead->DtrPortNum = 6;
pHWHead->DsrPortNum = 7;*/
#else
volatile IOPreg *s2440IOP;
s2440IOP = (volatile IOPreg *)IOP_BASE;
EnterCriticalSection(&(pHWHead->RegCritSec));
s2440IOP->rGPHCON &= ~(0x3<<12 | 0x3<<14 );
s2440IOP->rGPHCON |= (0x2<<12 | 0x2<<14 );
s2440IOP->rGPHUP |= 0xc0;
/* pHWHead->rDTRport = (volatile unsigned int *)(IOP_BASE+0x74); //s2440IOP->rGPHDAT
pHWHead->rDSRport = (volatile unsigned int *)(IOP_BASE+0x74);
pHWHead->DtrPortNum = 6;
pHWHead->DsrPortNum = 7;*/
#endif
}
LeaveCriticalSection(&(pHWHead->RegCritSec));
}
VOID
S2440_SetIOP(
PVOID pHead // @parm points to device head
)
{
PS2440_UART_INFO pHWHead = (PS2440_UART_INFO)pHead;
if ( pHWHead->UseIrDA )
{
RETAILMSG(DEBUGMODE, (TEXT("S2440_SetIOP : IRDA\r\n")));
S2440_SetIrDAIOP(pHWHead);
}
else
{
RETAILMSG(DEBUGMODE, (TEXT("S2440_SetIOP : SERIAL\r\n")));
S2440_SetSerialIOP(pHWHead);
}
}
//
/////////////////// Start of exported entrypoints ////////////////
//
//
// @doc OEM
// @func PVOID | SL_Open | Configures 16550 for default behaviour.
//
VOID
SL_Open(
PVOID pHead // @parm PVOID returned by HWinit.
)
{
PS2440_UART_INFO pHWHead = (PS2440_UART_INFO)pHead;
RETAILMSG(1, (TEXT("SL_Open 0x%X (%d opens)\r\n"), pHead, pHWHead->OpenCount));
// If the device is already open, all we do is increment count
if ( pHWHead->OpenCount++ ) {
RETAILMSG(1, (TEXT("SL_Open 0x%X (%d opens)\r\n"), pHead, pHWHead->OpenCount));
return ;
}
pHWHead->DroppedBytes = 0;
pHWHead->CTSFlowOff = FALSE; // Not flowed off yet
pHWHead->DSRFlowOff = FALSE; // Not flowed off yet
pHWHead->CommErrors = 0;
pHWHead->ModemStatus = 0;
pHWHead->ConSetup = 6;
pHWHead->vUMSTAT = 0;
pHWHead->fSW_EnTxINT = FALSE;
EnterCriticalSection(&(pHWHead->RegCritSec));
try {
S2440_SetIOP(pHead);
// Get defaults from the DCB structure
SL_SetBaudRate( pHead, pHWHead->dcb.BaudRate );
SL_SetByteSize( pHead, pHWHead->dcb.ByteSize );
SL_SetStopBits( pHead, pHWHead->dcb.StopBits );
SL_SetParity(pHead, pHWHead->dcb.Parity );
// UART Control, Modem, Fifo register setting.
OUTREG(pHWHead,rUCON,0x2c5); //Clock selection=PCLK, tx=level,rx=pulse,enable timeout int.,
//enable rx error int., Tx int, Rx int
OUTREG(pHWHead,rUFCON,0x6); // Reset FIFO
OUTREG(pHWHead,rUFCON,0x41); //FIFO enable : tx-4bytes, rx-4bytes
//OUTREG(pHWHead,rUMCON,0x10); //Enable auto flow control.
OUTREG(pHWHead,rUMCON,0x00); //Enable auto flow control.
if ( pHWHead->UseIrDA )
SETREG(pHWHead,rULCON,SER2440_IRMODE_MASK); // Infra-red mode enable.
EnINT(pHWHead, pHWHead->bINT);
EnSubINT(pHWHead, pHWHead->bRxINT);
// For CE 3.0, we are still supporting
// the old style MDDs, and they don't call our PostInit, which
// needs to happen sometime prior to this. So for now, we go ahead
// ahead and clear out interrupts one last time. In 4.0, we can
// kill the old serial MDD and assume that everyone uses the new
// MDD and calls post init.
SL_PostInit(pHWHead);
ReadLSR(pHWHead);
}
except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
// Just get out of here.
}
LeaveCriticalSection(&(pHWHead->RegCritSec));
}
//
// @doc OEM
// @func PVOID | SL_Close | Does nothing except keep track of the
// open count so that other routines know what to do.
//
VOID
SL_Close(
PVOID pHead // @parm PVOID returned by HWinit.
)
{
PS2440_UART_INFO pHWHead = (PS2440_UART_INFO)pHead;
RETAILMSG(DEBUGMODE, (TEXT("SL_Close \r\n")));
if ( pHWHead->OpenCount ) pHWHead->OpenCount--;
EnterCriticalSection(&(pHWHead->RegCritSec));
try {
SL_ClearRTS( pHWHead );
OUTREG(pHWHead,rUMSTAT,0x0);
// Disable all interrupts and clear MCR.
DisEnSubINT(pHWHead, pHWHead->bRxINT);
pHWHead->fSW_EnTxINT = FALSE;
// This routhine for auto detect.
S2440_SetIrDAIOP(pHead);
}
except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
// Just get out of here.
}
LeaveCriticalSection(&(pHWHead->RegCritSec));
}
//
// @doc OEM
// @func PVOID | SL_Init | Initializes 16550 device head.
//
/*
VOID
SL_Init(
PVOID pHead, // @parm points to device head
PUCHAR pRegBase, // Pointer to 16550 register base
UINT8 RegStride, // Stride amongst the 16550 registers
EVENT_FUNC EventCallback, // This callback exists in MDD
PVOID pMddHead, // This is the first parm to callback
PLOOKUP_TBL pBaudTable // BaudRate Table
)
{
PS2440_UART_INFO pHWHead = (PS2440_UART_INFO)pHead;
RETAILMSG(DEBUGMODE, (TEXT("SL_Init : IRDA = %d \r\n"), pHWHead->UseIrDA));
#if USEVIRTUAL
SER_VirtualAlloc();
#endif
if ( pHWHead->UseIrDA )
{
pHWHead->bINT = BIT_UART2;
pHWHead->bTxINT = INTSUB_TXD2;
pHWHead->bRxINT = INTSUB_RXD2;
pHWHead->bErrINT = INTSUB_ERR2;
#if USEVIRTUAL
pHWHead->s2440SerReg = (S2440_UART_REG *)v_pUART2regs;
pRegBase = (PUCHAR)pHWHead->s2440SerReg;
#else
pRegBase = (PUCHAR)UART2_BASE;
pHWHead->s2440SerReg = (S2440_UART_REG *)pRegBase;
#endif
}
else
{
pHWHead->bINT = BIT_UART0;
pHWHead->bTxINT = INTSUB_TXD0;
pHWHead->bRxINT = INTSUB_RXD0;
pHWHead->bErrINT = INTSUB_ERR0;
#if USEVIRTUAL
pHWHead->s2440SerReg = (S2440_UART_REG *)v_pUART0regs;
pRegBase = (PUCHAR)pHWHead->s2440SerReg;
#else
pRegBase = (PUCHAR)UART0_BASE;
pHWHead->s2440SerReg = (S2440_UART_REG *)pRegBase;
#endif
}
#if USEVIRTUAL
pHWHead->UART_INTMASK = (volatile unsigned int *)&(v_pINTregs->rINTMSK);
pHWHead->UART_INTSUBMASK = (volatile unsigned int *)&(v_pINTregs->rINTSUBMSK);
pHWHead->UART_INTPND = (volatile unsigned int *)&(v_pINTregs->rINTPND);
pHWHead->UART_INTSRCPND = (volatile unsigned int *)&(v_pINTregs->rSRCPND);
pHWHead->UART_INTSUBSRCPND = (volatile unsigned int *)&(v_pINTregs->rSUBSRCPND);
#else
pHWHead->UART_INTMASK = (volatile unsigned int *)(INT_BASE+0x8);
pHWHead->UART_INTSUBMASK = (volatile unsigned int *)(INTSUB_MSK);
pHWHead->UART_INTPND = (volatile unsigned int *)(INT_BASE+0x10);
pHWHead->UART_INTSRCPND = (volatile unsigned int *)(INT_BASE);
pHWHead->UART_INTSUBSRCPND = (volatile unsigned int *)(INTSUB_BASE);
#endif
pHWHead->vUMSTAT = 0;
#if USEVIRTUAL
if ( pHWHead->UseIrDA )
{
pHWHead->pUFTXH = (volatile unsigned char *)&(v_pUART2regs->rUTXH);
pHWHead->pUFRXH = (volatile unsigned char *)&(v_pUART2regs->rURXH);
}
else
{
pHWHead->pUFTXH = (volatile unsigned char *)&(v_pUART0regs->rUTXH);
pHWHead->pUFRXH = (volatile unsigned char *)&(v_pUART0regs->rURXH);
}
#else
pHWHead->pUFTXH = (volatile unsigned char *)&(pHWHead->s2440SerReg->rUTXH);
pHWHead->pUFRXH = (volatile unsigned char *)&(pHWHead->s2440SerReg->rURXH);
#endif
InitializeCriticalSection(&(pHWHead->TransmitCritSec));
InitializeCriticalSection(&(pHWHead->RegCritSec));
RETAILMSG(DEBUGMODE, (TEXT("+ S2440_SetIrDAIOP \r\n")));
S2440_SetIrDAIOP(pHead);
RETAILMSG(DEBUGMODE, (TEXT("- S2440_SetIrDAIOP \r\n")));
// Store info for callback function
pHWHead->EventCallback = EventCallback;
pHWHead->pMddHead = pMddHead;
// Now set up remaining fields
if ( pBaudTable != NULL )
pHWHead->pBaudTable = (LOOKUP_TBL *) pBaudTable;
else
pHWHead->pBaudTable = (LOOKUP_TBL *) &LS_BaudTable;
pHWHead->FlushDone = CreateEvent(0, FALSE, FALSE, NULL);
pHWHead->OpenCount = 0;
// Don't allow any interrupts till PostInit.
DisEnINT(pHWHead, pHWHead->bINT);
DisEnSubINT(pHWHead, pHWHead->bTxINT | pHWHead->bRxINT | pHWHead->bErrINT);
pHWHead->fSW_EnTxINT = FALSE;
pHWHead->RxDiscard = FALSE;
// Clear any interrupts which may be pending. Normally only
// happens if we were warm reset.
ClearPendingInts( pHWHead );
}*/
VOID
SL_Init(
PVOID pHead, // @parm points to device head
PUCHAR pRegBase, // Pointer to 16550 register base
UINT8 RegStride, // Stride amongst the 16550 registers
EVENT_FUNC EventCallback, // This callback exists in MDD
PVOID pMddHead, // This is the first parm to callback
PLOOKUP_TBL pBaudTable // BaudRate Table
)
{
PS2440_UART_INFO pHWHead = (PS2440_UART_INFO)pHead;
PSER_INFO pHWHead1 = (PSER_INFO)pHead;
RETAILMSG(DEBUGMODE, (TEXT("SL_Init : IRDA = %d \r\n"), pHWHead->UseIrDA));
#if USEVIRTUAL
SER_VirtualAlloc();
#endif
if ( pHWHead->UseIrDA )
{
pHWHead->bINT = BIT_UART2;
pHWHead->bTxINT = INTSUB_TXD2;
pHWHead->bRxINT = INTSUB_RXD2;
pHWHead->bErrINT = INTSUB_ERR2;
#if USEVIRTUAL
pHWHead->s2440SerReg = (S2440_UART_REG *)v_pUART2regs;
pRegBase = (PUCHAR)pHWHead->s2440SerReg;
#else
pRegBase = (PUCHAR)UART2_BASE;
pHWHead->s2440SerReg = (S2440_UART_REG *)pRegBase;
#endif
}
else
{
if(pHWHead1->dwIOBase == 0x50000000) // add by perry
{
pHWHead->bINT = BIT_UART0;
pHWHead->bTxINT = INTSUB_TXD0;
pHWHead->bRxINT = INTSUB_RXD0;
pHWHead->bErrINT = INTSUB_ERR0;
#if USEVIRTUAL
pHWHead->s2440SerReg = (S2440_UART_REG *)v_pUART0regs;
pRegBase = (PUCHAR)pHWHead->s2440SerReg;
#else
pRegBase = (PUCHAR)UART0_BASE;
pHWHead->s2440SerReg = (S2440_UART_REG *)pRegBase;
#endif
}
else if(pHWHead1->dwIOBase == 0x50004000)
{
pHWHead->bINT = BIT_UART1;
pHWHead->bTxINT = INTSUB_TXD1;
pHWHead->bRxINT = INTSUB_RXD1;
pHWHead->bErrINT = INTSUB_ERR1;
#if USEVIRTUAL
pHWHead->s2440SerReg = (S2440_UART_REG *)v_pUART1regs;
pRegBase = (PUCHAR)pHWHead->s2440SerReg;
#else
pRegBase = (PUCHAR)UART1_BASE;
pHWHead->s2440SerReg = (S2440_UART_REG *)pRegBase;
#endif
}
else if(pHWHead1->dwIOBase == 0x50008000)
{
pHWHead->bINT = BIT_UART2;
pHWHead->bTxINT = INTSUB_TXD2;
pHWHead->bRxINT = INTSUB_RXD2;
pHWHead->bErrINT = INTSUB_ERR2;
#if USEVIRTUAL
pHWHead->s2440SerReg = (S2440_UART_REG *)v_pUART2regs;
pRegBase = (PUCHAR)pHWHead->s2440SerReg;
#else
pRegBase = (PUCHAR)UART2_BASE;
pHWHead->s2440SerReg = (S2440_UART_REG *)pRegBase;
#endif
}
}
#if USEVIRTUAL
pHWHead->UART_INTMASK = (volatile unsigned int *)&(v_pINTregs->rINTMSK);
pHWHead->UART_INTSUBMASK = (volatile unsigned int *)&(v_pINTregs->rINTSUBMSK);
pHWHead->UART_INTPND = (volatile unsigned int *)&(v_pINTregs->rINTPND);
pHWHead->UART_INTSRCPND = (volatile unsigned int *)&(v_pINTregs->rSRCPND);
pHWHead->UART_INTSUBSRCPND = (volatile unsigned int *)&(v_pINTregs->rSUBSRCPND);
#else
pHWHead->UART_INTMASK = (volatile unsigned int *)(INT_BASE+0x8);
pHWHead->UART_INTSUBMASK = (volatile unsigned int *)(INTSUB_MSK);
pHWHead->UART_INTPND = (volatile unsigned int *)(INT_BASE+0x10);
pHWHead->UART_INTSRCPND = (volatile unsigned int *)(INT_BASE);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -