📄 ser16950.c
字号:
// Reset RX FIFO to clear any old data remaining in it.
OUTB(pHWHead, pIIR_FCR, pHWHead->FCR | SERIAL_FCR_RCVR_RESET);
// Reading MSR clear Modem Status interrupt
ReadMSR( pHWHead );
// Simply reading IIR is sufficient to clear THRE
pHWHead->IIR = INB(pHWHead, pIIR_FCR);
}
#ifdef DEBUG
if( ZONE_INIT )
DumpSerialRegisters(pHWHead);
#endif
}
except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
// Just get out of here.
}
DEBUGMSG (ZONE_OPEN,
(TEXT("-SL_Open 0x%X, IIR 0x%X\r\n"), pHead, pHWHead->IIR));
}
//
// @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.
)
{
PSER16950_INFO pHWHead = (PSER16950_INFO)pHead;
DEBUGMSG (ZONE_CLOSE,
(TEXT("+SL_Close 0x%X\r\n"), pHead));
if( pHWHead->OpenCount )
pHWHead->OpenCount--;
try
{
pHWHead->IER = 0;
OUTB(pHWHead, pIER, pHWHead->IER);
pHWHead->MCR = 0;
OUTB(pHWHead, pMCR, pHWHead->MCR);
pHWHead->IIR = INB(pHWHead, pIIR_FCR);
}
except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
// Just get out of here.
}
DEBUGMSG (ZONE_CLOSE,
(TEXT("-SL_Close 0x%X\r\n"), pHead));
}
//
// @doc OEM
// @func PVOID | SL_Init | Initializes 16950 device head.
//
VOID
SL_Init(
PVOID pHead, // @parm points to device head
PUCHAR pRegBase, // Pointer to 16950 register base
UINT8 RegStride, // Stride amongst the 16950 registers
EVENT_FUNC EventCallback, // This callback exists in MDD
PVOID pMddHead, // This is the first parm to callback
PLOOKUP_TBL pBaudTable // BaudRate Table
)
{
PSER16950_INFO pHWHead = (PSER16950_INFO)pHead;
DEBUGMSG (ZONE_CLOSE,(TEXT("+SL_INIT, 0x%X\r\n"), pHWHead));
// Set up pointers to 16950 registers
pHWHead->pData = pRegBase + (RegStride * RECEIVE_BUFFER_REGISTER);
pHWHead->pIER = pRegBase + (RegStride * INTERRUPT_ENABLE_REGISTER);
pHWHead->pIIR_FCR = pRegBase + (RegStride * INTERRUPT_IDENT_REGISTER);
pHWHead->pLCR = pRegBase + (RegStride * LINE_CONTROL_REGISTER);
pHWHead->pMCR = pRegBase + (RegStride * MODEM_CONTROL_REGISTER);
pHWHead->pLSR = pRegBase + (RegStride * LINE_STATUS_REGISTER);
pHWHead->pMSR = pRegBase + (RegStride * MODEM_STATUS_REGISTER);
pHWHead->pScratch = pRegBase + (RegStride * SCRATCH_REGISTER);
pHWHead->pICR = pRegBase + (RegStride * LINE_STATUS_REGISTER);
pHWHead->pEFR = pRegBase + (RegStride * INTERRUPT_IDENT_REGISTER);
// Store info for callback function
pHWHead->EventCallback = EventCallback;
pHWHead->pMddHead = pMddHead;
// Now set up remaining fields
// Setup the 'normal' baud rate table
//pHWHead->pBaudTable = (LOOKUP_TBL *) &LS_BaudTable;
pHWHead->FlushDone = CreateEvent(0, FALSE, FALSE, NULL);
pHWHead->OpenCount = 0;
/* Initialize the critical sections that will guard the parts of
* the receive buffer.
*/
InitializeCriticalSection(&(pHWHead->TransmitCritSec));
DEBUGMSG (ZONE_CLOSE,(TEXT("-SL_INIT, 0x%X\r\n"), pHWHead));
}
//
// @doc OEM
// @func PVOID | SL_Deinit | De-initializes 16950 device head.
//
VOID
SL_Deinit(
PVOID pHead // @parm points to device head
)
{
PSER16950_INFO pHWHead = (PSER16950_INFO)pHead;
DEBUGMSG (ZONE_CLOSE,(TEXT("+SL_DEINIT, 0x%X\r\n"), pHWHead));
DeleteCriticalSection(&(pHWHead->TransmitCritSec));
// Free the flushdone event
if( pHWHead->FlushDone )
CloseHandle( pHWHead->FlushDone );
DEBUGMSG (ZONE_CLOSE,(TEXT("-SL_DEINIT, 0x%X\r\n"), pHWHead));
}
//
// @doc OEM
// @func void | SL_ClearDtr | This routine clears DTR.
//
// @rdesc None.
//
VOID
SL_ClearDTR(
PVOID pHead // @parm PVOID returned by HWinit.
)
{
DEBUGMSG (ZONE_FUNCTION, (TEXT("+SL_ClearDTR, 0x%X\r\n"), pHead));
try
{
((PSER16950_INFO)pHead)->MCR &= ~SERIAL_MCR_DTR;
OUTB((PSER16950_INFO)pHead, pMCR, ((PSER16950_INFO)pHead)->MCR);
}
except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
// Just exit
}
DEBUGMSG (ZONE_FUNCTION, (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.
)
{
DEBUGMSG (ZONE_FUNCTION, (TEXT("+SL_SetDTR, 0x%X\r\n"), pHead));
try
{
((PSER16950_INFO)pHead)->MCR |= SERIAL_MCR_DTR;
OUTB((PSER16950_INFO)pHead, pMCR, ((PSER16950_INFO)pHead)->MCR);
}
except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
// Just exit
}
DEBUGMSG (ZONE_FUNCTION, (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.
)
{
DEBUGMSG (ZONE_FUNCTION, (TEXT("+SL_ClearRTS, 0x%X\r\n"), pHead));
try
{
((PSER16950_INFO)pHead)->MCR &= ~SERIAL_MCR_RTS;
OUTB((PSER16950_INFO)pHead, pMCR, ((PSER16950_INFO)pHead)->MCR);
}
except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
// Just exit
}
DEBUGMSG (ZONE_FUNCTION, (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.
)
{
DEBUGMSG (ZONE_FUNCTION, (TEXT("+SL_SetRTS, 0x%X\r\n"), pHead));
try
{
((PSER16950_INFO)pHead)->MCR |= SERIAL_MCR_RTS;
OUTB((PSER16950_INFO)pHead, pMCR, ((PSER16950_INFO)pHead)->MCR);
}
except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
// Just exit
}
DEBUGMSG (ZONE_FUNCTION, (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.
)
{
DEBUGMSG (ZONE_FUNCTION, (TEXT("+SL_ClearBreak, 0x%X\r\n"), pHead));
try
{
((PSER16950_INFO)pHead)->LCR &= ~SERIAL_LCR_BREAK;
OUTB((PSER16950_INFO)pHead, pLCR, ((PSER16950_INFO)pHead)->LCR);
}
except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
// Just exit
}
DEBUGMSG (ZONE_FUNCTION, (TEXT("-SL_ClearBreak, 0x%X\r\n"), pHead));
}
//
// @doc OEM
// @func VOID | SL_SetBreak | This routine sets break.
//
// @rdesc None.
//
VOID
SL_SetBreak(
PVOID pHead // @parm PVOID returned by HWinit.
)
{
DEBUGMSG (ZONE_FUNCTION, (TEXT("+SL_SetBreak, 0x%X\r\n"), pHead));
try
{
((PSER16950_INFO)pHead)->LCR |= SERIAL_LCR_BREAK;
OUTB((PSER16950_INFO)pHead, pLCR, ((PSER16950_INFO)pHead)->LCR);
}
except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
// Just exit
}
DEBUGMSG (ZONE_FUNCTION, (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, etc.
//
BOOL
SetBaudRate(
PVOID pHead,
ULONG BaudRate
)
{
// Baud rate setting does NOTHING on Wendy cards!
return (TRUE);
}
//
// @doc OEM
// @func VOID | 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;
PSER16950_INFO pHWHead = (PSER16950_INFO)pHead;
DEBUGMSG (ZONE_FUNCTION,
(TEXT("+SL_SetbaudRate 0x%X, x%X\r\n"), pHead, BaudRate));
try {
fRet = SetBaudRate(pHead, BaudRate);
} except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
return( FALSE );
}
if ( fRet )
{
pHWHead->dcb.BaudRate = BaudRate;
DEBUGMSG (ZONE_FUNCTION,
(TEXT("-SL_SetbaudRate 0x%X (%d Baud)\r\n"),
pHead, BaudRate));
return( TRUE );
}
else
{
DEBUGMSG (ZONE_FUNCTION | ZONE_ERROR,
(TEXT("-SL_SetbaudRate - Error setting %d, failing to %d\r\n"),
BaudRate, pHWHead->dcb.BaudRate) );
return( FALSE );
}
}
//
// @doc OEM
// @func VOID | 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.
)
{
PSER16950_INFO pHWHead = (PSER16950_INFO)pHead;
DEBUGMSG (ZONE_FUNCTION,
(TEXT("+SL_SetByteSize 0x%X, x%X\r\n"), pHead, ByteSize));
try
{
pHWHead->LCR &= ~SERIAL_DATA_MASK;
switch( ByteSize )
{
case 5:
pHWHead->LCR |= SERIAL_5_DATA;
break;
case 6:
pHWHead->LCR |= SERIAL_6_DATA;
break;
case 7:
pHWHead->LCR |= SERIAL_7_DATA;
break;
default:
case 8:
pHWHead->LCR |= SERIAL_8_DATA;
break;
}
OUTB(pHWHead, pLCR, pHWHead->LCR);
}
except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
// Do nothing - we're in enough trouble
}
DEBUGMSG (ZONE_FUNCTION,
(TEXT("-SL_SetByteSize 0x%X\r\n"), pHead));
return TRUE;
}
//
// @doc OEM
// @func VOID | 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.
)
{
PSER16950_INFO pHWHead = (PSER16950_INFO)pHead;
DEBUGMSG (ZONE_FUNCTION,
(TEXT("+SL_SetParity 0x%X, x%X\r\n"), pHead, Parity));
try
{
pHWHead->LCR &= ~SERIAL_PARITY_MASK;
switch( Parity )
{
case ODDPARITY:
pHWHead->LCR |= SERIAL_ODD_PARITY;
break;
case EVENPARITY:
pHWHead->LCR |= SERIAL_EVEN_PARITY;
break;
case MARKPARITY:
pHWHead->LCR |= SERIAL_MARK_PARITY;
break;
case SPACEPARITY:
pHWHead->LCR |= SERIAL_SPACE_PARITY;
break;
case NOPARITY:
default:
pHWHead->LCR |= SERIAL_NONE_PARITY;
break;
}
OUTB(pHWHead, pLCR, pHWHead->LCR);
}
except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
// Do nothing - we're in enough trouble
}
DEBUGMSG (ZONE_FUNCTION,
(TEXT("-SL_SetParity 0x%X\r\n"), pHead));
return TRUE;
}
//
// @doc OEM
// @func VOID | SL_SetStopBits |
// This routine sets the Stop Bits for the device.
//
// @rdesc None.
//
BOOL
SL_SetStopBits(
PVOID pHead, // @parm PVOID returned by HWInit
ULONG StopBits // @parm ULONG StopBits field from DCB.
)
{
PSER16950_INFO pHWHead = (PSER16950_INFO)pHead;
DEBUGMSG (ZONE_FUNCTION,
(TEXT("+SL_SetStopBits 0x%X, x%X\r\n"), pHead, StopBits));
pHWHead->LCR &= ~SERIAL_STOP_MASK;
try
{
// Note that 1.5 stop bits only works if the word size
// is 5 bits. Any other xmit word size will cause the
// 1.5 stop bit setting to generate 2 stop bits.
switch( StopBits )
{
case ONESTOPBIT :
pHWHead->LCR |= SERIAL_1_STOP ;
break;
case ONE5STOPBITS :
pHWHead->LCR |= SERIAL_1_5_STOP ;
break;
case TWOSTOPBITS :
pHWHead->LCR |= SERIAL_2_STOP ;
break;
}
OUTB(pHWHead, pLCR, pHWHead->LCR);
}
except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -