|
8 | 8 | #include <zephyr/irq.h>
|
9 | 9 | #include <kswap.h>
|
10 | 10 | #include <zephyr/tracing/tracing.h>
|
| 11 | +#include <zephyr/arch/rx/sw_nmi_table.h> |
11 | 12 |
|
12 | 13 | typedef void (*fp)(void);
|
13 | 14 | extern void _start(void);
|
14 | 15 | extern void z_rx_irq_exit(void);
|
| 16 | +extern void R_BSP_SoftwareReset(void); |
| 17 | + |
| 18 | +#define NMI_NMIST_MASK 0x01 |
| 19 | +#define NMI_OSTST_MASK 0x02 |
| 20 | +#define NMI_IWDTST_MASK 0x08 |
| 21 | +#define NMI_LVD1ST_MASK 0x10 |
| 22 | +#define NMI_LVD2ST_MASK 0x20 |
15 | 23 |
|
16 | 24 | /* this is mainly to give Visual Studio Code peace of mind */
|
17 | 25 | #ifndef CONFIG_GEN_IRQ_START_VECTOR
|
@@ -97,9 +105,9 @@ static void __ISR__ INT_Excep_FloatingPoint(void)
|
97 | 105 | static void __ISR__ INT_NonMaskableInterrupt(void)
|
98 | 106 | {
|
99 | 107 | REGISTER_SAVE();
|
100 |
| - ISR_DIRECT_HEADER(); |
101 |
| - z_fatal_error(K_ERR_CPU_EXCEPTION, NULL); |
102 |
| - ISR_DIRECT_FOOTER(1); |
| 108 | + int nmi_vector = get_nmi_request(); |
| 109 | + |
| 110 | + handle_nmi(nmi_vector); |
103 | 111 | REGISTER_RESTORE_EXIT();
|
104 | 112 | }
|
105 | 113 |
|
@@ -141,6 +149,64 @@ static void __ISR__ reserved_isr(void)
|
141 | 149 | /* wrapper for z_rx_context_switch_isr, defined in switch.S */
|
142 | 150 | extern void __ISR__ switch_isr_wrapper(void);
|
143 | 151 |
|
| 152 | +void nmi_enable(uint8_t nmi_vector, nmi_callback_t callback, void *arg) |
| 153 | +{ |
| 154 | + if (nmi_vector >= NMI_TABLE_SIZE) { |
| 155 | + return; |
| 156 | + } |
| 157 | + |
| 158 | + _nmi_vector_table[nmi_vector].callback = callback; |
| 159 | + _nmi_vector_table[nmi_vector].arg = arg; |
| 160 | +} |
| 161 | + |
| 162 | +int get_nmi_request(void) |
| 163 | +{ |
| 164 | + uint32_t nmi_status = ICU.NMISR.BYTE; |
| 165 | + |
| 166 | + if (nmi_status & NMI_NMIST_MASK) { |
| 167 | + return 0; |
| 168 | + } else if (nmi_status & NMI_OSTST_MASK) { |
| 169 | + return 1; |
| 170 | + } else if (nmi_status & NMI_IWDTST_MASK) { |
| 171 | + return 2; |
| 172 | + } else if (nmi_status & NMI_LVD1ST_MASK) { |
| 173 | + return 3; |
| 174 | + } else if (nmi_status & NMI_LVD2ST_MASK) { |
| 175 | + return 4; |
| 176 | + } |
| 177 | + |
| 178 | + return NMI_TABLE_SIZE; |
| 179 | +} |
| 180 | + |
| 181 | +void handle_nmi(uint8_t nmi_vector) |
| 182 | +{ |
| 183 | + if (nmi_vector >= NMI_TABLE_SIZE) { |
| 184 | + return; |
| 185 | + } |
| 186 | + |
| 187 | + _nmi_vector_table[nmi_vector].callback(_nmi_vector_table[nmi_vector].arg); |
| 188 | + |
| 189 | + switch (nmi_vector) { |
| 190 | + case 0: |
| 191 | + ICU.NMICLR.BIT.NMICLR = 0x01; |
| 192 | + break; |
| 193 | + case 1: |
| 194 | + ICU.NMICLR.BIT.OSTCLR = 0x01; |
| 195 | + break; |
| 196 | + case 2: |
| 197 | + ICU.NMICLR.BIT.IWDTCLR = 0x01; |
| 198 | + break; |
| 199 | + case 3: |
| 200 | + ICU.NMICLR.BIT.LVD1CLR = 0x01; |
| 201 | + break; |
| 202 | + case 4: |
| 203 | + ICU.NMICLR.BIT.LVD2CLR = 0x01; |
| 204 | + break; |
| 205 | + default: |
| 206 | + break; |
| 207 | + } |
| 208 | +} |
| 209 | + |
144 | 210 | /* this macro is used to define "demuxing" ISRs for all interrupts that are
|
145 | 211 | * handled through Zephyr's software isr table.
|
146 | 212 | */
|
@@ -394,6 +460,15 @@ INT_DEMUX(253);
|
394 | 460 | INT_DEMUX(254);
|
395 | 461 | INT_DEMUX(255);
|
396 | 462 |
|
| 463 | +struct nmi_vector_entry _nmi_vector_table[NMI_TABLE_SIZE] = { |
| 464 | + {(nmi_callback_t)0xFFFFFFFFU, (void *)0xFFFFFFFFU}, /* NMI Pin Interrupt */ |
| 465 | + {(nmi_callback_t)0xFFFFFFFFU, |
| 466 | + (void *)0xFFFFFFFFU}, /* Oscillation Stop Detection Interrupt */ |
| 467 | + {(nmi_callback_t)0xFFFFFFFFU, (void *)0xFFFFFFFFU}, /* IWDT Underflow/Refresh Error */ |
| 468 | + {(nmi_callback_t)0xFFFFFFFFU, (void *)0xFFFFFFFFU}, /* Voltage Monitoring 1 Interrupt */ |
| 469 | + {(nmi_callback_t)0xFFFFFFFFU, (void *)0xFFFFFFFFU}, /* Voltage Monitoring 2 Interrupt */ |
| 470 | +}; |
| 471 | + |
397 | 472 | const void *FixedVectors[] FVECT_SECT = {
|
398 | 473 | /* 0x00-0x4c: Reserved, must be 0xff (according to e2 studio example) */
|
399 | 474 | /* Reserved for OFSM */
|
|
0 commit comments