diff --git a/UARTReplacement/Properties/AssemblyInfoExtra.cs b/UARTReplacement/Properties/AssemblyInfoExtra.cs index cb29ab6..ee294a3 100644 --- a/UARTReplacement/Properties/AssemblyInfoExtra.cs +++ b/UARTReplacement/Properties/AssemblyInfoExtra.cs @@ -4,7 +4,7 @@ using System.Reflection; -[assembly: AssemblyConfiguration("04697a9")] +[assembly: AssemblyConfiguration("7e20a6b")] [assembly: AssemblyCopyright("Copyright © 2019-2024 Robin Verhagen-Guest")] [assembly: AssemblyVersion("1.6.0.0")] [assembly: AssemblyFileVersion("1.6.0.0")] diff --git a/UARTReplacement/SerialPort.cs b/UARTReplacement/SerialPort.cs index 8bf6b17..8554e3a 100644 --- a/UARTReplacement/SerialPort.cs +++ b/UARTReplacement/SerialPort.cs @@ -21,6 +21,7 @@ public class SerialPort : IDisposable private bool enablePiGpio5Output = false; private UARTTargets target; private string logPrefix; + private byte prescalerTop3Bits = 0x00; /// /// Creates an instance of the SerialPort class. @@ -135,6 +136,12 @@ public int SetPrescalerAndClock(byte BaudByte, byte VideoTimingByte) int oldBaud = Baud; try { + if ((BaudByte & 0x10) == 0x10) + { + // Get bits 14..16 of the new prescaler + prescalerTop3Bits = (byte)(BaudByte & 0b111); + //Console.WriteLine(UARTReplacement_Device.PluginName + "Prescaler 17..14: " + ToBin3(prescalerTop3Bits)); + } if (port == null) return 0; int mode = VideoTimingByte & 7; @@ -170,8 +177,7 @@ public int SetPrescalerAndClock(byte BaudByte, byte VideoTimingByte) } if ((BaudByte & 0x10) == 0x10) { - // Get bits 14..16 of the new prescaler - int newBits = (BaudByte & 0x07) << 14; + int newBits = prescalerTop3Bits << 14; // Mask out everything of the existing prescaler except bits 14..16 int oldBits = prescaler & 0x3fff; // Combine the two sets of bits @@ -195,6 +201,13 @@ public int SetPrescalerAndClock(byte BaudByte, byte VideoTimingByte) } } + private string ToBin3(byte value) + { + string val = Convert.ToString(value, 2).PadLeft(8, '0').ToLower(); + return "0b" + val.Substring(5); + } + + /// /// Given a raw byte written to PORT_UART_RX, parses the high bit to decide whether it represents a change /// to bits 6:0 or 13:7, and updates the prescaler accordingly. @@ -264,6 +277,17 @@ public int Baud } } + /// + /// Returns the value for a PORT_UART_CONTROL (0x153b) read. + /// Bit 6 is 0 for ESP and 1 for Pi. Bits 2..0 are the top three bits of the prescaler. + /// All other bits are 0. + /// + /// The byte value to be returned by a PORT_UART_CONTROL (0x153b) read. + public byte GetUartControlValue() + { + return (byte)((int)target | prescalerTop3Bits); + } + public void EspReset(byte ResetByte) { try diff --git a/UARTReplacement/UARTReplacement_Device.cs b/UARTReplacement/UARTReplacement_Device.cs index f056938..e0b6c0d 100644 --- a/UARTReplacement/UARTReplacement_Device.cs +++ b/UARTReplacement/UARTReplacement_Device.cs @@ -63,6 +63,7 @@ public List Init(iCSpect _CSpect) ports.Add(new sIO(PORT_UART_RX, eAccess.Port_Write)); ports.Add(new sIO(PORT_UART_RX, eAccess.Port_Read)); ports.Add(new sIO(PORT_UART_CONTROL, eAccess.Port_Write)); + ports.Add(new sIO(PORT_UART_CONTROL, eAccess.Port_Read)); ports.Add(new sIO(REG_RESET, eAccess.NextReg_Write)); ports.Add(new sIO(REG_ESP_GPIO_ENABLE, eAccess.NextReg_Write)); ports.Add(new sIO(REG_ESP_GPIO, eAccess.NextReg_Write)); @@ -123,6 +124,7 @@ public bool Write(eAccess _type, int _port, int _id, byte _value) // But just in case it can vary, let's do it. It doesn't seem to cause performance issues to do so. var oldTarget = Target; var target = (_value & 64) == 0 ? UARTTargets.ESP : UARTTargets.Pi; + //Console.WriteLine(UARTReplacement_Device.PluginName + "OUT 0x153b, " + ToBin(_value)); Target = target; if (oldTarget != Target) Console.WriteLine(UARTReplacement_Device.PluginName + "Target changed to " + Target.ToString()); @@ -136,6 +138,7 @@ public bool Write(eAccess _type, int _port, int _id, byte _value) return true; case PORT_UART_RX: // Writes to this port represent changes to the prescaler which cause the UART baud to change + //Console.WriteLine(UARTReplacement_Device.PluginName + "OUT 0x143b, " + ToBin(_value)); currentPort.SetPrescaler(_value); return true; case REG_RESET: @@ -183,6 +186,9 @@ public byte Read(eAccess _type, int _port, int _id, out bool _isvalid) { switch (_port) { + case PORT_UART_CONTROL: + _isvalid = true; + return currentPort.GetUartControlValue(); case PORT_UART_RX: if (UART_RX_Internal) { @@ -308,6 +314,12 @@ private object currentSync return Target == UARTTargets.ESP ? espSync : piSync; } } + + private string ToBin(byte value) + { + string val = Convert.ToString(value, 2).PadLeft(8, '0').ToLower(); + return "0b" + val.Substring(0, 4) + "'" + val.Substring(4); + } } } diff --git a/UARTReplacement/UARTTargets.cs b/UARTReplacement/UARTTargets.cs index d1351f7..ec3d844 100644 --- a/UARTReplacement/UARTTargets.cs +++ b/UARTReplacement/UARTTargets.cs @@ -7,11 +7,13 @@ namespace Plugins.UARTReplacement { /// - /// This represents the two different Next UARTs. Currently only the ESP UART is replaced by this plugin. + /// This represents the two different Next UARTs. + /// The numeric value determines what is returned from a port PORT_UART_CONTROL (0x153b) read. + /// Bits 17..15 of the prescaler value are ORed into the bottom three bits of this value. /// public enum UARTTargets { - ESP, - Pi + ESP = 0b0_0_000_000, + Pi = 0b0_1_000_000 } }