From 6092b78eca2d1a300a72bfb8e48ca4db45d787a8 Mon Sep 17 00:00:00 2001 From: Ruud van Falier Date: Sun, 6 Aug 2017 20:34:29 +0200 Subject: [PATCH] Added DataUploader executable and improved & documented the source code --- code/firmware/SerialIO/SerialIO.ino | 12 +- code/utilities/DataUploader/DataUploader.exe | Bin 0 -> 8192 bytes .../DataUploader/DataUploader/Program.cs | 119 ----------- .../DataUploader/{ => src}/DataUploader.sln | 0 .../{ => src}/DataUploader/App.config | 0 .../DataUploader/DataUploader.csproj | 0 .../DataUploader/src/DataUploader/Program.cs | 188 ++++++++++++++++++ .../DataUploader/Properties/AssemblyInfo.cs | 0 8 files changed, 194 insertions(+), 125 deletions(-) create mode 100644 code/utilities/DataUploader/DataUploader.exe delete mode 100644 code/utilities/DataUploader/DataUploader/Program.cs rename code/utilities/DataUploader/{ => src}/DataUploader.sln (100%) rename code/utilities/DataUploader/{ => src}/DataUploader/App.config (100%) rename code/utilities/DataUploader/{ => src}/DataUploader/DataUploader.csproj (100%) create mode 100644 code/utilities/DataUploader/src/DataUploader/Program.cs rename code/utilities/DataUploader/{ => src}/DataUploader/Properties/AssemblyInfo.cs (100%) diff --git a/code/firmware/SerialIO/SerialIO.ino b/code/firmware/SerialIO/SerialIO.ino index e153ed2..9973b9b 100644 --- a/code/firmware/SerialIO/SerialIO.ino +++ b/code/firmware/SerialIO/SerialIO.ino @@ -102,8 +102,8 @@ void display_boot_message() Serial.print(VT100_RESET_CURSOR); Serial.print(VT100_OFF); Serial.print(VT100_DEFAULT); - Serial.println("+-----------------------+"); - Serial.print("| "); + Serial.println("+------------------------+"); + Serial.print("| "); Serial.print(VT100_OFF); Serial.print(VT100_BOLD); Serial.print("APPLE 1 MINI"); @@ -112,10 +112,10 @@ void display_boot_message() Serial.println(" |"); Serial.print(VT100_OFF); Serial.print(VT100_DEFAULT); - Serial.println("|-----------------------|"); - Serial.println("| FIRMWARE VERSION 1.0 |"); - Serial.println("| RUUD VAN FALIER, 2017 |"); - Serial.println("+-----------------------+"); + Serial.println("|------------------------|"); + Serial.println("| FIRMWARE VERSION 1.0 |"); + Serial.println("| RUUD VAN FALIER, 2017 |"); + Serial.println("+------------------------+"); Serial.println(); Serial.println("READY..."); Serial.println(); diff --git a/code/utilities/DataUploader/DataUploader.exe b/code/utilities/DataUploader/DataUploader.exe new file mode 100644 index 0000000000000000000000000000000000000000..4783f1811b5ecdb72f32ec8baed24b168258a24c GIT binary patch literal 8192 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 literal 0 HcmV?d00001 diff --git a/code/utilities/DataUploader/DataUploader/Program.cs b/code/utilities/DataUploader/DataUploader/Program.cs deleted file mode 100644 index 7a65d07..0000000 --- a/code/utilities/DataUploader/DataUploader/Program.cs +++ /dev/null @@ -1,119 +0,0 @@ -using System; -using System.Diagnostics; -using System.IO; -using System.IO.Ports; -using System.Text; -using System.Threading; -using System.Windows.Forms; - -namespace DataUploader -{ - class Program - { - private const string PORT = "COM5"; - private const int DELAY_CHAR = 30; - private const int DELAY_LINE = 100; - - private static SerialPort serial = new SerialPort(PORT, 9600, Parity.None, 8, StopBits.One); - private static bool receiving; - private static Stopwatch duration; - - [STAThread] - static void Main(string[] args) - { - var dialog = new OpenFileDialog(); - - dialog.Title = "Select file to upload..."; - - if (dialog.ShowDialog() == DialogResult.OK) - { - serial.DataReceived += Serial_DataReceived; - serial.Open(); - - Console.WriteLine("Connected..."); - Console.WriteLine($"Uploading {dialog.FileName}"); - - // Wait for firmware to load (Arduino may reset on connect). - Thread.Sleep(2000); - - // Clear the buffer - SendNewLine(); - - duration = Stopwatch.StartNew(); - - using (var reader = new StreamReader(dialog.FileName, Encoding.ASCII)) - { - int progress = 0; - long total = reader.BaseStream.Length; - - while (reader.Peek() >= 0) - { - int data = reader.Read(); - - // Don't send any data if we are busy receiving - while (receiving) - { - Thread.Sleep(10); - } - - if (data < 96) - { - if (data != 10 && data != 13) - { - serial.Write(((char) data).ToString()); - Thread.Sleep(DELAY_CHAR); - } - else if (data == 13) - { - SendNewLine(); - } - - Console.Write((char) data); - } - else - { - Debug.Write(string.Format("[{0}]", data)); - } - - Progress(++progress, total); - } - } - - Console.WriteLine(""); - Console.WriteLine("Finishing..."); - - SendNewLine(); - - serial.Close(); - - Console.Title = "Upload succeeded!"; - Console.WriteLine("\r\nDone! Connection closed."); - } - - Console.ReadKey(); - } - - private static void SendNewLine() - { - serial.Write("\r"); - Thread.Sleep(DELAY_CHAR); - serial.Write("\n"); - Thread.Sleep(DELAY_LINE); - } - - private static void Serial_DataReceived(object sender, SerialDataReceivedEventArgs e) - { - receiving = true; - serial.ReadExisting(); - receiving = false; - } - - private static void Progress(int progress, long total) - { - decimal percentage = progress / ((decimal)total / 100); - int bytesPerSec = (int)(progress / duration.Elapsed.TotalSeconds); - - Console.Title = $"Uploading... ({progress:N0} of {total:N0} bytes - {bytesPerSec} bytes/sec - {percentage:N2}%)"; - } - } -} diff --git a/code/utilities/DataUploader/DataUploader.sln b/code/utilities/DataUploader/src/DataUploader.sln similarity index 100% rename from code/utilities/DataUploader/DataUploader.sln rename to code/utilities/DataUploader/src/DataUploader.sln diff --git a/code/utilities/DataUploader/DataUploader/App.config b/code/utilities/DataUploader/src/DataUploader/App.config similarity index 100% rename from code/utilities/DataUploader/DataUploader/App.config rename to code/utilities/DataUploader/src/DataUploader/App.config diff --git a/code/utilities/DataUploader/DataUploader/DataUploader.csproj b/code/utilities/DataUploader/src/DataUploader/DataUploader.csproj similarity index 100% rename from code/utilities/DataUploader/DataUploader/DataUploader.csproj rename to code/utilities/DataUploader/src/DataUploader/DataUploader.csproj diff --git a/code/utilities/DataUploader/src/DataUploader/Program.cs b/code/utilities/DataUploader/src/DataUploader/Program.cs new file mode 100644 index 0000000..575012f --- /dev/null +++ b/code/utilities/DataUploader/src/DataUploader/Program.cs @@ -0,0 +1,188 @@ +using System; +using System.Diagnostics; +using System.IO; +using System.IO.Ports; +using System.Text; +using System.Threading; +using System.Windows.Forms; + +namespace DataUploader +{ + class Program + { + private const int DELAY_CHAR = 30; + private const int DELAY_LINE = 100; + + private static SerialPort serial; + private static bool receiving; + private static Stopwatch duration; + + /// + /// Main program logic. + /// + /// + [STAThread] + private static void Main(string[] args) + { + bool execute = true; + + while (execute) + { + Console.Clear(); + + // Display boot message and ask user what COM port to use for the serial connection. + string comPort = DisplayBootMessage(); + + // Display file selection dialog. + Console.WriteLine("Select the file that you would like to upload..."); + var dialog = new OpenFileDialog + { + Title = "Select file to upload..." + }; + + if (dialog.ShowDialog() == DialogResult.OK) + { + Console.WriteLine($"Selected {dialog.FileName}\r\n"); + Console.WriteLine($"Connecting to {comPort}..."); + + // Create and open serial connection. + serial = new SerialPort(comPort, 9600, Parity.None, 8, StopBits.One); + serial.DataReceived += Serial_DataReceived; + serial.Open(); + + // Wait for firmware to load (Arduino may reset on connect). + // This turns out to be necessary for the upload to succeed. + Thread.Sleep(2000); + SendNewLine(); + + Console.WriteLine("Connected...\r\n"); + Console.WriteLine($"Uploading data..."); + + duration = Stopwatch.StartNew(); + int progress = 0; + + // Read the data from the selected file. + using (var reader = new StreamReader(dialog.FileName, Encoding.ASCII)) + { + long total = reader.BaseStream.Length; + + while (reader.Peek() >= 0) + { + int data = reader.Read(); + + while (receiving) + { + // Don't send any data while the Serial_DataReceived eventhandler is busy. + Thread.Sleep(10); + } + + if (data < 96) // Only process Apple 1 compatible characters. + { + if (data != 10 && data != 13 + ) // Skip CR and LF characters, we'll handle these differently. + { + serial.Write(((char) data).ToString()); + Thread.Sleep(DELAY_CHAR); // Wait for the Apple 1 to process the input. + } + else if (data == 13) + { + SendNewLine(); // Send a CRLF sequence. + } + + Console.Write((char) data); // Display the data we have sent in the console. + } + + Progress(++progress, total); + } + } + + Console.WriteLine(""); + Console.WriteLine("Finishing..."); + + // Send an extra CRLF and close the connection. + SendNewLine(); + serial.Close(); + + Console.Title = "Upload succeeded!"; + Console.WriteLine("Upload succeeded!\r\n"); + } + else + { + Console.WriteLine("No file was selected.\r\n"); + } + + Console.Write("Would you like to upload another file? (Y/N) "); + execute = Console.ReadLine().Equals("Y", StringComparison.OrdinalIgnoreCase); + } + } + + /// + /// Display the boot message and prompt user for COM port. + /// + /// + private static string DisplayBootMessage() + { + Console.WriteLine("+------------------------+"); + Console.WriteLine("| APPLE 1 MINI |"); + Console.WriteLine("|------------------------|"); + Console.WriteLine("| DATA UPLOADER UTILITY |"); + Console.WriteLine("+------------------------+"); + Console.WriteLine(""); + + int portNumber = 0; + + while (portNumber == 0) + { + Console.Write("What COM port number would you like to use? "); + + if (int.TryParse(Console.ReadLine(), out portNumber)) + { + Console.WriteLine($"Using COM{portNumber}\r\n"); + return $"COM{portNumber}"; + } + else + { + Console.WriteLine("That's not a valid number, try again."); + } + } + + return null; + } + + /// + /// Send serial data for CRLF. + /// + private static void SendNewLine() + { + serial.Write("\r"); + Thread.Sleep(DELAY_CHAR); + serial.Write("\n"); + Thread.Sleep(DELAY_LINE); + } + + /// + /// Serial DataReceived event handler. + /// + /// + /// + private static void Serial_DataReceived(object sender, SerialDataReceivedEventArgs e) + { + receiving = true; + serial.ReadExisting(); + receiving = false; + } + + /// + /// Update the progress indication (console window title). + /// + /// + /// + private static void Progress(int progress, long total) + { + decimal percentage = progress / ((decimal)total / 100); + int bytesPerSec = (int)(progress / duration.Elapsed.TotalSeconds); + + Console.Title = $"Uploading... ({progress:N0} of {total:N0} bytes - {bytesPerSec} bytes/sec - {percentage:N2}%)"; + } + } +} diff --git a/code/utilities/DataUploader/DataUploader/Properties/AssemblyInfo.cs b/code/utilities/DataUploader/src/DataUploader/Properties/AssemblyInfo.cs similarity index 100% rename from code/utilities/DataUploader/DataUploader/Properties/AssemblyInfo.cs rename to code/utilities/DataUploader/src/DataUploader/Properties/AssemblyInfo.cs