📄 ser2440_hw.c
字号:
except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
{
RETAILMSG(1,(TEXT("SL_PostInit, 0x%X - ERROR\r\n"), pHWHead));
// Just fall through & release CritSec
}
LeaveCriticalSection(&(pHWHead->RegCritSec));
}
// Routine to set some 2440 IO Ports.
VOID
S2440_SetIrDAIOP(PVOID pHead) // @parm points to device head
{
PS2440_UART_INFO pHWHead = (PS2440_UART_INFO)pHead;
RETAILMSG(DEBUGMODE, (TEXT("S2440_SetIrDAIOP \r\n")));
EnterCriticalSection(&(pHWHead->RegCritSec));
// by jylee 2003.04.15
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;
LeaveCriticalSection(&(pHWHead->RegCritSec));
}
S2440_SetSerialIOP(PVOID pHead) // @parm points to device head
{
PS2440_UART_INFO pHWHead = (PS2440_UART_INFO)pHead;
RETAILMSG(DEBUGMODE, (TEXT("S2440_SetSerialIOP \r\n")));
EnterCriticalSection(&(pHWHead->RegCritSec));
v_pIOPregs->rGPHCON &= ~(0x3<<0 | 0x3<<2 | 0x3<<4 | 0x3<<6); // clear uart 0 - rx, tx
v_pIOPregs->rGPHCON |= (0x2<<4 | 0x2<<6);
v_pIOPregs->rGPDCON &= ~(0x3<<0 | 0x3<<2);
v_pIOPregs->rGPDCON |= (0x1<<0 | 0x0<<2);
#if USE_AFC
// set nRTS to GPO mode
// for software flow-control
v_pIOPregs->rGPHCON |= (0x2<<0 | 0x1<<2 );
#else
v_pIOPregs->rGPHCON |= (0x2<<0 | 0x2<<2 );
#endif
/*
In the SMDK2440 board, if IRDA is enabled, following values are ignored.
*/
#if 0 // Board version is not 0.17
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;
#endif
v_pIOPregs->rGPDUP |= 0x3;
pHWHead->rDTRport = (volatile unsigned int *)&(v_pIOPregs->rGPDDAT);
pHWHead->rDSRport = (volatile unsigned int *)&(v_pIOPregs->rGPDDAT);
pHWHead->DtrPortNum = 0;
pHWHead->DsrPortNum = 1;
#if USE_AFC
pHWHead->rCTSport = (volatile unsigned int *)&(v_pIOPregs->rGPHDAT);
pHWHead->rRTSport = (volatile unsigned int *)&(v_pIOPregs->rGPHDAT);
pHWHead->CtsPortNum = 0;
pHWHead->RtsPortNum = 1;
#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
if (pHWHead->UseIrDA)
{
OUTREG(pHWHead,rUFCON,0x41); //FIFO enable : tx-4bytes, rx-4bytes
OUTREG(pHWHead,rUMCON,0x00); //Disable auto flow control.
}
else
{
#if USE_AFC
// by shin.0212.
OUTREG(pHWHead,rUFCON,0x61); //FIFO enable : tx-4bytes, rx-12bytes
OUTREG(pHWHead,rUMCON,0x10); //Enable auto flow control.
#else
OUTREG(pHWHead,rUFCON,0x41); //FIFO enable : tx-4bytes, rx-4bytes
OUTREG(pHWHead,rUMCON,0x00); //Disable auto flow control.
#endif
}
if ( pHWHead->UseIrDA )
SETREG(pHWHead,rULCON,SER2440_IRMODE_MASK); // Infra-red mode enable.
ClearPendingInts( pHWHead );
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(1, (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));
SER_VirtualAlloc();
if ( pHWHead->UseIrDA )
{
pHWHead->bINT = BIT_UART2;
pHWHead->bTxINT = INTSUB_TXD2;
pHWHead->bRxINT = INTSUB_RXD2;
pHWHead->bErrINT = INTSUB_ERR2;
pHWHead->s2440SerReg = (S2440_UART_REG *)v_pUART2regs;
pRegBase = (PUCHAR)pHWHead->s2440SerReg;
}
else
{
pHWHead->bINT = BIT_UART0;
pHWHead->bTxINT = INTSUB_TXD0;
pHWHead->bRxINT = INTSUB_RXD0;
pHWHead->bErrINT = INTSUB_ERR0;
pHWHead->s2440SerReg = (S2440_UART_REG *)v_pUART0regs;
pRegBase = (PUCHAR)pHWHead->s2440SerReg;
}
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);
pHWHead->vUMSTAT = 0;
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);
}
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;
InitializeCriticalSection(&(pHWHead->TransmitCritSec));
InitializeCriticalSection(&(pHWHead->RegCritSec));
// 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.
{
PS2440_UART_INFO pHWHead = (PS2440_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
{
PS2440_UART_INFO pHWHead = (PS2440_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 );
SER_VirtualFree();
}
//
// @doc OEM
// @func void | SL_ClearDtr | This routine clears DTR.
//
// @rdesc None.
//
VOID
SL_ClearDTR(PVOID pHead) // @parm PVOID returned by HWinit.
{
PS2440_UART_INFO pHWHead = (PS2440_UART_INFO)pHead;
RETAILMSG(DEBUGMODE, (TEXT("+SL_ClearDTR, 0x%X\r\n"), pHead));
RETAILMSG(DEBUGMODE, (TEXT("UseIrDA, %d\r\n"), pHWHead->UseIrDA));
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.
{
PS2440_UART_INFO pHWHead = (PS2440_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.
{
#if 0 // by shin
PS2440_UART_INFO pHWHead = (PS2440_UART_INFO)pHead;
RETAILMSG(0, (TEXT("+SL_ClearRTS, 0x%X\r\n"), pHead));
EnterCriticalSection(&(pHWHead->RegCritSec));
try
{
CLEARREG(pHWHead, rUMCON, SER2440_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));
#else
PS2440_UART_INFO pHWHead = (PS2440_UART_INFO)pHead;
RETAILMSG(DEBUGMODE, (TEXT("+SL_ClearRTS, 0x%X\r\n"), pHead));
if ( !pHWHead->UseIrDA )
{
#if USE_AFC
// by 0212.
*(pHWHead->rRTSport) |= (1<<(pHWHead->RtsPortNum));
#else
EnterCriticalSection(&(pHWHead->RegCritSec));
try
{
CLEARREG(pHWHead, rUMCON, SER2440_RTS);
}
except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
{
// Just exit
}
LeaveCriticalSection(&(pHWHead->RegCritSec));
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -