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 using static Antmicro.Renode.Peripherals.Miscellaneous.S32K3XX_FlexIO; 12 13 namespace Antmicro.Renode.Peripherals.Miscellaneous.S32K3XX_FlexIOModel 14 { 15 public class Timer : ResourceBlock 16 { BuildRegisters(IResourceBlockOwner owner, int count)17 public static IReadOnlyList<Timer> BuildRegisters(IResourceBlockOwner owner, int count) 18 { 19 var statusFlags = Interrupt.BuildRegisters(owner, count, "TimerStatus", Registers.TimerStatus, Registers.TimerInterruptEnable); 20 21 return statusFlags.Select((status, index) => BuildTimer( 22 owner, 23 index, 24 status 25 )).ToList().AsReadOnly(); 26 } 27 EncodeShifterAsTriggerSelect(Shifter shifter)28 public static uint EncodeShifterAsTriggerSelect(Shifter shifter) 29 { 30 return shifter.Identifier * 4 + 1; 31 } 32 33 public event Action ConfigurationChanged; 34 public event Action ControlChanged; 35 36 public override IEnumerable<Interrupt> Interrupts => new[] { Status }; 37 public override string Name => $"Timer{Identifier}"; 38 39 public Interrupt Status { get; } 40 public uint TriggerSelect => (uint)triggerSelect.Value; 41 public TimerTriggerPolarity TriggerPolarity => triggerPolarity.Value; 42 public TimerTriggerSource TriggerSource => triggerSource.Value; 43 public TimerTriggerOneTimeOperation OneTimeOperation => oneTimeOperation.Value; 44 public TimerMode Mode => mode.Value; 45 public TimerOutput Output => output.Value; 46 public TimerDecrement Decrement => decrement.Value; 47 public TimerReset ResetMode => resetMode.Value; 48 public TimerDisable Disable => disable.Value; 49 public TimerEnable Enable => enable.Value; 50 public TimerStopBit StopBit => stopBit.Value; 51 public TimerStartBit StartBit => startBit.Value; 52 public uint Compare 53 { 54 get => (uint)compare.Value; 55 set => compare.Value = value; 56 } 57 public uint Divider 58 { 59 get 60 { 61 switch(Decrement) 62 { 63 case TimerDecrement.OnFLEXIOClockDividedBy16: 64 return 16; 65 case TimerDecrement.OnFLEXIOClockDividedBy256: 66 return 256; 67 default: 68 return 1; 69 } 70 } 71 } 72 BuildTimer(IResourceBlockOwner owner, int index, Interrupt status)73 private static Timer BuildTimer(IResourceBlockOwner owner, int index, Interrupt status) 74 { 75 Timer timer = null; 76 var offset = index * 4; 77 78 var controlRegister = (Registers.TimerControl0 + offset).Define(owner) 79 .WithReservedBits(30, 2) 80 .WithReservedBits(18, 4) 81 .WithTag("PINCFG (Timer Pin Configuration)", 16, 2) 82 .WithReservedBits(13, 3) 83 .WithTag("PINSEL (Timer Pin Select)", 8, 5) 84 .WithTaggedFlag("PINPOL (Timer Pin Polarity)", 7) 85 .WithTaggedFlag("PIPINS (Timer Pin Input Select)", 6) 86 .WithReservedBits(3, 2); 87 88 var triggerSelectField = controlRegister.DefineValueField(24, 6, name: "TRGSEL (Trigger Select)"); 89 var triggerPolarityField = controlRegister.DefineEnumField<TimerTriggerPolarity>(23, 1, name: "TRGPOL (Trigger Polarity)"); 90 var triggerSourceField = controlRegister.DefineEnumField<TimerTriggerSource>(22, 1, name: "TRGSRC (Trigger Source)"); 91 var oneTimeOperationField = controlRegister.DefineEnumField<TimerTriggerOneTimeOperation>(5, 1, name: "ONETIM (Timer One Time Operation)"); 92 var modeField = controlRegister.DefineEnumField<TimerMode>(0, 3, name: "TIMOD (Timer Mode)"); 93 controlRegister.WithChangeCallback((_, __) => timer.ControlChanged?.Invoke()); 94 95 var configurationRegister = (Registers.TimerConfiguration0 + offset).Define(owner) 96 .WithReservedBits(26, 6) 97 .WithReservedBits(23, 1) 98 .WithReservedBits(19, 1) 99 .WithReservedBits(15, 1) 100 .WithReservedBits(11, 1) 101 .WithReservedBits(6, 2) 102 .WithReservedBits(2, 2) 103 .WithReservedBits(0, 1); 104 105 var outputField = configurationRegister.DefineEnumField<TimerOutput>(24, 2, name: "TIMOUT (Timer Output)"); 106 var decrementField = configurationRegister.DefineEnumField<TimerDecrement>(20, 3, name: "TIMDEC (Timer Decrement)"); 107 var resetField = configurationRegister.DefineEnumField<TimerReset>(16, 3, name: "TIMRST (Timer Reset)"); 108 var disableField = configurationRegister.DefineEnumField<TimerDisable>(12, 3, name: "TIMDIS (Timer Disable)"); 109 var enableField = configurationRegister.DefineEnumField<TimerEnable>(8, 3, name: "TIMENA (Timer Enable)"); 110 var stopBitField = configurationRegister.DefineEnumField<TimerStopBit>(4, 2, name: "TSTOP (Timer Stop Bit)"); 111 var startBitField = configurationRegister.DefineEnumField<TimerStartBit>(1, 1, name: "TSTART (Timer Start Bit)"); 112 configurationRegister.WithChangeCallback((_, __) => timer.ConfigurationChanged?.Invoke()); 113 114 var compareField = (Registers.TimerCompare0 + offset).Define(owner) 115 .WithReservedBits(16, 16) 116 .DefineValueField(0, 16, name: "CMP (Timer Compare Value)"); 117 118 timer = new Timer( 119 owner, 120 (uint)index, 121 status, 122 triggerSelectField, 123 triggerPolarityField, 124 triggerSourceField, 125 oneTimeOperationField, 126 modeField, 127 outputField, 128 decrementField, 129 resetField, 130 disableField, 131 enableField, 132 stopBitField, 133 startBitField, 134 compareField 135 ); 136 return timer; 137 } 138 Timer(IResourceBlockOwner owner, uint identifier, Interrupt status, IValueRegisterField triggerSelect, IEnumRegisterField<TimerTriggerPolarity> triggerPolarity, IEnumRegisterField<TimerTriggerSource> triggerSource, IEnumRegisterField<TimerTriggerOneTimeOperation> oneTimeOperation, IEnumRegisterField<TimerMode> mode, IEnumRegisterField<TimerOutput> output, IEnumRegisterField<TimerDecrement> decrement, IEnumRegisterField<TimerReset> resetMode, IEnumRegisterField<TimerDisable> disable, IEnumRegisterField<TimerEnable> enable, IEnumRegisterField<TimerStopBit> stopBit, IEnumRegisterField<TimerStartBit> startBit, IValueRegisterField compare )139 private Timer(IResourceBlockOwner owner, uint identifier, Interrupt status, 140 IValueRegisterField triggerSelect, 141 IEnumRegisterField<TimerTriggerPolarity> triggerPolarity, 142 IEnumRegisterField<TimerTriggerSource> triggerSource, 143 IEnumRegisterField<TimerTriggerOneTimeOperation> oneTimeOperation, 144 IEnumRegisterField<TimerMode> mode, 145 IEnumRegisterField<TimerOutput> output, 146 IEnumRegisterField<TimerDecrement> decrement, 147 IEnumRegisterField<TimerReset> resetMode, 148 IEnumRegisterField<TimerDisable> disable, 149 IEnumRegisterField<TimerEnable> enable, 150 IEnumRegisterField<TimerStopBit> stopBit, 151 IEnumRegisterField<TimerStartBit> startBit, 152 IValueRegisterField compare 153 ) : base(owner, identifier) 154 { 155 Status = status; 156 Status.MaskedFlagChanged += OnInterruptChange; 157 158 this.triggerSelect = triggerSelect; 159 this.triggerPolarity = triggerPolarity; 160 this.triggerSource = triggerSource; 161 this.oneTimeOperation = oneTimeOperation; 162 this.mode = mode; 163 this.output = output; 164 this.decrement = decrement; 165 this.resetMode = resetMode; 166 this.disable = disable; 167 this.enable = enable; 168 this.stopBit = stopBit; 169 this.startBit = startBit; 170 this.compare = compare; 171 } 172 173 private readonly IValueRegisterField triggerSelect; 174 private readonly IEnumRegisterField<TimerTriggerPolarity> triggerPolarity; 175 private readonly IEnumRegisterField<TimerTriggerSource> triggerSource; 176 private readonly IEnumRegisterField<TimerTriggerOneTimeOperation> oneTimeOperation; 177 private readonly IEnumRegisterField<TimerMode> mode; 178 private readonly IEnumRegisterField<TimerOutput> output; 179 private readonly IEnumRegisterField<TimerDecrement> decrement; 180 private readonly IEnumRegisterField<TimerReset> resetMode; 181 private readonly IEnumRegisterField<TimerDisable> disable; 182 private readonly IEnumRegisterField<TimerEnable> enable; 183 private readonly IEnumRegisterField<TimerStopBit> stopBit; 184 private readonly IEnumRegisterField<TimerStartBit> startBit; 185 private readonly IValueRegisterField compare; 186 } 187 188 public enum TimerTriggerPolarity 189 { 190 ActiveHigh = 0, 191 ActiveLow = 1 192 } 193 194 public enum TimerTriggerSource 195 { 196 External = 0, 197 Internal = 1 198 } 199 200 public enum TimerTriggerOneTimeOperation 201 { 202 Normal = 0, 203 BlockUntilClear = 1 204 } 205 206 public enum TimerMode 207 { 208 Disabled = 0b000, 209 DualBaud = 0b001, 210 DualPWMHigh = 0b010, 211 Single = 0b011, 212 SingleDisable = 0b100, 213 DualWord = 0b101, 214 DualPWMLow = 0b110, 215 SingleInputCapture = 0b111 216 } 217 218 public enum TimerOutput 219 { 220 One = 0b00, 221 Zero = 0b01, 222 OneOnResetToo = 0b10, 223 ZeroOnResetToo = 0b11 224 } 225 226 public enum TimerDecrement 227 { 228 OnFLEXIOClock = 0b000, 229 OnTriggerInputBothEdgesClockEqualsOutput = 0b001, 230 OnPinInputBothEdges = 0b010, 231 OnTriggerInputBothEdgesClockEqualsTrigger = 0b011, 232 OnFLEXIOClockDividedBy16 = 0b100, 233 OnFLEXIOClockDividedBy256 = 0b101, 234 OnPinInputRisingEdge = 0b110, 235 OnTriggerInputRisingEdge = 0b111 236 } 237 238 public enum TimerReset 239 { 240 Never = 0b000, 241 OnOutputHigh = 0b001, 242 OnPinEqualToOutput = 0b010, 243 OnTriggerEqualToOutput = 0b011, 244 OnPinRisingEdge = 0b100, 245 Reserved = 0b101, 246 OnTriggerRisingEdge = 0b110, 247 OnTriggerBothEdges = 0b111 248 } 249 250 public enum TimerDisable 251 { 252 Never = 0b000, 253 OnPreviousTimerDisable = 0b001, 254 OnTimerCompare = 0b010, 255 OnTimerCompareAndTriggerLow = 0b011, 256 OnPinBothEdges = 0b100, 257 OnPinBothEdgesProvidedTriggerIsHigh = 0b101, 258 OnTriggerFallingEdge = 0b110, 259 Reserved = 0b111 260 } 261 262 public enum TimerEnable 263 { 264 Always = 0b000, 265 OnPreviousTimerEnable = 0b001, 266 OnTriggerHigh = 0b010, 267 OnTriggerHighAndPinHigh = 0b011, 268 OnPinRisingEdge = 0b100, 269 OnPinRisingEdgeAndTriggerHigh = 0b101, 270 OnTriggerRisingEdge = 0b110, 271 OnTriggerBothEdges = 0b111 272 } 273 274 public enum TimerStopBit 275 { 276 Disabled = 0b00, 277 OnTimerCompare = 0b01, 278 OnTimerDisable = 0b10, 279 OnTimerCompareAndTimerDisable = 0b11 280 } 281 282 public enum TimerStartBit 283 { 284 Disabled = 0b0, 285 Always = 0b1 286 } 287 } 288