📄 cserpdd.cpp
字号:
}
else
if (inputData == m_DCB.EvtChar) {
EventCallback(EV_RXFLAG );
}
*puData = inputData;
}
}
return bReturn;
}
BOOL CSerialPDD::EventCallback(ULONG fdwEventMask,ULONG fdwModemStatus)
{
EvaluateEventFlag(m_pMdd,fdwEventMask);
if (!IsOpen() && ((fdwEventMask & EV_RLSD)!=0 && (fdwModemStatus & MS_RLSD_ON)!=0)) {
DEBUGMSG (ZONE_EVENTS,
(TEXT(" CSerialPDD::EventCallback (eventMask = 0x%x, modemstatus = 0x%x) - device was closed\r\n"),
fdwEventMask,fdwModemStatus));
CeEventHasOccurred (NOTIFICATION_EVENT_RS232_DETECTED, NULL);
}
return TRUE;
}
// For PurgeComm. The PDD only handle The clean up the hardware.
BOOL CSerialPDD::PurgeComm( DWORD fdwAction)
{
if (fdwAction & PURGE_RXCLEAR ) {
CancelReceive();
}
if (fdwAction & PURGE_TXCLEAR ) {
CancelXmit();
}
return TRUE;
}
void CSerialPDD::SetReceiveError(ULONG ulNewErrors)
{
if ( ulNewErrors!=0) {
m_HardwareLock.Lock();
m_ulCommErrors |= ulNewErrors;
m_HardwareLock.Unlock();
EventCallback(EV_ERR);
}
}
ULONG CSerialPDD::GetReceivedError()
{
m_HardwareLock.Lock();
ULONG ulReturn = m_ulCommErrors ;
m_ulCommErrors = 0;
m_HardwareLock.Unlock();
return ulReturn;
}
void CSerialPDD::SetDefaultConfiguration()
{
// Default Value. Can be altered.
m_CommPorp.wPacketLength = 0xffff;
m_CommPorp.wPacketVersion = 0xffff;
m_CommPorp.dwServiceMask = SP_SERIALCOMM;
m_CommPorp.dwReserved1 = 0;
m_CommPorp.dwMaxTxQueue = 16;
m_CommPorp.dwMaxRxQueue = 16;
m_CommPorp.dwMaxBaud = BAUD_115200;
m_CommPorp.dwProvSubType = PST_RS232;
m_CommPorp.dwProvCapabilities =
PCF_DTRDSR | PCF_RLSD | PCF_RTSCTS |
PCF_SETXCHAR |
PCF_INTTIMEOUTS |
PCF_PARITY_CHECK |
PCF_SPECIALCHARS |
PCF_TOTALTIMEOUTS |
PCF_XONXOFF;
m_CommPorp.dwSettableBaud =
BAUD_075 | BAUD_110 | BAUD_150 | BAUD_300 | BAUD_600 |
BAUD_1200 | BAUD_1800 | BAUD_2400 | BAUD_4800 |
BAUD_7200 | BAUD_9600 | BAUD_14400 |
BAUD_19200 | BAUD_38400 | BAUD_56K | BAUD_128K |
BAUD_115200 | BAUD_57600 | BAUD_USER;
m_CommPorp.dwSettableParams =
SP_BAUD | SP_DATABITS | SP_HANDSHAKING | SP_PARITY |
SP_PARITY_CHECK | SP_RLSD | SP_STOPBITS;
m_CommPorp.wSettableData =
DATABITS_5 | DATABITS_6 | DATABITS_7 | DATABITS_8;
m_CommPorp.wSettableStopParity =
STOPBITS_10 | STOPBITS_20 |
PARITY_NONE | PARITY_ODD | PARITY_EVEN | PARITY_SPACE |
PARITY_MARK;
// Setup m_DCB.
// Set Detault Parameter.
SetOutputMode(FALSE, TRUE ); // No IR.
// For DCB. The PDD only need to take care BaudRate, ByteSize Parity & StopBit
m_DCB.DCBlength = sizeof(DCB);
SetBaudRate(m_DCB.BaudRate = 9600,FALSE);
SetByteSize(m_DCB.ByteSize = 8);
SetParity(m_DCB.Parity = NOPARITY);
SetStopBits(m_DCB.StopBits = ONESTOPBIT);
}
BOOL CSerialPDD::SetDCB(LPDCB lpDCB)
{
BOOL bReturn = TRUE;
if (IsOpen() && lpDCB && lpDCB->DCBlength == sizeof(DCB)) {
m_HardwareLock.Lock();
DCB LocalDCB = *lpDCB;
if (lpDCB->BaudRate != m_DCB.BaudRate) {
if (!SetBaudRate(lpDCB->BaudRate, m_fIREnable)) {
LocalDCB.BaudRate = m_DCB.BaudRate ;
bReturn = FALSE;
}
}
if (lpDCB->ByteSize != m_DCB.ByteSize ) {
if (!SetByteSize(lpDCB->ByteSize)) {
LocalDCB.ByteSize = m_DCB.ByteSize;
bReturn = FALSE;
}
}
if (lpDCB->Parity != m_DCB.Parity) {
if (!SetParity(lpDCB->Parity)) {
LocalDCB.Parity = m_DCB.Parity ;
bReturn=FALSE;
}
}
if (lpDCB->StopBits != m_DCB.StopBits) {
if (!SetStopBits(lpDCB->StopBits)) {
LocalDCB.StopBits = m_DCB.StopBits;
bReturn = FALSE;
}
}
m_DCB = LocalDCB;
m_HardwareLock.Unlock();
}
else
bReturn = FALSE;
return bReturn;
};
// Default Rate to Divisor Converter.
BOOL CSerialPDD::GetDivisorOfRate(ULONG BaudRate,PULONG pulDivisor)
{
static const
PAIRS s_LS_BaudPairs[] = {
{50, 2307},
{75, 1538},
{110, 1049},
{135, 858},
{150, 769},
{300, 384},
{600, 192},
{1200, 96},
{1800, 64},
{2000, 58},
{2400, 48},
{3600, 32},
{4800, 24},
{7200, 16},
{9600, 12},
{12800, 9},
{14400, 8},
{19200, 6},
{23040, 5},
{28800, 4},
{38400, 3},
{57600, 2},
{115200, 1}
};
for (DWORD dwIndex =0 ; dwIndex <dim(s_LS_BaudPairs) && s_LS_BaudPairs[dwIndex].Key<=BaudRate; dwIndex ++) {
if (s_LS_BaudPairs[dwIndex].Key== BaudRate){
if (pulDivisor)
*pulDivisor = s_LS_BaudPairs[dwIndex].AssociatedValue;
return TRUE;
}
}
return FALSE;
}
//--------------------------------------------------------------------------------------------------------
//
// Converting C Style to C++ Serial Object.
/*
@doc OEM
@func PVOID | SerInit | Initializes device identified by argument.
* This routine sets information controlled by the user
* such as Line control and baud rate. It can also initialize events and
* interrupts, thereby indirectly managing initializing hardware buffers.
* Exported only to driver, called only once per process.
*
@rdesc The return value is a PVOID to be passed back into the HW
dependent layer when HW functions are called.
*/
PVOID
SerInit(
ULONG Identifier, // @parm Device identifier.
PVOID pMddHead, // @parm First argument to mdd callbacks.
PHWOBJ pHWObj // @parm Pointer to our own HW OBJ for this device
)
{
DEBUGMSG (ZONE_CLOSE,(TEXT("+SerInit, 0x%X\r\n"), Identifier));
CSerialPDD * pSerialPDD = NULL;
if (pHWObj) {
DWORD dwIndex= pHWObj->dwIntID;
pHWObj->dwIntID = 0;
pSerialPDD = CreateSerialObject((LPTSTR)Identifier,pMddHead, pHWObj,dwIndex);
}
if (pSerialPDD==NULL) {
ASSERT(FALSE);
LocalFree(pHWObj);
}
DEBUGMSG (ZONE_CLOSE,(TEXT("-SerInit, 0x%X\r\n"), pSerialPDD));
return pSerialPDD;
}
ULONG
SerDeinit(
PVOID pHead // @parm PVOID returned by SerInit.
)
{
CSerialPDD * pSerialPDD = (CSerialPDD *) pHead;
if (pSerialPDD ) {
PHWOBJ pHwObj = pSerialPDD->GetHwObject();
DeleteSerialObject(pSerialPDD);
if (pHwObj)
LocalFree(pHwObj);
return (TRUE);
}
else
return FALSE;
}
//
BOOL
SerPostInit(
PVOID pHead // @parm PVOID returned by HWinit.
)
{
CSerialPDD * pSerialPDD = (CSerialPDD *)pHead;
DEBUGMSG (ZONE_INIT,(TEXT("+SL_PostInit, 0x%X\r\n"), pSerialPDD ));
if ( pSerialPDD ) {
pSerialPDD->PostInit();
}
DEBUGMSG (ZONE_INIT,(TEXT("-SL_PostInit, 0x%X\r\n"), pSerialPDD ));
return(TRUE);
}
BOOL
SerOpen(
PVOID pHead /*@parm PVOID returned by Serinit. */
)
{
DEBUGMSG (ZONE_OPEN, (TEXT("SerOpen (%X)\r\n"),pHead));
CSerialPDD * pSerialPDD = (CSerialPDD *)pHead;
BOOL bReturn = FALSE;
if ( pSerialPDD) {
bReturn = pSerialPDD->Open();
}
DEBUGMSG (ZONE_OPEN, (TEXT("-SerOpen(%X) return %d \r\n"),pSerialPDD,bReturn));
return bReturn;
}
ULONG
SerClose(
PVOID pHead // @parm PVOID returned by SerInit.
)
{
DEBUGMSG (ZONE_CLOSE, (TEXT("SerClose (%X)\r\n"),pHead));
CSerialPDD * pSerialPDD = (CSerialPDD *)pHead;
BOOL bReturn = FALSE;
if ( pSerialPDD) {
bReturn = pSerialPDD->Close();
}
DEBUGMSG (ZONE_CLOSE, (TEXT("-SerClose(%X) return %d \r\n"),pSerialPDD,bReturn));
return (ULONG)bReturn;
}
INTERRUPT_TYPE
SerGetInterruptType(
PVOID pHead // Pointer to hardware head
)
{
CSerialPDD * pSerialPDD = ( CSerialPDD * )pHead;
INTERRUPT_TYPE interrupts=INTR_NONE;
DEBUGMSG (ZONE_EVENTS,(TEXT("+SerGetInterruptType 0x%X\r\n"), pHead));
if (pSerialPDD)
interrupts= pSerialPDD->GetInterruptType();
DEBUGMSG (ZONE_EVENTS,(TEXT("-SerGetInterruptType (0x%X) return %X\r\n"), pHead, interrupts));
return interrupts;
}
ULONG
SerRxIntr(
PVOID pHead, // @parm Pointer to hardware head
PUCHAR pRxBuffer, // @parm Pointer to receive buffer
ULONG *pBufflen // @parm In = max bytes to read, out = bytes read
)
{
DEBUGMSG (ZONE_READ|ZONE_EVENTS,(TEXT("+SerRxIntr( 0x%X,0x%X,0x%X)\r\n"),
pHead,pRxBuffer,(pBufflen!=NULL?*pBufflen:0)));
DWORD dwReturn=0;
CSerialPDD * pSerialPDD = ( CSerialPDD * )pHead;
if (pSerialPDD)
dwReturn = pSerialPDD->ReceiveInterruptHandler(pRxBuffer,pBufflen);
DEBUGMSG (ZONE_READ|ZONE_EVENTS,(TEXT("-SerRxIntr( 0x%X,0x%X,0x%X) return 0x%X\r\n"),
pHead,pRxBuffer,(pBufflen!=NULL?*pBufflen:0),dwReturn));
return dwReturn;
}
VOID
SerTxIntrEx(
PVOID pHead, // Hardware Head
PUCHAR pTxBuffer, // @parm Pointer to receive buffer
ULONG *pBufflen // @parm In = max bytes to transmit, out = bytes transmitted
)
{
DEBUGMSG (ZONE_WRITE|ZONE_EVENTS,(TEXT("+SerTxIntrEx( 0x%X,0x%X,0x%X)\r\n"),
pHead,pTxBuffer,(pBufflen!=NULL?*pBufflen:0)));
CSerialPDD * pSerialPDD = ( CSerialPDD * )pHead;
if (pSerialPDD)
pSerialPDD->XmitInterruptHandler(pTxBuffer,pBufflen);
DEBUGMSG (ZONE_WRITE|ZONE_EVENTS,(TEXT("-SerTxIntrEx( 0x%X,0x%X,0x%X)\r\n"),
pHead,pTxBuffer,(pBufflen!=NULL?*pBufflen:0)));
}
VOID
SerModemIntr(
PVOID pHead // Hardware Head
)
{
DEBUGMSG (ZONE_EVENTS,(TEXT("+SerModemIntr 0x%X\r\n"), pHead));
if (pHead)
((CSerialPDD *)pHead)->ModemInterruptHandler();
DEBUGMSG (ZONE_EVENTS,(TEXT("-SerModemIntr 0x%X\r\n"), pHead));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -