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 8 using System; 9 using System.Collections.Generic; 10 using System.Linq; 11 using Antmicro.Renode.Core; 12 using Antmicro.Renode.Core.Structure.Registers; 13 using Antmicro.Renode.Exceptions; 14 using Antmicro.Renode.Logging; 15 using Antmicro.Renode.Peripherals.Bus; 16 using Antmicro.Renode.Utilities; 17 18 namespace Antmicro.Renode.Peripherals.IRQControllers 19 { 20 [AllowedTranslations(AllowedTranslation.ByteToDoubleWord | AllowedTranslation.WordToDoubleWord)] 21 public class RenesasRA_ICU : BasicDoubleWordPeripheral, IIRQController, IKnownSize 22 { RenesasRA_ICU(IMachine machine, IGPIOReceiver nvic, EventToInterruptLinkType eventToInterruptLink = EventToInterruptLinkType.RA8, uint numberOfExternalInterrupts = DefaultNumberOfExternalInterrupts, uint highestEventNumber = DefaultHighestEventNumber, uint numberOfNVICOutputs = DefaultNumberOfNVICOutputs)23 public RenesasRA_ICU(IMachine machine, IGPIOReceiver nvic, EventToInterruptLinkType eventToInterruptLink = EventToInterruptLinkType.RA8, 24 uint numberOfExternalInterrupts = DefaultNumberOfExternalInterrupts, 25 uint highestEventNumber = DefaultHighestEventNumber, 26 uint numberOfNVICOutputs = DefaultNumberOfNVICOutputs) : base(machine) 27 { 28 // Type comparison like this is required due to NVIC model being in another project 29 if(nvic.GetType().FullName != "Antmicro.Renode.Peripherals.IRQControllers.NVIC") 30 { 31 throw new ConstructionException($"{nvic.GetType()} is invalid type for NVIC"); 32 } 33 34 var numberOfEvents = highestEventNumber + 1; 35 if(numberOfEvents < numberOfExternalInterrupts) 36 { 37 throw new ConstructionException($"The number of events ({numberOfEvents}) is lower than number of external interrupts ({numberOfExternalInterrupts})"); 38 } 39 40 this.nvic = nvic; 41 eventLinkType = eventToInterruptLink; 42 43 interruptsForEvent = Enumerable.Range(0, (int)numberOfEvents).Select(_ => new HashSet<int>()).ToArray(); 44 latestEventState = new bool[numberOfEvents]; 45 externalInterruptTrigger = new IEnumRegisterField<InterruptTrigger>[numberOfExternalInterrupts]; 46 interruptEventLink = new IValueRegisterField[numberOfNVICOutputs]; 47 interruptPending = new IFlagRegisterField[numberOfNVICOutputs]; 48 49 DefineRegisters(); 50 } 51 Reset()52 public override void Reset() 53 { 54 base.Reset(); 55 foreach(var irqs in interruptsForEvent) 56 { 57 irqs.Clear(); 58 } 59 Array.Clear(latestEventState, 0, latestEventState.Length); 60 } 61 OnGPIO(int eventIndex, bool state)62 public void OnGPIO(int eventIndex, bool state) 63 { 64 if(eventIndex >= latestEventState.Length) 65 { 66 this.Log(LogLevel.Warning, "Trying to update a state of event of index 0x{0:x}, which is larger than declared number of events", eventIndex); 67 return; 68 } 69 70 UpdateEventAndInterrupts(eventIndex, state); 71 } 72 73 public long Size => 0x1000; 74 75 public IReadOnlyDictionary<int, IGPIO> Connections { get; } 76 GetEventForInterruptIndex(int irqIndex)77 private int GetEventForInterruptIndex(int irqIndex) 78 { 79 var eventIndex = Array.FindIndex(interruptsForEvent, irqs => irqs.Contains(irqIndex)); 80 if(eventIndex == -1) 81 { 82 return NoEventIndex; 83 } 84 return eventIndex; 85 } 86 GetEventForEventLink(int irqIndex, ulong eventLink)87 private int GetEventForEventLink(int irqIndex, ulong eventLink) 88 { 89 // The IELS register in platforms other than RA2 directly indicate an event. 90 if(eventLinkType != EventToInterruptLinkType.RA2) 91 { 92 return (int)eventLink; 93 } 94 // For RA2 also a group of interrupt takes account. 95 var irqGroup = irqIndex % 8; 96 return eventLinkRA2[eventLink, irqGroup]; 97 } 98 IsEventTriggered(int eventIndex, bool previousState, bool state)99 private bool IsEventTriggered(int eventIndex, bool previousState, bool state) 100 { 101 if(eventIndex == NoEventIndex) 102 { 103 // There is no event with index 0. 104 return false; 105 } 106 107 if(eventIndex > externalInterruptTrigger.Length) 108 { 109 // Handle an event from a peripheral 110 return state; 111 } 112 113 // Handle an IRQn (an external interrupt) 114 // As number is between 1 and NumberOfExternalInterrupts, 115 // externalIrqNumber will be between 0 and NumberOfExternalInterrupts - 1. 116 var externalIrqNumber = eventIndex - 1; 117 var trigger = externalInterruptTrigger[externalIrqNumber].Value; 118 switch(trigger) 119 { 120 case InterruptTrigger.RisingEdge: 121 return !previousState && state; 122 case InterruptTrigger.FallingEdge: 123 return previousState && !state; 124 case InterruptTrigger.BothEdges: 125 return previousState != state; 126 case InterruptTrigger.ActiveLow: 127 return !state; 128 default: 129 throw new ArgumentOutOfRangeException($"Unknown value of interrupt trigger {trigger}"); 130 } 131 } 132 UpdateEventAndInterrupts(int eventIndex, bool? newEventState = null, ICollection<int> interruptIndexes = null)133 private void UpdateEventAndInterrupts(int eventIndex, bool? newEventState = null, ICollection<int> interruptIndexes = null) 134 { 135 var previousState = latestEventState[eventIndex]; 136 // If newEventState isn't passed just keep existing state. 137 var newState = newEventState ?? previousState; 138 latestEventState[eventIndex] = newState; 139 140 // Update the passed list of interrupts or all linked to the event. 141 var irqs = interruptIndexes ?? interruptsForEvent[eventIndex]; 142 var isTriggered = IsEventTriggered(eventIndex, previousState, newState); 143 144 if(irqs.Count() == 0 && isTriggered) 145 { 146 // If event mapping is not registered by software and there is no list of interrupts to update, ignore incoming IRQ. 147 this.Log(LogLevel.Warning, "Unhandled event request: 0x{0:X}. There is no configured link to the NVIC.", eventIndex); 148 return; 149 } 150 151 foreach(var irqIndex in irqs) 152 { 153 // Latch signal and pass to the NVIC. 154 interruptPending[irqIndex].Value |= isTriggered; 155 nvic.OnGPIO(irqIndex, interruptPending[irqIndex].Value); 156 } 157 } 158 DefineRegisters()159 private void DefineRegisters() 160 { 161 Registers.IRQControl0.DefineMany(this, (uint)externalInterruptTrigger.Length, (register, registerIndex) => 162 { 163 register 164 .WithEnumField(0, 2, out externalInterruptTrigger[registerIndex], name: $"IRQMD{registerIndex}") 165 .WithReservedBits(2, 2) 166 .WithTag($"FCLKSEL{registerIndex}", 4, 2) 167 .WithReservedBits(6, 1) 168 .WithTaggedFlag($"FLTEN{registerIndex}", 7) 169 .WithReservedBits(8, 24) 170 .WithChangeCallback((_, __) => UpdateEventAndInterrupts(registerIndex + 1)) 171 ; 172 }); 173 174 Registers.NMIPinInterruptControl.Define(this) 175 .WithTaggedFlag("NMIMD", 0) 176 .WithReservedBits(1, 3) 177 .WithTag("NFCLKSEL", 4, 2) 178 .WithReservedBits(6, 1) 179 .WithTaggedFlag("NFLTEN", 7) 180 .WithReservedBits(8, 24) 181 ; 182 183 Registers.NonMaskableInterruptEnable.Define(this) 184 .WithTaggedFlag("IWDTEN", 0) 185 .WithTaggedFlag("WDTEN", 1) 186 .WithTaggedFlag("LVD1EN", 2) 187 .WithTaggedFlag("LVD2EN", 3) 188 .WithReservedBits(4, 2) 189 .WithTaggedFlag("OSTEN", 6) 190 .WithTaggedFlag("NMIEN", 7) 191 .WithTaggedFlag("RPEEN", 8) 192 .WithTaggedFlag("RECCEN", 9) 193 .WithReservedBits(10, 1) 194 .WithTaggedFlag("BUSMEN", 11) 195 .WithReservedBits(12, 1) 196 .WithTaggedFlag("TZFEN", 13) 197 .WithReservedBits(14, 1) 198 .WithTaggedFlag("CPEEN", 15) 199 .WithReservedBits(16, 16) 200 ; 201 202 Registers.NonMaskableInterruptStatusClear.Define(this) 203 .WithTaggedFlag("IWDTCLR", 0) 204 .WithTaggedFlag("WDTCLR", 1) 205 .WithTaggedFlag("LVD1CLR", 2) 206 .WithTaggedFlag("LVD2CLR", 3) 207 .WithReservedBits(4, 2) 208 .WithTaggedFlag("OSTCLR", 6) 209 .WithTaggedFlag("NMICLR", 7) 210 .WithTaggedFlag("RPECLR", 8) 211 .WithTaggedFlag("RECCCLR", 9) 212 .WithReservedBits(10, 1) 213 .WithTaggedFlag("BUSMCLR", 11) 214 .WithReservedBits(12, 1) 215 .WithTaggedFlag("TZFCLR", 13) 216 .WithReservedBits(14, 1) 217 .WithTaggedFlag("CPECLR", 15) 218 .WithReservedBits(16, 16) 219 ; 220 221 Registers.NonMaskableInterruptStatus.Define(this) 222 .WithTaggedFlag("IWDTST", 0) 223 .WithTaggedFlag("WDTST", 1) 224 .WithTaggedFlag("LVD1ST", 2) 225 .WithTaggedFlag("LVD2ST", 3) 226 .WithReservedBits(4, 2) 227 .WithTaggedFlag("OSTST", 6) 228 .WithTaggedFlag("NMIST", 7) 229 .WithTaggedFlag("RPEST", 8) 230 .WithTaggedFlag("RECCST", 9) 231 .WithReservedBits(10, 1) 232 .WithTaggedFlag("BUSMST", 11) 233 .WithReservedBits(12, 1) 234 .WithTaggedFlag("TZFST", 13) 235 .WithReservedBits(14, 1) 236 .WithTaggedFlag("CPEST", 15) 237 .WithReservedBits(16, 16) 238 ; 239 240 Registers.WakeUpInterruptEnable0.Define(this) 241 .WithTag("IRQWUPEN", 0, 16) 242 .WithTaggedFlag("IWDTWUPEN", 16) 243 .WithReservedBits(17, 1) 244 .WithTaggedFlag("LVD1WUPEN", 18) 245 .WithTaggedFlag("LVD2WUPEN", 19) 246 .WithReservedBits(20, 4) 247 .WithTaggedFlag("RTCALMWUPEN", 24) 248 .WithTaggedFlag("RTCPRDWUPEN", 25) 249 .WithTaggedFlag("USBHSWUPEN", 26) 250 .WithTaggedFlag("USBFS0WUPEN", 27) 251 .WithTaggedFlag("AGT1UDWUPEN", 28) 252 .WithTaggedFlag("AGT1CAWUPEN", 29) 253 .WithTaggedFlag("AGT1CBWUPEN", 30) 254 .WithTaggedFlag("IIC0WUPEN", 31) 255 ; 256 257 Registers.WakeUpinterruptenableregister1.Define(this) 258 .WithTaggedFlag("AGT3UDWUPEN", 0) 259 .WithTaggedFlag("AGT3CAWUPEN", 1) 260 .WithTaggedFlag("AGT3CBWUPEN", 2) 261 .WithReservedBits(3, 29) 262 ; 263 264 Registers.SYSEventLinkSetting.Define(this) 265 .WithTag("SELSR0", 0, 16) 266 .WithReservedBits(16, 16) 267 ; 268 269 Registers.DMACEventLinkSetting0.DefineMany(this, DefaultNumberOfDMACEvents, (register, registerIndex) => 270 { 271 register 272 .WithTag($"DELS{registerIndex}", 0, 9) 273 .WithReservedBits(9, 7) 274 .WithTaggedFlag($"IR{registerIndex}", 16) 275 .WithReservedBits(17, 15) 276 ; 277 }); 278 279 var eventLinkRegisterLength = eventLinkType == EventToInterruptLinkType.RA2 ? 5 : 9; 280 Registers.ICUEventLinkSetting0.DefineMany(this, (uint)interruptEventLink.Length, (register, registerIndex) => 281 { 282 register 283 .WithValueField(0, eventLinkRegisterLength, out interruptEventLink[registerIndex], name: $"IELS{registerIndex}", 284 changeCallback: (prevVal, val) => 285 { 286 interruptsForEvent[GetEventForEventLink(registerIndex, prevVal)].Remove(registerIndex); 287 interruptsForEvent[GetEventForEventLink(registerIndex, val)].Add(registerIndex); 288 } 289 ) 290 .WithReservedBits(eventLinkRegisterLength, 16 - eventLinkRegisterLength) 291 .WithFlag(16, out interruptPending[registerIndex], FieldMode.Read | FieldMode.WriteZeroToClear, name: $"IR{registerIndex}") 292 .WithReservedBits(17, 7) 293 .WithTaggedFlag($"DTCE{registerIndex}", 24) 294 .WithReservedBits(25, 7) 295 // If there is no event for the interrupt, the event with index 0 is returned, which is never triggered. 296 .WithChangeCallback((_, __) => UpdateEventAndInterrupts(GetEventForInterruptIndex(registerIndex), null, new int[] { registerIndex })) 297 ; 298 }); 299 } 300 301 private readonly IEnumRegisterField<InterruptTrigger>[] externalInterruptTrigger; 302 private readonly IValueRegisterField[] interruptEventLink; 303 private readonly IFlagRegisterField[] interruptPending; 304 305 private readonly EventToInterruptLinkType eventLinkType; 306 private readonly ISet<int>[] interruptsForEvent; 307 private readonly bool[] latestEventState; 308 private readonly IGPIOReceiver nvic; 309 310 private const int NoEventIndex = 0; 311 private const uint DefaultNumberOfExternalInterrupts = 16; 312 private const uint DefaultHighestEventNumber = 0x1DA; 313 private const uint DefaultNumberOfDMACEvents = 8; 314 private const uint DefaultNumberOfNVICOutputs = 96; 315 316 private readonly int[,] eventLinkRA2 = 317 { 318 // GROUP0 GROUP1 GROUP2 GROUP3 GROUP4 GROUP5 GROUP6 GROUP7 319 { 320 // IELS = 0x00 321 // NO_EVENT, NO_EVENT, NO_EVENT, NO_EVENT, NO_EVENT, NO_EVENT, NO_EVENT, NO_EVENT 322 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 323 }, 324 { 325 // IELS = 0x01 326 // PORT_IRQ0, PORT_IRQ1, PORT_IRQ2, PORT_IRQ3, PORT_IRQ0, PORT_IRQ1, PORT_IRQ2, PORT_IRQ3 327 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04 328 }, 329 { 330 // IELS = 0x02 331 // DTC_COMPLETE, LVD_LVD2, FCU_FRDYI, SYSTEM_SNZREQ, DTC_COMPLETE, LVD_LVD2, FCU_FRDYI, SYSTEM_SNZREQ 332 0x09, 0x0E, 0x0C, 0x10, 0x09, 0x0E, 0x0C, 0x10 333 }, 334 { 335 // IELS = 0x03 336 // ICU_SNZCANCEL, AGT1_AGTCMAI, AGT1_AGTCMBI, IWDT_NMIUNDF, ICU_SNZCANCEL, AGT1_AGTCMAI, AGT1_AGTCMBI, IWDT_NMIUNDF 337 0x0B, 0x15, 0x16, 0x17, 0x0B, 0x15, 0x16, 0x17 338 }, 339 { 340 // IELS = 0x04 341 // LVD_LVD1, RTC_ALM, RTC_PRD, RTC_CUP, LVD_LVD1, RTC_ALM, RTC_PRD, RTC_CUP 342 0x0D, 0x19, 0x1A, 0x1B, 0x0D, 0x19, 0x1A, 0x1B 343 }, 344 { 345 // IELS = 0x05 346 // AGT1_AGTI, ADC120_GBADI, ADC120_CMPAI, ADC120_CMPBI, AGT1_AGTI, ADC120_GBADI, ADC120_CMPAI, ADC120_CMPBI 347 0x14, 0x1D, 0x1E, 0x1F, 0x14, 0x1D, 0x1E, 0x1F 348 }, 349 { 350 // IELS = 0x06 351 // WDT_NMIUNDF, ADC120_WCMPUM, IIC0_TEI, IIC0_EEI, WDT_NMIUNDF, ADC120_WCMPUM, IIC0_TEI, IIC0_EEI 352 0x18, 0x21, 0x29, 0x2A, 0x18, 0x21, 0x29, 0x2A 353 }, 354 { 355 // IELS = 0x07 356 // ADC120_ADI, ACMP_LP1, CTSU_CTSURD, CTSU_CTSUFN, ADC120_ADI, ACMP_LP1, CTSU_CTSURD, CTSU_CTSUFN 357 0x1C, 0x24, 0x31, 0x32, 0x1C, 0x24, 0x31, 0x32 358 }, 359 { 360 // IELS = 0x08 361 // ADC120_WCMPM, IIC0_TXI, CAC_MENDI, CAC_OVFI, ADC120_WCMPM, IIC0_TXI, CAC_MENDI, CAC_OVFI 362 0x20, 0x28, 0x36, 0x37, 0x20, 0x28, 0x36, 0x37 363 }, 364 { 365 // IELS = 0x09 366 // ACMP_LP0, CTSU_CTSUWR, CAN0_TXF, CAN0_RXM, ACMP_LP0, CTSU_CTSUWR, CAN0_TXF, CAN0_RXM 367 0x23, 0x30, 0x3A, 0x3B, 0x23, 0x30, 0x3A, 0x3B 368 }, 369 { 370 // IELS = 0x0A 371 // IIC0_RXI, DOC_DOPCI, ELC_SWEVT0, ELC_SWEVT1, IIC0_RXI, DOC_DOPCI, ELC_SWEVT0, ELC_SWEVT1 372 0x27, 0x34, 0x3F, 0x40, 0x27, 0x34, 0x3F, 0x40 373 }, 374 { 375 // IELS = 0x0B 376 // IIC0_WUI, CAC_FERRI, POEG_GROUP0, POEG_GROUP1, IIC0_WUI, CAC_FERRI, POEG_GROUP0, POEG_GROUP1 377 0x2B, 0x35, 0x41, 0x42, 0x2B, 0x35, 0x41, 0x42 378 }, 379 { 380 // IELS = 0x0C 381 // CAN0_ERS, CAN0_RXF, GPT0_CMPC, GPT0_CMPD, CAN0_ERS, CAN0_RXF, GPT0_CMPC, GPT0_CMPD 382 0x38, 0x39, 0x48, 0x49, 0x38, 0x39, 0x48, 0x49 383 }, 384 { 385 // IELS = 0x0D 386 // CAN0_TXM, GPT0_CCMPB, GPT2_CMPC, GPT2_CMPD, CAN0_TXM, GPT0_CCMPB, GPT2_CMPC, GPT2_CMPD 387 0x3C, 0x47, 0x54, 0x55, 0x3C, 0x47, 0x54, 0x55 388 }, 389 { 390 // IELS = 0x0E 391 // GPT0_CCMPA, GPT0_UDF, GPT2_OVF, GPT2_UDF, GPT0_CCMPA, GPT0_UDF, GPT2_OVF, GPT2_UDF 392 0x46, 0x4B, 0x56, 0x57, 0x46, 0x4B, 0x56, 0x57 393 }, 394 { 395 // IELS = 0x0F 396 // GPT0_OVF, GPT2_CCMPB, SCI0_TEI, SCI0_ERI, GPT0_OVF, GPT2_CCMPB, SCI0_TEI, SCI0_ERI 397 0x4A, 0x53, 0x73, 0x74, 0x4A, 0x53, 0x73, 0x74 398 }, 399 { 400 // IELS = 0x10 401 // GPT2_CCMPA, SCI0_TXI, SPI0_SPII, SPI0_SPEI, GPT2_CCMPA, SCI0_TXI, SPI0_SPII, SPI0_SPEI 402 0x52, 0x72, 0x83, 0x84, 0x52, 0x72, 0x83, 0x84 403 }, 404 { 405 // IELS = 0x11 406 // GPT_UVWEDGE, SPI0_SPTI, SPI0_SPTEND, AGT0_AGTI, GPT_UVWEDGE, SPI0_SPTI, SPI0_SPTEND, PORT_IRQ7 407 0x70, 0x82, 0x85, 0x11, 0x70, 0x82, 0x85, 0x08 408 }, 409 { 410 // IELS = 0x12 411 // SCI0_RXI, AES_RDREQ, TRNG_RDREQ, GPT1_CMPD, SCI0_RXI, AES_RDREQ, TRNG_RDREQ, GPT3_CMPD 412 0x71, 0x8C, 0x8D, 0x4F, 0x71, 0x8C, 0x8D, 0x5B 413 }, 414 { 415 // IELS = 0x13 416 // SCI0_AM, AGT0_AGTCMBI, IOPORT_GROUP2, GPT4_CMPD, SCI0_AM, PORT_IRQ5, PORT_IRQ6, GPT4_UDF 417 0x75, 0x13, 0x3E, 0x61, 0x75, 0x06, 0x07, 0x63 418 }, 419 { 420 // IELS = 0x14 421 // SPI0_SPRI, IIC1_TXI, GPT1_CMPC, GPT5_UDF, SPI0_SPRI, IIC1_EEI, MOSC_STOP, GPT5_CMPD 422 0x81, 0x2D, 0x4E, 0x69, 0x81, 0x2F, 0x0F, 0x67 423 }, 424 { 425 // IELS = 0x15 426 // AES_WRREQ, IOPORT_GROUP1, GPT4_CMPC, GPT6_CMPD, AES_WRREQ, GPT1_UDF, GPT3_CMPC, GPT6_UDF 427 0x8B, 0x3D, 0x60, 0x6D, 0x8B, 0x51, 0x5A, 0x6F 428 }, 429 { 430 // IELS = 0x16 431 // AGT0_AGTCMAI, GPT1_CCMPB, GPT5_OVF, GPT7_UDF, PORT_IRQ4, GPT3_CCMPB, GPT4_OVF, GPT7_CMPD 432 0x12, 0x4D, 0x68, 0x9D, 0x05, 0x59, 0x62, 0x9B 433 }, 434 { 435 // IELS = 0x17 436 // IIC1_RXI, GPT3_UDF, GPT6_CMPC, GPT8_CMPD, IIC1_TEI, GPT5_CCMPB, GPT5_CMPC, GPT8_UDF 437 0x2C, 0x5D, 0x6C, 0xA1, 0x2E, 0x65, 0x66, 0xA3 438 }, 439 { 440 // IELS = 0x18 441 // KEY_INTKR, GPT4_CCMPB, GPT7_OVF, GPT9_UDF, GPT1_OVF, GPT7_CCMPB, GPT6_OVF, GPT9_CMPD 442 0x33, 0x5F, 0x9C, 0xA9, 0x50, 0x99, 0x6E, 0xA7 443 }, 444 { 445 // IELS = 0x19 446 // GPT1_CCMPA, GPT6_CCMPB, GPT8_CMPC, SCI1_ERI, GPT3_CCMPA, GPT9_CCMPB, GPT7_CMPC, SCI2_ERI 447 0x4C, 0x6B, 0xA0, 0x7A, 0x58, 0xA5, 0x9A, 0x91 448 }, 449 { 450 // IELS = 0x1A 451 // GPT3_OVF, GPT8_CCMPB, GPT9_OVF, SCI3_ERI, GPT5_CCMPA, SCI1_AM, GPT8_OVF, SCI9_ERI 452 0x5C, 0x9F, 0xA8, 0x96, 0x64, 0x7B, 0xA2, 0x7F 453 }, 454 { 455 // IELS = 0x1B 456 // GPT4_CCMPA, SCI1_TXI, SCI1_TEI, SCI9_AM, GPT7_CCMPA, SCI2_TXI, GPT9_CMPC, SPI1_SPEI 457 0x5E, 0x78, 0x79, 0x80, 0x98, 0x8F, 0xA6, 0x89 458 }, 459 { 460 // IELS = 0x1C 461 // GPT6_CCMPA, SCI2_AM, SCI3_TEI, NO_EVENT, GPT9_CCMPA, SCI9_TXI, SCI2_TEI, NO_EVENT 462 0x6A, 0x92, 0x95, 0x00, 0xA4, 0x7D, 0x90, 0x00 463 }, 464 { 465 // IELS = 0x1D 466 // GPT8_CCMPA, SCI3_TXI, SPI1_SPII, NO_EVENT, SCI2_RXI, SPI1_SPTI, SCI3_AM, NO_EVENT 467 0x9E, 0x94, 0x88, 0x00, 0x8E, 0x87, 0x97, 0x00 468 }, 469 { 470 // IELS = 0x1E 471 // SCI1_RXI, NO_EVENT, NO_EVENT, NO_EVENT, SCI9_RXI, NO_EVENT, SCI9_TEI, NO_EVENT 472 0x77, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x7E, 0x00 473 }, 474 { 475 // IELS = 0x1F 476 // SCI3_RXI, NO_EVENT, NO_EVENT, NO_EVENT, SPI1_SPRI, NO_EVENT, SPI1_SPTEND, NO_EVENT 477 0x93, 0x00, 0x00, 0x00, 0x86, 0x00, 0x8A, 0x00 478 } 479 }; 480 481 public enum EventToInterruptLinkType 482 { 483 RA8, 484 RA6 = RA8, 485 RA4 = RA8, 486 RA2 487 } 488 489 private enum InterruptTrigger 490 { 491 FallingEdge, 492 RisingEdge, 493 BothEdges, 494 ActiveLow, 495 } 496 497 private enum Registers 498 { 499 IRQControl0 = 0x0, 500 NMIPinInterruptControl = 0x100, 501 NonMaskableInterruptEnable = 0x120, 502 NonMaskableInterruptStatusClear = 0x130, 503 NonMaskableInterruptStatus = 0x140, 504 WakeUpInterruptEnable0 = 0x1a0, 505 WakeUpinterruptenableregister1 = 0x1a4, 506 SYSEventLinkSetting = 0x200, 507 DMACEventLinkSetting0 = 0x280, 508 ICUEventLinkSetting0 = 0x300, 509 } 510 } 511 } 512