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 0000000..4783f18 Binary files /dev/null and b/code/utilities/DataUploader/DataUploader.exe differ 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