1 // 2 // Copyright (c) 2010-2025 Antmicro 3 // Copyright (c) 2022-2025 Silicon Labs 4 // 5 // This file is licensed under the MIT License. 6 // Full license text is available in 'licenses/MIT.txt'. 7 // 8 9 using System.Collections.Generic; 10 using System.IO; 11 using System; 12 using Antmicro.Renode.Core; 13 using Antmicro.Renode.Core.Structure.Registers; 14 using Antmicro.Renode.Exceptions; 15 using Antmicro.Renode.Logging; 16 using Antmicro.Renode.Peripherals.Bus; 17 using Antmicro.Renode.Time; 18 using Antmicro.Renode.Peripherals.GPIOPort; 19 20 namespace Antmicro.Renode.Peripherals.GPIOPort 21 { 22 public class EFR32xG2_GPIO_1 : BaseGPIOPort, IDoubleWordPeripheral, IKnownSize 23 { EFR32xG2_GPIO_1(Machine machine)24 public EFR32xG2_GPIO_1(Machine machine) : base(machine, NumberOfPins * NumberOfPorts) 25 { 26 OddIRQ = new GPIO(); 27 EvenIRQ = new GPIO(); 28 29 registersCollection = BuildRegistersCollection(); 30 InnerReset(); 31 } 32 Reset()33 public override void Reset() 34 { 35 lock(internalLock) 36 { 37 base.Reset(); 38 InnerReset(); 39 } 40 } 41 ReadDoubleWord(long offset)42 public uint ReadDoubleWord(long offset) 43 { 44 return ReadRegister(offset); 45 } 46 ReadByte(long offset)47 public byte ReadByte(long offset) 48 { 49 int byteOffset = (int)(offset & 0x3); 50 uint registerValue = ReadRegister(offset, true); 51 byte result = (byte)((registerValue >> byteOffset*8) & 0xFF); 52 return result; 53 } 54 ReadRegister(long offset, bool internal_read = false)55 private uint ReadRegister(long offset, bool internal_read = false) 56 { 57 var result = 0U; 58 long internal_offset = offset; 59 60 lock(internalLock) 61 { 62 // Set, Clear, Toggle registers should only be used for write operations. But just in case we convert here as well. 63 if (offset >= SetRegisterOffset && offset < ClearRegisterOffset) 64 { 65 // Set register 66 internal_offset = offset - SetRegisterOffset; 67 if(!internal_read) 68 { 69 this.Log(LogLevel.Noisy, "SET Operation on {0}, offset=0x{1:X}, internal_offset=0x{2:X}", (Registers)internal_offset, offset, internal_offset); 70 } 71 } else if (offset >= ClearRegisterOffset && offset < ToggleRegisterOffset) 72 { 73 // Clear register 74 internal_offset = offset - ClearRegisterOffset; 75 if(!internal_read) 76 { 77 this.Log(LogLevel.Noisy, "CLEAR Operation on {0}, offset=0x{1:X}, internal_offset=0x{2:X}", (Registers)internal_offset, offset, internal_offset); 78 } 79 } else if (offset >= ToggleRegisterOffset) 80 { 81 // Toggle register 82 internal_offset = offset - ToggleRegisterOffset; 83 if(!internal_read) 84 { 85 this.Log(LogLevel.Noisy, "TOGGLE Operation on {0}, offset=0x{1:X}, internal_offset=0x{2:X}", (Registers)internal_offset, offset, internal_offset); 86 } 87 } 88 89 if(!registersCollection.TryRead(internal_offset, out result)) 90 { 91 if(!internal_read) 92 { 93 this.Log(LogLevel.Noisy, "Unhandled read at offset 0x{0:X} ({1}).", internal_offset, (Registers)internal_offset); 94 } 95 } 96 else 97 { 98 if(!internal_read) 99 { 100 this.Log(LogLevel.Noisy, "Read at offset 0x{0:X} ({1}), returned 0x{2:X}.", internal_offset, (Registers)internal_offset, result); 101 } 102 } 103 104 return result; 105 } 106 } 107 WriteDoubleWord(long offset, uint value)108 public void WriteDoubleWord(long offset, uint value) 109 { 110 // TODO: A subset of registers is lockable: if the lock is on (see LockStatus register), these registers should not be accessible. 111 WriteRegister(offset, value); 112 } 113 WriteRegister(long offset, uint value, bool internal_write = false)114 private void WriteRegister(long offset, uint value, bool internal_write = false) 115 { 116 lock(internalLock) 117 { 118 long internal_offset = offset; 119 uint internal_value = value; 120 121 if (offset >= SetRegisterOffset && offset < ClearRegisterOffset) 122 { 123 // Set register 124 internal_offset = offset - SetRegisterOffset; 125 uint old_value = ReadRegister(internal_offset, true); 126 internal_value = old_value | value; 127 this.Log(LogLevel.Noisy, "SET Operation on {0}, offset=0x{1:X}, internal_offset=0x{2:X}, SET_value=0x{3:X}, old_value=0x{4:X}, new_value=0x{5:X}", (Registers)internal_offset, offset, internal_offset, value, old_value, internal_value); 128 } else if (offset >= ClearRegisterOffset && offset < ToggleRegisterOffset) 129 { 130 // Clear register 131 internal_offset = offset - ClearRegisterOffset; 132 uint old_value = ReadRegister(internal_offset, true); 133 internal_value = old_value & ~value; 134 this.Log(LogLevel.Noisy, "CLEAR Operation on {0}, offset=0x{1:X}, internal_offset=0x{2:X}, CLEAR_value=0x{3:X}, old_value=0x{4:X}, new_value=0x{5:X}", (Registers)internal_offset, offset, internal_offset, value, old_value, internal_value); 135 } else if (offset >= ToggleRegisterOffset) 136 { 137 // Toggle register 138 internal_offset = offset - ToggleRegisterOffset; 139 uint old_value = ReadRegister(internal_offset, true); 140 internal_value = old_value ^ value; 141 this.Log(LogLevel.Noisy, "TOGGLE Operation on {0}, offset=0x{1:X}, internal_offset=0x{2:X}, TOGGLE_value=0x{3:X}, old_value=0x{4:X}, new_value=0x{5:X}", (Registers)internal_offset, offset, internal_offset, value, old_value, internal_value); 142 } 143 144 this.Log(LogLevel.Noisy, "Write at offset 0x{0:X} ({1}), value 0x{2:X}.", internal_offset, (Registers)internal_offset, internal_value); 145 146 if(!registersCollection.TryWrite(internal_offset, internal_value)) 147 { 148 this.Log(LogLevel.Noisy, "Unhandled write at offset 0x{0:X} ({1}), value 0x{2:X}.", internal_offset, (Registers)internal_offset, internal_value); 149 return; 150 } 151 } 152 } 153 BuildRegistersCollection()154 private DoubleWordRegisterCollection BuildRegistersCollection() 155 { 156 var registerDictionary = new Dictionary<long, DoubleWordRegister> 157 { 158 {(long)Registers.ExternalInterruptPortSelectLow, new DoubleWordRegister(this) 159 .WithEnumField<DoubleWordRegister, Port>(0, 2, out externalInterruptPortSelect[0], name: "EXTIPSEL0") 160 .WithReservedBits(2, 2) 161 .WithEnumField<DoubleWordRegister, Port>(4, 2, out externalInterruptPortSelect[1], name: "EXTIPSEL1") 162 .WithReservedBits(6, 2) 163 .WithEnumField<DoubleWordRegister, Port>(8, 2, out externalInterruptPortSelect[2], name: "EXTIPSEL2") 164 .WithReservedBits(10, 2) 165 .WithEnumField<DoubleWordRegister, Port>(12, 2, out externalInterruptPortSelect[3], name: "EXTIPSEL3") 166 .WithReservedBits(14, 2) 167 .WithEnumField<DoubleWordRegister, Port>(16, 2, out externalInterruptPortSelect[4], name: "EXTIPSEL4") 168 .WithReservedBits(18, 2) 169 .WithEnumField<DoubleWordRegister, Port>(20, 2, out externalInterruptPortSelect[5], name: "EXTIPSEL5") 170 .WithReservedBits(22, 2) 171 .WithEnumField<DoubleWordRegister, Port>(24, 2, out externalInterruptPortSelect[6], name: "EXTIPSEL6") 172 .WithReservedBits(26, 2) 173 .WithEnumField<DoubleWordRegister, Port>(28, 2, out externalInterruptPortSelect[7], name: "EXTIPSEL7") 174 .WithReservedBits(30, 2) 175 .WithChangeCallback((_, __) => UpdateRouting()) 176 }, 177 {(long)Registers.ExternalInterruptPortSelectHigh, new DoubleWordRegister(this) 178 .WithEnumField<DoubleWordRegister, Port>(0, 2, out externalInterruptPortSelect[8], name: "EXTIPSEL8") 179 .WithReservedBits(2, 2) 180 .WithEnumField<DoubleWordRegister, Port>(4, 2, out externalInterruptPortSelect[9], name: "EXTIPSEL9") 181 .WithReservedBits(6, 2) 182 .WithEnumField<DoubleWordRegister, Port>(8, 2, out externalInterruptPortSelect[10], name: "EXTIPSEL10") 183 .WithReservedBits(10, 2) 184 .WithEnumField<DoubleWordRegister, Port>(12, 2, out externalInterruptPortSelect[11], name: "EXTIPSEL11") 185 .WithReservedBits(14, 18) 186 .WithChangeCallback((_, __) => UpdateRouting()) 187 }, 188 {(long)Registers.ExternalInterruptPinSelectLow, new DoubleWordRegister(this) 189 .WithValueField(0, 2, out externalInterruptPinSelect[0], name: "EXTIPINSEL0") 190 .WithReservedBits(2, 2) 191 .WithValueField(4, 2, out externalInterruptPinSelect[1], name: "EXTIPINSEL1") 192 .WithReservedBits(6, 2) 193 .WithValueField(8, 2, out externalInterruptPinSelect[2], name: "EXTIPINSEL2") 194 .WithReservedBits(10, 2) 195 .WithValueField(12, 2, out externalInterruptPinSelect[3], name: "EXTIPINSEL3") 196 .WithReservedBits(14, 2) 197 .WithValueField(16, 2, out externalInterruptPinSelect[4], name: "EXTIPINSEL4") 198 .WithReservedBits(18, 2) 199 .WithValueField(20, 2, out externalInterruptPinSelect[5], name: "EXTIPINSEL5") 200 .WithReservedBits(22, 2) 201 .WithValueField(24, 2, out externalInterruptPinSelect[6], name: "EXTIPINSEL6") 202 .WithReservedBits(26, 2) 203 .WithValueField(28, 2, out externalInterruptPinSelect[7], name: "EXTIPINSEL7") 204 .WithReservedBits(30, 2) 205 .WithChangeCallback((_, __) => UpdateRouting()) 206 }, 207 {(long)Registers.ExternalInterruptPinSelectHigh, new DoubleWordRegister(this) 208 .WithValueField(0, 2, out externalInterruptPinSelect[8], name: "EXTIPINSEL8") 209 .WithReservedBits(2, 2) 210 .WithValueField(4, 2, out externalInterruptPinSelect[9], name: "EXTIPINSEL9") 211 .WithReservedBits(6, 2) 212 .WithValueField(8, 2, out externalInterruptPinSelect[10], name: "EXTIPINSEL10") 213 .WithReservedBits(10, 2) 214 .WithValueField(12, 2, out externalInterruptPinSelect[11], name: "EXTIPINSEL11") 215 .WithReservedBits(14, 18) 216 .WithChangeCallback((_, __) => UpdateRouting()) 217 }, 218 {(long)Registers.ExternalInterruptRisingEdgeTrigger, new DoubleWordRegister(this) 219 .WithFlags(0, 12, 220 writeCallback: (i, _, value) => 221 { 222 if (value) 223 { 224 interruptTrigger[i] |= (uint)InterruptTrigger.RisingEdge; 225 } 226 else 227 { 228 interruptTrigger[i] ^= (uint)InterruptTrigger.RisingEdge; 229 } 230 }, 231 valueProviderCallback: (i, _) => ((interruptTrigger[i] & (uint)InterruptTrigger.RisingEdge) > 0), 232 name: "EXTIRISE") 233 .WithReservedBits(12, 20) 234 }, 235 {(long)Registers.ExternalInterruptFallingEdgeTrigger, new DoubleWordRegister(this) 236 .WithFlags(0, 12, 237 writeCallback: (i, _, value) => 238 { 239 if (value) 240 { 241 interruptTrigger[i] |= (uint)InterruptTrigger.FallingEdge; 242 } 243 else 244 { 245 interruptTrigger[i] ^= (uint)InterruptTrigger.FallingEdge; 246 } 247 }, 248 valueProviderCallback: (i, _) => ((interruptTrigger[i] & (uint)InterruptTrigger.FallingEdge) > 0), 249 name: "EXTIFALL") 250 .WithReservedBits(12, 20) 251 }, 252 {(long)Registers.InterruptFlag, new DoubleWordRegister(this) 253 .WithFlag(0, out externalInterrupt[0], name: "EXTIF0") 254 .WithFlag(1, out externalInterrupt[1], name: "EXTIF1") 255 .WithFlag(2, out externalInterrupt[2], name: "EXTIF2") 256 .WithFlag(3, out externalInterrupt[3], name: "EXTIF3") 257 .WithFlag(4, out externalInterrupt[4], name: "EXTIF4") 258 .WithFlag(5, out externalInterrupt[5], name: "EXTIF5") 259 .WithFlag(6, out externalInterrupt[6], name: "EXTIF6") 260 .WithFlag(7, out externalInterrupt[7], name: "EXTIF7") 261 .WithFlag(8, out externalInterrupt[8], name: "EXTIF8") 262 .WithFlag(9, out externalInterrupt[9], name: "EXTIF9") 263 .WithFlag(10, out externalInterrupt[10], name: "EXTIF10") 264 .WithFlag(11, out externalInterrupt[11], name: "EXTIF11") 265 .WithReservedBits(12, 4) 266 .WithTaggedFlag("EM4WUIF0", 16) 267 .WithTaggedFlag("EM4WUIF1", 17) 268 .WithTaggedFlag("EM4WUIF2", 18) 269 .WithTaggedFlag("EM4WUIF3", 19) 270 .WithTaggedFlag("EM4WUIF4", 20) 271 .WithTaggedFlag("EM4WUIF5", 21) 272 .WithTaggedFlag("EM4WUIF6", 22) 273 .WithTaggedFlag("EM4WUIF7", 23) 274 .WithTaggedFlag("EM4WUIF8", 24) 275 .WithTaggedFlag("EM4WUIF9", 25) 276 .WithTaggedFlag("EM4WUIF10", 26) 277 .WithTaggedFlag("EM4WUIF11", 27) 278 .WithReservedBits(28, 4) 279 .WithWriteCallback((_, __) => UpdateInterrupts()) 280 }, 281 {(long)Registers.InterruptEnable, new DoubleWordRegister(this) 282 .WithFlag(0, out externalInterruptEnable[0], name: "EXTIEN0") 283 .WithFlag(1, out externalInterruptEnable[1], name: "EXTIEN1") 284 .WithFlag(2, out externalInterruptEnable[2], name: "EXTIEN2") 285 .WithFlag(3, out externalInterruptEnable[3], name: "EXTIEN3") 286 .WithFlag(4, out externalInterruptEnable[4], name: "EXTIEN4") 287 .WithFlag(5, out externalInterruptEnable[5], name: "EXTIEN5") 288 .WithFlag(6, out externalInterruptEnable[6], name: "EXTIEN6") 289 .WithFlag(7, out externalInterruptEnable[7], name: "EXTIEN7") 290 .WithFlag(8, out externalInterruptEnable[8], name: "EXTIEN8") 291 .WithFlag(9, out externalInterruptEnable[9], name: "EXTIEN9") 292 .WithFlag(10, out externalInterruptEnable[10], name: "EXTIEN10") 293 .WithFlag(11, out externalInterruptEnable[11], name: "EXTIEN11") 294 .WithReservedBits(12, 4) 295 .WithTaggedFlag("EM4WUIEN0", 16) 296 .WithTaggedFlag("EM4WUIEN1", 17) 297 .WithTaggedFlag("EM4WUIEN2", 18) 298 .WithTaggedFlag("EM4WUIEN3", 19) 299 .WithTaggedFlag("EM4WUIEN4", 20) 300 .WithTaggedFlag("EM4WUIEN5", 21) 301 .WithTaggedFlag("EM4WUIEN6", 22) 302 .WithTaggedFlag("EM4WUIEN7", 23) 303 .WithTaggedFlag("EM4WUIEN8", 24) 304 .WithTaggedFlag("EM4WUIEN9", 25) 305 .WithTaggedFlag("EM4WUIEN10", 26) 306 .WithTaggedFlag("EM4WUIEN11", 27) 307 .WithReservedBits(28, 4) 308 .WithWriteCallback((_, __) => UpdateInterrupts()) 309 }, 310 {(long)Registers.Lock, new DoubleWordRegister(this) 311 .WithValueField(0, 16, writeCallback: (_, value) => configurationLocked = (value != UnlockCode), name: "LOCKKEY") 312 .WithReservedBits(16, 16) 313 }, 314 {(long)Registers.LockStatus, new DoubleWordRegister(this) 315 .WithFlag(0, FieldMode.Read, valueProviderCallback: _ => configurationLocked, name: "LOCK") 316 .WithReservedBits(1, 31) 317 }, 318 {(long)Registers.USART0_RouteEnable, new DoubleWordRegister(this) 319 .WithFlag(0, out USART0_RouteEnable_CsPin, name: "CSPEN") 320 .WithFlag(1, out USART0_RouteEnable_RtsPin, name: "RTSPEN") 321 .WithFlag(2, out USART0_RouteEnable_RxPin, name: "RXPEN") 322 .WithFlag(3, out USART0_RouteEnable_SclkPin, name: "SCLKPEN") 323 .WithFlag(4, out USART0_RouteEnable_TxPin, name: "TXPEN") 324 }, 325 {(long)Registers.USART0_RX_Route, new DoubleWordRegister(this) 326 .WithEnumField<DoubleWordRegister, Port>(0, 2, out USART0_RxRoutePort, name: "PORT") 327 .WithReservedBits(2, 14) 328 .WithValueField(16, 4, out USART0_RxRoutePin, name: "PIN") 329 .WithReservedBits(20, 12) 330 }, 331 {(long)Registers.USART0_TX_Route, new DoubleWordRegister(this) 332 .WithEnumField<DoubleWordRegister, Port>(0, 2, out USART0_TxRoutePort, name: "PORT") 333 .WithReservedBits(2, 14) 334 .WithValueField(16, 4, out USART0_TxRoutePin, name: "PIN") 335 .WithReservedBits(20, 12) 336 }, 337 {(long)Registers.USART1_RouteEnable, new DoubleWordRegister(this) 338 .WithFlag(0, out USART1_RouteEnable_CsPin, name: "CSPEN") 339 .WithFlag(1, out USART1_RouteEnable_RtsPin, name: "RTSPEN") 340 .WithFlag(2, out USART1_RouteEnable_RxPin, name: "RXPEN") 341 .WithFlag(3, out USART1_RouteEnable_SclkPin, name: "SCLKPEN") 342 .WithFlag(4, out USART1_RouteEnable_TxPin, name: "TXPEN") 343 }, 344 {(long)Registers.USART1_RX_Route, new DoubleWordRegister(this) 345 .WithEnumField<DoubleWordRegister, Port>(0, 2, out USART1_RxRoutePort, name: "PORT") 346 .WithReservedBits(2, 14) 347 .WithValueField(16, 4, out USART1_RxRoutePin, name: "PIN") 348 .WithReservedBits(20, 12) 349 }, 350 {(long)Registers.USART1_TX_Route, new DoubleWordRegister(this) 351 .WithEnumField<DoubleWordRegister, Port>(0, 2, out USART1_TxRoutePort, name: "PORT") 352 .WithReservedBits(2, 14) 353 .WithValueField(16, 4, out USART1_TxRoutePin, name: "PIN") 354 .WithReservedBits(20, 12) 355 }, 356 }; 357 358 for(var i = 0; i < NumberOfPorts; ++i) 359 { 360 BuildPortRegisters(registerDictionary, i); 361 } 362 363 return new DoubleWordRegisterCollection(this, registerDictionary); 364 } 365 BuildPortRegisters(Dictionary<long, DoubleWordRegister> regs, int portNumber)366 private void BuildPortRegisters(Dictionary<long, DoubleWordRegister> regs, int portNumber) 367 { 368 var regOffset = PortOffset * portNumber; 369 var pinOffset = portNumber * NumberOfPins; 370 371 regs.Add((long)Registers.PortAControl + regOffset, new DoubleWordRegister(this) 372 .WithReservedBits(0, 4) 373 .WithTag("SLEWRATE", 4, 3) 374 .WithReservedBits(7, 5) 375 .WithTaggedFlag("DINDIS", 12) 376 .WithReservedBits(13, 7) 377 .WithTag("SLEWRATEALT", 20, 3) 378 .WithReservedBits(23, 5) 379 .WithTaggedFlag("DINDISALT", 28) 380 .WithReservedBits(29, 3) 381 ); 382 regs.Add((long)Registers.PortAModeLow + regOffset, new DoubleWordRegister(this) 383 .WithEnumField<DoubleWordRegister, PinMode>(0, 4, out pinMode[pinOffset], name: "MODE0") 384 .WithEnumField<DoubleWordRegister, PinMode>(4, 4, out pinMode[pinOffset + 1], name: "MODE1") 385 .WithEnumField<DoubleWordRegister, PinMode>(8, 4, out pinMode[pinOffset + 2], name: "MODE2") 386 .WithEnumField<DoubleWordRegister, PinMode>(12, 4, out pinMode[pinOffset + 3], name: "MODE3") 387 .WithEnumField<DoubleWordRegister, PinMode>(16, 4, out pinMode[pinOffset + 4], name: "MODE4") 388 .WithEnumField<DoubleWordRegister, PinMode>(20, 4, out pinMode[pinOffset + 5], name: "MODE5") 389 .WithEnumField<DoubleWordRegister, PinMode>(24, 4, out pinMode[pinOffset + 6], name: "MODE6") 390 .WithEnumField<DoubleWordRegister, PinMode>(28, 4, out pinMode[pinOffset + 7], name: "MODE7") 391 ); 392 regs.Add((long)Registers.PortAModeHigh + regOffset, new DoubleWordRegister(this) 393 .WithEnumField<DoubleWordRegister, PinMode>(0, 4, out pinMode[pinOffset + 8], name: "MODE8") 394 .WithEnumField<DoubleWordRegister, PinMode>(4, 4, out pinMode[pinOffset + 9], name: "MODE9") 395 .WithEnumField<DoubleWordRegister, PinMode>(8, 4, out pinMode[pinOffset + 10], name: "MODE10") 396 .WithEnumField<DoubleWordRegister, PinMode>(12, 4, out pinMode[pinOffset + 11], name: "MODE11") 397 .WithEnumField<DoubleWordRegister, PinMode>(16, 4, out pinMode[pinOffset + 12], name: "MODE12") 398 .WithEnumField<DoubleWordRegister, PinMode>(20, 4, out pinMode[pinOffset + 13], name: "MODE13") 399 .WithEnumField<DoubleWordRegister, PinMode>(24, 4, out pinMode[pinOffset + 14], name: "MODE14") 400 .WithEnumField<DoubleWordRegister, PinMode>(28, 4, out pinMode[pinOffset + 15], name: "MODE15") 401 ); 402 regs.Add((long)Registers.PortADataOut + regOffset, new DoubleWordRegister(this) 403 .WithFlags(0, 8, 404 writeCallback: (i, _, value) => 405 { 406 var pin = pinOffset + i; 407 if (IsOutput(pinMode[pin].Value)) 408 { 409 Connections[pin].Set(value); 410 } 411 }, 412 valueProviderCallback: (i, _) => 413 { 414 var pin = pinOffset + i; 415 return Connections[pin].IsSet; 416 }, 417 name: "DOUT") 418 .WithReservedBits(8, 24) 419 ); 420 regs.Add((long)Registers.PortADataIn + regOffset, new DoubleWordRegister(this) 421 .WithFlags(0, 8, FieldMode.Read, 422 valueProviderCallback: (i, _) => 423 { 424 var pin = pinOffset + i; 425 return State[pin]; 426 }, 427 name: "DIN") 428 .WithReservedBits(8, 24) 429 ); 430 } 431 432 public long Size => 0x4000; 433 public GPIO OddIRQ { get; } 434 public GPIO EvenIRQ { get; } 435 private readonly DoubleWordRegisterCollection registersCollection; 436 private readonly object internalLock = new object(); 437 private const uint SetRegisterOffset = 0x1000; 438 private const uint ClearRegisterOffset = 0x2000; 439 private const uint ToggleRegisterOffset = 0x3000; 440 private const int NumberOfPorts = 4; 441 private const int NumberOfPins = 16; 442 private const int NumberOfExternalInterrupts = 12; 443 private const int UnlockCode = 0xA534; 444 private const int PortOffset = 0x30; 445 #region register fields 446 private readonly IEnumRegisterField<Port>[] externalInterruptPortSelect = new IEnumRegisterField<Port>[NumberOfExternalInterrupts]; 447 private readonly IValueRegisterField[] externalInterruptPinSelect = new IValueRegisterField[NumberOfExternalInterrupts]; 448 private readonly IEnumRegisterField<PinMode>[] pinMode = new IEnumRegisterField<PinMode>[NumberOfPins * NumberOfPorts]; 449 private readonly IFlagRegisterField[] externalInterrupt = new IFlagRegisterField[NumberOfExternalInterrupts]; 450 private readonly IFlagRegisterField[] externalInterruptEnable = new IFlagRegisterField[NumberOfExternalInterrupts]; 451 private readonly uint[] interruptTrigger = new uint[NumberOfExternalInterrupts]; 452 private readonly bool[] previousState = new bool[NumberOfExternalInterrupts]; 453 private readonly uint[] targetExternalPins = new uint[NumberOfPins * NumberOfPorts]; 454 private bool configurationLocked; 455 // USART0 456 private IFlagRegisterField USART0_RouteEnable_TxPin; 457 private IFlagRegisterField USART0_RouteEnable_SclkPin; 458 private IFlagRegisterField USART0_RouteEnable_RxPin; 459 private IFlagRegisterField USART0_RouteEnable_RtsPin; 460 private IFlagRegisterField USART0_RouteEnable_CsPin; 461 private IEnumRegisterField<Port> USART0_RxRoutePort; 462 private IValueRegisterField USART0_RxRoutePin; 463 private IEnumRegisterField<Port> USART0_TxRoutePort; 464 private IValueRegisterField USART0_TxRoutePin; 465 // USART1 466 private IFlagRegisterField USART1_RouteEnable_TxPin; 467 private IFlagRegisterField USART1_RouteEnable_SclkPin; 468 private IFlagRegisterField USART1_RouteEnable_RxPin; 469 private IFlagRegisterField USART1_RouteEnable_RtsPin; 470 private IFlagRegisterField USART1_RouteEnable_CsPin; 471 private IEnumRegisterField<Port> USART1_RxRoutePort; 472 private IValueRegisterField USART1_RxRoutePin; 473 private IEnumRegisterField<Port> USART1_TxRoutePort; 474 private IValueRegisterField USART1_TxRoutePin; 475 #endregion 476 477 #region methods InnerReset()478 public void InnerReset() 479 { 480 registersCollection.Reset(); 481 configurationLocked = false; 482 EvenIRQ.Unset(); 483 OddIRQ.Unset(); 484 for(var i = 0; i < NumberOfExternalInterrupts; i++) 485 { 486 interruptTrigger[i] = (uint)InterruptTrigger.None; 487 previousState[i] = false; 488 } 489 for(var i = 0; i < NumberOfPins * NumberOfPorts; i++) 490 { 491 targetExternalPins[i] = 0; 492 } 493 } 494 OnGPIO(int number, bool value)495 public override void OnGPIO(int number, bool value) 496 { 497 bool internalSignal = ((number & 0x1000) > 0); 498 499 // Override the GPIO number if this is an internal signal. 500 if (internalSignal) 501 { 502 SignalSource signalSource = (SignalSource)(number & 0xFF); 503 SignalType signalType = (SignalType)((number & 0xF00) >> 8); 504 505 number = GetPinNumberFromInternalSignal(signalSource, signalType); 506 507 if (number < 0) 508 { 509 this.Log(LogLevel.Warning, "Pin number not found for internal signal (source={0} signal={1})", signalSource, signalType); 510 return; 511 } 512 } 513 514 if(number < 0 || number >= State.Length) 515 { 516 this.Log(LogLevel.Error, string.Format("Gpio #{0} called, but only {1} lines are available", number, State.Length)); 517 return; 518 } 519 520 lock(internalLock) 521 { 522 if(IsOutput(pinMode[number].Value)) 523 { 524 this.Log(LogLevel.Warning, "Writing to an output GPIO pin #{0}", number); 525 return; 526 } 527 528 base.OnGPIO(number, value); 529 UpdateInterrupts(); 530 } 531 } 532 GetPinNumberFromInternalSignal(SignalSource signalSource, SignalType signalType)533 int GetPinNumberFromInternalSignal(SignalSource signalSource, SignalType signalType) 534 { 535 int pinNumber = -1; 536 537 switch(signalSource) 538 { 539 case SignalSource.USART0: 540 { 541 switch(signalType) 542 { 543 case SignalType.USART0_RX: 544 { 545 if (USART0_RouteEnable_RxPin.Value) 546 { 547 pinNumber = GetPinNumber(USART0_RxRoutePort.Value, (uint)USART0_RxRoutePin.Value); 548 } 549 break; 550 } 551 default: 552 this.Log(LogLevel.Error, string.Format("GPIO Signal type {0} for USART0 not supported", signalType)); 553 return pinNumber; 554 } 555 break; 556 } 557 case SignalSource.USART1: 558 { 559 switch(signalType) 560 { 561 case SignalType.USART1_RX: 562 { 563 if (USART1_RouteEnable_RxPin.Value) 564 { 565 pinNumber = GetPinNumber(USART1_RxRoutePort.Value, (uint)USART1_RxRoutePin.Value); 566 } 567 break; 568 } 569 default: 570 this.Log(LogLevel.Error, string.Format("GPIO Signal type {0} for USART0 not supported", signalType)); 571 return pinNumber; 572 } 573 break; 574 } 575 default: 576 this.Log(LogLevel.Error, string.Format("GPIO Signal source {0} not supported", signalSource)); 577 return pinNumber; 578 } 579 580 return pinNumber; 581 } 582 UpdateInterrupts()583 private void UpdateInterrupts() 584 { 585 machine.ClockSource.ExecuteInLock(delegate { 586 for(var i = 0; i < NumberOfPorts*NumberOfPins; ++i) 587 { 588 var externalInterruptIndex = targetExternalPins[i]; 589 590 if (!externalInterruptEnable[externalInterruptIndex].Value) 591 { 592 continue; 593 } 594 595 var isEdge = (State[i] != previousState[externalInterruptIndex]); 596 previousState[externalInterruptIndex] = State[i]; 597 598 if(isEdge 599 && ((State[i] && ((interruptTrigger[externalInterruptIndex] & (uint)InterruptTrigger.RisingEdge) > 0)) 600 || (!State[i] && ((interruptTrigger[externalInterruptIndex] & (uint)InterruptTrigger.FallingEdge) > 0)))) 601 { 602 externalInterrupt[externalInterruptIndex].Value = true; 603 } 604 } 605 606 // Set even and/or odd interrupt as needed 607 var even = false; 608 var odd = false; 609 for(var i = 0; i < NumberOfExternalInterrupts; i += 2) 610 { 611 even |= externalInterrupt[i].Value; 612 } 613 for(var i = 1; i < NumberOfExternalInterrupts; i += 2) 614 { 615 odd |= externalInterrupt[i].Value; 616 } 617 OddIRQ.Set(odd); 618 EvenIRQ.Set(even); 619 }); 620 } 621 UpdateRouting()622 private void UpdateRouting() 623 { 624 for(uint i=0; i<NumberOfPins * NumberOfPorts; i++) 625 { 626 targetExternalPins[i] = 0; 627 } 628 629 for(uint i=0; i<NumberOfExternalInterrupts; i++) 630 { 631 Port port = externalInterruptPortSelect[i].Value; 632 uint pin = (uint)externalInterruptPinSelect[i].Value; 633 634 uint pinGroup = i / 4; 635 uint pinNumber = ((uint)port * NumberOfPins) + (pinGroup * 4) + pin; 636 637 targetExternalPins[pinNumber] = i; 638 } 639 640 UpdateInterrupts(); 641 } 642 GetPinNumber(Port port, uint pinSelect)643 private int GetPinNumber(Port port, uint pinSelect) 644 { 645 return (int)(((uint)port)*NumberOfPins + pinSelect); 646 } 647 IsOutput(PinMode mode)648 private bool IsOutput(PinMode mode) 649 { 650 return mode >= PinMode.PushPull; 651 } 652 TrySyncTime()653 private bool TrySyncTime() 654 { 655 if(machine.SystemBus.TryGetCurrentCPU(out var cpu)) 656 { 657 cpu.SyncTime(); 658 return true; 659 } 660 return false; 661 } 662 GetTime()663 private TimeInterval GetTime() => machine.LocalTimeSource.ElapsedVirtualTime; 664 #endregion 665 666 #region enums 667 private enum Port 668 { 669 PortA = 0, 670 PortB = 1, 671 PortC = 2, 672 PortD = 3, 673 } 674 675 private enum PinMode 676 { 677 Disabled = 0, 678 Input = 1, 679 InputPull = 2, 680 InputPullFilter = 3, 681 PushPull = 4, 682 PushPullAlt = 5, 683 WiredOr = 6, 684 WiredOrPullDown = 7, 685 WiredAnd = 8, 686 WiredAndFilter = 9, 687 WiredAndPullUp = 10, 688 WiredAndPullUpFilter = 11, 689 WiredAndAlt = 12, 690 WiredAndAltFilter = 13, 691 WiredAndAltPullUp = 14, 692 WiredAndAltPullUpFilter = 15, 693 } 694 695 private enum InterruptTrigger 696 { 697 None = 0x0, 698 FallingEdge = 0x1, 699 RisingEdge = 0x2, 700 } 701 702 private enum SignalSource 703 { 704 None = 0, 705 USART0 = 1, 706 USART1 = 2, 707 } 708 709 private enum SignalType 710 { 711 // If SignalSource is USART0 712 USART0_CTS = 0, 713 USART0_RTS = 1, 714 USART0_RX = 2, 715 USART0_SCLK = 3, 716 USART0_TX = 4, 717 // If SignalSource is USART1 718 USART1_CTS = 0, 719 USART1_RTS = 1, 720 USART1_RX = 2, 721 USART1_SCLK = 3, 722 USART1_TX = 4, 723 } 724 725 private enum Registers 726 { 727 PortAControl = 0x0000, 728 PortAModeLow = 0x0004, 729 PortAModeHigh = 0x000C, 730 PortADataOut = 0x0010, 731 PortADataIn = 0x0014, 732 PortBControl = 0x0030, 733 PortBModeLow = 0x0034, 734 PortBModeHigh = 0x004C, 735 PortBDataOut = 0x0040, 736 PortBDataIn = 0x0044, 737 PortCControl = 0x0060, 738 PortCModeLow = 0x0064, 739 PortCModeHigh = 0x006C, 740 PortCDataOut = 0x0070, 741 PortCDataIn = 0x0074, 742 PortDControl = 0x0090, 743 PortDModeLow = 0x0094, 744 PortDModeHigh = 0x009C, 745 PortDDataOut = 0x00A0, 746 PortDDataIn = 0x00A4, 747 Lock = 0x0300, 748 LockStatus = 0x0310, 749 ABusAllocation = 0x0320, 750 BBusAllocation = 0x0324, 751 CDBusAllocation = 0x0328, 752 ExternalInterruptPortSelectLow = 0x0400, 753 ExternalInterruptPortSelectHigh = 0x0404, 754 ExternalInterruptPinSelectLow = 0x0408, 755 ExternalInterruptPinSelectHigh = 0x040C, 756 ExternalInterruptRisingEdgeTrigger = 0x0410, 757 ExternalInterruptFallingEdgeTrigger = 0x0414, 758 InterruptFlag = 0x0420, 759 InterruptEnable = 0x0424, 760 EM4WakeUpEnable = 0x042C, 761 EM4WakeUpPolarity = 0x0430, 762 DebugRoutePinEn = 0x0440, 763 TraceRoutePinEn = 0x0444, 764 CMU_RouteEnable = 0x0450, 765 CMU_CLKIN0_Route = 0x0454, 766 CMU_CLKOUT0_Route = 0x0458, 767 CMU_CLKOUT1_Route = 0x045C, 768 CMU_CLKOUT2_Route = 0x0460, 769 DCDC_RouteEnable = 0x046C, 770 FRC_RouteEnable = 0x047C, 771 FRC_DCLK_Route = 0x0480, 772 FRC_DFRAME_Route = 0x0484, 773 FRC_DOUT_Route = 0x0488, 774 I2C0_RouteEnable = 0x0490, 775 I2C0_SCL_Route = 0x0494, 776 I2C0_SDA_Route = 0x0498, 777 I2C1_RouteEnable = 0x04A0, 778 I2C1_SCL_Route = 0x04A4, 779 I2C1_SDA_Route = 0x04A8, 780 LETIMER_RouteEnable = 0x04B0, 781 LETIMER_OUT0_Route = 0x04B4, 782 LETIMER_OUT1_Route = 0x04B8, 783 ESART0_RouteEnable = 0x04C0, 784 ESART0_CS_Route = 0x04C4, 785 ESART0_CTS_Route = 0x04C8, 786 ESART0_RTS_Route = 0x04CC, 787 ESART0_RX_Route = 0x04D0, 788 MODEM_RouteEnable = 0x04D8, 789 MODEM_ANT0_Route = 0x04DC, 790 MODEM_ANT1_Route = 0x04E0, 791 MODEM_ANTROLLOVER_Route = 0x04E4, 792 MODEM_ANTRR0_Route = 0x04E8, 793 MODEM_ANTRR1_Route = 0x04EC, 794 MODEM_ANTRR2_Route = 0x04F0, 795 MODEM_ANTRR3_Route = 0x04F4, 796 MODEM_ANTRR4_Route = 0x04F8, 797 MODEM_ANTRR5_Route = 0x04FC, 798 MODEM_ANTSWEN_Route = 0x0500, 799 MODEM_ANTSWUS_Route = 0x0504, 800 MODEM_ANTTRIG_Route = 0x0508, 801 MODEM_ANTTRIGSTOP_Route = 0x050C, 802 MODEM_DCLK_Route = 0x0510, 803 MODEM_DIN_Route = 0x0514, 804 MODEM_DOUT_Route = 0x0518, 805 PDM_RouteEnable = 0x0520, 806 PDM_CLK_Route = 0x0524, 807 PDM_DAT0_Route = 0x0528, 808 PDM_DAT1_Route = 0x052C, 809 PRS0_RouteEnable = 0x0534, 810 PRS0_ASYNCH0_Route = 0x0538, 811 PRS0_ASYNCH1_Route = 0x053C, 812 PRS0_ASYNCH2_Route = 0x0540, 813 PRS0_ASYNCH3_Route = 0x0544, 814 PRS0_ASYNCH4_Route = 0x0548, 815 PRS0_ASYNCH5_Route = 0x054C, 816 PRS0_ASYNCH6_Route = 0x0550, 817 PRS0_ASYNCH7_Route = 0x0554, 818 PRS0_ASYNCH8_Route = 0x0558, 819 PRS0_ASYNCH9_Route = 0x055C, 820 PRS0_ASYNCH10_Route = 0x0560, 821 PRS0_ASYNCH11_Route = 0x0564, 822 PRS0_SYNCH0_Route = 0x0568, 823 PRS0_SYNCH1_Route = 0x056C, 824 PRS0_SYNCH2_Route = 0x0570, 825 PRS0_SYNCH3_Route = 0x0574, 826 TIMER0_RouteEnable = 0x057C, 827 TIMER0_CC0_Route = 0x0580, 828 TIMER0_CC1_Route = 0x0584, 829 TIMER0_CC2_Route = 0x0588, 830 TIMER0_CDTI0_Route = 0x058C, 831 TIMER0_CDTI1_Route = 0x0590, 832 TIMER0_CDTI2_Route = 0x0594, 833 TIMER1_RouteEnable = 0x059C, 834 TIMER1_CC0_Route = 0x05A0, 835 TIMER1_CC1_Route = 0x05A4, 836 TIMER1_CC2_Route = 0x05A8, 837 TIMER1_CDTI0_Route = 0x05AC, 838 TIMER1_CDTI1_Route = 0x05B0, 839 TIMER1_CDTI2_Route = 0x05B4, 840 TIMER2_RouteEnable = 0x05BC, 841 TIMER2_CC0_Route = 0x05C0, 842 TIMER2_CC1_Route = 0x05C4, 843 TIMER2_CC2_Route = 0x05C8, 844 TIMER2_CDTI0_Route = 0x05CC, 845 TIMER2_CDTI1_Route = 0x05D0, 846 TIMER2_CDTI2_Route = 0x05D4, 847 TIMER3_RouteEnable = 0x05DC, 848 TIMER3_CC0_Route = 0x05E0, 849 TIMER3_CC1_Route = 0x05E4, 850 TIMER3_CC2_Route = 0x05E8, 851 TIMER3_CDTI0_Route = 0x05EC, 852 TIMER3_CDTI1_Route = 0x05F0, 853 TIMER3_CDTI2_Route = 0x05F4, 854 TIMER4_RouteEnable = 0x05FC, 855 TIMER4_CC0_Route = 0x0600, 856 TIMER4_CC1_Route = 0x0604, 857 TIMER4_CC2_Route = 0x0608, 858 TIMER4_CDTI0_Route = 0x060C, 859 TIMER4_CDTI1_Route = 0x0610, 860 TIMER4_CDTI2_Route = 0x0614, 861 USART0_RouteEnable = 0x061C, 862 USART0_CS_Route = 0x0620, 863 USART0_CTS_Route = 0x0624, 864 USART0_RTS_Route = 0x0628, 865 USART0_RX_Route = 0x062C, 866 USART0_CLK_Route = 0x0630, 867 USART0_TX_Route = 0x0634, 868 USART1_RouteEnable = 0x063C, 869 USART1_CS_Route = 0x0640, 870 USART1_CTS_Route = 0x0644, 871 USART1_RTS_Route = 0x0648, 872 USART1_RX_Route = 0x064C, 873 USART1_CLK_Route = 0x0650, 874 USART1_TX_Route = 0x0654, 875 // Set registers 876 PortAControl_Set = 0x1000, 877 PortAModeLow_Set = 0x1004, 878 PortAModeHigh_Set = 0x100C, 879 PortADataOut_Set = 0x1010, 880 PortADataIn_Set = 0x1014, 881 PortBControl_Set = 0x1030, 882 PortBModeLow_Set = 0x1034, 883 PortBModeHigh_Set = 0x104C, 884 PortBDataOut_Set = 0x1040, 885 PortBDataIn_Set = 0x1044, 886 PortCControl_Set = 0x1060, 887 PortCModeLow_Set = 0x1064, 888 PortCModeHigh_Set = 0x106C, 889 PortCDataOut_Set = 0x1070, 890 PortCDataIn_Set = 0x1074, 891 PortDControl_Set = 0x1090, 892 PortDModeLow_Set = 0x1094, 893 PortDModeHigh_Set = 0x109C, 894 PortDDataOut_Set = 0x10A0, 895 PortDDataIn_Set = 0x10A4, 896 Lock_Set = 0x1300, 897 LockStatus_Set = 0x1310, 898 ABusAllocation_Set = 0x1320, 899 BBusAllocation_Set = 0x1324, 900 CDBusAllocation_Set = 0x1328, 901 ExternalInterruptPortSelectLow_Set = 0x1400, 902 ExternalInterruptPortSelectHigh_Set = 0x1404, 903 ExternalInterruptPinSelectLow_Set = 0x1408, 904 ExternalInterruptPinSelectHigh_Set = 0x140C, 905 ExternalInterruptRisingEdgeTrigger_Set = 0x1410, 906 ExternalInterruptFallingEdgeTrigger_Set = 0x1414, 907 InterruptFlag_Set = 0x1420, 908 InterruptEnable_Set = 0x1424, 909 EM4WakeUpEnable_Set = 0x142C, 910 EM4WakeUpPolarity_Set = 0x1430, 911 DebugRoutePinEn_Set = 0x1440, 912 TraceRoutePinEn_Set = 0x1444, 913 CMU_RouteEnable_Set = 0x1450, 914 CMU_CLKIN0_Route_Set = 0x1454, 915 CMU_CLKOUT0_Route_Set = 0x1458, 916 CMU_CLKOUT1_Route_Set = 0x145C, 917 CMU_CLKOUT2_Route_Set = 0x1460, 918 DCDC_RouteEnable_Set = 0x146C, 919 FRC_RouteEnable_Set = 0x147C, 920 FRC_DCLK_Route_Set = 0x1480, 921 FRC_DFRAME_Route_Set = 0x1484, 922 FRC_DOUT_Route_Set = 0x1488, 923 I2C0_RouteEnable_Set = 0x1490, 924 I2C0_SCL_Route_Set = 0x1494, 925 I2C0_SDA_Route_Set = 0x1498, 926 I2C1_RouteEnable_Set = 0x14A0, 927 I2C1_SCL_Route_Set = 0x14A4, 928 I2C1_SDA_Route_Set = 0x14A8, 929 LETIMER_RouteEnable_Set = 0x14B0, 930 LETIMER_OUT0_Route_Set = 0x14B4, 931 LETIMER_OUT1_Route_Set = 0x14B8, 932 ESART0_RouteEnable_Set = 0x14C0, 933 ESART0_CS_Route_Set = 0x14C4, 934 ESART0_CTS_Route_Set = 0x14C8, 935 ESART0_RTS_Route_Set = 0x14CC, 936 ESART0_RX_Route_Set = 0x14D0, 937 MODEM_RouteEnable_Set = 0x14D8, 938 MODEM_ANT0_Route_Set = 0x14DC, 939 MODEM_ANT1_Route_Set = 0x14E0, 940 MODEM_ANTROLLOVER_Route_Set = 0x14E4, 941 MODEM_ANTRR0_Route_Set = 0x14E8, 942 MODEM_ANTRR1_Route_Set = 0x14EC, 943 MODEM_ANTRR2_Route_Set = 0x14F0, 944 MODEM_ANTRR3_Route_Set = 0x14F4, 945 MODEM_ANTRR4_Route_Set = 0x14F8, 946 MODEM_ANTRR5_Route_Set = 0x14FC, 947 MODEM_ANTSWEN_Route_Set = 0x1500, 948 MODEM_ANTSWUS_Route_Set = 0x1504, 949 MODEM_ANTTRIG_Route_Set = 0x1508, 950 MODEM_ANTTRIGSTOP_Route_Set = 0x150C, 951 MODEM_DCLK_Route_Set = 0x1510, 952 MODEM_DIN_Route_Set = 0x1514, 953 MODEM_DOUT_Route_Set = 0x1518, 954 PDM_RouteEnable_Set = 0x1520, 955 PDM_CLK_Route_Set = 0x1524, 956 PDM_DAT0_Route_Set = 0x1528, 957 PDM_DAT1_Route_Set = 0x152C, 958 PRS0_RouteEnable_Set = 0x1534, 959 PRS0_ASYNCH0_Route_Set = 0x1538, 960 PRS0_ASYNCH1_Route_Set = 0x153C, 961 PRS0_ASYNCH2_Route_Set = 0x1540, 962 PRS0_ASYNCH3_Route_Set = 0x1544, 963 PRS0_ASYNCH4_Route_Set = 0x1548, 964 PRS0_ASYNCH5_Route_Set = 0x154C, 965 PRS0_ASYNCH6_Route_Set = 0x1550, 966 PRS0_ASYNCH7_Route_Set = 0x1554, 967 PRS0_ASYNCH8_Route_Set = 0x1558, 968 PRS0_ASYNCH9_Route_Set = 0x155C, 969 PRS0_ASYNCH10_Route_Set = 0x1560, 970 PRS0_ASYNCH11_Route_Set = 0x1564, 971 PRS0_SYNCH0_Route_Set = 0x1568, 972 PRS0_SYNCH1_Route_Set = 0x156C, 973 PRS0_SYNCH2_Route_Set = 0x1570, 974 PRS0_SYNCH3_Route_Set = 0x1574, 975 TIMER0_RouteEnable_Set = 0x157C, 976 TIMER0_CC0_Route_Set = 0x1580, 977 TIMER0_CC1_Route_Set = 0x1584, 978 TIMER0_CC2_Route_Set = 0x1588, 979 TIMER0_CDTI0_Route_Set = 0x158C, 980 TIMER0_CDTI1_Route_Set = 0x1590, 981 TIMER0_CDTI2_Route_Set = 0x1594, 982 TIMER1_RouteEnable_Set = 0x159C, 983 TIMER1_CC0_Route_Set = 0x15A0, 984 TIMER1_CC1_Route_Set = 0x15A4, 985 TIMER1_CC2_Route_Set = 0x15A8, 986 TIMER1_CDTI0_Route_Set = 0x15AC, 987 TIMER1_CDTI1_Route_Set = 0x15B0, 988 TIMER1_CDTI2_Route_Set = 0x15B4, 989 TIMER2_RouteEnable_Set = 0x15BC, 990 TIMER2_CC0_Route_Set = 0x15C0, 991 TIMER2_CC1_Route_Set = 0x15C4, 992 TIMER2_CC2_Route_Set = 0x15C8, 993 TIMER2_CDTI0_Route_Set = 0x15CC, 994 TIMER2_CDTI1_Route_Set = 0x15D0, 995 TIMER2_CDTI2_Route_Set = 0x15D4, 996 TIMER3_RouteEnable_Set = 0x15DC, 997 TIMER3_CC0_Route_Set = 0x15E0, 998 TIMER3_CC1_Route_Set = 0x15E4, 999 TIMER3_CC2_Route_Set = 0x15E8, 1000 TIMER3_CDTI0_Route_Set = 0x15EC, 1001 TIMER3_CDTI1_Route_Set = 0x15F0, 1002 TIMER3_CDTI2_Route_Set = 0x15F4, 1003 TIMER4_RouteEnable_Set = 0x15FC, 1004 TIMER4_CC0_Route_Set = 0x1600, 1005 TIMER4_CC1_Route_Set = 0x1604, 1006 TIMER4_CC2_Route_Set = 0x1608, 1007 TIMER4_CDTI0_Route_Set = 0x160C, 1008 TIMER4_CDTI1_Route_Set = 0x1610, 1009 TIMER4_CDTI2_Route_Set = 0x1614, 1010 USART0_RouteEnable_Set = 0x161C, 1011 USART0_CS_Route_Set = 0x1620, 1012 USART0_CTS_Route_Set = 0x1624, 1013 USART0_RTS_Route_Set = 0x1628, 1014 USART0_RX_Route_Set = 0x162C, 1015 USART0_CLK_Route_Set = 0x1630, 1016 USART0_TX_Route_Set = 0x1634, 1017 USART1_RouteEnable_Set = 0x163C, 1018 USART1_CS_Route_Set = 0x1640, 1019 USART1_CTS_Route_Set = 0x1644, 1020 USART1_RTS_Route_Set = 0x1648, 1021 USART1_RX_Route_Set = 0x164C, 1022 USART1_CLK_Route_Set = 0x1650, 1023 USART1_TX_Route_Set = 0x1654, 1024 // Clear registers 1025 PortAControl_Clr = 0x2000, 1026 PortAModeLow_Clr = 0x2004, 1027 PortAModeHigh_Clr = 0x200C, 1028 PortADataOut_Clr = 0x2010, 1029 PortADataIn_Clr = 0x2014, 1030 PortBControl_Clr = 0x2030, 1031 PortBModeLow_Clr = 0x2034, 1032 PortBModeHigh_Clr = 0x204C, 1033 PortBDataOut_Clr = 0x2040, 1034 PortBDataIn_Clr = 0x2044, 1035 PortCControl_Clr = 0x2060, 1036 PortCModeLow_Clr = 0x2064, 1037 PortCModeHigh_Clr = 0x206C, 1038 PortCDataOut_Clr = 0x2070, 1039 PortCDataIn_Clr = 0x2074, 1040 PortDControl_Clr = 0x2090, 1041 PortDModeLow_Clr = 0x2094, 1042 PortDModeHigh_Clr = 0x209C, 1043 PortDDataOut_Clr = 0x20A0, 1044 PortDDataIn_Clr = 0x20A4, 1045 Lock_Clr = 0x2300, 1046 LockStatus_Clr = 0x2310, 1047 ABusAllocation_Clr = 0x2320, 1048 BBusAllocation_Clr = 0x2324, 1049 CDBusAllocation_Clr = 0x2328, 1050 ExternalInterruptPortSelectLow_Clr = 0x2400, 1051 ExternalInterruptPortSelectHigh_Clr = 0x2404, 1052 ExternalInterruptPinSelectLow_Clr = 0x2408, 1053 ExternalInterruptPinSelectHigh_Clr = 0x240C, 1054 ExternalInterruptRisingEdgeTrigger_Clr = 0x2410, 1055 ExternalInterruptFallingEdgeTrigger_Clr = 0x2414, 1056 InterruptFlag_Clr = 0x2420, 1057 InterruptEnable_Clr = 0x2424, 1058 EM4WakeUpEnable_Clr = 0x242C, 1059 EM4WakeUpPolarity_Clr = 0x2430, 1060 DebugRoutePinEn_Clr = 0x2440, 1061 TraceRoutePinEn_Clr = 0x2444, 1062 CMU_RouteEnable_Clr = 0x2450, 1063 CMU_CLKIN0_Route_Clr = 0x2454, 1064 CMU_CLKOUT0_Route_Clr = 0x2458, 1065 CMU_CLKOUT1_Route_Clr = 0x245C, 1066 CMU_CLKOUT2_Route_Clr = 0x2460, 1067 DCDC_RouteEnable_Clr = 0x246C, 1068 FRC_RouteEnable_Clr = 0x247C, 1069 FRC_DCLK_Route_Clr = 0x2480, 1070 FRC_DFRAME_Route_Clr = 0x2484, 1071 FRC_DOUT_Route_Clr = 0x2488, 1072 I2C0_RouteEnable_Clr = 0x2490, 1073 I2C0_SCL_Route_Clr = 0x2494, 1074 I2C0_SDA_Route_Clr = 0x2498, 1075 I2C1_RouteEnable_Clr = 0x24A0, 1076 I2C1_SCL_Route_Clr = 0x24A4, 1077 I2C1_SDA_Route_Clr = 0x24A8, 1078 LETIMER_RouteEnable_Clr = 0x24B0, 1079 LETIMER_OUT0_Route_Clr = 0x24B4, 1080 LETIMER_OUT1_Route_Clr = 0x24B8, 1081 ESART0_RouteEnable_Clr = 0x24C0, 1082 ESART0_CS_Route_Clr = 0x24C4, 1083 ESART0_CTS_Route_Clr = 0x24C8, 1084 ESART0_RTS_Route_Clr = 0x24CC, 1085 ESART0_RX_Route_Clr = 0x24D0, 1086 MODEM_RouteEnable_Clr = 0x24D8, 1087 MODEM_ANT0_Route_Clr = 0x24DC, 1088 MODEM_ANT1_Route_Clr = 0x24E0, 1089 MODEM_ANTROLLOVER_Route_Clr = 0x24E4, 1090 MODEM_ANTRR0_Route_Clr = 0x24E8, 1091 MODEM_ANTRR1_Route_Clr = 0x24EC, 1092 MODEM_ANTRR2_Route_Clr = 0x24F0, 1093 MODEM_ANTRR3_Route_Clr = 0x24F4, 1094 MODEM_ANTRR4_Route_Clr = 0x24F8, 1095 MODEM_ANTRR5_Route_Clr = 0x24FC, 1096 MODEM_ANTSWEN_Route_Clr = 0x2500, 1097 MODEM_ANTSWUS_Route_Clr = 0x2504, 1098 MODEM_ANTTRIG_Route_Clr = 0x2508, 1099 MODEM_ANTTRIGSTOP_Route_Clr = 0x250C, 1100 MODEM_DCLK_Route_Clr = 0x2510, 1101 MODEM_DIN_Route_Clr = 0x2514, 1102 MODEM_DOUT_Route_Clr = 0x2518, 1103 PDM_RouteEnable_Clr = 0x2520, 1104 PDM_CLK_Route_Clr = 0x2524, 1105 PDM_DAT0_Route_Clr = 0x2528, 1106 PDM_DAT1_Route_Clr = 0x252C, 1107 PRS0_RouteEnable_Clr = 0x2534, 1108 PRS0_ASYNCH0_Route_Clr = 0x2538, 1109 PRS0_ASYNCH1_Route_Clr = 0x253C, 1110 PRS0_ASYNCH2_Route_Clr = 0x2540, 1111 PRS0_ASYNCH3_Route_Clr = 0x2544, 1112 PRS0_ASYNCH4_Route_Clr = 0x2548, 1113 PRS0_ASYNCH5_Route_Clr = 0x254C, 1114 PRS0_ASYNCH6_Route_Clr = 0x2550, 1115 PRS0_ASYNCH7_Route_Clr = 0x2554, 1116 PRS0_ASYNCH8_Route_Clr = 0x2558, 1117 PRS0_ASYNCH9_Route_Clr = 0x255C, 1118 PRS0_ASYNCH10_Route_Clr = 0x2560, 1119 PRS0_ASYNCH11_Route_Clr = 0x2564, 1120 PRS0_SYNCH0_Route_Clr = 0x2568, 1121 PRS0_SYNCH1_Route_Clr = 0x256C, 1122 PRS0_SYNCH2_Route_Clr = 0x2570, 1123 PRS0_SYNCH3_Route_Clr = 0x2574, 1124 TIMER0_RouteEnable_Clr = 0x257C, 1125 TIMER0_CC0_Route_Clr = 0x2580, 1126 TIMER0_CC1_Route_Clr = 0x2584, 1127 TIMER0_CC2_Route_Clr = 0x2588, 1128 TIMER0_CDTI0_Route_Clr = 0x258C, 1129 TIMER0_CDTI1_Route_Clr = 0x2590, 1130 TIMER0_CDTI2_Route_Clr = 0x2594, 1131 TIMER1_RouteEnable_Clr = 0x259C, 1132 TIMER1_CC0_Route_Clr = 0x25A0, 1133 TIMER1_CC1_Route_Clr = 0x25A4, 1134 TIMER1_CC2_Route_Clr = 0x25A8, 1135 TIMER1_CDTI0_Route_Clr = 0x25AC, 1136 TIMER1_CDTI1_Route_Clr = 0x25B0, 1137 TIMER1_CDTI2_Route_Clr = 0x25B4, 1138 TIMER2_RouteEnable_Clr = 0x25BC, 1139 TIMER2_CC0_Route_Clr = 0x25C0, 1140 TIMER2_CC1_Route_Clr = 0x25C4, 1141 TIMER2_CC2_Route_Clr = 0x25C8, 1142 TIMER2_CDTI0_Route_Clr = 0x25CC, 1143 TIMER2_CDTI1_Route_Clr = 0x25D0, 1144 TIMER2_CDTI2_Route_Clr = 0x25D4, 1145 TIMER3_RouteEnable_Clr = 0x25DC, 1146 TIMER3_CC0_Route_Clr = 0x25E0, 1147 TIMER3_CC1_Route_Clr = 0x25E4, 1148 TIMER3_CC2_Route_Clr = 0x25E8, 1149 TIMER3_CDTI0_Route_Clr = 0x25EC, 1150 TIMER3_CDTI1_Route_Clr = 0x25F0, 1151 TIMER3_CDTI2_Route_Clr = 0x25F4, 1152 TIMER4_RouteEnable_Clr = 0x25FC, 1153 TIMER4_CC0_Route_Clr = 0x2600, 1154 TIMER4_CC1_Route_Clr = 0x2604, 1155 TIMER4_CC2_Route_Clr = 0x2608, 1156 TIMER4_CDTI0_Route_Clr = 0x260C, 1157 TIMER4_CDTI1_Route_Clr = 0x2610, 1158 TIMER4_CDTI2_Route_Clr = 0x2614, 1159 USART0_RouteEnable_Clr = 0x261C, 1160 USART0_CS_Route_Clr = 0x2620, 1161 USART0_CTS_Route_Clr = 0x2624, 1162 USART0_RTS_Route_Clr = 0x2628, 1163 USART0_RX_Route_Clr = 0x262C, 1164 USART0_CLK_Route_Clr = 0x2630, 1165 USART0_TX_Route_Clr = 0x2634, 1166 USART1_RouteEnable_Clr = 0x263C, 1167 USART1_CS_Route_Clr = 0x2640, 1168 USART1_CTS_Route_Clr = 0x2644, 1169 USART1_RTS_Route_Clr = 0x2648, 1170 USART1_RX_Route_Clr = 0x264C, 1171 USART1_CLK_Route_Clr = 0x2650, 1172 USART1_TX_Route_Clr = 0x2654, 1173 // Toggle registers 1174 PortAControl_Tgl = 0x3000, 1175 PortAModeLow_Tgl = 0x3004, 1176 PortAModeHigh_Tgl = 0x300C, 1177 PortADataOut_Tgl = 0x3010, 1178 PortADataIn_Tgl = 0x3014, 1179 PortBControl_Tgl = 0x3030, 1180 PortBModeLow_Tgl = 0x3034, 1181 PortBModeHigh_Tgl = 0x304C, 1182 PortBDataOut_Tgl = 0x3040, 1183 PortBDataIn_Tgl = 0x3044, 1184 PortCControl_Tgl = 0x3060, 1185 PortCModeLow_Tgl = 0x3064, 1186 PortCModeHigh_Tgl = 0x306C, 1187 PortCDataOut_Tgl = 0x3070, 1188 PortCDataIn_Tgl = 0x3074, 1189 PortDControl_Tgl = 0x3090, 1190 PortDModeLow_Tgl = 0x3094, 1191 PortDModeHigh_Tgl = 0x309C, 1192 PortDDataOut_Tgl = 0x30A0, 1193 PortDDataIn_Tgl = 0x30A4, 1194 Lock_Tgl = 0x3300, 1195 LockStatus_Tgl = 0x3310, 1196 ABusAllocation_Tgl = 0x3320, 1197 BBusAllocation_Tgl = 0x3324, 1198 CDBusAllocation_Tgl = 0x3328, 1199 ExternalInterruptPortSelectLow_Tgl = 0x3400, 1200 ExternalInterruptPortSelectHigh_Tgl = 0x3404, 1201 ExternalInterruptPinSelectLow_Tgl = 0x3408, 1202 ExternalInterruptPinSelectHigh_Tgl = 0x340C, 1203 ExternalInterruptRisingEdgeTrigger_Tgl = 0x3410, 1204 ExternalInterruptFallingEdgeTrigger_Tgl = 0x3414, 1205 InterruptFlag_Tgl = 0x3420, 1206 InterruptEnable_Tgl = 0x3424, 1207 EM4WakeUpEnable_Tgl = 0x342C, 1208 EM4WakeUpPolarity_Tgl = 0x3430, 1209 DebugRoutePinEn_Tgl = 0x3440, 1210 TraceRoutePinEn_Tgl = 0x3444, 1211 CMU_RouteEnable_Tgl = 0x3450, 1212 CMU_CLKIN0_Route_Tgl = 0x3454, 1213 CMU_CLKOUT0_Route_Tgl = 0x3458, 1214 CMU_CLKOUT1_Route_Tgl = 0x345C, 1215 CMU_CLKOUT2_Route_Tgl = 0x3460, 1216 DCDC_RouteEnable_Tgl = 0x346C, 1217 FRC_RouteEnable_Tgl = 0x347C, 1218 FRC_DCLK_Route_Tgl = 0x3480, 1219 FRC_DFRAME_Route_Tgl = 0x3484, 1220 FRC_DOUT_Route_Tgl = 0x3488, 1221 I2C0_RouteEnable_Tgl = 0x3490, 1222 I2C0_SCL_Route_Tgl = 0x3494, 1223 I2C0_SDA_Route_Tgl = 0x3498, 1224 I2C1_RouteEnable_Tgl = 0x34A0, 1225 I2C1_SCL_Route_Tgl = 0x34A4, 1226 I2C1_SDA_Route_Tgl = 0x34A8, 1227 LETIMER_RouteEnable_Tgl = 0x34B0, 1228 LETIMER_OUT0_Route_Tgl = 0x34B4, 1229 LETIMER_OUT1_Route_Tgl = 0x34B8, 1230 ESART0_RouteEnable_Tgl = 0x34C0, 1231 ESART0_CS_Route_Tgl = 0x34C4, 1232 ESART0_CTS_Route_Tgl = 0x34C8, 1233 ESART0_RTS_Route_Tgl = 0x34CC, 1234 ESART0_RX_Route_Tgl = 0x34D0, 1235 MODEM_RouteEnable_Tgl = 0x34D8, 1236 MODEM_ANT0_Route_Tgl = 0x34DC, 1237 MODEM_ANT1_Route_Tgl = 0x34E0, 1238 MODEM_ANTROLLOVER_Route_Tgl = 0x34E4, 1239 MODEM_ANTRR0_Route_Tgl = 0x34E8, 1240 MODEM_ANTRR1_Route_Tgl = 0x34EC, 1241 MODEM_ANTRR2_Route_Tgl = 0x34F0, 1242 MODEM_ANTRR3_Route_Tgl = 0x34F4, 1243 MODEM_ANTRR4_Route_Tgl = 0x34F8, 1244 MODEM_ANTRR5_Route_Tgl = 0x34FC, 1245 MODEM_ANTSWEN_Route_Tgl = 0x3500, 1246 MODEM_ANTSWUS_Route_Tgl = 0x3504, 1247 MODEM_ANTTRIG_Route_Tgl = 0x3508, 1248 MODEM_ANTTRIGSTOP_Route_Tgl = 0x350C, 1249 MODEM_DCLK_Route_Tgl = 0x3510, 1250 MODEM_DIN_Route_Tgl = 0x3514, 1251 MODEM_DOUT_Route_Tgl = 0x3518, 1252 PDM_RouteEnable_Tgl = 0x3520, 1253 PDM_CLK_Route_Tgl = 0x3524, 1254 PDM_DAT0_Route_Tgl = 0x3528, 1255 PDM_DAT1_Route_Tgl = 0x352C, 1256 PRS0_RouteEnable_Tgl = 0x3534, 1257 PRS0_ASYNCH0_Route_Tgl = 0x3538, 1258 PRS0_ASYNCH1_Route_Tgl = 0x353C, 1259 PRS0_ASYNCH2_Route_Tgl = 0x3540, 1260 PRS0_ASYNCH3_Route_Tgl = 0x3544, 1261 PRS0_ASYNCH4_Route_Tgl = 0x3548, 1262 PRS0_ASYNCH5_Route_Tgl = 0x354C, 1263 PRS0_ASYNCH6_Route_Tgl = 0x3550, 1264 PRS0_ASYNCH7_Route_Tgl = 0x3554, 1265 PRS0_ASYNCH8_Route_Tgl = 0x3558, 1266 PRS0_ASYNCH9_Route_Tgl = 0x355C, 1267 PRS0_ASYNCH10_Route_Tgl = 0x3560, 1268 PRS0_ASYNCH11_Route_Tgl = 0x3564, 1269 PRS0_SYNCH0_Route_Tgl = 0x3568, 1270 PRS0_SYNCH1_Route_Tgl = 0x356C, 1271 PRS0_SYNCH2_Route_Tgl = 0x3570, 1272 PRS0_SYNCH3_Route_Tgl = 0x3574, 1273 TIMER0_RouteEnable_Tgl = 0x357C, 1274 TIMER0_CC0_Route_Tgl = 0x3580, 1275 TIMER0_CC1_Route_Tgl = 0x3584, 1276 TIMER0_CC2_Route_Tgl = 0x3588, 1277 TIMER0_CDTI0_Route_Tgl = 0x358C, 1278 TIMER0_CDTI1_Route_Tgl = 0x3590, 1279 TIMER0_CDTI2_Route_Tgl = 0x3594, 1280 TIMER1_RouteEnable_Tgl = 0x359C, 1281 TIMER1_CC0_Route_Tgl = 0x35A0, 1282 TIMER1_CC1_Route_Tgl = 0x35A4, 1283 TIMER1_CC2_Route_Tgl = 0x35A8, 1284 TIMER1_CDTI0_Route_Tgl = 0x35AC, 1285 TIMER1_CDTI1_Route_Tgl = 0x35B0, 1286 TIMER1_CDTI2_Route_Tgl = 0x35B4, 1287 TIMER2_RouteEnable_Tgl = 0x35BC, 1288 TIMER2_CC0_Route_Tgl = 0x35C0, 1289 TIMER2_CC1_Route_Tgl = 0x35C4, 1290 TIMER2_CC2_Route_Tgl = 0x35C8, 1291 TIMER2_CDTI0_Route_Tgl = 0x35CC, 1292 TIMER2_CDTI1_Route_Tgl = 0x35D0, 1293 TIMER2_CDTI2_Route_Tgl = 0x35D4, 1294 TIMER3_RouteEnable_Tgl = 0x35DC, 1295 TIMER3_CC0_Route_Tgl = 0x35E0, 1296 TIMER3_CC1_Route_Tgl = 0x35E4, 1297 TIMER3_CC2_Route_Tgl = 0x35E8, 1298 TIMER3_CDTI0_Route_Tgl = 0x35EC, 1299 TIMER3_CDTI1_Route_Tgl = 0x35F0, 1300 TIMER3_CDTI2_Route_Tgl = 0x35F4, 1301 TIMER4_RouteEnable_Tgl = 0x35FC, 1302 TIMER4_CC0_Route_Tgl = 0x3600, 1303 TIMER4_CC1_Route_Tgl = 0x3604, 1304 TIMER4_CC2_Route_Tgl = 0x3608, 1305 TIMER4_CDTI0_Route_Tgl = 0x360C, 1306 TIMER4_CDTI1_Route_Tgl = 0x3610, 1307 TIMER4_CDTI2_Route_Tgl = 0x3614, 1308 USART0_RouteEnable_Tgl = 0x361C, 1309 USART0_CS_Route_Tgl = 0x3620, 1310 USART0_CTS_Route_Tgl = 0x3624, 1311 USART0_RTS_Route_Tgl = 0x3628, 1312 USART0_RX_Route_Tgl = 0x362C, 1313 USART0_CLK_Route_Tgl = 0x3630, 1314 USART0_TX_Route_Tgl = 0x3634, 1315 USART1_RouteEnable_Tgl = 0x363C, 1316 USART1_CS_Route_Tgl = 0x3640, 1317 USART1_CTS_Route_Tgl = 0x3644, 1318 USART1_RTS_Route_Tgl = 0x3648, 1319 USART1_RX_Route_Tgl = 0x364C, 1320 USART1_CLK_Route_Tgl = 0x3650, 1321 USART1_TX_Route_Tgl = 0x3654, 1322 } 1323 #endregion 1324 } 1325 }