1 // 2 // Copyright (c) 2010-2024 Antmicro 3 // 4 // This file is licensed under the MIT License. 5 // Full license text is available in 'licenses/MIT.txt'. 6 // 7 using Antmicro.Renode.Logging; 8 using Antmicro.Renode.Peripherals.UART; 9 using Antmicro.Renode.Peripherals.Miscellaneous.S32K3XX_FlexIOModel; 10 11 namespace Antmicro.Renode.Peripherals.Miscellaneous 12 { 13 public abstract class UARTDirectionBase 14 { UARTDirectionBase(IEmulationElement owner, Shifter shifter)15 public UARTDirectionBase(IEmulationElement owner, Shifter shifter) 16 { 17 this.owner = owner; 18 this.shifter = shifter; 19 shifter.ControlOrConfigurationChanged += () => warningsShown = false; 20 } 21 Reset()22 public virtual void Reset() 23 { 24 warningsShown = false; 25 } 26 27 // The following properties support also unexpected configurations. 28 public uint BaudRateDivider => (((shifter.Timer?.Compare ?? 0) & 0xFF) + 1) * 2 * (shifter.Timer?.Divider ?? 1); 29 public Bits StopBits => shifter.StopBit == ShifterStopBitConfiguration ? Bits.One : Bits.None; 30 LogWarnings()31 protected void LogWarnings() 32 { 33 if(warningsShown) 34 { 35 return; 36 } 37 warningsShown = true; 38 39 LogCommonWarnings(); 40 LogSpecificWarnings(); 41 } 42 LogWarningNonEqual(uint given, uint expected, string configuration, string block)43 protected void LogWarningNonEqual(uint given, uint expected, string configuration, string block) 44 { 45 if(given != expected) 46 { 47 owner.Log(LogLevel.Warning, "{0}{1} of {2} is unexpected, given 0x{3:X}, expected 0x{4:X}", WarningPrefix, configuration, block, given, expected); 48 } 49 } 50 LogWarning(string message, params object[] arg)51 protected void LogWarning(string message, params object[] arg) 52 { 53 owner.Log(LogLevel.Warning, WarningPrefix + message, arg); 54 } 55 LogSpecificWarnings()56 protected abstract void LogSpecificWarnings(); 57 58 protected abstract string WarningPrefix { get; } 59 60 protected readonly Shifter shifter; 61 protected const uint Compare8bitShift = 2 * 8 - 1; 62 protected const uint ShifterStopBitConfiguration = 0b11; 63 LogCommonWarnings()64 private void LogCommonWarnings() 65 { 66 LogWarningNonEqual(shifter.StartBit, 0b10, "start bit", shifter.Name); 67 LogWarningNonEqual(shifter.StopBit, ShifterStopBitConfiguration, "stop bit", shifter.Name); 68 69 if(shifter.Timer == null) 70 { 71 LogWarning("No timer set for {1}", shifter.Name); 72 return; 73 } 74 75 LogWarningNonEqual(shifter.Timer.Compare >> 8, Compare8bitShift, "compare value (upper bits)", shifter.Timer.Name); 76 LogWarningNonEqual((uint)shifter.Timer.Decrement, (uint)TimerDecrement.OnFLEXIOClockDividedBy16, "decrement configuration", shifter.Timer.Name); 77 LogWarningNonEqual((uint)shifter.Timer.StartBit, (uint)TimerStartBit.Always, "start bit", shifter.Timer.Name); 78 LogWarningNonEqual((uint)shifter.Timer.StopBit, (uint)TimerStopBit.OnTimerDisable, "stop bit", shifter.Timer.Name); 79 LogWarningNonEqual((uint)shifter.Timer.Mode, (uint)TimerMode.DualBaud, "mode", shifter.Timer.Name); 80 LogWarningNonEqual((uint)shifter.Timer.OneTimeOperation, (uint)TimerTriggerOneTimeOperation.Normal, "one time operation", shifter.Timer.Name); 81 } 82 83 private IEmulationElement owner; 84 private bool warningsShown; 85 } 86 } 87