📄 ser2410_hw.c
字号:
v_pIOPregs->rGPBCON &= ~(0x3<<2); // clear GPBCON for GPB1 (nIRDAEN)
v_pIOPregs->rGPBCON |= (0x1<<2); // set GPBCON for GPB1 output
v_pIOPregs->rGPBUP |= (0x1<<1); // set GPB1 pullup disable (external pullup)
v_pIOPregs->rGPBDAT &= ~(0x1<<1); // set GPB1 signal low
v_pIOPregs->rGPHCON &= ~(0x3<<12 | 0x3<<14); // clear uart 2 - rx, tx
v_pIOPregs->rGPHCON |= (0x2<<12 | 0x2<<14);
v_pIOPregs->rGPHUP |= 0xc0;
#else
volatile IOPreg *s2410IOP;
s2410IOP = (volatile IOPreg *)IOP_BASE;
EnterCriticalSection(&(pHWHead->RegCritSec));
// by jylee 2003.04.15
s2410IOP->rGPBCON &= ~(0x3<<2); // clear GPBCON for GPB1 (nIRDAEN)
s2410IOP->rGPBCON |= (0x1<<2); // set GPBCON for GPB1 output
s2410IOP->rGPBUP |= (0x1<<1); // set GPB1 pullup disable (external pullup)
s2410IOP->rGPBDAT &= ~(0x1<<1); // set GPB1 signal low
s2410IOP->rGPHCON &= ~(0x3<<12 | 0x3<<14); // clear uart 2 - rx, tx
s2410IOP->rGPHCON |= (0x2<<12 | 0x2<<14);
s2410IOP->rGPHUP |= 0xc0;
#endif
LeaveCriticalSection(&(pHWHead->RegCritSec));
}
S2410_SetSerialIOP(
PVOID pHead // @parm points to device head
)
{
PS2410_UART_INFO pHWHead = (PS2410_UART_INFO)pHead;
RETAILMSG(DEBUGMODE, (TEXT("S2410_SetSerialIOP \r\n")));
#if USEVIRTUAL
EnterCriticalSection(&(pHWHead->RegCritSec));
v_pIOPregs->rGPHCON &= ~(0x3<<0 | 0x3<<2 | 0x3<<4 | 0x3<<6 | 0x3<<12 | 0x3<<14); // clear uart 0 - rx, tx
v_pIOPregs->rGPHCON |= (0x2<<4 | 0x2<<6 | 0x1<<12 | 0x0<<14);
v_pIOPregs->rGPHCON |= (0x2<<0 | 0x2<<2 );
v_pIOPregs->rGPHUP |= 0xc3;
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 *s2410IOP;
s2410IOP = (volatile IOPreg *)IOP_BASE;
EnterCriticalSection(&(pHWHead->RegCritSec));
s2410IOP->rGPHCON &= ~(0x3<<0 | 0x3<<2 | 0x3<<4 | 0x3<<6 | 0x3<<12 | 0x3<<14); // clear uart 0 - rx, tx
s2410IOP->rGPHCON |= (0x2<<4 | 0x2<<6 | 0x1<<12 | 0x0<<14);
s2410IOP->rGPHCON |= (0x2<<0 | 0x2<<2 );
s2410IOP->rGPHUP |= 0xc3;
pHWHead->rDTRport = (volatile unsigned int *)(IOP_BASE+0x74); //s2410IOP->rGPHDAT
pHWHead->rDSRport = (volatile unsigned int *)(IOP_BASE+0x74);
pHWHead->DtrPortNum = 6;
pHWHead->DsrPortNum = 7;
#endif
LeaveCriticalSection(&(pHWHead->RegCritSec));
}
VOID
S2410_SetIOP(
PVOID pHead // @parm points to device head
)
{
PS2410_UART_INFO pHWHead = (PS2410_UART_INFO)pHead;
if ( pHWHead->UseIrDA )
{
RETAILMSG(DEBUGMODE, (TEXT("S2410_SetIOP : IRDA\r\n")));
S2410_SetIrDAIOP(pHWHead);
}
else
{
RETAILMSG(DEBUGMODE, (TEXT("S2410_SetIOP : SERIAL\r\n")));
S2410_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.
)
{
PS2410_UART_INFO pHWHead = (PS2410_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 {
S2410_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,SER2410_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.
)
{
PS2410_UART_INFO pHWHead = (PS2410_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.
S2410_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
)
{
PS2410_UART_INFO pHWHead = (PS2410_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->s2410SerReg = (S2410_UART_REG *)v_pUART2regs;
pRegBase = (PUCHAR)pHWHead->s2410SerReg;
#else
pRegBase = (PUCHAR)UART2_BASE;
pHWHead->s2410SerReg = (S2410_UART_REG *)pRegBase;
#endif
}
else
{
pHWHead->bINT = BIT_UART0;
pHWHead->bTxINT = INTSUB_TXD0;
pHWHead->bRxINT = INTSUB_RXD0;
pHWHead->bErrINT = INTSUB_ERR0;
#if USEVIRTUAL
pHWHead->s2410SerReg = (S2410_UART_REG *)v_pUART0regs;
pRegBase = (PUCHAR)pHWHead->s2410SerReg;
#else
pRegBase = (PUCHAR)UART0_BASE;
pHWHead->s2410SerReg = (S2410_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->s2410SerReg->rUTXH);
pHWHead->pUFRXH = (volatile unsigned char *)&(pHWHead->s2410SerReg->rURXH);
#endif
InitializeCriticalSection(&(pHWHead->TransmitCritSec));
InitializeCriticalSection(&(pHWHead->RegCritSec));
RETAILMSG(DEBUGMODE, (TEXT("+ S2410_SetIrDAIOP \r\n")));
S2410_SetIrDAIOP(pHead);
RETAILMSG(DEBUGMODE, (TEXT("- S2410_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 );
}
//
// @doc OEM
// @func void | SL_PostInit | This routine takes care of final initialization.
//
// @rdesc None.
//
BOOL
SL_PostInit(
PVOID pHead // @parm PVOID returned by HWinit.
)
{
PS2410_UART_INFO pHWHead = (PS2410_UART_INFO)pHead;
RETAILMSG(DEBUGMODE, (TEXT("SL_PostInit \r\n")));
// Since we are just a library which might get used for
// builtin ports which init at boot, or by PCMCIA ports
// which init at Open, we can't do anything too fancy.
// Lets just make sure we cancel any pending interrupts so
// that if we are being used with an edge triggered PIC, he
// will see an edge after the MDD hooks the interrupt.
ClearPendingInts( pHWHead );
return(TRUE);
}
//
// @doc OEM
// @func PVOID | SL_Deinit | De-initializes 16550 device head.
//
VOID
SL_Deinit(
PVOID pHead // @parm points to device head
)
{
PS2410_UART_INFO pHWHead = (PS2410_UART_INFO)pHead;
RETAILMSG(DEBUGMODE, (TEXT("SL_Deinit \r\n")));
DeleteCriticalSection(&(pHWHead->TransmitCritSec));
DeleteCriticalSection(&(pHWHead->RegCritSec));
// Free the flushdone event
if ( pHWHead->FlushDone )
CloseHandle( pHWHead->FlushDone );
}
//
// @doc OEM
// @func void | SL_ClearDtr | This routine clears DTR.
//
// @rdesc None.
//
VOID
SL_ClearDTR(
PVOID pHead // @parm PVOID returned by HWinit.
)
{
PS2410_UART_INFO pHWHead = (PS2410_UART_INFO)pHead;
RETAILMSG(DEBUGMODE, (TEXT("+SL_ClearDTR, 0x%X\r\n"), pHead));
RETAILMSG(DEBUGMODE, (TEXT("UseIrDA, %d\r\n"), pHWHead->UseIrDA));
// RETAILMSG(DEBUGMODE, (TEXT("SL_ClearDTR:\r\n")));
EnterCriticalSection(&(pHWHead->RegCritSec));
try {
// Low active pin.
if ( !pHWHead->UseIrDA )
*(pHWHead->rDTRport) |= (1<<(pHWHead->DtrPortNum));
}
except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
// Just exit
}
LeaveCriticalSection(&(pHWHead->RegCritSec));
RETAILMSG(DEBUGMODE, (TEXT("-SL_ClearDTR, 0x%X\r\n"), pHead));
}
//
// @doc OEM
// @func VOID | SL_SetDTR | This routine sets DTR.
//
// @rdesc None.
//
VOID
SL_SetDTR(
PVOID pHead // @parm PVOID returned by HWinit.
)
{
PS2410_UART_INFO pHWHead = (PS2410_UART_INFO)pHead;
RETAILMSG(DEBUGMODE, (TEXT("+SL_SetDTR, 0x%X\r\n"), pHead));
EnterCriticalSection(&(pHWHead->RegCritSec));
try {
// Low active
if ( !pHWHead->UseIrDA )
*(pHWHead->rDTRport) &= ~(1<<(pHWHead->DtrPortNum));
}
except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
// Just exit
}
LeaveCriticalSection(&(pHWHead->RegCritSec));
RETAILMSG(DEBUGMODE, (TEXT("-SL_SetDTR, 0x%X\r\n"), pHead));
}
//
// @doc OEM
// @func VOID | SL_ClearRTS | This routine clears RTS.
//
// @rdesc None.
//
VOID
SL_ClearRTS(
PVOID pHead // @parm PVOID returned by HWinit.
)
{
PS2410_UART_INFO pHWHead = (PS2410_UART_INFO)pHead;
RETAILMSG(DEBUGMODE, (TEXT("+SL_ClearRTS, 0x%X\r\n"), pHead));
EnterCriticalSection(&(pHWHead->RegCritSec));
try {
CLEARREG(pHWHead, rUMCON, SER2410_RTS);
}
except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
// Just exit
}
LeaveCriticalSection(&(pHWHead->RegCritSec));
RETAILMSG(DEBUGMODE, (TEXT("-SL_ClearRTS, 0x%X\r\n"), pHead));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -