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