ardupilot/Tools/ArdupilotMegaPlanner/Comms/CommsSerialPort.cs
Michael Oborne 8f084ae8ee Mission Planner 1.2.23
ammend serial dispose on usb devices detach
add item currentstate item description and units
ammend battery screen for 3dr power module
add trackbar zoom to flight data
add unit desccription
ammend PREFLIGHT_REBOOT_SHUTDOWN timeout
2012-11-27 22:19:59 +08:00

145 lines
4.6 KiB
C#

using System;
using System.Collections.Generic;
using System.Text;
using System.IO.Ports;
using System.IO;
using System.Linq;
using System.Management;
using ArdupilotMega.Utilities;
using System.Reflection;
namespace ArdupilotMega.Comms
{
public class SerialPort : System.IO.Ports.SerialPort,ICommsSerial
{
static bool serialportproblem = false;
protected override void Dispose(bool disposing)
{
try
{
try
{
Type mytype = typeof(System.IO.Ports.SerialPort);
FieldInfo field = mytype.GetField("internalSerialStream", BindingFlags.Instance | BindingFlags.NonPublic);
Stream stream = (Stream)field.GetValue(this);
if (stream != null)
{
stream.Dispose();
}
}
catch { }
base.Dispose(disposing);
}
catch { }
}
public new void Open()
{
// 500ms write timeout - win32 api default
this.WriteTimeout = 500;
if (base.IsOpen)
return;
base.Open();
}
public void toggleDTR()
{
bool open = this.IsOpen;
if (!open)
this.Open();
base.DtrEnable = false;
base.RtsEnable = false;
System.Threading.Thread.Sleep(50);
base.DtrEnable = true;
base.RtsEnable = true;
System.Threading.Thread.Sleep(50);
if (!open)
this.Close();
}
public new static string[] GetPortNames()
{
List<string> allPorts = new List<string>();
if (Directory.Exists("/dev/"))
{
if (Directory.Exists("/dev/serial/by-id/"))
allPorts.AddRange(Directory.GetFiles("/dev/serial/by-id/", "*"));
allPorts.AddRange(Directory.GetFiles("/dev/", "ttyACM*"));
allPorts.AddRange(Directory.GetFiles("/dev/", "ttyUSB*"));
allPorts.AddRange(Directory.GetFiles("/dev/", "rfcomm*"));
}
string[] ports = System.IO.Ports.SerialPort.GetPortNames()
.Select(p => p.TrimEnd())
.Select(FixBlueToothPortNameBug)
.ToArray();
allPorts.AddRange(ports);
return allPorts.ToArray();
}
internal static string GetNiceName(string port)
{
if (serialportproblem)
return "";
DateTime start = DateTime.Now;
try
{
ObjectQuery query = new ObjectQuery("SELECT * FROM Win32_SerialPort"); // Win32_USBControllerDevice
ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
foreach (ManagementObject obj2 in searcher.Get())
{
//DeviceID
if (obj2.Properties["DeviceID"].Value.ToString().ToUpper() == port.ToUpper())
{
DateTime end = DateTime.Now;
if ((end - start).TotalSeconds > 5)
serialportproblem = true;
return obj2.Properties["Name"].Value.ToString();
}
}
}
catch { }
return "";
}
// .NET bug: sometimes bluetooth ports are enumerated with bogus characters
// eg 'COM10' becomes 'COM10c' - one workaround is to remove the non numeric
// char. Annoyingly, sometimes a numeric char is added, which means this
// does not work in all cases.
// See http://connect.microsoft.com/VisualStudio/feedback/details/236183/system-io-ports-serialport-getportnames-error-with-bluetooth
private static string FixBlueToothPortNameBug(string portName)
{
if (!portName.StartsWith("COM"))
return portName;
var newPortName = "COM"; // Start over with "COM"
foreach (var portChar in portName.Substring(3).ToCharArray()) // Remove "COM", put the rest in a character array
{
if (char.IsDigit(portChar))
newPortName += portChar.ToString(); // Good character, append to portName
// else
//log.WarnFormat("Bad (Non Numeric) character in port name '{0}' - removing", portName);
}
return newPortName;
}
}
}