📄 ser2440_hw.c
字号:
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
{
if(pHWHead1->dwIOBase == 0x50000000)
{
pHWHead->pUFTXH = (volatile unsigned char *)&(v_pUART0regs->rUTXH);
pHWHead->pUFRXH = (volatile unsigned char *)&(v_pUART0regs->rURXH);
}
else if(pHWHead1->dwIOBase == 0x50004000) // add by perry
{
pHWHead->pUFTXH = (volatile unsigned char *)&(v_pUART1regs->rUTXH);
pHWHead->pUFRXH = (volatile unsigned char *)&(v_pUART1regs->rURXH);
}
else if(pHWHead1->dwIOBase == 0x50008000)
{
pHWHead->pUFTXH = (volatile unsigned char *)&(v_pUART2regs->rUTXH);
pHWHead->pUFRXH = (volatile unsigned char *)&(v_pUART2regs->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 );
}
//
// @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 );
}
//
// @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));
// 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.
)
{
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.
)
{
PS2440_UART_INFO pHWHead = (PS2440_UART_INFO)pHead;
RETAILMSG(DEBUGMODE, (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));
}
//
// @doc OEM
// @func VOID | SL_SetRTS | This routine sets RTS.
//
// @rdesc None.
//
VOID
SL_SetRTS(
PVOID pHead // @parm PVOID returned by HWinit.
)
{
PS2440_UART_INFO pHWHead = (PS2440_UART_INFO)pHead;
RETAILMSG(DEBUGMODE, (TEXT("+SL_SetRTS, 0x%X\r\n"), pHead));
EnterCriticalSection(&(pHWHead->RegCritSec));
try {
SETREG(pHWHead, rUMCON, SER2440_RTS);
}
except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
// Just exit
}
LeaveCriticalSection(&(pHWHead->RegCritSec));
RETAILMSG(DEBUGMODE, (TEXT("-SL_SetRTS, 0x%X\r\n"), pHead));
}
//
// @doc OEM
// @func VOID | SL_ClearBreak | This routine clears break.
//
// @rdesc None.
//
VOID
SL_ClearBreak(
PVOID pHead // @parm PVOID returned by HWinit.
)
{
PS2440_UART_INFO pHWHead = (PS2440_UART_INFO)pHead;
RETAILMSG(DEBUGMODE, (TEXT("SL_ClearBreak:\r\n")));
// S2440 does not need to clear break signal, for cleared by automatic.
}
//
// @doc OEM
// @func VOID | SL_SetBreak | This routine sets break.
//
// @rdesc None.
//
VOID
SL_SetBreak(
PVOID pHead // @parm PVOID returned by HWinit.
)
{
PS2440_UART_INFO pHWHead = (PS2440_UART_INFO)pHead;
RETAILMSG(DEBUGMODE, (TEXT("+SL_SetBreak, 0x%X\r\n"), pHead));
EnterCriticalSection(&(pHWHead->RegCritSec));
try {
SETREG(pHWHead,rUCON,BS_SEND);
}
except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
// Just exit
}
LeaveCriticalSection(&(pHWHead->RegCritSec));
RETAILMSG(DEBUGMODE, (TEXT("-SL_SetBreak, 0x%X\r\n"), pHead));
}
//
// SetBaudRate
//
// Internal function. The only real reason for splitting this out
// is so that we can call it from PowerOn and still allow SL_SetBaud
// to do debug messages, acquire critical sections, etc.
//
BOOL
SetBaudRate(
PVOID pHead,
ULONG BaudRate
)
{
PS2440_UART_INFO pHWHead = (PS2440_UART_INFO)pHead;
RETAILMSG(DEBUGMODE, (TEXT("SetBaudRate -> %d\r\n"), BaudRate));
if ( (pHWHead->s2440SerReg->rUCON & CS_MASK) == CS_PCLK )
OUTREG(pHWHead,rUBRDIV,( (int)(S2440PCLK/16.0/BaudRate) -1 ));
else // if ( (pHWHead2->s2440SerReg->rUCON & CS_MASK) == CS_UCLK )
OUTREG(pHWHead,rUBRDIV,( (int)(S2440UCLK/16.0/BaudRate) -1 ));
return( TRUE );
}
//
// @doc OEM
// @func BOOL | SL_SetBaudRate |
// This routine sets the baud rate of the device.
//
// @rdesc None.
//
BOOL
SL_SetBaudRate(
PVOID pHead, // @parm PVOID returned by HWInit
ULONG BaudRate // @parm ULONG representing decimal baud rate.
)
{
BOOL fRet;
PS2440_UART_INFO pHWHead = (PS2440_UART_INFO)pHead;
RETAILMSG (DEBUGMODE, (TEXT("+SL_SetbaudRate 0x%X, %d\r\n"), pHead, BaudRate));
try {
// Enter critical section before calling function, since
// we can't make sys calls inside SetBaudRate
EnterCriticalSection(&(pHWHead->RegCritSec));
fRet = SetBaudRate(pHead, BaudRate);
LeaveCriticalSection(&(pHWHead->RegCritSec));
}except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
return( FALSE );
}
if ( fRet ) {
pHWHead->dcb.BaudRate = BaudRate;
RETAILMSG(DEBUGMODE,
(TEXT("-SL_SetbaudRate 0x%X (%d Baud)\r\n"),
pHead, BaudRate));
return( TRUE );
} else {
RETAILMSG(DEBUGMODE,
(TEXT("-SL_SetbaudRate - Error setting %d, failing to %d\r\n"),
BaudRate, pHWHead->dcb.BaudRate) );
return( FALSE );
}
}
//
// @doc OEM
// @func BOOL | SL_SetByteSize |
// This routine sets the WordSize of the device.
//
// @rdesc None.
//
BOOL
SL_SetByteSize(
PVOID pHead, // @parm PVOID returned by HWInit
ULONG ByteSize // @parm ULONG ByteSize field from DCB.
)
{
PS2440_UART_INFO pHWHead = (PS2440_UART_INFO)pHead;
UINT32 lcr;
BOOL bRet;
RETAILMSG(DEBUGMODE,(TEXT("+SL_SetByteSize 0x%X, 0x%X\r\n"), pHead, ByteSize));
bRet = TRUE;
EnterCriticalSection(&(pHWHead->RegCritSec));
try {
lcr = (UINT32)INREG(pHWHead,rULCON);
lcr &= ~SER2440_DATABIT_MASK;
switch ( ByteSize ) {
case 5:
lcr |= 0;//SERIAL_5_DATA;
break;
case 6:
lcr |= 1;//SERIAL_6_DATA;
break;
case 7:
lcr |= 2;//SERIAL_7_DATA;
break;
case 8:
lcr |= 3;//SERIAL_8_DATA;
break;
default:
bRet = FALSE;
break;
}
if (bRet) {
OUTREG(pHWHead,rULCON,lcr);
}
}
except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
bRet = FALSE;
}
LeaveCriticalSection(&(pHWHead->RegCritSec));
RETAILMSG(DEBUGMODE,(TEXT("-SL_SetByteSize 0x%X\r\n"), pHead));
return(bRet);
}
//
// @doc OEM
// @func BOOL | SL_SetParity |
// This routine sets the parity of the device.
//
// @rdesc None.
//
BOOL
SL_SetParity(
PVOID pHead, // @parm PVOID returned by HWInit
ULONG Parity // @parm ULONG parity field from DCB.
)
{
PS2440_UART_INFO pHWHead = (PS2440_UART_INFO)pHead;
UINT32 lcr;
BOOL bRet;
RETAILMSG(DEBUGMODE,(TEXT("+SL_SetParity 0x%X, 0x%X\r\n"), pHead, Parity));
bRet = TRUE;
EnterCriticalSection(&(pHWHead->RegCritSec));
try {
lcr = (UINT32)INREG(pHWHead,rULCON);
lcr &= ~SER2440_PARITY_MASK;
switch ( Parity ) {
case ODDPARITY:
lcr |= 0x20;//SERIAL_ODD_PARITY;
break;
case EVENPARITY:
lcr |= 0x28;//SERIAL_EVEN_PARITY;
break;
case MARKPARITY:
lcr |= 0x30;//SERIAL_MARK_PARITY;
break;
case SPACEPARITY:
lcr |= 0x38;//SERIAL_SPACE_PARITY;
break;
case NOPARITY:
lcr |= 0;//SERIAL_NONE_PARITY;
break;
default:
bRet = FALSE;
break;
}
if (bRet) {
OUTREG(pHWHead,rULCON,lcr) ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -