?? port.cs
字號(hào):
/// <summary>
/// Returns whether or not the current port support an RTS signal
/// </summary>
public bool RTSAvailable
{
get
{
return rtsavail;
}
}
/// <summary>
/// Gets or sets the current RTS line state (true = 1, false = 0)
/// </summary>
public bool RTSEnable
{
get
{
return (rts == 1);
}
set
{
if(rts < 0) return;
if(hPort == (IntPtr)CommAPI.INVALID_HANDLE_VALUE) return;
if (value)
{
if (m_CommAPI.EscapeCommFunction(hPort, CommEscapes.SETRTS))
rts = 1;
else
throw new CommPortException("Failed to set RTS!");
}
else
{
if (m_CommAPI.EscapeCommFunction(hPort, CommEscapes.CLRRTS))
rts = 0;
else
throw new CommPortException("Failed to clear RTS!");
}
}
}
/// <summary>
/// Gets or sets the com port for IR use (true = 1, false = 0)
/// </summary>
public bool IREnable
{
get
{
return (setir == 1);
}
set
{
if(setir < 0) return;
if(hPort == (IntPtr)CommAPI.INVALID_HANDLE_VALUE) return;
if (value)
{
if (m_CommAPI.EscapeCommFunction(hPort, CommEscapes.SETIR))
setir = 1;
else
throw new CommPortException("Failed to set IR!");
}
else
{
if (m_CommAPI.EscapeCommFunction(hPort, CommEscapes.CLRIR))
setir = 0;
else
throw new CommPortException("Failed to clear IR!");
}
}
}
/// <summary>
/// Get or Set the Port's DetailedPortSettings
/// </summary>
public DetailedPortSettings DetailedSettings
{
get
{
return portSettings;
}
set
{
portSettings = value;
UpdateSettings();
}
}
/// <summary>
/// Get or Set the Port's BasicPortSettings
/// </summary>
public BasicPortSettings Settings
{
get
{
return portSettings.BasicSettings;
}
set
{
portSettings.BasicSettings = value;
UpdateSettings();
}
}
/// <summary>
/// <code>GetPortProperties initializes the commprop member of the port object</code>
/// </summary>
/// <returns></returns>
private bool GetPortProperties()
{
bool success;
success=m_CommAPI.GetCommProperties(hPort,Capabilities);
return (success);
}
private void CommEventThread()
{
CommEventFlags eventFlags = new CommEventFlags();
byte[] readbuffer = new Byte[rxBufferSize];
int bytesread = 0;
AutoResetEvent rxevent = new AutoResetEvent(false);
// specify the set of events to be monitored for the port.
if(CommAPI.FullFramework)
{
m_CommAPI.SetCommMask(hPort, CommEventFlags.ALLPC);
// set up the overlapped IO
OVERLAPPED o = new OVERLAPPED();
rxOverlapped = LocalAlloc(0x40, Marshal.SizeOf(o));
o.Offset = 0;
o.OffsetHigh = 0;
o.hEvent = rxevent.Handle;
Marshal.StructureToPtr(o, rxOverlapped, true);
}
else
{
m_CommAPI.SetCommMask(hPort, CommEventFlags.ALLCE);
}
try
{
// let Open() know we're started
threadStarted.Set();
#region >>>> thread loop <<<<
while(hPort != (IntPtr)CommAPI.INVALID_HANDLE_VALUE)
{
// wait for a Comm event
if(!m_CommAPI.WaitCommEvent(hPort, ref eventFlags))
{
int e = Marshal.GetLastWin32Error();
if(e == (int)APIErrors.ERROR_IO_PENDING)
{
// IO pending so just wait and try again
rxevent.WaitOne();
Thread.Sleep(0);
continue;
}
if(e == (int)APIErrors.ERROR_INVALID_HANDLE)
{
// Calling Port.Close() causes hPort to become invalid
// Since Thread.Abort() is unsupported in the CF, we must
// accept that calling Close will throw an error here.
// Close signals the closeEvent, so wait on it
// We wait 1 second, though Close should happen much sooner
int eventResult = m_CommAPI.WaitForSingleObject(closeEvent, 1000);
if(eventResult == (int)APIConstants.WAIT_OBJECT_0)
{
// the event was set so close was called
hPort = (IntPtr)CommAPI.INVALID_HANDLE_VALUE;
// reset our ResetEvent for the next call to Open
threadStarted.Reset();
if(isOpen) // this should not be the case...if so, throw an exception for the owner
{
string error = String.Format("Wait Failed: {0}", e);
throw new CommPortException(error);
}
return;
}
}
// WaitCommEvent failed
// 995 means an exit was requested (thread killed)
if(e == 995)
{
return;
}
else
{
string error = String.Format("Wait Failed: {0}", e);
throw new CommPortException(error);
}
}
// Re-specify the set of events to be monitored for the port.
if(CommAPI.FullFramework)
{
m_CommAPI.SetCommMask(hPort, CommEventFlags.ALLPC);
}
else
{
m_CommAPI.SetCommMask(hPort, CommEventFlags.ALLCE);
}
// check the event for errors
#region >>>> error checking <<<<
if(((uint)eventFlags & (uint)CommEventFlags.ERR) != 0)
{
CommErrorFlags errorFlags = new CommErrorFlags();
CommStat commStat = new CommStat();
// get the error status
if(!m_CommAPI.ClearCommError(hPort, ref errorFlags, commStat))
{
// ClearCommError failed!
string error = String.Format("ClearCommError Failed: {0}", Marshal.GetLastWin32Error());
throw new CommPortException(error);
}
if(((uint)errorFlags & (uint)CommErrorFlags.BREAK) != 0)
{
// BREAK can set an error, so make sure the BREAK bit is set an continue
eventFlags |= CommEventFlags.BREAK;
}
else
{
// we have an error. Build a meaningful string and throw an exception
StringBuilder s = new StringBuilder("UART Error: ", 80);
if ((errorFlags & CommErrorFlags.FRAME) != 0)
{ s = s.Append("Framing,"); }
if ((errorFlags & CommErrorFlags.IOE) != 0)
{ s = s.Append("IO,"); }
if ((errorFlags & CommErrorFlags.OVERRUN) != 0)
{ s = s.Append("Overrun,"); }
if ((errorFlags & CommErrorFlags.RXOVER) != 0)
{ s = s.Append("Receive Overflow,"); }
if ((errorFlags & CommErrorFlags.RXPARITY) != 0)
{ s = s.Append("Parity,"); }
if ((errorFlags & CommErrorFlags.TXFULL) != 0)
{ s = s.Append("Transmit Overflow,"); }
// no known bits are set
if(s.Length == 12)
{ s = s.Append("Unknown"); }
// raise an error event
if(OnError != null)
OnError(s.ToString());
continue;
}
} // if(((uint)eventFlags & (uint)CommEventFlags.ERR) != 0)
#endregion
#region >>>> Receive data subsection <<<<
// check for RXCHAR
if((eventFlags & CommEventFlags.RXCHAR) != 0)
{
do
{
// make sure the port handle is valid
if(hPort == (IntPtr)CommAPI.INVALID_HANDLE_VALUE)
{
bytesread = 0;
break;
}
// data came in, put it in the buffer and set the event
if (!m_CommAPI.ReadFile(hPort, readbuffer, rxBufferSize, ref bytesread, rxOverlapped))
{
string errString = String.Format("ReadFile Failed: {0}", Marshal.GetLastWin32Error());
if(OnError != null)
OnError(errString);
return;
}
if (bytesread >= 1)
{
// take the mutex
rxBufferBusy.WaitOne();
// put the data into the fifo
// this *may* be a perf problem and needs testing
for(int b = 0 ; b < bytesread ; b++)
rxFIFO.Enqueue(readbuffer[b]);
// get the FIFO length
int fifoLength = rxFIFO.Count;
// release the mutex
rxBufferBusy.ReleaseMutex();
// fire the DataReceived event every RThreshold bytes
if((DataReceived != null) && (rthreshold != 0) && (fifoLength >= rthreshold))
{
DataReceived();
}
}
} while (bytesread > 0);
} // if((eventFlags & CommEventFlags.RXCHAR) != 0)
#endregion
#region >>>> line status checking <<<<
// check for status changes
uint status = 0;
m_CommAPI.GetCommModemStatus(hPort, ref status);
// check the CTS
if(((uint)eventFlags & (uint)CommEventFlags.CTS) != 0)
{
if(CTSChange != null)
CTSChange((status & (uint)CommModemStatusFlags.MS_CTS_ON) != 0);
}
// check the DSR
if(((uint)eventFlags & (uint)CommEventFlags.DSR) != 0)
{
if(DSRChange != null)
DSRChange((status & (uint)CommModemStatusFlags.MS_DSR_ON) != 0);
}
// check for a RING
if(((uint)eventFlags & (uint)CommEventFlags.RING) != 0)
{
if(RingChange != null)
RingChange((status & (uint)CommModemStatusFlags.MS_RING_ON) != 0);
}
// check for a RLSD
if(((uint)eventFlags & (uint)CommEventFlags.RLSD) != 0)
{
if(RLSDChange != null)
RLSDChange((status & (uint)CommModemStatusFlags.MS_RLSD_ON) != 0);
}
// check for TXEMPTY
if(((uint)eventFlags & (uint)CommEventFlags.TXEMPTY) != 0)
if(TxDone != null) { TxDone(); }
// check for RXFLAG
if(((uint)eventFlags & (uint)CommEventFlags.RXFLAG) != 0)
if(FlagCharReceived != null) { FlagCharReceived(); }
// check for POWER
if(((uint)eventFlags & (uint)CommEventFlags.POWER) != 0)
if(PowerEvent != null) { PowerEvent(); }
// check for high-water state
if((eventFlags & CommEventFlags.RX80FULL) != 0)
if(HighWater != null) { HighWater(); }
#endregion
} // while(true)
#endregion
} // try
catch(Exception e)
{
if(rxOverlapped != IntPtr.Zero)
LocalFree(rxOverlapped);
if(OnError != null)
OnError(e.Message);
return;
}
}
}
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -