Cosmos/source/Cosmos.Debug.Hosts/Slave.cs
2017-01-17 00:35:58 +00:00

122 lines
2.8 KiB
C#

#if !NETSTANDARD1_6
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Text;
using System.Threading;
using System.IO.Ports;
using Cosmos.Build.Common;
namespace Cosmos.Debug.Hosts {
public class Slave : Host {
string mPortName;
SerialPort mPort;
Thread mPowerStateThread;
public Slave(Dictionary<string, string> aParams, bool aUseGDB)
: base(aParams, aUseGDB) {
var xPort = mParams[BuildPropertyNames.SlavePortString];
if (xPort == "None") {
throw new Exception("No slave port is set.");
}
var xParts = xPort.Split(' ');
mPortName = xParts[1];
}
string WaitForPrompt() {
var xSB = new StringBuilder();
char xLastChar = ' ';
char xChar = ' ';
while (true) {
xLastChar = xChar;
xChar = (char)mPort.ReadChar();
xSB.Append(xChar);
if (xChar == ':' && xLastChar == ':') {
break;
}
}
// Remove ::
xSB.Length = xSB.Length - 2;
return xSB.ToString();
}
void TogglePowerSwitch() {
Send("REL4.ON");
Thread.Sleep(500);
Send("REL4.OFF");
}
bool IsOn() {
var xResult = Send("CH1.GET").Split('\n');
return xResult[1][0] == '1';
}
string Send(string aData) {
// Dont use writeline, it only sends /n or /r (didnt bother to find out which, we need both)
mPort.Write(aData + "\r\n");
return WaitForPrompt();
}
void WaitPowerState(bool aOn) {
int xCount = 0;
while (IsOn() == !aOn) {
Thread.Sleep(250);
xCount++;
// 5 seconds
if (xCount == 20) {
throw new Exception("Slave did not respond to power command.");
}
}
}
public override void Start() {
mPort = new SerialPort(mPortName);
mPort.Open();
Send("");
// Set to digital input
Send("CH1.SETMODE(2)");
if (IsOn()) {
TogglePowerSwitch();
WaitPowerState(false);
// Small pause for discharge
Thread.Sleep(1000);
}
TogglePowerSwitch();
// Give PC some time to turn on, else we will detect it as off right away.
WaitPowerState(true);
if (OnShutDown != null) {
mPowerStateThread = new Thread(delegate() {
while (true) {
Thread.Sleep(1000);
if (!IsOn()) {
mPort.Close();
OnShutDown(this, EventArgs.Empty);
break;
}
}
});
mPowerStateThread.Start();
}
}
public override void Stop() {
if (mPowerStateThread != null) {
mPowerStateThread.Abort();
mPowerStateThread.Join();
}
if (IsOn()) {
TogglePowerSwitch();
WaitPowerState(false);
}
mPort.Close();
}
}
}
#endif