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 System; 8 using System.Collections.Generic; 9 using System.Linq; 10 using Antmicro.Renode.Core.Structure.Registers; 11 12 namespace Antmicro.Renode.Peripherals.Miscellaneous.S32K3XX_FlexIOModel 13 { 14 public class Interrupt 15 { BuildRegisters(IProvidesRegisterCollection<DoubleWordRegisterCollection> owner, int count, string name, System.Enum flagOffset, System.Enum enableOffset)16 public static IReadOnlyList<Interrupt> BuildRegisters(IProvidesRegisterCollection<DoubleWordRegisterCollection> owner, int count, string name, System.Enum flagOffset, System.Enum enableOffset) 17 { 18 var flagRegister = flagOffset.Define(owner) 19 .WithReservedBits(count, 32 - count); 20 var enableRegister = enableOffset.Define(owner) 21 .WithReservedBits(count, 32 - count); 22 23 return Enumerable.Range(0, count).Select(index => 24 { 25 Interrupt interrupt = null; 26 var flag = flagRegister.DefineFlagField(index, FieldMode.Read | FieldMode.WriteOneToClear, name: $"{name}Flag", 27 changeCallback: (prev, val) => interrupt.OnFlagChange(prev, val) 28 ); 29 var enable = enableRegister.DefineFlagField(index, name: $"{name}Enable", 30 changeCallback: (prev, val) => interrupt.OnMaskChange(prev, val) 31 ); 32 interrupt = new Interrupt(flag, enable); 33 return interrupt; 34 } 35 ).ToList().AsReadOnly(); 36 } 37 Reset()38 public void Reset() 39 { 40 isFlagUnchangeable = false; 41 } 42 SetFlag(bool value, bool unchangeableFlag = false)43 public void SetFlag(bool value, bool unchangeableFlag = false) 44 { 45 isFlagUnchangeable = unchangeableFlag; 46 if(flag.Value != value) 47 { 48 flag.Value = value; 49 HandleChange(!value, mask.Value); 50 } 51 } 52 53 public bool MaskedFlag => flag.Value && mask.Value; 54 55 public event Action<bool> MaskedFlagChanged; 56 Interrupt(IFlagRegisterField flag, IFlagRegisterField mask)57 private Interrupt(IFlagRegisterField flag, IFlagRegisterField mask) 58 { 59 this.flag = flag; 60 this.mask = mask; 61 } 62 OnFlagChange(bool previousValue, bool value)63 private void OnFlagChange(bool previousValue, bool value) 64 { 65 if(isFlagUnchangeable) 66 { 67 flag.Value = previousValue; 68 return; 69 } 70 HandleChange(previousValue, mask.Value); 71 } 72 OnMaskChange(bool previousValue, bool value)73 private void OnMaskChange(bool previousValue, bool value) 74 { 75 HandleChange(flag.Value, previousValue); 76 } 77 HandleChange(bool previousFlag, bool previousMask)78 private void HandleChange(bool previousFlag, bool previousMask) 79 { 80 var previousMasked = previousFlag && previousMask; 81 if(previousMasked != MaskedFlag) 82 { 83 MaskedFlagChanged?.Invoke(MaskedFlag); 84 } 85 } 86 87 private bool isFlagUnchangeable; 88 private readonly IFlagRegisterField flag; 89 private readonly IFlagRegisterField mask; 90 } 91 } 92