using System; using System.Text; using System.Reflection; using Microsoft.SPOT; using Microsoft.SPOT.Hardware; using Microsoft.SPOT.IO; using System.IO; using System.IO.Ports; using System.Threading; using GHI.IO.Storage; using GHI.Processor; using GHI.Usb.Client; using SWModules; using HWModules; using Zmodem; namespace SensorModules { public class FactoryConsole { // Constants private const bool GC_LOCALECHO = true; private const byte GC_MAXTOKENS = 10; // Limits of FAT32 Filesystems //private const int GC_MAXFILES = 125; private const byte GC_MAXFILEN = 0xFF; private const int GC_MAXPATHL = 0xFFF; private char[] GC_DELIMITERS = new char[] { ' ', ',' }; public enum CMD { HELP, PWD, DIR, SCAN, CD, MKDIR, CP, RM, MV, SZ, RZ, COM, REBOOT, POW, DATE, CPF, SLEEP, CHARGEMON, UNKNOWN, READSTRINGPOT, VALVE, PUMP, PUMPMON, TOUCH, ENABLE, DISABLE, MASSSTORAGE, STATUS }; private enum UT { Iridium, Rudics, Ctd, Optode, Pump, Elmo, Pth, Flbb, Gps, Watchdog, EMonBatt, EMonPump, Msc, IncBuoy, DecBuoy, FileFlood, SurfaceOps, DualLead, MotorizedValve, BellowsPosition, Unknown, Ocr }; //To add a UT to this list // 1) Add the name to the enumerator above this // 2) Add a string look up DecodeUnitTest method // 3) Add a callback to UT method // IO private SerialPort sPort; private SerialPort comPort; private I2CSerialPort i2cComport; private bool isI2cPort; private MotherBoard _mb; private HWModules.LheBoard _lhe; private StringBuilder sbTemp = new StringBuilder(GC_MAXMESSAGESIZE); private MessageQueue _messageQueue; private QRecord _msgQEntry; // SD CARD private SDCard sdCard; private VolumeInfo viSDCard; // SerialPort BUFFER private const int GC_MAXMESSAGESIZE = 0xFFF; private StringBuilder sbInput = new StringBuilder(GC_MAXMESSAGESIZE); private byte[] txbuff; private byte[] rxbuff; private int rxbuffpos; int bytesAvailable; private bool closeOnEtx = true; // Program Mode public CMD modeCMD { get; protected set; } // Console Active flage public bool Enabled { get; protected set; } //CommandParser private string[] cmdtok = new string[GC_MAXTOKENS]; //Directory buffers //private string[] dirbuff = new string[GC_MAXFILES]; private StringBuilder srcdir = new StringBuilder(GC_MAXPATHL); private StringBuilder desdir = new StringBuilder(GC_MAXPATHL); private StringBuilder pwDir = new StringBuilder(GC_MAXPATHL); private SDStorage _sdStorage; public FactoryConsole(SerialPort port) { modeCMD = CMD.UNKNOWN; Enabled = false; sPort = port; txbuff = new byte[GC_MAXMESSAGESIZE]; rxbuff = new byte[GC_MAXMESSAGESIZE]; _mb = HWModules.MotherBoard.Instance; _lhe = HWModules.LheBoard.Instance; rxbuffpos = 0; if (!sPort.IsOpen) sPort.Open(); _messageQueue = MessageQueue.Instance; _msgQEntry = new QRecord(ProcessMessage); } private void initFileSystem() { if (_sdStorage != null) return; // SD Card init _sdStorage = SDStorage.Instance; try { viSDCard = new VolumeInfo("\\SD"); } catch (Exception e) { writeLine("Can't Load SDCard:" + e.ToString()); } pwDir.Clear(); pwDir.Append(viSDCard.RootDirectory); } public void welcomeMessage() { Assembly asm = Assembly.GetExecutingAssembly(); writeLine("\r\nCoastal Profiling Float Console \r\n" + "Assembly: " + asm.FullName + "\r\n\r\n"); } private readonly byte[] prompt = Encoding.UTF8.GetBytes("CPF> "); public void printPrompt() { sPort.Write(prompt, 0, prompt.Length); } public void printPowerTable() { writeLine(" 1: CTD\r\n 2: Elmo12\r\n 3: BT\r\n 4: IRIDIUM\r\n 5: MSC\r\n"+ " 6: Optode\r\n 7: Slot3-J2\r\n 8: OCR\r\n 9: FLBB\r\n 10: Open\r\n"+ " 11: Open\r\n 12: Open\r\n 13: N/A\r\n 14: BellowPos\r\n 15: GPS\r\n"+ " 16: Valve\r\n 17: I2C ISB-J4\r\n 18: I2C ISB-J5\r\n 19: SPI ISB-J6\r\n"); } public void sleep() { if (cmdtok.Length < 2) { writeLine("usage sleep <2^(n-1) Minutes [0-7]>\r\n"); return; } int n; try { n = int.Parse(cmdtok[1]); if (n < 1 || n > 7) throw new ArgumentException("Invalid input, please choose a value between 1 and 7"); } catch (Exception e) { writeLine("Input failure for command sleep.\r\n"+e+"\r\n"); return; } writeLine("Sleeping system for "+((int)System.Math.Pow(2,(n-1)))+ " minutes.\r\n"); _lhe.Sleep((byte)n); } public void touch() { if (cmdtok.Length < 2) { writeLine("usage touch \r\n"); return; } var fs = File.Create(cmdtok[1]); var info = new UTF8Encoding().GetBytes("TEST FILE"); fs.Write(info, 0, info.Length); fs.Close(); EngrLogger.Comment(" Touch: "+cmdtok[1]); } public void read() { bytesAvailable = sPort.BytesToRead; if (bytesAvailable > 0) { sPort.Read(rxbuff, rxbuffpos, 1); if (GC_LOCALECHO) sPort.Write(rxbuff, rxbuffpos, 1); //echo the character rxbuffpos++; } else return; if (rxbuff[rxbuffpos - 1] == '\r') //|| rxbuff[rxbuffpos - 1] == '\n') { this.gotCommand(); } } public bool getch(ref byte ch, bool nonblock=true) { bytesAvailable = sPort.BytesToRead; if (bytesAvailable <= 0) { if (nonblock) return false; getch(ref ch, false); } sPort.Read(rxbuff, rxbuffpos, 1); ch = rxbuff[rxbuffpos]; rxbuffpos++; return true; } public void readUntilLN() { bytesAvailable = sPort.BytesToRead; if (bytesAvailable <= 0) return; for (int i = 0; i < bytesAvailable; i++) { sPort.Read(rxbuff, rxbuffpos, 1); if (GC_LOCALECHO) { sPort.Write(rxbuff, rxbuffpos, 1); } // If we are in a serial Port command program if (modeCMD == CMD.COM) { try { if (rxbuff[rxbuffpos] == 0x03 && closeOnEtx) //ETX CTRL-C Received { writeLine("CTRL-C Received, exiting program...\r\n\r\n"); modeCMD = CMD.UNKNOWN; if (isI2cPort) i2cComport.Close(); else comPort.Close(); } else if (isI2cPort) i2cComport.WriteByte(rxbuff[rxbuffpos]); else comPort.WriteByte(rxbuff[rxbuffpos]); return; } catch { writeLine("Error writing to com port, exiting com program.\r\n"); if (isI2cPort) i2cComport.Close(); else comPort.Close(); modeCMD = CMD.UNKNOWN; return; } } rxbuffpos++; //enable backspace functionality. if (rxbuff[rxbuffpos - 1] == '\b') { rxbuffpos -= 2; if (rxbuffpos < 0) rxbuffpos = 0; sPort.WriteByte(32); sPort.WriteByte(8); continue; } if ((rxbuff[rxbuffpos - 1] == '\r' || rxbuff[rxbuffpos - 1] == '\n')) { this.gotCommand(); } } } public void writeLine(string s) { txbuff = Encoding.UTF8.GetBytes(s); sPort.Write(txbuff, 0, txbuff.Length); } public void writeLine(StringBuilder s) { writeLine(s.ToString()); } // BUFFER COMMANDS public void gotCommand() { // Test for Case in rcving \r\n from the console if (rxbuffpos == 1) { rxbuffpos = 0; Array.Clear(rxbuff, 0, rxbuff.Length); writeLine("\r\n"); printPrompt(); return; } //else sbInput.Clear(); try { sbInput.Append(SafeEncoding.GetChars(rxbuff, 0, rxbuffpos - 1)); Debug.Print("GOT LINE: " + sbInput.ToString()); this.ProcessCommand(); } catch { // ignored } rxbuffpos = 0; Array.Clear(rxbuff, 0, rxbuff.Length); } public void ProcessMessage(QRecord qRecord) { //TODO P5 copy the message and call ProcessCommand? } private void ProcessCommand() { CMD cmd = CMD.UNKNOWN; byte itok = 0; Array.Clear(cmdtok, 0, cmdtok.Length); cmdtok = sbInput.ToString().Trim().Split(GC_DELIMITERS, (int)GC_MAXTOKENS); //Decode Command cmd = decodeCommand(cmdtok[0]); //Output to DEBUG foreach (var s in cmdtok) { if (itok == 0) continue; Debug.Print("GOT TOK: " + s); itok++; } writeLine("\r\n"); switch (cmd) { case CMD.HELP: printHelp(); break; case CMD.PWD: presentWorkingDirectory(); break; case CMD.DIR: dir(); break; case CMD.SCAN: scanFiles(); break; case CMD.CD: cd(); break; case CMD.MKDIR: mkdir(); break; case CMD.CP: cpormv(CMD.CP); break; case CMD.RM: rm(); break; case CMD.MV: cpormv(CMD.MV); break; case CMD.SZ: sz(); break; case CMD.RZ: rz(); break; case CMD.COM: com(); break; case CMD.POW: pow(); break; case CMD.REBOOT: reboot(); break; case CMD.DATE: date(); break; case CMD.CPF: cpfChange(); break; case CMD.SLEEP: sleep(); break; case CMD.READSTRINGPOT: readStringPot(); break; case CMD.TOUCH: touch(); break; case CMD.VALVE: valve(); break; case CMD.PUMP: pump(); break; case CMD.CHARGEMON: //TODO implement locally chargemon(); break; case CMD.PUMPMON: monitor_pump(); break; case CMD.STATUS: status(); break; case CMD.ENABLE: Enabled = true; break; case CMD.DISABLE: Enabled = false; break; case CMD.MASSSTORAGE: mass_storage_mode(); break; case CMD.UNKNOWN: writeLine("ERROR: Unknown CMD\r\n"); break; } //at end print out new prompt printPrompt(); } private void status() { var em = EnergyMonitorHotel.Instance; var data = em.getVandI(); sbTemp.Clear().Append("STATUS: ").Append(data); writeLine(sbTemp); } private void chargemon() { var mb = MotherBoard.Instance; mb.Enable5V(); var lhe = LheBoard.Instance; var inLoop = true; writeLine("Beginning Charge Monitor, press CTRL-C to end program...\r\n"); while (inLoop) { //POLL BATTERIES if (!lhe.UpdateBatteryBank()) { EngrLogger.Comment("[Error] Polling Battery Pack\r\n"); Thread.Sleep(5000); continue; } //LOG DATA COLUMNS IN ENGRLOGGER AND DEBUGGER writeLine("----------------\r\n"); lhe.PrintBatteryData(); //SLEEP, wait for escape Thread.Sleep(5000); //Check for keyboard interrupt byte input = 0; while (getch(ref input, true)) inLoop = (input != 0x03);//CTRL-C } } private void mass_storage_mode() { if (_sdStorage != null) { sbTemp.Clear().Append("Cannot enter USB Mass Storage Mode, SD Card has been initialized.\r\n"); SendLine(sbTemp); return; } sbTemp.Clear().Append("Entering USB Mass Storage Mode, make sure the Mode pin is set on the bulkhead...\r\n"); SendLine(sbTemp); // Start MS MassStorage ms = new MassStorage(); Controller.ActiveDevice = ms; // Assume SD card is connected SDCard sd; Thread.Sleep(250); try { sd = new SDCard(); } catch { throw new Exception("SD card not detected"); } Thread.Sleep(250); ms.AttachLogicalUnit(sd, 0, " ", " "); Thread.Sleep(250); // enable host access ms.EnableLogicalUnit(0); Thread.Sleep(Timeout.Infinite); } private void monitor_pump() { var emPump = EnergyMonitorPump.Instance; EngrLogger.Comment(emPump.getVoltsAndMilliAmps().ToString()); } private void cpfChange() { if (cmdtok.Length < 2) { writeLine("usage: cpf \r\n"+ "\t Actions: \r\n"+ "\t GO: Start profiling operations\r\n"+ "\t RECOVERYTRUE: Enable recovery mode\r\n"+ "\t RECOVERYFALSE: Disable recovery mode\r\n"+ "\t STARTDOG: Start watchdog timer\r\n"+ "\t FAKEMTSBD: Send fase MTSBD using Iridium\r\n"+ "\t EXIT: Halt state machine\r\n"); return; } switch (cmdtok[1].ToLower()) { case "go": SV.SurfaceOpsGo = true; break; case "recoverytrue": SV.ManualProfileMode = true; EngrLogger.writeToColumns("Recovery mode set true"); break; case "recoveryfalse": SV.ManualProfileMode = false; EngrLogger.writeToColumns("Recovery mode set false"); break; case "startdog": WatchDog.startWatchdog(); EngrLogger.writeToColumns("Starting watchdog"); break; case "fakemtsbd": NAL_A3LAR.fakeMTSBD(); break; case "exit": SV.CurrentState = CPFStates.exit; // EngrLogger.CurrentState = cpfStatesArray[(int)SV.CurrentState].stateName; break; default: writeLine("ERROR: Unknown cpf action requested\r\n"); break; } } /* private void changeSetting() { if (cmdtok.Length < 3) { writeLine("usage: set \r\n"); return; } // Parse field double argValue = -1; try { argValue = double.Parse(cmdtok[2]); } catch { writeLine("ERROR: Cannot parse setting field.\r\n"); } // Field name switch (cmdtok[1].ToLower()) { case "simp": // TODO P2 do we use this? break; case "upengr": SV.UploadEngrFile = true; break; case "maxprofiles": if ((int) argValue <= 0 || (int) argValue >= 200) { writeLine("ERROR: Invalid profile setting\r\n"); return; } SV.MaxProfiles = (int) argValue; sbTemp.Clear().Append("Setting Max Number of Profiles to: ").Append(SV.MaxProfiles); EngrLogger.writeToColumns(sbTemp); break; case "missiontimeout": if ((int) argValue <= 0 || (int) argValue >= 120) { writeLine("ERROR: Invalid mission timeout\r\n"); return; } SV.MissionTimeoutTS = new TimeSpan(0, (int) argValue, 0, 0); SV.MissionTimedOut = false; sbTemp.Clear().Append("Set MissionTimeout hours to: ").Append(SV.MissionTimeoutTS); EngrLogger.writeToColumns(sbTemp); break; case "parktime": if ((int) argValue <= 0 || (int) argValue >= 172800) //2*24*3600 { writeLine("ERROR: Invalid park time\r\n"); return; } Mission.descendTable[0].parkTime = new TimeSpan(0, 0, (int)argValue, 0); sbTemp.Clear().Append("Park time minutes to: "); sbTemp.Append(Mission.descendTable[0].parkTime); EngrLogger.writeToColumns(sbTemp); break; case "parkpressure": if ((float) argValue <= 4 || (float) argValue >= 300) { writeLine("ERROR: Invalid park pressure\r\n"); return; } Mission.descendTable[9].pressure = (float) argValue; sbTemp.Clear().Append("Setting Park Pressure to: "); sbTemp.Append(Mission.descendTable[0].pressure); EngrLogger.writeToColumns(sbTemp); break; default: writeLine("ERROR: Unknown field.\r\n"); break; } } */ private void date() { if (cmdtok.Length < 7) { writeLine(DateTime.Now.ToString()+"\r\n"); writeLine("usage: date [NUMERIC]\r\n"); return; } int year = int.Parse(cmdtok[1]); int month = int.Parse(cmdtok[2]); int day = int.Parse(cmdtok[3]); int hour = int.Parse(cmdtok[4]); int minute = int.Parse(cmdtok[5]); int second = int.Parse(cmdtok[6]); var set_time = new DateTime(year, month, day, hour, minute, second); Utility.SetLocalTime(set_time); RealTimeClock.SetDateTime(set_time); EngrLogger.openNewEngFile(); } private void pow() { int channel = -1; if (cmdtok.Length < 3) { writeLine("usage: pow \r\n"); printPowerTable(); for (int i = 1; i <= 19; i++) { writeLine("CH"+i+":"+_mb.QueryChannelPower(i)+"\r\n"); } return; } //channel number try { channel = int.Parse(cmdtok[1]); if (channel < 1 || channel >20) throw new ArgumentOutOfRangeException(); } catch { writeLine("Invalid channel number: "+cmdtok[1]+"\r\n"); return; } //state if (string.Equals("on", cmdtok[2])) { if (channel <= 19) _mb.EnableChannelPower(channel); else _lhe.EnablePumpPower(true); } else if (string.Equals("off", cmdtok[2])) { if (channel <= 19) _mb.DisableChannelPower(channel); else _lhe.EnablePumpPower(false); } } private void com() { if (cmdtok.Length < 2) { writeLine("usage: com \r\n" + "\t defaults are 9600 8 N 1 1\r\n\r\n"); return; } //Set Defaults int portnum = 2; int baud = 19200; int databits = 8; Parity parity = Parity.None; StopBits stopbits = StopBits.One; if (!ParseSerialConfig(ref portnum, ref baud, ref databits, ref parity, ref closeOnEtx)) return; //For traditional serialports if (portnum <= 6) { try { comPort = new SerialPort("COM" + portnum.ToString(), baud, parity, databits, stopbits); if (!comPort.IsOpen) comPort.Open(); comPort.DataReceived += ComPortOnDataReceived; isI2cPort = false; } catch (Exception e) { writeLine("Error Opening SerialPort " + portnum.ToString() + ":" + e.ToString()+"\r\n\r\n"); return; } } //For i2c ports (slots 3-6) if (portnum > 6) { i2cComport = new I2CSerialPort("COM" + portnum.ToString(), baud, databits, parity, stopbits); i2cComport.Open(); i2cComport.DataReceived += I2CPortOnDataReceived; isI2cPort = true; } writeLine(closeOnEtx ? "Serial Port Connected, press CTRL-C to exit program...\r\n\r\n" : "Serial Port Connected, reboot to exit...\r\n\r\n"); modeCMD = CMD.COM; } private void I2CPortOnDataReceived(object sender, EventArgs e) { int bytesToRead = i2cComport.BytesToRead; int inChar; if (bytesToRead == 0) return; for (int i = 0; i < bytesToRead; ++i) { inChar = i2cComport.ReadByte(); if (inChar == -1) return; sPort.WriteByte((byte) inChar); } } private void ComPortOnDataReceived(object sender, SerialDataReceivedEventArgs serialDataReceivedEventArgs) { int bytesToRead = comPort.BytesToRead; int inChar; if (bytesToRead == 0) return; for (int i = 0; i < bytesToRead; ++i) { inChar = comPort.ReadByte(); if (inChar == -1) return; sPort.WriteByte((byte) inChar); } } private bool ParseSerialConfig(ref int portnum, ref int baud, ref int databits, ref Parity parity, ref bool closeOnEtx) { StopBits stopbits; for (int i = 1; i < cmdtok.Length; ++i) { switch (i) { case 1: //portnum try { portnum = int.Parse(cmdtok[1]); if (string.Equals("COM"+portnum.ToString(), sPort.PortName) || portnum < 1 || portnum > 12) throw new ArgumentOutOfRangeException("invalid portnum"); } catch { writeLine("Invalid Portnum Specified " + cmdtok[1] + "\r\n"); return false; } break; case 2: //baudrate try { baud = int.Parse(cmdtok[2]); } catch { writeLine("Invalid Baud Rate Specified: " + cmdtok[2] + "\r\n"); return false; } break; case 3: //databits try { databits = int.Parse(cmdtok[3]); if (databits < 5 || databits > 8) throw new ArgumentOutOfRangeException("invalid databits"); } catch { writeLine("Invalid Databits Specified: " + cmdtok[3] + "\r\n"); return false; } break; case 4: //parity try { if (string.Equals(cmdtok[4].ToLower(), "n")) parity = Parity.None; else if (string.Equals(cmdtok[4].ToLower(), "e")) parity = Parity.Even; else if (string.Equals(cmdtok[4].ToLower(), "o")) parity = Parity.Odd; else if (string.Equals(cmdtok[4].ToLower(), "m")) parity = Parity.Mark; else if (string.Equals(cmdtok[4].ToLower(), "s")) parity = Parity.Space; else throw new ArgumentOutOfRangeException("Invalid parity"); } catch { writeLine("Invalid Parity Specified: " + cmdtok[4] + "\r\n"); return false; } break; case 5: //stopbits try { double dStopbits = double.Parse(cmdtok[5]); if (dStopbits == 1) stopbits = StopBits.One; else if (dStopbits == 1.5) stopbits = StopBits.OnePointFive; else if (dStopbits == 2) stopbits = StopBits.Two; else if (dStopbits == 0) stopbits = StopBits.None; else throw new ArgumentOutOfRangeException("Invalid stopbits"); } catch { writeLine("Invalid Stopbits Specified: " + cmdtok[5] + "\r\n"); return false; } break; case 6: // close on etx try { int iCloseOnETX = int.Parse(cmdtok[6]); if (iCloseOnETX == 1 || iCloseOnETX == 0) { closeOnEtx = (iCloseOnETX == 1); } else throw new ArgumentOutOfRangeException("0 or 1 for close on etx"); } catch { writeLine("Invalid CloseOnEtx Specified, use a 0 or 1\r\n"); return false; } break; } } return true; } private void mkdir() { initFileSystem(); DirectoryInfo dinfo; if (cmdtok.Length < 2) { writeLine("usage: mkdir \r\n\r\n"); return; } changeWorkingDir(ref desdir, 1); try { if (Directory.Exists(desdir.ToString())) { writeLine("ERROR: directory already exists.\r\n"); return; } dinfo = Directory.CreateDirectory(desdir.ToString()); if (dinfo == null) { writeLine("ERROR: directory creation failed.\r\n"); return; } } catch { writeLine("ERROR: directory creation failed.\r\n"); return; } writeLine("Directory successfully created at " + dinfo.CreationTimeUtc.ToString() + "\r\n"); } private void rm() { initFileSystem(); int sarg = 0; if (cmdtok.Length < 2) { writeLine("usage: rm or rm -f \r\n"); return; } sarg = (cmdtok[1][0] == '-') ? 1 : 0; bool wildcard = cmdtok[1][0] == '*'; //change input to full path changeWorkingDir(ref srcdir, 1 + sarg); try { if (wildcard) //delete all files { string[] dirbuff = Directory.GetFiles(pwDir.ToString()); foreach (var fname in dirbuff) { writeLine("Deleting: " + fname + "\r\n"); try { File.Delete(fname); } catch (IOException) { writeLine("Cannot delete file.\r\n"); } } return; } if (!File.Exists(srcdir.ToString()) && !Directory.Exists(srcdir.ToString())) { writeLine("ERROR: file/dir does not exist\r\n"); return; } } catch { writeLine("ERROR: file/dir does not exist\r\n"); return; } //delete file if (sarg == 0) { try { File.Delete(srcdir.ToString()); } catch { writeLine("ERROR: File delete failed.\r\n"); return; } writeLine("File(s) deleted.\r\n"); } else if (sarg == 1) { try { Directory.Delete(srcdir.ToString()); } catch { writeLine("ERROR: Directory delete failed.\r\n"); return; } writeLine("Directory deleted. \r\n"); } } private void rz() { initFileSystem(); writeLine("Beginning Zmodem Receive.\r\n"); ZmodemReceiver zr = new ZmodemReceiver(sPort, false); zr.filePrefix = "\\SD\\"; int ret = 0; do { ret = zr.doTasks(); } while (ret == 0); } private void sz() { initFileSystem(); if (cmdtok.Length < 2) { writeLine("usage sz \r\n"); return; } changeWorkingDir(ref srcdir, 1); try { if (File.Exists(srcdir.ToString()) == false) { writeLine("ERROR: No such source file.\r\n"); return; } } catch { writeLine("ERROR: No such source file.\r\n"); return; } //Ok, we can try to conduct a ZMODEM interaction... ZmodemSender zs = new ZmodemSender(sPort, srcdir.ToString()); //it will eventually give up or finish... single file at this point. int ret = 0; do { ret = zs.doTasks(); } while (ret == 0); writeLine("Zmodem Finished... Result code: "+ret+"\r\n"); } private void reboot() { PowerState.RebootDevice(false); } private void readStringPot() { var buoyancyEngine = BuoyancyEngine.Instance; _mb.EnableChannelPower(MotherBoard.ChannelNames.PositionSensorChannel); int bellowsVoltsRaw = buoyancyEngine.getBellowsADCValue(); int bellowsVolts = (int)(bellowsVoltsRaw ^ 0x80000000); var bellowsPosition = buoyancyEngine.getBellowsPositionStringPot(); EngrLogger.Comment("\tUnit Test Bellows Position = " + bellowsPosition.ToString("f3") + " Volts = "+bellowsVolts + " Raw = "+bellowsVoltsRaw.ToString("X")); } private void valve() { if (cmdtok.Length < 2) { writeLine("usage valve \r\n"); return; } //parse the valve instruction var desiredOpenState = false; if (string.Equals(cmdtok[1], "open")) desiredOpenState = true; else if (string.Equals(cmdtok[1], "close")) desiredOpenState = false; else { writeLine("Please enter open or close\r\n"); } //power the valve var buoyancyEngine = BuoyancyEngine.Instance; _mb.EnableChannelPower(MotherBoard.ChannelNames.MotorizedValve); var attempts = 10; while (--attempts > 0 && _mb.getMVReadyStatus()) { EngrLogger.Comment("MV Not Ready"); Thread.Sleep(2000); } if (desiredOpenState) buoyancyEngine.openMV(); else buoyancyEngine.closeMV(); } private void pump() { if (cmdtok.Length < 2) { writeLine("usage: pump \r\n"); return; } int jv; try { jv = int.Parse(cmdtok[1]); } catch (Exception) { writeLine("bad int value\r\nusage: pump \r\n"); return; } _mb.EnableChannelPower((int)HWModules.MotherBoard.ChannelNames.PumpMotorControllerElexChannel); Thread.Sleep(250); var lheBoard = HWModules.LheBoard.Instance; lheBoard.EnablePumpPower(true); Thread.Sleep(250); var buoyancyEngine = BuoyancyEngine.Instance; Thread.Sleep(250); buoyancyEngine.initPumpMotor(); if (jv == 0) { buoyancyEngine.stopMotor(); } else if (jv > 0) { buoyancyEngine.increaseBuoyancy(jv); writeLine("Increasing buoyancy at " + jv + " bellows at " + buoyancyEngine.getBellowsPositionStringPot() + "\r\n"); } else if (jv < 0) { buoyancyEngine.decreaseBuoyancy(jv); writeLine("Decreasing buoyancy at " + (-1 * jv) + " bellows at " + buoyancyEngine.getBellowsPositionStringPot() + "\r\n"); } } /* private void ut() { if (cmdtok.Length < 2) { writeLine("usage ut \r\n"); writeLine("\t available options are: \r\n" + "\t\t iridium - test iridium driver functions except for rudics\r\n" + "\t\t rudics - test iridium drivers for full rudics connections to the main server\r\n" + "\t\t ctd - test the seabird 41 drivers\r\n" + "\t\t optode - optode driver test\r\n" + "\t\t ocr - ocr driver test"+ "\t\t gps - test the GPS and driver\r\n" + "\t\t pump - test the elmo driver\r\n" + "\t\t bellows - test the string pot adc\r\n" + "\t\t IncBuoy - Increase buoyancy\r\n" + "\t\t DecBuoy - Decrease buoyancy\r\n" + "\t\t pth - test pressure temp and humid sensor\r\n" + "\t\t msc - test MBARI multi-sensor controller\r\n" + "\t\t flbb - test the flbb driver\r\n" + "\t\t emonbatt - test energy monitors on the battery\r\n" + "\t\t emonpump - test energy monitor on the pump\r\n" + "\t\t valve - test motorized valve\r\n" + //"\t\t fileflood - flood the sd with files\r\n" + //"\t\t surfaceops \t - test the surfaceops state\r\n" + //"\t\t duallead \t - test the dual lead controller\r\n" + "\t\t watchdog - test the watchdog\r\n"); return; } int nattempts = 1; int natt; if (cmdtok.Length == 3) { try { natt = int.Parse(cmdtok[2]); } catch { writeLine("Bad Input, try again \r\n"); return; } if (natt > 1) { nattempts = natt; } } for (int i = 0; i < nattempts; i++) { switch (DecodeUnitTest(cmdtok[1])) { case UT.Ctd: writeLine("Running Unit Test\r\n"); TestManager.RunTest(typeof(CTDUnitTests)); break; case UT.Gps: writeLine("Running GPS Unit Test\r\n"); TestManager.RunTest(typeof(UnitTest_MotherBoard_GPS)); break; case UT.Optode: writeLine("Running Optode Unit Test\r\n"); TestManager.RunTest(typeof(OptodeUnitTests)); break; case UT.Pth: writeLine("Running PTH Unit Test\r\n"); TestManager.RunTest(typeof(UnitTest_BoschPTH)); break; case UT.Flbb: writeLine("Running Flbb Unit Test\r\n"); TestManager.RunTest(typeof(FLBBUnitTest)); break; case UT.Ocr: writeLine("Running OCR Unit Test\r\n"); TestManager.RunTest(typeof(OCR504UnitTest)); break; case UT.Pump: writeLine("Running Pump Unit Test\r\n"); TestManager.RunTest(typeof(PumpMotorUnitTests)); break; case UT.Elmo: writeLine("Running Elmo Twitter Unit Test\r\n"); TestManager.RunTest(typeof(ElmoTwitterUnitTest)); break; case UT.Watchdog: //TODO P3 unimplemented writeLine("Running Watchdog Unit Test\r\n"); break; case UT.Iridium: writeLine("Running Iridium Unit Test\r\n"); TestManager.RunTest(typeof(UnitTestIridium)); break; case UT.Rudics: writeLine("Running Rudics Unit Test\r\n"); TestManager.RunTest(typeof(UnitTestIridiumRUDICS)); break; case UT.EMonBatt: writeLine("Running Battery Energy Monitor Test\r\n"); TestManager.RunTest(typeof(UnitTest_MotherBoard_EnergyMonitor),"TestEnergyMonitorVI"); break; case UT.EMonPump: writeLine("Running Pump Energy Monitor Pump\r\n"); TestManager.RunTest(typeof(LheBoardUnitTests), "TestLhePumpEnergyMonitor"); break; case UT.Msc: writeLine("Running MSC Unit Test\r\n"); TestManager.RunTest(typeof(UnitTestMsc), "TestPHandNO3SampleT1T2"); break; case UT.IncBuoy: writeLine("Running IncreaseBuoyancy Unit Test\r\n"); TestManager.RunTest(typeof(PumpMotorUnitTests), "IncreaseBuoyancy"); break; case UT.DecBuoy: writeLine("Running DecreaseBuoyancy Unit Test\r\n"); TestManager.RunTest(typeof(PumpMotorUnitTests), "DecreaseBuoyancy"); break; //case UT.FileFlood: // writeLine("Running FileFlood Unit Test\r\n"); // TestManager.RunTest(typeof(UnitTestEngLogger), "TestManyFileCreations"); // break; case UT.SurfaceOps: writeLine("Running SurfaceOps Unit Test\r\n"); TestManager.RunTest(typeof(SurfaceOpsUnitTests), "TestSurfaceOps"); break; case UT.DualLead: writeLine("Running Dual Lead Controller Unit Test\r\n"); TestManager.RunTest(typeof(BEUnitTests), "TestDualLeadController"); break; case UT.MotorizedValve: writeLine("Running Motorized Valve Unit Test\r\n"); TestManager.RunTest(typeof(MotorizedValveUnitTests)); break; case UT.BellowsPosition: writeLine("Running Bellows ADC Test\r\n"); TestManager.RunTest(typeof(StringPotUT)); break; default: writeLine("Unknown Unit Test \r\n"); break; } } } private UT DecodeUnitTest(string s) { s = s.ToLower(); if (string.Equals(s, "iridium")) return UT.Iridium; if (string.Equals(s, "rudics")) return UT.Rudics; if (string.Equals(s, "ctd")) return UT.Ctd; if (string.Equals(s, "optode")) return UT.Optode; if (string.Equals(s, "pump")) return UT.Pump; if (string.Equals(s, "elmo")) return UT.Elmo; if (string.Equals(s, "decbuoy")) return UT.DecBuoy; if (string.Equals(s, "incbuoy")) return UT.IncBuoy; if (string.Equals(s, "pth")) return UT.Pth; if (string.Equals(s, "gps")) return UT.Gps; if (string.Equals(s, "emonbatt")) return UT.EMonBatt; if (string.Equals(s, "emonpump")) return UT.EMonPump; if (string.Equals(s, "watchdog")) return UT.Watchdog; if (string.Equals(s, "msc")) return UT.Msc; if (string.Equals(s, "flbb")) return UT.Flbb; if (string.Equals(s, "ocr")) return UT.Ocr; //if (string.Equals(s, "fileflood")) // return UT.FileFlood; if (string.Equals(s, "surfaceops")) return UT.SurfaceOps; if (string.Equals(s, "duallead")) return UT.DualLead; if (string.Equals(s, "valve")) return UT.MotorizedValve; if (string.Equals(s, "bellows")) return UT.BellowsPosition; return UT.Unknown; } */ private void cpormv(CMD type) { initFileSystem(); int sarg = 0; bool overwrite = false; //ok this has to have multiple inputs if (cmdtok.Length < 3) { writeLine("usage: cp \r\n"); return; } //create offset if flag exists sarg = (cmdtok[1][0] == '-') ? 1 : 0; overwrite = (sarg == 1) ? true : false; // Change and verify inputs. changeWorkingDir(ref srcdir, 1 + sarg); try { if (File.Exists(srcdir.ToString()) == false) { writeLine("ERROR: No such source file.\r\n"); return; } } catch { writeLine("ERROR: No such source file.\r\n"); return; } changeWorkingDir(ref desdir, 2 + sarg); if (Path.GetDirectoryName(desdir.ToString()) == String.Empty || Path.GetDirectoryName(desdir.ToString()) == null) { writeLine("ERROR: No such destination directory.\r\n"); return; } try { if (File.Exists(desdir.ToString()) == true && overwrite == false) { writeLine(Path.GetFileName(desdir.ToString()) + ":exists, use -f flag to overwrite\r\n"); return; } } catch { writeLine("ERROR: No such destination directory.\r\n"); return; } //OK We can attempt the copy. try { if (type == CMD.CP) File.Copy(srcdir.ToString(), desdir.ToString(), overwrite); else if (type == CMD.MV) File.Move(srcdir.ToString(), desdir.ToString()); } catch { if (type == CMD.CP) writeLine("ERROR: Copy Failed\r\n"); else if (type == CMD.MV) writeLine("ERROR: Move Failed\r\n"); return; } if (type == CMD.CP) writeLine("1 File(s) copied.\r\n"); else if (type == CMD.MV) writeLine("1 File(s) moved.\r\n"); } /* private void breakLogs() { writeLine("Breaking all log files\r\n"); SciLogger.closeFiles(); EngrLogger.closeEngrLogFile(); EngrLogger.openNewEngFile(); SciLogger.openNewFiles(); //writeLine("Writing blob\r\n"); //FileSystemCheck.WriteManyBytes(int.MaxValue); //writeLine("Blob written\r\n"); } */ private void cd() { initFileSystem(); changeWorkingDir(ref srcdir, 1); try { if (Directory.Exists(srcdir.ToString()) == false) { writeLine("ERROR: No such directory.\r\n"); return; } } catch { writeLine("ERROR: No such directory.\r\n"); return; } pwDir.Clear(); pwDir.Append(srcdir); writeLine("Changed working directory to " + pwDir.ToString()+"\r\n"); } private void dir() { initFileSystem(); changeWorkingDir(ref srcdir, 1); try { if (Directory.Exists(srcdir.ToString()) == false) { writeLine("ERROR: No such directory.\r\n"); return; } } catch { writeLine("ERROR: Invalid Input\r\n"); return; } Path path; //list files in directory string[] dirbuff = Directory.GetFiles(srcdir.ToString()); writeLine("\r\nFiles in " + srcdir.ToString() + "\r\n"); FileInfo fi; for (int i = 0; i < dirbuff.Length; i++) { fi = new FileInfo(dirbuff[i]); if (fi.Exists) { if (fi.Length > 999) writeLine("\t" + Path.GetFileName(dirbuff[i]) + "\t" + fi.Length/1000 + " KB\r\n"); else writeLine("\t" + Path.GetFileName(dirbuff[i]) + "\t" + fi.Length + " B\r\n"); } } //list directories in directory dirbuff = Directory.GetDirectories(srcdir.ToString()); writeLine("\r\nDirectories in " + srcdir.ToString() + "\r\n"); for (int i = 0; i < dirbuff.Length; i++) { writeLine("\t" + dirbuff[i] + "\r\n"); Debug.Print(dirbuff.Length.ToString()); } } private void scanFiles() { initFileSystem(); changeWorkingDir(ref srcdir, 1); try { if (Directory.Exists(srcdir.ToString()) == false) { writeLine("ERROR: No such directory.\r\n"); return; } } catch { writeLine("ERROR: Invalid Input\r\n"); return; } String fileName = "2011-6-1T0-0-34.eng"; StreamReader fileStream; String inString; try { fileStream = new StreamReader(fileName); int numLoops = 1000; for (int i = 0; i < numLoops; i++) { inString = fileStream.ReadLine(); Debug.Print(inString); } fileStream.Close(); } catch { Debug.Print("Couldn't open " + fileName); } } private void changeWorkingDir(ref StringBuilder sb, int offset) { initFileSystem(); sb.Clear(); //Form the directory input if (cmdtok.Length == 1) { sb.Append(pwDir); } else { if (cmdtok[offset][0] == '\\') //This a is fully qualified path. sb.Append(cmdtok[offset]); else { sb.Append(pwDir); sb.Append("\\"); sb.Append(cmdtok[offset]); } } } private void presentWorkingDirectory() { initFileSystem(); writeLine(this.pwDir.ToString() + "\r\n"); } private void printHelp() { writeLine("AVAILABLE COMMANDS:\r\n"); writeLine("HELP - This message\r\n"); writeLine("PWD - Present Working Dir\r\n"); writeLine("DIR - List files in PWD\r\n"); writeLine("CD - Change Directory\r\n"); writeLine("MKDIR - Make Directory\r\n"); writeLine("CP - Copy\r\n"); writeLine("RM - Delete/Remove\r\n"); writeLine("TOUCH - Create a file\r\n"); writeLine("MV - Move\r\n"); writeLine("SZ - Send via ZMODEM\r\n"); writeLine("RZ - Receive via ZMODEM\r\n"); writeLine("REBOOT - Hard Reboot Processor\r\n"); writeLine("COM - Open an native or i2c serial port\r\n"); writeLine(" (enable power first)\r\n"); writeLine("POW - Switch power on available channels.\r\n"); writeLine("CHARGEMON - Print status of the batteries.\r\n"); writeLine("PUMPMON - Read out the energymonitor for the pump\r\n"); writeLine("SLEEP - Sleep the system for a fixed time.\r\n"); writeLine("READSTRINGPOT - Read the position of the bellows.\r\n"); } private CMD decodeCommand(string s) { s = s.ToLower(); if (String.Equals(s, "help")) return CMD.HELP; if (String.Equals(s, "pwd")) return CMD.PWD; if (String.Equals(s, "dir")) return CMD.DIR; if (String.Equals(s, "scan")) return CMD.SCAN; if (String.Equals(s, "cd")) return CMD.CD; if (String.Equals(s, "mkdir")) return CMD.MKDIR; if (String.Equals(s, "cp")) return CMD.CP; if (String.Equals(s, "rm")) return CMD.RM; if (String.Equals(s, "mv")) return CMD.MV; if (String.Equals(s, "sz")) return CMD.SZ; if (String.Equals(s, "rz")) return CMD.RZ; if (String.Equals(s, "com")) return CMD.COM; if (String.Equals(s, "pow")) return CMD.POW; if (String.Equals(s, "reboot")) return CMD.REBOOT; if (String.Equals(s, "date")) return CMD.DATE; if (String.Equals(s, "cpf")) return CMD.CPF; if (String.Equals(s, "sleep")) return CMD.SLEEP; if (String.Equals(s, "chargemon")) return CMD.CHARGEMON; if (string.Equals(s, "pumpmon")) return CMD.PUMPMON; if (string.Equals(s, "status")) return CMD.STATUS; if (String.Equals(s, "readstringpot")) return CMD.READSTRINGPOT; if (String.Equals(s, "touch")) return CMD.TOUCH; if (String.Equals(s, "valve")) return CMD.VALVE; if (String.Equals(s, "pump")) return CMD.PUMP; if (String.Equals(s, "$$$")) return CMD.ENABLE; if (String.Equals(s, "exit")) return CMD.DISABLE; if (String.Equals(s, "usb")) return CMD.MASSSTORAGE; return CMD.UNKNOWN; } public void SendLine(StringBuilder builder) { writeLine(builder.ToString()); } } }