# RA4M1 Interrupts

**URL:** <https://forum.arduino.cc/t/ra4m1-interrupts/1346513>\
**Category:** UNO R4 WiFi\
**Created:** [October 17, 2023, 4:23am UTC](https://forum.arduino.cc/t/ra4m1-interrupts/1346513 "2023-10-17T04:23:19Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![flynace](https://avatars.discourse-cdn.com/v4/letter/f/e95f7d/32.png) [@flynace](https://forum.arduino.cc/u/flynace)\
**Post date:** [October 17, 2023, 4:23am UTC](https://forum.arduino.cc/t/ra4m1-interrupts/1346513/1 "2023-10-17T04:23:19Z")

</div>

Continuing the discussion from [**RA4M1 Interrupts**](https://web.archive.org/web/20241209163044/https://forum.arduino.cc/t/ra4m1-interrupts/1179222):

> [@](#):
>
> I want to use the CAC unit on [this thread](https://forum.arduino.cc/t/can-we-fix-the-rtc/1179142) and my first issue is that there's not any FSP support for that function in our core. There's also not a good way to add the interrupt handler I need without modifying core files. So I started a new thread to doc this part and I'll link it back. This issue is going to repeat itself and I want to have a good set of notes for next time.
> 
> **Interrupts on the RA4M1**
> 
> The interrupt controller works differently on the RA4M1 chip on the UNO-R4 than it does on the old AVR micro on the UNO-R3. On the old chip the interrupt vector table was set in memory and there was an entry for each possible interrupt source. If you wanted to service an interrupt then you would set the pointer in the appropriate slot in the vector table to your function and then enable the interrupt in whatever register turned it on.
> 
> With the new chip, there are non-maskable interrupts that work the same way as the old chips. These cover things like watchdog timer interrupts and voltage monitors. But there are also a number of ICU Event Link slots that can be used as interrupts where you can select the source. This allows us to have a lot more possible interrupt sources than there are slots in the vector table. We just use the ones we want.
> 
> On our RA4M1 we get 32 of these slots controlled by the IELSR[0-31] registers. Each register has a 8 bit selection for the event link. This chooses the interrupt source for that interrupt. For example if you set it to 0x5D then this interrupt will service the overflow interrupt for GPT0.
> 
> A list of interrupt sources can be found in Table 13.4
> 
> Some of these interrupts can do some neat extra things. For instance, some of them can also trigger the DTC or DMA to automatically transfer data without the CPU. This might be handy for a display driver where you have a timer interrupt that is refreshing a display buffer or something. Using the DMA or DTC that could be done without code.
> 
> **Interrupt Code**
> 
> The problem that we have here is that everything is controlled through the `IRQManager` class in `IRQManager.h`. It contains code that is specific to all sorts of interrupts, but it does not cover them all. For instance, I want to use the CAC interrupt and it is not available here.
> 
> I could add code elsewhere to add the even link I want, but I am afraid to mess with this table without letting this IRQManager know. It has an index called `last_interrupt_index` so it knows where to put the next IRQ. If I start writing to the table and then some other code adds a new IRQ, then it would overwrite the one I just added.
> 
> If we look at all the different entries in `addPeripheral` or any of the `addTimer...` interrupt functions they all seem to follow a standard pattern. I think the thing to do will be to start here and add a function that allows us to add a general ISR as long as we have the mask.
> 
> This is the function I'm adding
> 
> ```arduino
> // allows to put any maskable interrupt into the table and keep last_interrupt_index up to date. 
> bool IRQManager::addMaskableInterrupt(uint8_t eventMask, Irq_f fnc /*= nullptr*/) {
> /* getting the address of the current location of the irq vector table */
> volatile uint32_t *irq_ptr = (volatile uint32_t *)SCB->VTOR;
> /* set the displacement to the "programmable" part of the table */
> irq_ptr += FIXED_IRQ_NUM;
> bool rv = true;
>     
> __disable_irq();
>     
> *(irq_ptr + last_interrupt_index) = (uint32_t)fnc;
> R_ICU->IELSR[last_interrupt_index] = eventMask;
> R_BSP_IrqDisable((IRQn_Type)last_interrupt_index);
> R_BSP_IrqStatusClear((IRQn_Type)last_interrupt_index);
> NVIC_SetPriority((IRQn_Type)last_interrupt_index, 12);
> R_BSP_IrqEnable ((IRQn_Type)last_interrupt_index);
>     
> last_interrupt_index++;
>     
> __enable_irq();
>     
> return rv;
> 
> }
> 
> ```
> 
> It compiles. I'll be back to this soon to see if it works.

You might also be interested in @susan-parker 's similar investigations...

[https://forum.arduino.cc/t/uno-r4-schematic/1160263/21](https://forum.arduino.cc/t/uno-r4-schematic/1160263/21)

[https://github.com/TriodeGirl/Arduino\_\_UNO\_R4\_CTC\_Clock\_Frequency\_Accuracy\_Measurement\_Circuit](https://github.com/TriodeGirl/Arduino__UNO_R4_CTC_Clock_Frequency_Accuracy_Measurement_Circuit)

[https://forum.arduino.cc/t/uno-r4-attachinterrupt/1148214/25](https://forum.arduino.cc/t/uno-r4-attachinterrupt/1148214/25)

---

<div class="post-metadata">

**Author:** ![westfw](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/westfw/32/213443_2.png) [@westfw](https://forum.arduino.cc/u/westfw)\
**Post date:** [October 20, 2023, 12:33am UTC](https://forum.arduino.cc/t/ra4m1-interrupts/1346513/4 "2023-10-20T00:33:05Z")

</div>

Did you figure out a way to map more than 32 simultaneous peripheral interrupts to the NVIC at the same time? This is a really strange thing that Renesas has done, given that the CM4 architecture allows for 496 external interrupts. I was hoping that there was at least a way to say "map all of the USART interrupts to this NVIC vector", but I didn't see anything in my relatively brief reading of the datasheet.

(I also find the IRQManager to be unnecessarily complex. I would have thought that a constant mapping between the "core" interrupts and the NVIC would have been sufficient, with a simpler scheme to add additional interrupts from user requests.)

(questionable code on top of questionable hardware. And both without explanations as to "WHY??" Sigh. I applaud your willingness to delve into it!)

---

<div class="post-metadata">

**Author:** ![bplu4t2f](https://avatars.discourse-cdn.com/v4/letter/b/f04885/32.png) [@bplu4t2f](https://forum.arduino.cc/u/bplu4t2f)\
**Post date:** [April 9, 2024, 1:43pm UTC](https://forum.arduino.cc/t/ra4m1-interrupts/1346513/9 "2024-04-09T13:43:51Z")

</div>

Just stumbled across this, and now I'm a bit confused.

I was under the impression that the whole point of the event link controller is to _avoid_ generating CPU interrupts, and instead connecting actions on peripherals directly with interrupts from other peripherals, without having the CPU run any software code.

See [The Event Link Controller – Automatically Manage Low Level System Tasks on RA MCUs](https://www.renesas.com/us/en/blogs/event-link-controller-automatically-manage-low-level-system-tasks-ra-mcus)

As such I assumed that using IELSR to generate user callbacks is sort of missing the point, but... A glance in the RA4M1 user manual shows that actually the interrupt vector table almost entirely consists of IELSR entries, like there aren't even any "classic" interrupts in the table for any peripheral. I would have expected to find at least one entry for each peripheral in there.

That means, as far as I understand, going through the event link stuff is indeed as you say the only way to attach an ISR to a peripheral... Which means that you can actually only have up to 32 peripheral events with an ISR at any given time

Something tells me I'm missing something here. I guess 32 is "enough". But it doesn't feel "comfortably enough" - keeping in mind that many peripherals have multiple events that need to be handled...

---

<div class="post-metadata">

**Author:** ![bplu4t2f](https://avatars.discourse-cdn.com/v4/letter/b/f04885/32.png) [@bplu4t2f](https://forum.arduino.cc/u/bplu4t2f)\
**Post date:** [April 9, 2024, 10:51pm UTC](https://forum.arduino.cc/t/ra4m1-interrupts/1346513/11 "2024-04-09T22:51:35Z")

</div>

OK. I don't think Interrupt Link Controller is an official term though.  
The only 2 results I get for that on google are both authored by you, one is your github page, and the other is some thread in this forum.  
According to the RA4M1 manual, the thing that fires interrupts to the NVIC is the same thing that would also enable the DTC (if applicable and if supported for the respective event).  
It's just that not all events can be linked to DTC or DMA (Table 13.4 in the manual).

Where did you find the info that those are 2 separate entities?

---

<div class="post-metadata">

**Author:** ![jose5555](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/jose5555/32/1098976_2.png) [@jose5555](https://forum.arduino.cc/u/jose5555)\
**Post date:** [November 25, 2024, 5:22pm UTC](https://forum.arduino.cc/t/ra4m1-interrupts/1346513/16 "2024-11-25T17:22:38Z")

</div>

Hello

I'm reading and studying many pages where you talk about interruptions.

I've read; That although you can use the instructions attachinterrupt() 0 and 1 just like the arduino R3  
But in the arduino R4 we have a lot of inputs that can be used as interruptions....

I'm in a project reading 3 inputs of the pulse counter, mounted in (A1, A2 and A3 used as digital inputs, which I don't know if they have anything to do with 17, 18 and 19) I can put them in other inputs (2, 8 and 13)

So far so good

Now I'm trying to transfer it to your code... and I'm sorry but as much as I read your instructions... I can't figure it out.

I'm reading the code and I don't know where to adapt it and I can't find other examples.

Can you help me?

Thank you very much

---

<div class="post-metadata">

**Author:** ![KurtE](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/kurte/32/1246572_2.png) [@KurtE](https://forum.arduino.cc/u/KurtE)\
**Post date:** [November 25, 2024, 6:08pm UTC](https://forum.arduino.cc/t/ra4m1-interrupts/1346513/18 "2024-11-25T18:08:49Z")

</div>

It has been a while since I looked at this, but I believe the UNO R4 supports  
interrupts on several different pins. Although the documentation:  
[attachInterrupt() - Arduino Reference](https://reference.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/)  
Shows it for only pins 2 and 3...

However if you look at the advanced sections of the pin outs for the two R4 boards, for example the Minima:

 ![image](https://europe1.discourse-cdn.com/arduino/original/4X/3/a/6/3a696f6e2e48b575118631e76a93d5d7e7ca5bb7.png)

You will see that there are several pins marked with Interrupts. I did quick and dirty arrows to the columns that show this. I am pretty sure that many of these pins that are marked  
with these numbers can be used.... However, there are compilications,  
That is you will notice I highlighted 3 of them, which all 3 of which are IRQ1. So there is  
only one unique interrupt for these three pins, so probably only use one of them.

Also I don't remember if using any of these pins, might interfere with other things such as  
PWM.

I believe the new API that @Delta_G mentioned in post15, is for other more generic  
things like example Timer interrupts, or ...

But could easily be wrong.

Good luck

---

<div class="post-metadata">

**Author:** ![KurtE](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/kurte/32/1246572_2.png) [@KurtE](https://forum.arduino.cc/u/KurtE)\
**Post date:** [November 25, 2024, 6:34pm UTC](https://forum.arduino.cc/t/ra4m1-interrupts/1346513/20 "2024-11-25T18:34:16Z")

</div>

AFAIK - The attachInterrupt code: (Interrupt.cpp)  
Uses the function: int ch = pin2IrqChannel(pinNumber);

Which uses the g\_pin\_cfg[] array which has the mapping of Arduino pin numbers  
to BSP pin/port plus pointer to data about each pin...

```arduino
extern "C" const PinMuxCfg_t g_pin_cfg[] = { 
  { BSP_IO_PORT_03_PIN_01, P301 }, /* (0) D0 ------------------------- DIGITAL */
  { BSP_IO_PORT_03_PIN_02, P302 }, /* (1) D1 */
  { BSP_IO_PORT_01_PIN_05, P105 }, /* (2) D2 */
  { BSP_IO_PORT_01_PIN_04, P104 }, /* (3) D3~ */
  { BSP_IO_PORT_01_PIN_03, P103 }, /* (4) D4 */
  { BSP_IO_PORT_01_PIN_02, P102 }, /* (5) D5~ */
  { BSP_IO_PORT_01_PIN_06, P106 }, /* (6) D6~ */
  { BSP_IO_PORT_01_PIN_07, P107 }, /* (7) D7 */
  { BSP_IO_PORT_03_PIN_04, P304 }, /* (8) D8 */
  { BSP_IO_PORT_03_PIN_03, P303 }, /* (9) D9~ */

,,,

```

The \variants\MINIMA\pinmux.inc: file  
So for pin2 it use P105, which has:

```arduino
const uint16_t P105[] = {
PIN_PWM|CHANNEL_1|PWM_CHANNEL_A|GPT_ODD_CFG,
PIN_INTERRUPT|CHANNEL_0|LAST_ITEM_GUARD
};

```

Which maps the pin to Interrupt Channel 0...

Likewise if you look at D8, it has P304

```arduino
const uint16_t P304[] = {
PIN_PWM|CHANNEL_7|PWM_CHANNEL_A|GPT_ODD_CFG,
PIN_INTERRUPT|CHANNEL_9|LAST_ITEM_GUARD
};

```

So it maps to Int 9...

---

<div class="post-metadata">

**Author:** ![jose5555](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/jose5555/32/1098976_2.png) [@jose5555](https://forum.arduino.cc/u/jose5555)\
**Post date:** [November 25, 2024, 6:50pm UTC](https://forum.arduino.cc/t/ra4m1-interrupts/1346513/22 "2024-11-25T18:50:55Z")

</div>

Thanks for your quick reply:  
As far as I've read attachInterrupt only works like in the Arduino R3 (0 and 1) just like in the Arduino R3.

Delta\_G, I think you've done a great job. The problem I have when trying to use your libraries is that I don't understand how to use the codes to make the libraries work, so it's impossible for me to use an interrupt in the code.

If I generate the code for my project, I understand that we should copy:

```arduino
#include "IRQManager.h"

volatile bool interruptFired = false; //The variables we need

GenericIrqCfg_t cfg; //We should copy this as is to generate the cfg

void setup() {

R_ICU->IRQCR[0] = 0xB0; // Configure some peripheral for an interrupt... I understand that IRQCR[0] corresponds to interrupt group 0 and 0xB0; .... Sorry, I don't know where it comes from

cfg.irq = FSP_INVALID_VECTOR; //It is copied as is
cfg.ipl = 12; // this is what you say is the sensitivity (for now, as is)
cfg.event = ELC_EVENT_ICU_IRQ0; // Does IRQ0 refer to interrupt group 0?

```

What if I want to add another 2 interrupts?

Sorry, in these lines, I don't understand what you are doing: (I don't know what variables you are moving)

```arduino
R_PFS->PORT[1].PIN[5].PmnPFS = (1 << R_PFS_PORT_PIN_PmnPFS_PCR_Pos) | (1 << R_PFS_PORT_PIN_PmnPFS_ISEL_Pos);

void Myirq0_callback() {
R_ICU->IELSR[cfg.irq] &= ~(R_ICU_IELSR_IR_Msk);
interruptFired = true;
}

```

I hope that the explanations are not only useful to me, but also to anyone who tries to program interrupts.

---

<div class="post-metadata">

**Author:** ![KurtE](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/kurte/32/1246572_2.png) [@KurtE](https://forum.arduino.cc/u/KurtE)\
**Post date:** [November 25, 2024, 8:10pm UTC](https://forum.arduino.cc/t/ra4m1-interrupts/1346513/24 "2024-11-25T20:10:25Z")

</div>

> [@Delta\_G](#):
>
> How does it deal with pins that have the same IRQ number?

My assumption, is they ignore the problem. Could easily be last one wins. Or first one wins, or it faults...

I know I should try it out, but my R4s are put away right now... Playing with GIGAs... My backup Giga arrived at my mailbox today... They have a pretty good Black Friday sale going on:  
[SHOP THE BEST DEALS! — Arduino Online Shop](https://store-usa.arduino.cc/collections/black-friday)  
Did not see GIGA on that list, but my eyes may have skipped over them  
[Arduino GIGA R1 WiFi — Arduino Online Shop](https://store-usa.arduino.cc/products/giga-r1-wifi?pr_prod_strat=jac&pr_rec_id=33ed14d36&pr_rec_pid=7178001776847&pr_ref_pid=7235556344015&pr_seq=uniform)

---

<div class="post-metadata">

**Author:** ![jose5555](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/jose5555/32/1098976_2.png) [@jose5555](https://forum.arduino.cc/u/jose5555)\
**Post date:** [November 26, 2024, 7:11pm UTC](https://forum.arduino.cc/t/ra4m1-interrupts/1346513/25 "2024-11-26T19:11:06Z")

</div>

Hi everyone  
I've been doing some tests.  
I've tried using the Delta\_G code... Sorry, you're way beyond my level.

I thought of trying a code based on attachInterrupt(). According to Arduino's instructions, it only works on inputs 2 and 3.  
I've tried more inputs and surprise! All the inputs marked as interrupt work. (The ones KurtE indicated in the photo)

Here's a little code for you.

```arduino

const int button1 = A1;
const int button2 = A2;
const int button3 = A3;
const int threshold = 200;
int cont = 0;
volatile int ISRcont = 0;
volatile int lastTime = 0;
void setup(){
  Serial.begin(9600);
  pinMode(button1, INPUT);
  pinMode(button2, INPUT);
  pinMode(button3, INPUT);
  attachInterrupt(digitalPinToInterrupt(button1), counter, CHANGE);
   attachInterrupt(digitalPinToInterrupt(button2), counter, CHANGE);
    attachInterrupt(digitalPinToInterrupt(button3), counter, CHANGE);
 delay(100);
 
}
void loop(){
  if(cont != ISRcont){
    cont = ISRcont;
    Serial.print(digitalRead(A1));Serial.print(digitalRead(A2));Serial.print(digitalRead(A3));
    Serial.print (" ");
    Serial.println(cont);
  } 
  delay(10);
 // Serial.println( digitalPinToInterrupt(button));
}
void counter(){
  if((millis()-lastTime) > threshold){
    ISRcont++;
    lastTime = millis();
  }
}

```

In my case, I'm trying to see what happens on the 3 inputs of the pulse counter.  
As you can see, it's A1, A2 and A3 and it seems to work. (I've tried with 2,8... and it also works. It doesn't work on 5, which is not interrupt)

For my part, it seems to be solved. Thank you very much for your help.
