📄 mdd.c
字号:
pHWHead = pHWObj->pFuncTbl->HWInit(Identifier, pSerialHead);
pSerialHead->pHWHead = pHWHead;
pSerialHead->pHWObj = pHWObj;
/* Check that HWInit did stuff ok. From here on out, call Deinit function
* when things fail.
*/
if ( !pHWHead ) {
DEBUGMSG (ZONE_INIT | ZONE_ERROR,
(TEXT("Hardware doesn't init correctly, COM_Init failed\r\n")));
COM_Deinit(pSerialHead);
return (NULL);
}
DEBUGMSG (ZONE_INIT,
(TEXT("Back from hardware init\r\n")));
// Allocate at least twice the hardware buffer size so we have headroom
HWBufferSize = 2 * pHWObj->pFuncTbl->HWGetRxBufferSize(pHWHead);
// Init rx buffer and buffer length here.
pSerialHead->RxBufferInfo.Length =
HWBufferSize > RX_BUFFER_SIZE ? HWBufferSize:RX_BUFFER_SIZE;
pSerialHead->RxBufferInfo.RxCharBuffer =
LocalAlloc(LPTR, pSerialHead->RxBufferInfo.Length);
if ( !pSerialHead->RxBufferInfo.RxCharBuffer ) {
DEBUGMSG(ZONE_INIT|ZONE_ERROR,
(TEXT("Error allocating receive buffer, COM_Init failed\n\r")));
COM_Deinit(pSerialHead);
return (NULL);
}
DEBUGMSG (ZONE_INIT, (TEXT("RxHead init'ed\r\n")));
RxResetFifo(pSerialHead);
InitializeCriticalSection(&(pSerialHead->RxBufferInfo.CS));
DEBUGMSG (ZONE_INIT, (TEXT("RxBuffer init'ed with start at %x\r\n"),
pSerialHead->RxBufferInfo.RxCharBuffer));
if ( pHWObj->BindFlags & THREAD_AT_INIT ) {
// Hook the interrupt and start the associated thread.
if ( ! StartDispatchThread( pSerialHead ) ) {
// Failed on InterruptInitialize or CreateThread.
COM_Deinit(pSerialHead);
return (NULL);
}
}
DEBUGMSG (ZONE_INIT | ZONE_FUNCTION, (TEXT("-COM_Init\r\n")));
return (pSerialHead);
}
/*
* @doc INTERNAL
* @func BOOL | ApplyDCB | Apply the current DCB.
*
* This function will apply the current DCB settings to the device.
* It will also call to the PDD to set the PDD values.
*/
BOOL
ApplyDCB (PHW_INDEP_INFO pSerialHead,DCB *pDCB, BOOL fOpen)
{
PHWOBJ pHWObj = pSerialHead->pHWObj;
if ( !pHWObj->pFuncTbl->HWSetDCB(pSerialHead->pHWHead,
pDCB) ) {
return(FALSE);
}
if ( !fOpen ) {
return TRUE;
}
// If PDD SetDCB was successful, save the supplied DCB and
// configure port to match these settings.
memcpy(&(pSerialHead->DCB), pDCB, sizeof(DCB));
if ( pSerialHead->DCB.fDtrControl == DTR_CONTROL_DISABLE ) {
pHWObj->pFuncTbl->HWClearDTR(pSerialHead->pHWHead);
} else if ( pSerialHead->DCB.fDtrControl == DTR_CONTROL_ENABLE ) {
pHWObj->pFuncTbl->HWSetDTR(pSerialHead->pHWHead);
}
if ( pSerialHead->DCB.fRtsControl == RTS_CONTROL_DISABLE ) {
pHWObj->pFuncTbl->HWClearRTS(pSerialHead->pHWHead);
} else if ( pSerialHead->DCB.fRtsControl == RTS_CONTROL_ENABLE ) {
pHWObj->pFuncTbl->HWSetRTS(pSerialHead->pHWHead);
}
if ( pSerialHead->DCB.fDtrControl == DTR_CONTROL_HANDSHAKE ) {
if ( (!pSerialHead->DtrFlow) &&
(4*RxBytesAvail(pSerialHead) > (3*RxLength(pSerialHead))) ) {
DEBUGMSG (ZONE_READ|ZONE_FLOW,
(TEXT("IOCTL:DTR_CONTROL_HANDSHAKE Clearing DTR\r\n")));
pSerialHead->DtrFlow = 1;
pHWObj->pFuncTbl->HWClearDTR(pSerialHead->pHWHead);
} else {
DEBUGMSG (ZONE_READ|ZONE_FLOW,
(TEXT("IOCTL:DTR_CONTROL_HANDSHAKE Setting DTR\r\n")));
pSerialHead->DtrFlow = 0;
pHWObj->pFuncTbl->HWSetDTR(pSerialHead->pHWHead);
}
}
if ( pSerialHead->DCB.fRtsControl == RTS_CONTROL_HANDSHAKE ) {
if ( (pSerialHead->RtsFlow) &&
(4*RxBytesAvail(pSerialHead) > (3*RxLength(pSerialHead))) ) {
DEBUGMSG (ZONE_READ|ZONE_FLOW,
(TEXT("IOCTL:RTS_CONTROL_HANDSHAKE Clearing RTS\r\n")));
pSerialHead->RtsFlow = 1;
pHWObj->pFuncTbl->HWClearRTS(pSerialHead->pHWHead);
} else {
DEBUGMSG (ZONE_READ|ZONE_FLOW,
(TEXT("IOCTL:RTS_CONTROL_HANDSHAKE Setting RTS\r\n")));
pSerialHead->RtsFlow = 0;
pHWObj->pFuncTbl->HWSetRTS(pSerialHead->pHWHead);
}
}
if ( pSerialHead->DCB.fOutX || pSerialHead->DCB.fInX ) {
pSerialHead->XFlow = 1;
} else {
pSerialHead->XFlow = 0;
}
return TRUE;
}
/*
@doc EXTERNAL
@func HANDLE | COM_Open | Serial port driver initialization.
* Description: This routine must be called by the user to open the
* serial device. The HANDLE returned must be used by the application in
* all subsequent calls to the serial driver. This routine starts the thread
* which handles the serial events.
* Exported to users.
*
@rdesc This routine returns a HANDLE representing the device.
*/
HANDLE
COM_Open(
HANDLE pHead, // @parm Handle returned by COM_Init.
DWORD AccessCode, // @parm access code.
DWORD ShareMode // @parm share mode - Not used in this driver.
)
{
PHW_INDEP_INFO pSerialHead = (PHW_INDEP_INFO)pHead;
PHW_OPEN_INFO pOpenHead;
PHWOBJ pHWObj = pSerialHead->pHWObj;
DEBUGMSG (ZONE_OPEN|ZONE_FUNCTION, (TEXT("+COM_Open handle x%X, access x%X, share x%X\r\n"),
pHead, AccessCode, ShareMode));
// Return NULL if SerialInit failed.
if ( !pSerialHead ) {
DEBUGMSG (ZONE_OPEN|ZONE_ERROR,
(TEXT("Open attempted on uninited device!\r\n")));
SetLastError(ERROR_INVALID_HANDLE);
return (NULL);
}
// Return NULL if opening with access & someone else already has
if ( (AccessCode & (GENERIC_READ | GENERIC_WRITE)) &&
pSerialHead->pAccessOwner ) {
DEBUGMSG (ZONE_OPEN|ZONE_ERROR,
(TEXT("Open requested access %x, handle x%X already has x%X!\r\n"),
AccessCode, pSerialHead->pAccessOwner,
pSerialHead->pAccessOwner->AccessCode));
SetLastError(ERROR_INVALID_ACCESS);
return (NULL);
}
// OK, lets allocate an open structure
pOpenHead = (PHW_OPEN_INFO)LocalAlloc(LPTR, sizeof(HW_OPEN_INFO));
if ( !pOpenHead ) {
DEBUGMSG(ZONE_INIT | ZONE_ERROR,
(TEXT("Error allocating memory for pOpenHead, COM_Open failed\n\r")));
return (NULL);
}
// Init the structure
pOpenHead->pSerialHead = pSerialHead; // pointer back to our parent
pOpenHead->StructUsers = 0;
pOpenHead->AccessCode = AccessCode;
pOpenHead->ShareMode = ShareMode;
pOpenHead->CommEvents.hCommEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
pOpenHead->CommEvents.fEventMask = 0;
pOpenHead->CommEvents.fEventData = 0;
pOpenHead->CommEvents.fAbort = 0;
// if we have access permissions, note it in pSerialhead
if ( AccessCode & (GENERIC_READ | GENERIC_WRITE) ) {
DEBUGMSG(ZONE_INIT|ZONE_CLOSE,
(TEXT("COM_Open: Access permission handle granted x%X\n\r"),
pOpenHead));
pSerialHead->pAccessOwner = pOpenHead;
}
// add this open entry to list of open entries.
EnterCriticalSection(&(pSerialHead->OpenListCS));
InsertHeadList(&pSerialHead->OpenList,
&pOpenHead->llist);
LeaveCriticalSection(&(pSerialHead->OpenListCS));
// If port not yet opened, we need to do some init
if ( ! pSerialHead->OpenCnt ) {
DEBUGMSG(ZONE_INIT|ZONE_OPEN,
(TEXT("COM_Open: First open : Do Init x%X\n\r"),
pOpenHead));
if ( pSerialHead->pHWObj->BindFlags & THREAD_AT_OPEN ) {
DEBUGMSG(ZONE_INIT|ZONE_OPEN,
(TEXT("COM_Open: Starting DispatchThread x%X\n\r"),
pOpenHead));
// Hook the interrupt and start the associated thread.
if ( ! StartDispatchThread( pSerialHead ) ) {
// Failed on InterruptInitialize or CreateThread. Bail.
DEBUGMSG(ZONE_INIT|ZONE_OPEN,
(TEXT("COM_Open: Failed StartDispatchThread x%X\n\r"),
pOpenHead));
goto OpenFail;
}
CeSetThreadPriority(pSerialHead->pDispatchThread,
pSerialHead->Priority256);
}
pSerialHead->RxBytes = 0;
pSerialHead->TxBytes = 0;
pSerialHead->TxBytesPending = 0;
pSerialHead->DroppedBytesMDD = 0;
pSerialHead->DroppedBytesPDD = 0;
pSerialHead->DCB.DCBlength = sizeof(DCB);
pSerialHead->DCB.BaudRate = 9600;
pSerialHead->DCB.fBinary = TRUE;
pSerialHead->DCB.fParity = FALSE;
pSerialHead->DCB.fOutxCtsFlow = FALSE;
pSerialHead->DCB.fOutxDsrFlow = FALSE;
pSerialHead->DCB.fDtrControl = DTR_CONTROL_ENABLE;
pSerialHead->DCB.fDsrSensitivity = FALSE;
pSerialHead->DCB.fTXContinueOnXoff = FALSE;
pSerialHead->DCB.fOutX = FALSE;
pSerialHead->DCB.fInX = FALSE;
pSerialHead->DCB.fErrorChar = FALSE; //NOTE: ignored
pSerialHead->DCB.fNull = FALSE; //NOTE: ignored
pSerialHead->DCB.fRtsControl = RTS_CONTROL_ENABLE;
pSerialHead->DCB.fAbortOnError = FALSE; //NOTE: ignored
pSerialHead->DCB.XonLim = 512;
pSerialHead->DCB.XoffLim = 128;
pSerialHead->DCB.ByteSize = 8;
pSerialHead->DCB.Parity = NOPARITY;
pSerialHead->DCB.StopBits = ONESTOPBIT;
pSerialHead->DCB.XonChar = X_ON_CHAR;
pSerialHead->DCB.XoffChar = X_OFF_CHAR;
pSerialHead->DCB.ErrorChar = ERROR_CHAR;
pSerialHead->DCB.EofChar = E_OF_CHAR;
pSerialHead->DCB.EvtChar = EVENT_CHAR;
pSerialHead->StopXmit = 0;
pSerialHead->SentXoff = 0;
pSerialHead->DtrFlow = 0;
pSerialHead->RtsFlow = 0;
ApplyDCB (pSerialHead,&pSerialHead->DCB, FALSE);
pHWObj->pFuncTbl->HWSetCommTimeouts(pSerialHead->pHWHead,
&(pSerialHead->CommTimeouts));
if ( !pHWObj->pFuncTbl->HWOpen(pSerialHead->pHWHead) ) {
DEBUGMSG (ZONE_OPEN|ZONE_ERROR, (TEXT("HW Open failed.\r\n")));
goto OpenFail;
}
pHWObj->pFuncTbl->HWPurgeComm(pSerialHead->pHWHead, PURGE_RXCLEAR);
memset(pSerialHead->RxBufferInfo.RxCharBuffer, 0, pSerialHead->RxBufferInfo.Length);
if ( pHWObj->BindFlags & THREAD_IN_MDD ) {
CeSetThreadPriority(pSerialHead->pDispatchThread,
pSerialHead->Priority256);
}
RxResetFifo (pSerialHead);
}
++(pSerialHead->OpenCnt);
DEBUGMSG (ZONE_OPEN|ZONE_FUNCTION, (TEXT("-COM_Open handle x%X, x%X, Ref x%X\r\n"),
pOpenHead, pOpenHead->pSerialHead, pSerialHead->OpenCnt));
return (pOpenHead);
OpenFail :
DEBUGMSG (ZONE_OPEN|ZONE_FUNCTION, (TEXT("-COM_Open handle x%X, x%X, Ref x%X\r\n"),
NULL, pOpenHead->pSerialHead, pSerialHead->OpenCnt));
SetLastError(ERROR_OPEN_FAILED);
// If this was the handle with access permission, remove pointer
if ( pOpenHead == pSerialHead->pAccessOwner )
pSerialHead->pAccessOwner = NULL;
// Remove the Open entry from the linked list
EnterCriticalSection(&(pSerialHead->OpenListCS));
RemoveEntryList(&pOpenHead->llist);
LeaveCriticalSection(&(pSerialHead->OpenListCS));
// Free all data allocated in open
if ( pOpenHead->CommEvents.hCommEvent )
CloseHandle(pOpenHead->CommEvents.hCommEvent);
LocalFree( pOpenHead );
return (NULL);
}
// ****************************************************************
//
// @doc EXTERNAL
//
// @func BOOL | COM_Close | close the serial device.
//
// @parm DWORD | pHead | Context pointer returned from COM_Open
//
// @rdesc TRUE if success; FALSE if failure
//
// @remark This routine is called by the device manager to close the device.
//
//
//
BOOL
COM_Close(PHW_OPEN_INFO pOpenHead)
{
PHW_INDEP_INFO pSerialHead = pOpenHead->pSerialHead;
PHWOBJ pHWObj;
int i;
DEBUGMSG (ZONE_CLOSE|ZONE_FUNCTION, (TEXT("+COM_Close\r\n")));
if ( !pSerialHead ) {
DEBUGMSG (ZONE_ERROR, (TEXT("!!COM_Close: pSerialHead == NULL!!\r\n")));
SetLastError(ERROR_INVALID_HANDLE);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -