📄 uartser.c
字号:
/* Initialize the receive buffer critical sections */
InitializeCriticalSection(&(pHWHead->TransmitCritSec));
DEBUGMSG (ZONE_CLOSE,(TEXT("-HW_SA1100INIT, 0x%X\r\n"), pHWHead));
//SA_DumpSerialRegisters(pHWHead);
}
//
// @doc OEM
// @func PVOID | HW_SA1100Deinit | De-initializes 16550 device head.
//
VOID
HW_SA1100Deinit(
PVOID pHead // @parm points to device head
)
{
PSER_HW_INFO pHWHead = (PSER_HW_INFO)pHead;
//RETAILMSG(1,(TEXT("+HW_SA1100Deinit, 0x%X\r\n"), pHWHead));
DEBUGMSG (ZONE_CLOSE,(TEXT("+HW_SA1100DEINIT, 0x%X\r\n"), pHWHead));
DeleteCriticalSection(&(pHWHead->TransmitCritSec));
// Free the flushdone event
if( pHWHead->FlushDone )
CloseHandle( pHWHead->FlushDone );
DEBUGMSG (ZONE_CLOSE,(TEXT("-HW_SA1100DEINIT, 0x%X\r\n"), pHWHead));
//SA_DumpSerialRegisters(pHWHead);
//RETAILMSG(1,(TEXT("-HW_SA1100DEINIT, 0x%X\r\n"), pHWHead));
}
//
// @doc OEM
// @func VOID | HW_SA1100ClearBreak | This routine clears break.
//
// @rdesc None.
//
VOID
HW_SA1100ClearBreak(
PVOID pHead // @parm PVOID returned by HWinit.
)
{
//RETAILMSG(1, (TEXT("+HW_SA1100ClearBreak, 0x%X\r\n"), pHead));
PSER_HW_INFO pHWHead;
DEBUGMSG (ZONE_FUNCTION, (TEXT("+HW_SA1100ClearBreak, 0x%X\r\n"), pHead));
pHWHead=(PSER_HW_INFO)pHead;
EnterCriticalSection(&(pHWHead->TransmitCritSec)); // This will stop xmit action
try {
while (pHWHead->pUART->utsr1.tby);
IOW_REG_FIELD (struct utcr3Bits, &pHWHead->pUART->utcr3, brk, 0);
}
except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
}
LeaveCriticalSection(&(pHWHead->TransmitCritSec));
//SA_DumpSerialRegisters((PSER_HW_INFO)pHead);
DEBUGMSG (ZONE_FUNCTION, (TEXT("-HW_SA1100ClearBreak, 0x%X\r\n"), pHead));
}
//
// @doc OEM
// @func VOID | HW_SA1100SetBreak | This routine sets break.
//
// @rdesc None.
//
VOID
HW_SA1100SetBreak(
PVOID pHead // @parm PVOID returned by HWinit.
)
{
//RETAILMSG(1, (TEXT("+HW_SA1100SetBreak, 0x%X\r\n"), pHead));
DEBUGMSG (ZONE_FUNCTION, (TEXT("+HW_SA1100SetBreak, 0x%X\r\n"), pHead));
try {
IOW_REG_FIELD (struct utcr3Bits, &((PSER_HW_INFO)pHead)->pUART->utcr3, brk, 1);
}
except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
}
//SA_DumpSerialRegisters((PSER_HW_INFO)pHead);
DEBUGMSG (ZONE_FUNCTION, (TEXT("-HW_SA1100SetBreak, 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 HW_SA1100SetBaud
// to do debug messages, etc.
//
BOOL
SA_SetBaudRate(
PVOID pHead,
ULONG BaudRate
)
{
PSER_HW_INFO pHWHead = (PSER_HW_INFO)pHead;
USHORT divisor;
struct utcr3Bits utcr3Save;
divisor = SA_DivisorOfRate(pHead, BaudRate);
// RETAILMSG(1,(TEXT("+SA_SetBaudRate 0x%x and Divisor=%d\r\n"),BaudRate,divisor));
if (divisor) {
divisor-=1;
utcr3Save = HW_SA1100DisableTxRx(pHWHead);
IOW_REG_FIELD (struct utcr1Bits, &pHWHead->pUART->utcr1, brdHi, (divisor >> 8));
IOW_REG_FIELD (struct utcr2Bits, &pHWHead->pUART->utcr2, brdLo, (divisor & 0xff));
// HW_SA1100RestoreUTCR3(pHWHead,utcr3Save);
HW_EnableTxRx(pHWHead);
//SA_DumpSerialRegisters(pHWHead);
return(TRUE);
}
else {
return(FALSE);
}
}
//
// @doc OEM
// @func VOID | HW_SA1100SetBaudRate |
// This routine sets the baud rate of the device.
//
// @rdesc None.
//
BOOL
HW_SA1100SetBaudRate(
PVOID pHead, // @parm PVOID returned by HWInit
ULONG BaudRate // @parm ULONG representing decimal baud rate.
)
{
BOOL fRet;
PSER_HW_INFO pHWHead = (PSER_HW_INFO)pHead;
//RETAILMSG(1,(TEXT("+HW_SA1100SetbaudRate 0x%X, x%X\r\n"), pHead, BaudRate));
DEBUGMSG (ZONE_FUNCTION,
(TEXT("+HW_SA1100SetbaudRate 0x%X, x%X\r\n"), pHead, BaudRate));
try {
fRet = SA_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("-HW_SA1100SetbaudRate 0x%X (%d Baud)\r\n"),pHead,BaudRate));
//SA_DumpSerialRegisters(pHWHead);
return( TRUE );
} else {
DEBUGMSG (ZONE_FUNCTION | ZONE_ERROR,
(TEXT("-HW_SA1100SetbaudRate - Error setting %d, failing to %d\r\n"),
BaudRate, pHWHead->dcb.BaudRate) );
//SA_DumpSerialRegisters(pHWHead);
return(FALSE);
}
}
//
// @doc OEM
// @func VOID | HW_SA1100SetByteSize |
// This routine sets the WordSize of the device.
//
// @rdesc None.
//
BOOL
HW_SA1100SetByteSize(
PVOID pHead, // @parm PVOID returned by HWInit
ULONG ByteSize // @parm ULONG ByteSize field from DCB.
)
{
PSER_HW_INFO pHWHead = (PSER_HW_INFO)pHead;
//RETAILMSG(1,(TEXT("+HW_SA1100SetByteSize 0x%X, x%X\r\n"), pHead, ByteSize));
DEBUGMSG (ZONE_FUNCTION,
(TEXT("+HW_SA1100SetByteSize 0x%X, x%X\r\n"), pHead, ByteSize));
try {
switch( ByteSize ) {
case 7:
IOW_REG_FIELD (struct utcr0Bits, &pHWHead->pUART->utcr0, dss, 0);
break;
default:
case 8:
IOW_REG_FIELD (struct utcr0Bits, &pHWHead->pUART->utcr0, dss, 1);
break;
}
}
except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
}
DEBUGMSG (ZONE_FUNCTION,
(TEXT("-HW_SA1100SetByteSize 0x%X\r\n"), pHead));
//SA_DumpSerialRegisters(pHWHead);
return TRUE;
}
//
// @doc OEM
// @func VOID | HW_SA1100SetParity |
// This routine sets the parity of the device.
//
// @rdesc None.
//
BOOL
HW_SA1100SetParity(
PVOID pHead, // @parm PVOID returned by HWInit
ULONG Parity // @parm ULONG parity field from DCB.
)
{
PSER_HW_INFO pHWHead = (PSER_HW_INFO)pHead;
//RETAILMSG(1,(TEXT("+HW_SA1100SetParity 0x%X, x%X\r\n"), pHead, Parity));
DEBUGMSG (ZONE_FUNCTION,
(TEXT("+HW_SA1100SetParity 0x%X, x%X\r\n"), pHead, Parity));
try {
switch( Parity ) {
case ODDPARITY:
IOW_REG_FIELD (struct utcr0Bits, &pHWHead->pUART->utcr0, oes, 0);
IOW_REG_FIELD (struct utcr0Bits, &pHWHead->pUART->utcr0, pe, 1);
break;
case EVENPARITY:
IOW_REG_FIELD (struct utcr0Bits, &pHWHead->pUART->utcr0, oes, 1);
IOW_REG_FIELD (struct utcr0Bits, &pHWHead->pUART->utcr0, pe, 1);
break;
case NOPARITY:
default:
IOW_REG_FIELD (struct utcr0Bits, &pHWHead->pUART->utcr0, oes, 0);
IOW_REG_FIELD (struct utcr0Bits, &pHWHead->pUART->utcr0, pe, 0);
break;
}
}
except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
}
DEBUGMSG (ZONE_FUNCTION,(TEXT("-HW_SA1100SetParity 0x%X\r\n"), pHead));
//SA_DumpSerialRegisters(pHWHead);
return TRUE;
}
//
// @doc OEM
// @func VOID | HW_SA1100SetStopBits |
// This routine sets the Stop Bits for the device.
//
// @rdesc None.
//
BOOL
HW_SA1100SetStopBits(
PVOID pHead, // @parm PVOID returned by HWInit
ULONG StopBits // @parm ULONG StopBits field from DCB.
)
{
PSER_HW_INFO pHWHead = (PSER_HW_INFO)pHead;
//RETAILMSG(1,(TEXT("+HW_SA1100SetStopBits 0x%X, x%X\r\n"), pHead, StopBits));
DEBUGMSG (ZONE_FUNCTION,(TEXT("+HW_SA1100SetStopBits 0x%X, x%X\r\n"), pHead, StopBits));
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 TWOSTOPBITS :
IOW_REG_FIELD (struct utcr0Bits, &pHWHead->pUART->utcr0, sbs, 1);
break;
case ONESTOPBIT :
default:
IOW_REG_FIELD (struct utcr0Bits, &pHWHead->pUART->utcr0, sbs, 0);
break;
}
}
except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
}
DEBUGMSG (ZONE_FUNCTION,(TEXT("-HW_SA1100SetStopBits 0x%X\r\n"), pHead));
//SA_DumpSerialRegisters(pHWHead);
return TRUE;
}
//
// @doc OEM
// @func ULONG | HW_SA1100GetRxBufferSize | This function returns
// the size of the hardware buffer passed to the interrupt
// initialize function. It would be used only for devices
// which share a buffer between the MDD/PDD and an ISR.
//
//
// @rdesc This routine always returns 0 for 16550 UARTS.
//
ULONG
HW_SA1100GetRxBufferSize(
PVOID pHead
)
{
return 0;
}
//
// @doc OEM
// @func PVOID | SC_GetRxStart | This routine returns the start of the hardware
// receive buffer. See HW_SA1100GetRxBufferSize.
//
// @rdesc The return value is a pointer to the start of the device receive buffer.
//
PVOID
HW_SA1100GetRxStart(
PVOID pHead // @parm PVOID returned by SC_init.
)
{
//RETAILMSG(1,(TEXT("HW_SA1100GetRxStart\r\n")));
return (NULL);
}
//
// @doc OEM
// @func ULONG | HW_SA1100GetGetInterruptType | This function is called
// by the MDD whenever an interrupt occurs. The return code
// is then checked by the MDD to determine which of the four
// interrupt handling routines are to be called.
//
// @rdesc This routine returns a bitmask indicating which interrupts
// are currently pending.
//
INTERRUPT_TYPE
HW_SA1100GetInterruptType(
PVOID pHead // Pointer to hardware head
)
{
PSER_HW_INFO pHWHead = (PSER_HW_INFO)pHead;
INTERRUPT_TYPE interrupts=INTR_NONE;
BOOL irqError=0;
//RETAILMSG(1,(TEXT("HW_SA1100GetInterruptType\r\n")));
DEBUGMSG (0,(TEXT("+HW_SA1100GetInterruptType 0x%X\r\n"), pHead));
// The interrupt value is valid
if ((pHWHead->pUART->utsr0.rbb) || (pHWHead->pUART->utsr0.reb)
//|| (pHWHead->pUART->utsr0.eif) We do not need Frame error interrupt.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -