From 40d5e5fd103f0f24734e47435ec352af1b49368c Mon Sep 17 00:00:00 2001 From: Christian Werner Date: Sun, 28 Sep 2025 20:11:02 +0200 Subject: [PATCH] ree --- build/c64_c_userport.prg | Bin 11612 -> 11612 bytes nano/nano_c64/src/main.cpp | 56 +++++--- src/main.c | 2 +- web/c64_inteface/.gitignore | 2 + web/c64_inteface/ArduinoMessageContainer.cs | 7 + web/c64_inteface/MonitorBackgroundService.cs | 124 ++++++++++++++++++ web/c64_inteface/Program.cs | 31 +++++ .../Properties/launchSettings.json | 23 ++++ web/c64_inteface/appsettings.Development.json | 8 ++ web/c64_inteface/appsettings.json | 9 ++ web/c64_inteface/c64_inteface.csproj | 20 +++ web/c64_inteface/c64_inteface.sln | 16 +++ 12 files changed, 280 insertions(+), 18 deletions(-) create mode 100644 web/c64_inteface/.gitignore create mode 100644 web/c64_inteface/ArduinoMessageContainer.cs create mode 100644 web/c64_inteface/MonitorBackgroundService.cs create mode 100644 web/c64_inteface/Program.cs create mode 100644 web/c64_inteface/Properties/launchSettings.json create mode 100644 web/c64_inteface/appsettings.Development.json create mode 100644 web/c64_inteface/appsettings.json create mode 100644 web/c64_inteface/c64_inteface.csproj create mode 100644 web/c64_inteface/c64_inteface.sln diff --git a/build/c64_c_userport.prg b/build/c64_c_userport.prg index 1f075cb36bf737dfb061e677fa21426840d76813..ba2f3493c94722bf90b8e392a0f92068abd6d317 100644 GIT binary patch delta 14 VcmcZ;bth^=3J2ql&8ZyURRA`Q2E70P delta 14 VcmcZ;bth^=3J2qd&8ZyURRA_#2DJbH diff --git a/nano/nano_c64/src/main.cpp b/nano/nano_c64/src/main.cpp index 03b19cc..fbb1cd3 100644 --- a/nano/nano_c64/src/main.cpp +++ b/nano/nano_c64/src/main.cpp @@ -12,8 +12,10 @@ #define WRITE 2 char count = 0; -unsigned short delayAmount = 100; -char textToSent[] = "The Commodore 64, also known as the C64, is an 8-bit home computer introduced in January 1982 by Commodore International. It has been listed in the Guinness World Records as the best-selling desktop computer model of all time, with independent estimates placing the number sold between 12.5 and 17 million units."; +unsigned short delayAmount = 2; +const char* ArduinoPingMsg = "ping F28339B0-78C6-4445-905A-76F77F667D95"; +const char* ArduinoPongMsg = "pong F28339B0-78C6-4445-905A-76F77F667D95"; + char mode; @@ -68,13 +70,27 @@ void initMode(const char modeToSet) { } +String waitForLine() { + return Serial.readStringUntil('\n'); +} + +void waitForPing() { + while (true) { + while (Serial.available() == 0) {} //wait for data available + String pingStr = waitForLine(); //read until timeout + pingStr.trim(); + if (pingStr == ArduinoPingMsg) { + Serial.println(ArduinoPongMsg); + break; + } + } +} + void setup() { - delay(2000); mode = STANDBY; initMode(mode); - Serial.begin(9600); - + waitForPing(); } void send4Bit(char c) { @@ -94,8 +110,8 @@ void send4Bit(char c) { digitalWrite(AR, HIGH); - // while (digitalRead(CR) == LOW) {} - // while (digitalRead(CR) == HIGH) {} + while (digitalRead(CR) == LOW) {} + while (digitalRead(CR) == HIGH) {} delay(delayAmount); @@ -120,8 +136,7 @@ void sendByte(char a, char byte) { send4Bit(lower); } -void startWrite() { - Serial.print("start\n"); +void startWrite(String str) { mode = WRITE; initMode(mode); digitalWrite(AR, LOW); @@ -129,7 +144,7 @@ void startWrite() { int i = 0; char c, sc; do { - c = textToSent[i]; + c = str[i]; sc = getScreenCode(c); i++; sendByte(c, sc); @@ -147,16 +162,23 @@ void startWrite() { void loop() { - if (mode == WRITE) { + String line = waitForLine(); - } else if (mode == READ) { - - } else { - startWrite(); + if (line.length() > 0) { + startWrite(line); } - Serial.print("\nAAAAAAAA\n"); - delay(1000); + // if (mode == WRITE) { + // + // } else if (mode == READ) { + // + // } else { + // startWrite(); + // } + // + // Serial.print("\nAAAAAAAA\n"); + + // delay(1000); } \ No newline at end of file diff --git a/src/main.c b/src/main.c index 9104f49..a127d85 100644 --- a/src/main.c +++ b/src/main.c @@ -270,7 +270,7 @@ void recieveTest(char* title) { lower = 16; upper = 16; - *dirPtr = 0b11110000; + *dirPtr = 0b11111000; *dataPtr = 0; while (1) { diff --git a/web/c64_inteface/.gitignore b/web/c64_inteface/.gitignore new file mode 100644 index 0000000..cbbd0b5 --- /dev/null +++ b/web/c64_inteface/.gitignore @@ -0,0 +1,2 @@ +bin/ +obj/ \ No newline at end of file diff --git a/web/c64_inteface/ArduinoMessageContainer.cs b/web/c64_inteface/ArduinoMessageContainer.cs new file mode 100644 index 0000000..633b45e --- /dev/null +++ b/web/c64_inteface/ArduinoMessageContainer.cs @@ -0,0 +1,7 @@ +namespace c64_inteface; + +public class ArduinoMessageContainer +{ + public string Message { get; set; } = ""; + public bool Ready { get; set; } = false; +} \ No newline at end of file diff --git a/web/c64_inteface/MonitorBackgroundService.cs b/web/c64_inteface/MonitorBackgroundService.cs new file mode 100644 index 0000000..807ce66 --- /dev/null +++ b/web/c64_inteface/MonitorBackgroundService.cs @@ -0,0 +1,124 @@ +using System.IO.Ports; + +namespace c64_inteface; + +public class MonitorBackgroundService : IHostedService, IDisposable +{ + private const string ArduinoId = "F28339B0-78C6-4445-905A-76F77F667D95"; + private const string ArduinoPingMsg = "ping " + ArduinoId + "\n"; + private const string ArduinoPongMsg = "pong " + ArduinoId; + + private readonly ILogger _logger; + private readonly ArduinoMessageContainer _arduinoMessageContainer; + private SerialPort? _arduinoPort; + + public MonitorBackgroundService(ILogger logger, ArduinoMessageContainer arduinoMessageContainer) + { + _logger = logger; + _arduinoMessageContainer = arduinoMessageContainer; + } + + public Task StartAsync(CancellationToken stoppingToken) + { + _logger.LogInformation("{Service} running.", nameof(MonitorBackgroundService)); + Task.Run(() => RunServiceAsync(stoppingToken), stoppingToken); + return Task.CompletedTask; + } + + private async Task DoWork(CancellationToken cancellationToken) + { + _logger.LogInformation("DoWork running..."); + while (!cancellationToken.IsCancellationRequested) + { + if (_arduinoMessageContainer.Ready) + { + try + { + _logger.LogInformation("Sending message: {Message}", _arduinoMessageContainer.Message); + _arduinoPort?.WriteLine(_arduinoMessageContainer.Message); + _arduinoMessageContainer.Ready = false; + } + catch (Exception e) + { + Console.WriteLine(e); + } + } + } + } + + private async Task RunServiceAsync(CancellationToken cancellationToken) + { + await FindArduinoPort(cancellationToken); + await DoWork(cancellationToken); + } + + public Task StopAsync(CancellationToken stoppingToken) + { + _logger.LogInformation("{Service} is stopping.", nameof(MonitorBackgroundService)); + return Task.CompletedTask; + } + + private async Task FindArduinoPort(CancellationToken cancellationToken) + { + while (_arduinoPort is null && !cancellationToken.IsCancellationRequested) + { + var ports = SerialPort.GetPortNames().ToList(); + + _logger.LogInformation("available ports: {Ports}", ports); + + foreach (var portName in ports) + { + var port = new SerialPort(portName, 9600); + + port.ReadTimeout = 1000; + + try + { + port.Open(); + await Task.Delay(2000, cancellationToken); + } + catch (IOException) + { + continue; + } + + port.WriteLine(ArduinoPingMsg); + + try + { + var response = port.ReadLine(); + + + _logger.LogInformation(response); + + if (!response.Contains(ArduinoPongMsg)) + { + _logger.LogInformation("{portName} not my arduino", portName); + port.Close(); + continue; + } + } + catch (Exception ex) + { + _logger.LogError(ex, ex.Message); + _logger.LogInformation("{portName} did not respond", portName); + continue; + } + + _logger.LogInformation("Arduino found on {portName}", portName); + + _arduinoPort = port; + + return; + } + + await Task.Delay(1000, cancellationToken); + } + } + + public void Dispose() + { + _arduinoPort?.Close(); + _arduinoPort?.Dispose(); + } +} \ No newline at end of file diff --git a/web/c64_inteface/Program.cs b/web/c64_inteface/Program.cs new file mode 100644 index 0000000..ccfd2f7 --- /dev/null +++ b/web/c64_inteface/Program.cs @@ -0,0 +1,31 @@ +using c64_inteface; +using Microsoft.AspNetCore.Http.HttpResults; + +var builder = WebApplication.CreateBuilder(args); + +// Add services to the container. +// Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi +builder.Services.AddOpenApi(); + +builder.Services.AddSingleton(); +builder.Services.AddHostedService(); + +var app = builder.Build(); + +// Configure the HTTP request pipeline. +if (app.Environment.IsDevelopment()) +{ + app.MapOpenApi(); +} + +app.UseHttpsRedirection(); + +app.MapGet("/api/{message}", (string message, ArduinoMessageContainer arduinoMessageContainer) => + { + arduinoMessageContainer.Message = message.Trim(); + arduinoMessageContainer.Ready = true; + return true; + }) + .WithName("SendMessageToArduino"); + +app.Run(); \ No newline at end of file diff --git a/web/c64_inteface/Properties/launchSettings.json b/web/c64_inteface/Properties/launchSettings.json new file mode 100644 index 0000000..c1fb9c0 --- /dev/null +++ b/web/c64_inteface/Properties/launchSettings.json @@ -0,0 +1,23 @@ +{ + "$schema": "https://json.schemastore.org/launchsettings.json", + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": false, + "applicationUrl": "http://localhost:5216", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": false, + "applicationUrl": "https://localhost:7088;http://localhost:5216", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/web/c64_inteface/appsettings.Development.json b/web/c64_inteface/appsettings.Development.json new file mode 100644 index 0000000..0c208ae --- /dev/null +++ b/web/c64_inteface/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/web/c64_inteface/appsettings.json b/web/c64_inteface/appsettings.json new file mode 100644 index 0000000..10f68b8 --- /dev/null +++ b/web/c64_inteface/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +} diff --git a/web/c64_inteface/c64_inteface.csproj b/web/c64_inteface/c64_inteface.csproj new file mode 100644 index 0000000..1410600 --- /dev/null +++ b/web/c64_inteface/c64_inteface.csproj @@ -0,0 +1,20 @@ + + + + net9.0 + enable + enable + true + true + win-x64 + none + false + OutOfProcess + + + + + + + + diff --git a/web/c64_inteface/c64_inteface.sln b/web/c64_inteface/c64_inteface.sln new file mode 100644 index 0000000..627b843 --- /dev/null +++ b/web/c64_inteface/c64_inteface.sln @@ -0,0 +1,16 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "c64_inteface", "c64_inteface.csproj", "{53F85B44-8B21-41EE-88AE-A9BBDB3CED0A}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {53F85B44-8B21-41EE-88AE-A9BBDB3CED0A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {53F85B44-8B21-41EE-88AE-A9BBDB3CED0A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {53F85B44-8B21-41EE-88AE-A9BBDB3CED0A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {53F85B44-8B21-41EE-88AE-A9BBDB3CED0A}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal