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; 11 using Antmicro.Renode.Exceptions; 12 using Antmicro.Renode.Core.Extensions; 13 using Antmicro.Renode.Core.Structure.Registers; 14 using Antmicro.Renode.Logging; 15 using Antmicro.Renode.Peripherals.Bus; 16 using Antmicro.Renode.Peripherals.GPIOPort; 17 using Antmicro.Renode.Utilities; 18 19 using Endianness = ELFSharp.ELF.Endianess; 20 21 namespace Antmicro.Renode.Peripherals.Miscellaneous 22 { 23 public class S32K3XX_SystemIntegrationUnitLite2 : BaseGPIOPort, IDoubleWordPeripheral, IWordPeripheral, IBytePeripheral, IKnownSize, 24 IProvidesRegisterCollection<DoubleWordRegisterCollection>, IProvidesRegisterCollection<ByteRegisterCollection> 25 { S32K3XX_SystemIntegrationUnitLite2(IMachine machine)26 public S32K3XX_SystemIntegrationUnitLite2(IMachine machine) : base(machine, MaximumValidPadIndex + 1) 27 { 28 IRQ1 = new GPIO(); 29 IRQ2 = new GPIO(); 30 IRQ3 = new GPIO(); 31 IRQ4 = new GPIO(); 32 33 interruptType = new InterruptType[ExternalInterruptCount]; 34 interruptPending = new IFlagRegisterField[ExternalInterruptCount]; 35 interruptEnabled = new IFlagRegisterField[ExternalInterruptCount]; 36 37 doubleWordRegisterCollection = new DoubleWordRegisterCollection(this); 38 byteRegisterCollection = new ByteRegisterCollection(this); 39 40 DefineRegisters(); 41 } 42 ReadDoubleWord(long offset)43 public uint ReadDoubleWord(long offset) 44 { 45 if(!doubleWordRegisterCollection.TryRead(offset, out var value)) 46 { 47 return this.ReadDoubleWordUsingByte(offset); 48 } 49 return value; 50 } 51 WriteDoubleWord(long offset, uint value)52 public void WriteDoubleWord(long offset, uint value) 53 { 54 if(!doubleWordRegisterCollection.TryWrite(offset, value)) 55 { 56 this.WriteDoubleWordUsingByte(offset, value); 57 } 58 } 59 ReadWord(long offset)60 public ushort ReadWord(long offset) 61 { 62 return this.ReadWordUsingByte(offset); 63 } 64 WriteWord(long offset, ushort value)65 public void WriteWord(long offset, ushort value) 66 { 67 this.WriteWordUsingByte(offset, value); 68 } 69 ReadByte(long offset)70 public byte ReadByte(long offset) 71 { 72 return byteRegisterCollection.Read(offset); 73 } 74 WriteByte(long offset, byte value)75 public void WriteByte(long offset, byte value) 76 { 77 byteRegisterCollection.Write(offset, value); 78 } 79 Reset()80 public override void Reset() 81 { 82 base.Reset(); 83 doubleWordRegisterCollection.Reset(); 84 byteRegisterCollection.Reset(); 85 } 86 OnGPIO(int number, bool value)87 public override void OnGPIO(int number, bool value) 88 { 89 if(!validPadIndexes.Contains(number)) 90 { 91 this.Log(LogLevel.Warning, "Tried to set {0} to pad#{1} is not an valid pad index", value, number); 92 return; 93 } 94 95 var previousState = State[number]; 96 base.OnGPIO(number, value); 97 98 if(previousState == value) 99 { 100 return; 101 } 102 103 var mapping = eirqToPadMapping 104 .Select((Pads, Index) => new { Pads, Index }) 105 .Where(item => item.Pads.Contains(number)) 106 .FirstOrDefault(); 107 108 if(mapping == null) 109 { 110 return; 111 } 112 113 var externalIRQ = mapping.Index; 114 if(interruptType[externalIRQ].HasFlag(InterruptType.RisingEdge) && !previousState) 115 { 116 interruptPending[externalIRQ].Value = true; 117 } 118 if(interruptType[externalIRQ].HasFlag(InterruptType.FallingEdge) && previousState) 119 { 120 interruptPending[externalIRQ].Value = true; 121 } 122 123 UpdateInterrupts(); 124 } 125 TranslatePinName(string pinName)126 public int TranslatePinName(string pinName) 127 { 128 var normalizedPinName = pinName.ToUpper(); 129 130 // Pin name is in format PTxy, where x is between A and H, and y can be between 0 and 31 131 if(normalizedPinName.Length < 4 || !normalizedPinName.StartsWith("PT")) 132 { 133 throw new RecoverableException($"{pinName} is invalid pin name. Correct pin names are in format PTxyy"); 134 } 135 136 var portIndexChar = normalizedPinName[2]; 137 if(portIndexChar > 'H' || portIndexChar < 'A') 138 { 139 throw new RecoverableException("Pin name should be in range PTAxx to PTHxx"); 140 } 141 var portIndex = portIndexChar - 'A'; 142 143 var pinIndexString = normalizedPinName.Substring(3); 144 if(!Int32.TryParse(pinIndexString, out var pinIndex) || pinIndex < 0 || pinIndex > 31) 145 { 146 throw new RecoverableException("Pin name should be in range PTx00 to PTx31"); 147 } 148 149 var padIndex = portIndex * 32 + pinIndex; 150 if(!validPadIndexes.Contains(padIndex)) 151 { 152 throw new RecoverableException("This pin is unavailable for GPIO"); 153 } 154 155 return padIndex; 156 } 157 158 public long Size => 0x4000; 159 public GPIO IRQ1 { get; } 160 public GPIO IRQ2 { get; } 161 public GPIO IRQ3 { get; } 162 public GPIO IRQ4 { get; } 163 164 DoubleWordRegisterCollection IProvidesRegisterCollection<DoubleWordRegisterCollection>.RegistersCollection => doubleWordRegisterCollection; 165 ByteRegisterCollection IProvidesRegisterCollection<ByteRegisterCollection>.RegistersCollection => byteRegisterCollection; 166 UpdateInterrupts()167 private void UpdateInterrupts() 168 { 169 IRQ1.Set(Enumerable.Range(0, 8).Any(irq => interruptEnabled[irq].Value && interruptPending[irq].Value)); 170 IRQ2.Set(Enumerable.Range(8, 8).Any(irq => interruptEnabled[irq].Value && interruptPending[irq].Value)); 171 IRQ3.Set(Enumerable.Range(16, 8).Any(irq => interruptEnabled[irq].Value && interruptPending[irq].Value)); 172 IRQ4.Set(Enumerable.Range(24, 8).Any(irq => interruptEnabled[irq].Value && interruptPending[irq].Value)); 173 } 174 DefineRegisters()175 private void DefineRegisters() 176 { 177 IProvidesRegisterCollection<DoubleWordRegisterCollection> asDoubleWordCollection = this; 178 179 Registers.MCUIDRegister1.Define(asDoubleWordCollection) 180 .WithTag("MinorMaskRevision", 0, 4) 181 .WithTag("MajorMaskRevision", 4, 4) 182 .WithReservedBits(8, 8) 183 .WithTag("MCUPartNumber", 16, 10) 184 .WithTag("ProductLineLetter", 26, 6) 185 ; 186 187 Registers.MCUIDRegister2.Define(asDoubleWordCollection) 188 .WithTag("FlashSizeCode0", 0, 7) 189 .WithTag("FlashSizeData0", 8, 4) 190 .WithTag("FlashData0", 12, 2) 191 .WithTag("FlashCode0", 14, 2) 192 .WithTag("Frequency0", 16, 4) 193 .WithTag("Package0", 20, 6) 194 .WithTag("Temperature0", 26, 3) 195 .WithTag("Technology0", 29, 3) 196 ; 197 198 var interruptStatusFlag = Registers.DMAInterruptStatusFlag0.Define(asDoubleWordCollection); 199 var interruptRequestEnable = Registers.DMAInterruptRequestEnable0.Define(asDoubleWordCollection); 200 var interruptRequestSelect = Registers.DMAInterruptRequestSelect0.Define(asDoubleWordCollection); 201 var interruptRisingEdgeEventEnable = Registers.InterruptRisingEdgeEventEnable0.Define(asDoubleWordCollection); 202 var interruptFallingEdgeEventEnable = Registers.InterruptFallingEdgeEventEnable0.Define(asDoubleWordCollection); 203 var interruptFilterEnable = Registers.InterruptFilterEnable0.Define(asDoubleWordCollection); 204 205 for(var i = 0; i < ExternalInterruptCount; ++i) 206 { 207 var irq = i; 208 209 interruptStatusFlag.WithFlag(irq, out interruptPending[irq], FieldMode.Read | FieldMode.WriteOneToClear, name: $"ExternalInterruptStatusFlag{irq}"); 210 interruptRequestEnable.WithFlag(irq, out interruptEnabled[irq], name: $"ExternalRequestEnable{irq}"); 211 interruptRequestSelect.WithTaggedFlag($"RequestSelect{irq}", irq); 212 interruptRisingEdgeEventEnable.WithFlag(irq, name: $"EnableRisingEdgeEventsToSetDISR0[{irq}]", 213 valueProviderCallback: _ => interruptType[irq].HasFlag(InterruptType.RisingEdge), 214 changeCallback: (_, value) => interruptType[irq] = value ? (interruptType[irq] | InterruptType.RisingEdge) : (interruptType[irq] & ~InterruptType.RisingEdge) 215 ); 216 interruptFallingEdgeEventEnable.WithFlag(irq, name: $"EnableFallingEdgeEventsToSetDISR0[{irq}]", 217 valueProviderCallback: _ => interruptType[irq].HasFlag(InterruptType.FallingEdge), 218 changeCallback: (_, value) => interruptType[irq] = value ? (interruptType[irq] | InterruptType.FallingEdge) : (interruptType[irq] & ~InterruptType.FallingEdge) 219 ); 220 interruptFilterEnable.WithTaggedFlag($"EnableFilterOnInterruptPad{irq}", irq); 221 } 222 223 interruptStatusFlag.WithChangeCallback((_, __) => UpdateInterrupts()); 224 interruptRequestEnable.WithChangeCallback((_, __) => UpdateInterrupts()); 225 interruptRisingEdgeEventEnable.WithChangeCallback((_, __) => UpdateInterrupts()); 226 interruptFallingEdgeEventEnable.WithChangeCallback((_, __) => UpdateInterrupts()); 227 228 Registers.InterruptFilterMaximumCounter0.DefineMany(asDoubleWordCollection, ExternalInterruptCount, (register, registerIndex) => 229 { 230 register 231 .WithTag("MaximumInterruptFilterCounter", 0, 4) 232 .WithReservedBits(4, 28) 233 ; 234 }); 235 236 Registers.InterruptFilterClockPrescaler.Define(asDoubleWordCollection) 237 .WithTag("InterruptFilterClockPrescaler", 0, 4) 238 .WithReservedBits(4, 28) 239 ; 240 241 Registers.MUX0EMIOSEnable1.DefineMany(asDoubleWordCollection, MuxCount, (register, registerIndex) => 242 { 243 var lowerFlags = Enumerable.Range(0, 8).ToDictionary(x => x, x => x + 16); 244 var upperFlags = Enumerable.Range(16, 16).ToDictionary(x => x, x => x - 16); 245 246 foreach(var flag in upperFlags.Concat(lowerFlags)) 247 { 248 register.WithTaggedFlag($"EMIOS0OutputFlag{flag.Value}MonitorEnable", flag.Key); 249 } 250 register.WithReservedBits(8, 8); 251 }, stepInBytes: Registers.MUX1EMIOSEnable - Registers.MUX0EMIOSEnable1); 252 253 Registers.MCUIDRegister3.Define(asDoubleWordCollection) 254 .WithTag("SystemRAMSize", 0, 6) 255 .WithReservedBits(6, 4) 256 .WithTag("PartNumberSuffix", 10, 6) 257 .WithTag("ProductFamilyNumber", 16, 10) 258 .WithTag("ProductFamilyLetter", 26, 6) 259 ; 260 261 Registers.MCUIDRegister4.Define(asDoubleWordCollection) 262 .WithTag("CorePlatformOptionsFeature", 0, 3) 263 .WithTag("EthernetFeature", 3, 2) 264 .WithTag("SecurityFeature", 5, 2) 265 .WithReservedBits(7, 7) 266 .WithTag("CorePlatformOptionsFeature", 14, 2) 267 .WithReservedBits(16, 16) 268 ; 269 270 var multiplexedSignalConfigurationIndexes = Enumerable.Empty<int>() 271 .ConcatRangeFromTo(0, 37) 272 .ConcatRangeFromTo(40, 140) 273 .ConcatRangeFromTo(142, 236); 274 275 var multiplexedSignalConfigurationResets = new Dictionary<int, uint> 276 { 277 {4, 0x82827}, 278 {10, 0x127}, 279 {12, 0x3}, 280 {68, 0x82000}, 281 {69, 0x82800}, 282 {76, 0x4000}, 283 {80, 0x4000}, 284 {66, 0x4000}, 285 {67, 0x4000}, 286 {101, 0x4000}, 287 {102, 0x4000}, 288 {103, 0x4000}, 289 {106, 0x4000}, 290 {107, 0x4000}, 291 {108, 0x4000}, 292 {136, 0x4000}, 293 }; 294 295 foreach(var index in multiplexedSignalConfigurationIndexes) 296 { 297 var offset = Registers.MultiplexedSignalConfiguration0 + index * 4; 298 if(!multiplexedSignalConfigurationResets.TryGetValue(index, out var resetValue)) 299 { 300 resetValue = 0; 301 } 302 303 offset.Define(asDoubleWordCollection, resetValue, name: $"MSCR{index}") 304 .WithTag("SourceSignalSelect", 0, 4) 305 .WithReservedBits(4, 1) 306 .WithTaggedFlag("SafeModeControl", 5) 307 .WithTaggedFlag("InputFilterEnable", 6) 308 .WithReservedBits(7, 1) 309 .WithTaggedFlag("DriveStrengthEnable", 8) 310 .WithReservedBits(9, 2) 311 .WithTaggedFlag("PullSelect", 11) 312 .WithReservedBits(12, 1) 313 .WithTaggedFlag("PullEnable", 13) 314 .WithTaggedFlag("SlewRateControl", 14) 315 .WithReservedBits(15, 1) 316 .WithTaggedFlag("PadKeepingEnable", 16) 317 .WithTaggedFlag("Invert", 17) 318 .WithReservedBits(18, 1) 319 .WithTaggedFlag("InputBufferEnable", 19) 320 .WithReservedBits(20, 1) 321 .WithTaggedFlag("GPIOOutputBufferEnable", 21) 322 .WithReservedBits(22, 10) 323 ; 324 } 325 326 var inputMultiplexedSignalConfigurationRanges = Enumerable.Empty<int>() 327 .ConcatRangeFromTo(0, 5) 328 .ConcatRangeFromTo(16, 71) 329 .ConcatRangeFromTo(80, 103) 330 .ConcatRangeFromTo(112, 135) 331 .ConcatRangeFromTo(144, 149) 332 .ConcatRangeFromTo(152, 202) 333 .ConcatRangeFromTo(211, 268) 334 .ConcatRangeFromTo(289, 309) 335 .ConcatRangeFromTo(315, 325) 336 .ConcatRangeFromTo(343, 370) 337 .ConcatRangeFromTo(373, 378) 338 .ConcatRangeFromTo(389, 389) 339 .ConcatRangeFromTo(398, 399) 340 .ConcatRangeFromTo(409, 418) 341 .ConcatRangeFromTo(440, 440) 342 .ConcatRangeFromTo(448, 469); 343 344 foreach(var index in inputMultiplexedSignalConfigurationRanges) 345 { 346 var offset = Registers.InputMultiplexedSignalConfiguration0 + index * 4; 347 offset.Define(asDoubleWordCollection, name: $"IMCR{index}") 348 .WithTag($"SourceSignalSelect{index}", 0, 4) 349 .WithReservedBits(4, 28) 350 ; 351 } 352 353 IProvidesRegisterCollection<ByteRegisterCollection> asByteCollection = this; 354 355 foreach(var i in validPadIndexes.OrderBy(item => item)) 356 { 357 var index = i; 358 var registerOffset = index + 3 - 2 * (index % 4); 359 var outputOffset = Registers.GPIOPadDataOutput3 + registerOffset; 360 outputOffset.Define(asByteCollection, name: $"GPDO{index}") 361 .WithFlag(0, name: $"PadDataOut{index}", 362 valueProviderCallback: _ => Connections[index].IsSet, 363 changeCallback: (_, value) => Connections[index].Set(value)) 364 .WithReservedBits(1, 7) 365 ; 366 367 var inputOffset = Registers.GPIOPadDataInput3 + registerOffset; 368 inputOffset.Define(asByteCollection, name: $"GPDI{index}") 369 .WithFlag(0, FieldMode.Read, name: $"PadDataInput{index}", 370 valueProviderCallback: _ => State[index]) 371 .WithReservedBits(1, 7) 372 ; 373 } 374 375 // NOTE: As we are managing address translation manually in this peripheral, 376 // we have to carefully calculate bit-offsets for 16-bit registers... 377 var peripheralEndianness = this.GetEndianness(machine.SystemBus.Endianess); 378 Func<int, int, int> getStartPadIndex = (int registerIndex, int byteIndex) => 379 { 380 // Registers are 16-bit wide 381 var startPadIndex = registerIndex * 16; 382 // Bits are in reversed order 383 switch(peripheralEndianness) 384 { 385 case Endianness.LittleEndian: 386 startPadIndex += (1 - byteIndex) * 8; 387 break; 388 case Endianness.BigEndian: 389 startPadIndex += byteIndex * 8; 390 break; 391 } 392 393 return startPadIndex; 394 }; 395 396 // While the register addresses are one after another... 397 for(var registerOffset = 0; registerOffset < PadDataCount; ++registerOffset) 398 { 399 // ...the register indexes are in reversed order pair-wise, so 1, 0, 3, 2, 5, 4, etc. 400 var registerIndex = registerOffset ^ 1; 401 var outputOffset = Registers.ParallelGPIOPadDataOut0 + registerOffset * 2; 402 var inputOffset = Registers.ParallelGPIOPadDataIn0 + registerOffset * 2; 403 404 for(var byteIndex = 0; byteIndex < 2; ++byteIndex) 405 { 406 var startPadIndex = getStartPadIndex(registerIndex, byteIndex); 407 var padRange = Enumerable.Range(startPadIndex, 8).Reverse(); 408 409 (outputOffset + byteIndex).Define(asByteCollection) 410 .WithValueField(0, 8, name: $"ParallelPadDataOutput{registerIndex}.{byteIndex}", 411 valueProviderCallback: _ => BitHelper.GetValueFromBitsArray(padRange.Select(pinIndex => Connections[pinIndex].IsSet)), 412 changeCallback: (previousValue, currentValue) => 413 { 414 var difference = previousValue ^ currentValue; 415 foreach(var padIndex in BitHelper.GetSetBits(difference).Select(index => 7 - index)) 416 { 417 if(validPadIndexes.Contains(startPadIndex + padIndex)) 418 { 419 Connections[startPadIndex + padIndex].Toggle(); 420 } 421 } 422 }) 423 ; 424 425 (inputOffset + byteIndex).Define(asByteCollection) 426 .WithValueField(0, 8, FieldMode.Read, name: $"ParallelPadDataInput{registerIndex}.{byteIndex}", 427 valueProviderCallback: _ => BitHelper.GetValueFromBitsArray(padRange.Select(pinIndex => State[pinIndex]))) 428 ; 429 } 430 } 431 432 // Parallel GPIO Pad Data is implemented as two byte registers, instead of a single word register, to simplify implementation. 433 // Those registers are accessible using all widths same as Pad Data registers (non-parallel). 434 var parallelPadDataReservedFlags = new Dictionary<int, int[]> 435 { 436 {2, new int [] {8, 9}}, 437 {8, new int [] {2}}, 438 {14, new int [] {0, 1, 2}} 439 }; 440 441 Registers.MaskedParallelGPIOPadDataOut0.DefineMany(asDoubleWordCollection, PadDataCount, (register, registerIndex) => 442 { 443 for(var flagIndex = 0; flagIndex < 16; ++flagIndex) 444 { 445 var maskFlagIndex = 16 + flagIndex; 446 if(parallelPadDataReservedFlags.TryGetValue(registerIndex, out var reservedFlagIndexes) 447 && reservedFlagIndexes.Contains(flagIndex)) 448 { 449 register.WithReservedBits(maskFlagIndex, 1); 450 register.WithReservedBits(flagIndex, 1); 451 continue; 452 } 453 register.WithTaggedFlag($"MaskField{flagIndex}", maskFlagIndex); 454 register.WithTaggedFlag($"MaskedParallelPadDataOut{flagIndex}", flagIndex); 455 } 456 }); 457 } 458 459 private readonly HashSet<int> validPadIndexes = 460 new HashSet<int>(Enumerable.Empty<int>() 461 .ConcatRangeFromTo(0, 37) 462 .ConcatRangeFromTo(40, 140) 463 .ConcatRangeFromTo(142, 236)); 464 465 private readonly List<int[]> eirqToPadMapping = new List<int[]> { 466 /* EIRQ00 */ new[] { 0, 18, 64, 128, 160 }, 467 /* EIRQ01 */ new[] { 1, 19, 65, 129, 161 }, 468 /* EIRQ02 */ new[] { 2, 20, 66, 130, 162 }, 469 /* EIRQ03 */ new[] { 3, 21, 67, 131, 163 }, 470 /* EIRQ04 */ new[] { 4, 16, 68, 132, 164 }, 471 /* EIRQ05 */ new[] { 5, 69, 133, 165 }, 472 /* EIRQ06 */ new[] { 6, 28, 70, 134, 166 }, 473 /* EIRQ07 */ new[] { 7, 30, 71, 136, 167 }, 474 /* EIRQ08 */ new[] { 32, 53, 96, 137, 192 }, 475 /* EIRQ09 */ new[] { 33, 54, 97, 138, 193 }, 476 /* EIRQ10 */ new[] { 34, 55, 98, 139, 194 }, 477 /* EIRQ11 */ new[] { 35, 56, 99, 140, 195 }, 478 /* EIRQ12 */ new[] { 36, 57, 100, 196 }, 479 /* EIRQ13 */ new[] { 37, 58, 101, 142, 197 }, 480 /* EIRQ14 */ new[] { 40, 60, 102, 143, 198 }, 481 /* EIRQ15 */ new[] { 41, 63, 103, 144, 199 }, 482 /* EIRQ16 */ new[] { 8, 72, 84, 168, 224 }, 483 /* EIRQ17 */ new[] { 9, 73, 85, 169, 225 }, 484 /* EIRQ18 */ new[] { 10, 74, 87, 170, 226 }, 485 /* EIRQ19 */ new[] { 11, 75, 88, 171, 227 }, 486 /* EIRQ20 */ new[] { 12, 76, 89, 172, 228 }, 487 /* EIRQ21 */ new[] { 13, 77, 90, 173, 229 }, 488 /* EIRQ22 */ new[] { 14, 78, 91, 174, 230 }, 489 /* EIRQ23 */ new[] { 15, 79, 93, 175, 231 }, 490 /* EIRQ24 */ new[] { 42, 104, 113, 200, 232 }, 491 /* EIRQ25 */ new[] { 43, 105, 116, 201, 233 }, 492 /* EIRQ26 */ new[] { 44, 106, 117, 202, 234 }, 493 /* EIRQ27 */ new[] { 45, 107, 118, 203, 235 }, 494 /* EIRQ28 */ new[] { 46, 108, 119, 204, 236 }, 495 /* EIRQ29 */ new[] { 47, 109, 120, 205, 221 }, 496 /* EIRQ30 */ new[] { 48, 110, 123, 206, 222 }, 497 /* EIRQ31 */ new[] { 49, 111, 124, 207, 223 }, 498 }; 499 500 private readonly DoubleWordRegisterCollection doubleWordRegisterCollection; 501 private readonly ByteRegisterCollection byteRegisterCollection; 502 private readonly IFlagRegisterField[] interruptPending; 503 private readonly IFlagRegisterField[] interruptEnabled; 504 505 private const int MaximumValidPadIndex = 236; 506 private const uint ExternalInterruptCount = 32; 507 private const uint MuxCount = 3; 508 private const int PadDataCount = 15; 509 510 private readonly InterruptType[] interruptType; 511 512 [Flags] 513 private enum InterruptType 514 { 515 Disabled, 516 RisingEdge, 517 FallingEdge, 518 } 519 520 private enum Registers 521 { 522 MCUIDRegister1 = 0x4, // MIDR1 523 MCUIDRegister2 = 0x8, // MIDR2 524 DMAInterruptStatusFlag0 = 0x10, // DISR0 525 DMAInterruptRequestEnable0 = 0x18, // DIRER0 526 DMAInterruptRequestSelect0 = 0x20, // DIRSR0 527 InterruptRisingEdgeEventEnable0 = 0x28, // IREER0 528 InterruptFallingEdgeEventEnable0 = 0x30, // IFEER0 529 InterruptFilterEnable0 = 0x38, // IFER0 530 InterruptFilterMaximumCounter0 = 0x40, // IFMCR0 531 InterruptFilterMaximumCounter31 = 0xBC, // IFMCR31 532 InterruptFilterClockPrescaler = 0xC0, // IFCPR 533 MUX0EMIOSEnable1 = 0x100, // MUX0_EMIOS_EN1 534 MUX0MISCEnable = 0x104, // MUX0_MISC_EN 535 MUX1EMIOSEnable = 0x108, // MUX1_EMIOS_EN 536 MUX1MISCEnable = 0x10C, // MUX1_MISC_EN 537 MUX2EMIOSEnable = 0x110, // MUX2_EMIOS_EN 538 MUX2MISCEnable = 0x114, // MUX2_MISC_EN 539 MCUIDRegister3 = 0x200, // MIDR3 540 MCUIDRegister4 = 0x204, // MIDR4 541 MultiplexedSignalConfiguration0 = 0x240, // MSCR0 542 MultiplexedSignalConfiguration236 = 0x5F0, // MSCR236 543 InputMultiplexedSignalConfiguration0 = 0xA40, // IMCR0 544 InputMultiplexedSignalConfiguration469 = 0x1194, // IMCR469 545 GPIOPadDataOutput3 = 0x1300, // GPDO3 546 GPIOPadDataOutput236 = 0x13EF, // GPDO236 547 GPIOPadDataInput3 = 0x1500, // GPDI3 548 GPIOPadDataInput236 = 0x15EF, // GPDI236 549 ParallelGPIOPadDataOut0 = 0x1700, // PGPDO0 550 ParallelGPIOPadDataOut14 = 0x171E, // PGPDO14 551 ParallelGPIOPadDataIn0 = 0x1740, // PGPDI0 552 ParallelGPIOPadDataIn14 = 0x175E, // PGPDI14 553 MaskedParallelGPIOPadDataOut0 = 0x1780, // MPGPDO0 554 MaskedParallelGPIOPadDataOut14 = 0x17B8 // MPGPDO14 555 } 556 } 557 } 558