altos: Start work on stm32f1 support
[fw/altos] / src / stm32f1 / stm32f1.h
1 /*
2  * Copyright © 2023 Keith Packard <keithp@keithp.com>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
17  */
18
19 #ifndef _STM32F1_H_
20 #define _STM32F1_H_
21
22 #include <stdint.h>
23
24 typedef volatile uint32_t       vuint32_t;
25 typedef volatile uint16_t       vuint16_t;
26 typedef volatile void *         vvoid_t;
27
28 struct stm_rcc {
29         vuint32_t       cr;
30         vuint32_t       cfgr;
31         vuint32_t       cir;
32         vuint32_t       apb2rstr;
33
34         vuint32_t       apb1rstr;
35         vuint32_t       ahbenr;
36         vuint32_t       apb2enr;
37         vuint32_t       apb1enr;
38
39         vuint32_t       bdcr;
40         vuint32_t       csr;
41         vuint32_t       ahbstr;
42         vuint32_t       cfgr2;
43 };
44
45 extern struct stm_rcc stm_rcc;
46
47 //#define stm_rcc    (*((struct stm_rcc *) 0x40021000))
48
49 #define STM_RCC_CR_RTCPRE       (29)
50 #define  STM_RCC_CR_RTCPRE_HSE_DIV_2    0
51 #define  STM_RCC_CR_RTCPRE_HSE_DIV_4    1
52 #define  STM_RCC_CR_RTCPRE_HSE_DIV_8    2
53 #define  STM_RCC_CR_RTCPRE_HSE_DIV_16   3
54 #define  STM_RCC_CR_RTCPRE_HSE_MASK     3UL
55
56 #define STM_RCC_CR_PLL3RDY      (29)
57 #define STM_RCC_CR_PLL3ON       (28)
58 #define STM_RCC_CR_PLL2RDY      (27)
59 #define STM_RCC_CR_PLL2ON       (26)
60 #define STM_RCC_CR_PLLRDY       (25)
61 #define STM_RCC_CR_PLLON        (24)
62 #define STM_RCC_CR_CSSON        (19)
63 #define STM_RCC_CR_HSEBYP       (18)
64 #define STM_RCC_CR_HSERDY       (17)
65 #define STM_RCC_CR_HSEON        (16)
66 #define STM_RCC_CR_HSICAL       (8)
67 #define STM_RCC_CR_HSITRIM      (3)
68 #define STM_RCC_CR_HSIRDY       (1)
69 #define STM_RCC_CR_HSION        (0)
70
71 #define STM_RCC_CFGR_MCOPRE     (28)
72 #define  STM_RCC_CFGR_MCOPRE_DIV_1      0
73 #define  STM_RCC_CFGR_MCOPRE_DIV_2      1
74 #define  STM_RCC_CFGR_MCOPRE_DIV_4      2
75 #define  STM_RCC_CFGR_MCOPRE_DIV_8      3
76 #define  STM_RCC_CFGR_MCOPRE_DIV_16     4
77 #define  STM_RCC_CFGR_MCOPRE_MASK       7UL
78
79 #define STM_RCC_CFGR_MCO        (24)
80 #define  STM_RCC_CFGR_MCO_DISABLE       0
81 #define  STM_RCC_CFGR_MCO_SYSCLK        4
82 #define  STM_RCC_CFGR_MCO_HSI   5
83 #define  STM_RCC_CFGR_MCO_HSE   6
84 #define  STM_RCC_CFGR_MCO_PLL_2 7
85 #define  STM_RCC_CFGR_MCO_MASK  7UL
86
87 #define STM_RCC_CFGR_USBPRE     (22)
88 #define  STM_RCC_CFGR_USBPRE_1_5        0
89 #define  STM_RCC_CFGR_USBPRE_1          1
90
91 #define STM_RCC_CFGR_PLLMUL     (18)
92 #define  STM_RCC_CFGR_PLLMUL_2          0
93 #define  STM_RCC_CFGR_PLLMUL_3          1
94 #define  STM_RCC_CFGR_PLLMUL_4          2
95 #define  STM_RCC_CFGR_PLLMUL_5          3
96 #define  STM_RCC_CFGR_PLLMUL_6          4
97 #define  STM_RCC_CFGR_PLLMUL_7          5
98 #define  STM_RCC_CFGR_PLLMUL_8          6
99 #define  STM_RCC_CFGR_PLLMUL_9          7
100 #define  STM_RCC_CFGR_PLLMUL_10         8
101 #define  STM_RCC_CFGR_PLLMUL_11         9
102 #define  STM_RCC_CFGR_PLLMUL_12         10
103 #define  STM_RCC_CFGR_PLLMUL_13         11
104 #define  STM_RCC_CFGR_PLLMUL_14         12
105 #define  STM_RCC_CFGR_PLLMUL_15         13
106 #define  STM_RCC_CFGR_PLLMUL_16         14
107 #define  STM_RCC_CFGR_PLLMUL_MASK       0xfUL
108
109 #define STM_RCC_CFGR_PLLXTPRE   (17)
110 #define  STM_RCC_CFGR_PLLXTPRE_1        0
111 #define  STM_RCC_CFGR_PLLXTPRE_2        1
112
113 #define STM_RCC_CFGR_PLLSRC     (16)
114 #define  STM_RCC_CFGR_PLLSRC_HSI_2      0
115 #define  STM_RCC_CFGR_PLLSRC_HSE        1
116
117 #define STM_RCC_CFGR_ADCPRE     (14)
118 #define  STM_RCC_CFGR_ADCPRE_2          0
119 #define  STM_RCC_CFGR_ADCPRE_4          1
120 #define  STM_RCC_CFGR_ADCPRE_6          2
121 #define  STM_RCC_CFGR_ADCPRE_8          3
122
123 #define STM_RCC_CFGR_PPRE2      (11)
124 #define  STM_RCC_CFGR_PPRE2_DIV_1       0
125 #define  STM_RCC_CFGR_PPRE2_DIV_2       4
126 #define  STM_RCC_CFGR_PPRE2_DIV_4       5
127 #define  STM_RCC_CFGR_PPRE2_DIV_8       6
128 #define  STM_RCC_CFGR_PPRE2_DIV_16      7
129 #define  STM_RCC_CFGR_PPRE2_MASK        7UL
130
131 #define STM_RCC_CFGR_PPRE1      (8)
132 #define  STM_RCC_CFGR_PPRE1_DIV_1       0
133 #define  STM_RCC_CFGR_PPRE1_DIV_2       4
134 #define  STM_RCC_CFGR_PPRE1_DIV_4       5
135 #define  STM_RCC_CFGR_PPRE1_DIV_8       6
136 #define  STM_RCC_CFGR_PPRE1_DIV_16      7
137 #define  STM_RCC_CFGR_PPRE1_MASK        7UL
138
139 #define STM_RCC_CFGR_HPRE       (4)
140 #define  STM_RCC_CFGR_HPRE_DIV_1        0
141 #define  STM_RCC_CFGR_HPRE_DIV_2        8
142 #define  STM_RCC_CFGR_HPRE_DIV_4        9
143 #define  STM_RCC_CFGR_HPRE_DIV_8        0xa
144 #define  STM_RCC_CFGR_HPRE_DIV_16       0xb
145 #define  STM_RCC_CFGR_HPRE_DIV_64       0xc
146 #define  STM_RCC_CFGR_HPRE_DIV_128      0xd
147 #define  STM_RCC_CFGR_HPRE_DIV_256      0xe
148 #define  STM_RCC_CFGR_HPRE_DIV_512      0xf
149 #define  STM_RCC_CFGR_HPRE_MASK         0xfUL
150
151 #define STM_RCC_CFGR_SWS        (2)
152 #define  STM_RCC_CFGR_SWS_HSI           0
153 #define  STM_RCC_CFGR_SWS_HSE           1
154 #define  STM_RCC_CFGR_SWS_PLL           2
155 #define  STM_RCC_CFGR_SWS_MASK          3UL
156
157 #define STM_RCC_CFGR_SW         (0)
158 #define  STM_RCC_CFGR_SW_HSI            0
159 #define  STM_RCC_CFGR_SW_HSE            1
160 #define  STM_RCC_CFGR_SW_PLL            2
161 #define  STM_RCC_CFGR_SW_MASK           3UL
162
163 #define STM_RCC_AHBENR_CRCEN    6
164 #define STM_RCC_AHBENR_FLITFEN  4
165 #define STM_RCC_AHBENR_SRAMEN   2
166 #define STM_RCC_AHBENR_DMA2EN   1
167 #define STM_RCC_AHBENR_DMA1EN   0
168
169
170 #define STM_RCC_APB2ENR_USART1EN        14
171 #define STM_RCC_APB2ENR_SPI1EN          12
172 #define STM_RCC_APB2ENR_TIM1EN          11
173 #define STM_RCC_APB2ENR_ADC2EN          10
174 #define STM_RCC_APB2ENR_ADC1EN          9
175 #define STM_RCC_APB2ENR_IOPEEN          6
176 #define STM_RCC_APB2ENR_IOPDEN          5
177 #define STM_RCC_APB2ENR_IOPCEN          4
178 #define STM_RCC_APB2ENR_IOPBEN          3
179 #define STM_RCC_APB2ENR_IOPAEN          2
180 #define STM_RCC_APB2ENR_AFIOEN          0
181
182 #define STM_RCC_APB1ENR_DACEN           29
183 #define STM_RCC_APB1ENR_PWREN           28
184 #define STM_RCC_APB1ENR_BKPEN           27
185 #define STM_RCC_APB1ENR_CAN2EN          26
186 #define STM_RCC_APB1ENR_CAN1EN          25
187 #define STM_RCC_APB1ENR_I2C2EN          22
188 #define STM_RCC_APB1ENR_I2C1EN          21
189 #define STM_RCC_APB1ENR_UART5EN         20
190 #define STM_RCC_APB1ENR_UART4EN         19
191 #define STM_RCC_APB1ENR_USART3EN        18
192 #define STM_RCC_APB1ENR_USART2EN        17
193 #define STM_RCC_APB1ENR_SPI3EN          15
194 #define STM_RCC_APB1ENR_SPI2EN          14
195 #define STM_RCC_APB1ENR_WWDGEN          11
196 #define STM_RCC_APB1ENR_TIM7EN          5
197 #define STM_RCC_APB1ENR_TIM6EN          4
198 #define STM_RCC_APB1ENR_TIM5EN          3
199 #define STM_RCC_APB1ENR_TIM4EN          2
200 #define STM_RCC_APB1ENR_TIM3EN          1
201 #define STM_RCC_APB1ENR_TIM2EN          0
202
203 #define STM_RCC_CSR_LPWRRSTF            (31)
204 #define STM_RCC_CSR_WWDGRSTF            (30)
205 #define STM_RCC_CSR_IWDGRSTF            (29)
206 #define STM_RCC_CSR_SFTRSTF             (28)
207 #define STM_RCC_CSR_PORRSTF             (27)
208 #define STM_RCC_CSR_PINRSTF             (26)
209 #define STM_RCC_CSR_RMVF                (24)
210 #define STM_RCC_CSR_LSIRDY              (1)
211 #define STM_RCC_CSR_LSION               (0)
212
213 struct stm_systick {
214         vuint32_t       ctrl;
215         vuint32_t       load;
216         vuint32_t       val;
217         vuint32_t       calib;
218 };
219
220 extern struct stm_systick stm_systick;
221
222 #define stm_systick     (*((struct stm_systick *) 0xe000e010))
223
224 #define STM_SYSTICK_CTRL_ENABLE         0
225 #define STM_SYSTICK_CTRL_TICKINT        1
226 #define STM_SYSTICK_CTRL_CLKSOURCE      2
227 #define  STM_SYSTICK_CTRL_CLKSOURCE_HCLK_8              0
228 #define  STM_SYSTICK_CTRL_CLKSOURCE_HCLK                1
229 #define STM_SYSTICK_CTRL_COUNTFLAG      16
230
231 /* The NVIC starts at 0xe000e100, so add that to the offsets to find the absolute address */
232
233 struct stm_nvic {
234         vuint32_t       iser[8];        /* 0x000 0xe000e100 Set Enable Register */
235
236         uint8_t         _unused020[0x080 - 0x020];
237
238         vuint32_t       icer[8];        /* 0x080 0xe000e180 Clear Enable Register */
239
240         uint8_t         _unused0a0[0x100 - 0x0a0];
241
242         vuint32_t       ispr[8];        /* 0x100 0xe000e200 Set Pending Register */
243
244         uint8_t         _unused120[0x180 - 0x120];
245
246         vuint32_t       icpr[8];        /* 0x180 0xe000e280 Clear Pending Register */
247
248         uint8_t         _unused1a0[0x200 - 0x1a0];
249
250         vuint32_t       iabr[8];        /* 0x200 0xe000e300 Active Bit Register */
251
252         uint8_t         _unused220[0x300 - 0x220];
253
254         vuint32_t       ipr[60];        /* 0x300 0xe000e400 Priority Register */
255
256         uint8_t         _unused3f0[0xc00 - 0x3f0];
257
258         vuint32_t       cpuid_base;     /* 0xc00 0xe000ed00 CPUID Base Register */
259         vuint32_t       ics;            /* 0xc04 0xe000ed04 Interrupt Control State Register */
260         vuint32_t       vto;            /* 0xc08 0xe000ed08 Vector Table Offset Register */
261         vuint32_t       ai_rc;          /* 0xc0c 0xe000ed0c Application Interrupt/Reset Control Register */
262         vuint32_t       sc;             /* 0xc10 0xe000ed10 System Control Register */
263         vuint32_t       cc;             /* 0xc14 0xe000ed14 Configuration Control Register */
264
265         vuint32_t       shpr7_4;        /* 0xc18 0xe000ed18 System Hander Priority Registers */
266         vuint32_t       shpr11_8;       /* 0xc1c */
267         vuint32_t       shpr15_12;      /* 0xc20 */
268
269         uint8_t         _unusedc18[0xe00 - 0xc24];
270
271         vuint32_t       stir;           /* 0xe00 */
272 };
273
274 extern struct stm_nvic stm_nvic;
275
276 #define stm_nvic (*((struct stm_nvic *) 0xe000e100))
277
278 #define IRQ_REG(irq)    ((irq) >> 5)
279 #define IRQ_BIT(irq)    ((irq) & 0x1f)
280 #define IRQ_MASK(irq)   (1 << IRQ_BIT(irq))
281 #define IRQ_BOOL(v,irq) (((v) >> IRQ_BIT(irq)) & 1)
282
283 static inline void
284 stm_nvic_set_enable(int irq) {
285         stm_nvic.iser[IRQ_REG(irq)] = IRQ_MASK(irq);
286 }
287
288 static inline void
289 stm_nvic_clear_enable(int irq) {
290         stm_nvic.icer[IRQ_REG(irq)] = IRQ_MASK(irq);
291 }
292
293 static inline int
294 stm_nvic_enabled(int irq) {
295         return IRQ_BOOL(stm_nvic.iser[IRQ_REG(irq)], irq);
296 }
297
298 static inline void
299 stm_nvic_set_pending(int irq) {
300         stm_nvic.ispr[IRQ_REG(irq)] = IRQ_MASK(irq);
301 }
302
303 static inline void
304 stm_nvic_clear_pending(int irq) {
305         stm_nvic.icpr[IRQ_REG(irq)] = IRQ_MASK(irq);
306 }
307
308 static inline int
309 stm_nvic_pending(int irq) {
310         return IRQ_BOOL(stm_nvic.ispr[IRQ_REG(irq)], irq);
311 }
312
313 static inline int
314 stm_nvic_active(int irq) {
315         return IRQ_BOOL(stm_nvic.iabr[IRQ_REG(irq)], irq);
316 }
317
318 #define IRQ_PRIO_REG(irq)       ((irq) >> 2)
319 #define IRQ_PRIO_BIT(irq)       (((irq) & 3) << 3)
320 #define IRQ_PRIO_MASK(irq)      (0xff << IRQ_PRIO_BIT(irq))
321
322 static inline void
323 stm_nvic_set_priority(int irq, uint8_t prio) {
324         int             n = IRQ_PRIO_REG(irq);
325         uint32_t        v;
326
327         v = stm_nvic.ipr[n];
328         v &= (uint32_t) ~IRQ_PRIO_MASK(irq);
329         v |= (prio) << IRQ_PRIO_BIT(irq);
330         stm_nvic.ipr[n] = v;
331 }
332
333 static inline uint8_t
334 stm_nvic_get_priority(int irq) {
335         return (stm_nvic.ipr[IRQ_PRIO_REG(irq)] >> IRQ_PRIO_BIT(irq)) & IRQ_PRIO_MASK(0);
336 }
337
338 struct stm_flash_data {
339         vuint16_t       f_size;
340         vuint16_t       unused02;
341         vuint32_t       unused04;
342         vuint32_t       device_id[3];
343 };
344
345 extern struct stm_flash_data    stm_flash_data;
346
347 static inline uint32_t stm_flash_size(void) { return (uint32_t) stm_flash_data.f_size * 1024; }
348
349 #define stm_flash_data  (*((struct stm_flash_data *) 0x1ffff7e0))
350
351 struct stm_gpio {
352         vuint32_t       cr[2];
353         vuint32_t       idr;
354         vuint32_t       odr;
355
356         vuint32_t       bsrr;
357         vuint32_t       brr;
358         vuint32_t       lckr;
359 };
360
361 #define STM_GPIO_CR(y)          ((uint8_t) (y) >> 3)
362 #define STM_GPIO_CR_CNF(y)      ((((uint8_t) (y) & 7) << 2) + 2)
363 #define  STM_GPIO_CR_CNF_INPUT_ANALOG           0
364 #define  STM_GPIO_CR_CNF_INPUT_FLOATING         1
365 #define  STM_GPIO_CR_CNF_INPUT_PULL             2
366 #define  STM_GPIO_CR_CNF_OUTPUT_PUSH_PULL       0
367 #define  STM_GPIO_CR_CNF_OUTPUT_OPEN_DRAIN      1
368 #define  STM_GPIO_CR_CNF_OUTPUT_AF_PUSH_PULL    2
369 #define  STM_GPIO_CR_CNF_OUTPUT_AF_OPEN_DRAIN   3
370 #define  STM_GPIO_CR_CNF_MASK                   3U
371 #define STM_GPIO_CR_MODE(y)     ((((y) & 7) << 2))
372 #define  STM_GPIO_CR_MODE_INPUT                 0
373 #define  STM_GPIO_CR_MODE_OUTPUT_10MHZ          1
374 #define  STM_GPIO_CR_MODE_OUTPUT_2MHZ           2
375 #define  STM_GPIO_CR_MODE_OUTPUT_50MHZ          3
376 #define  STM_GPIO_CR_MODE_MASK                  3U
377
378 static inline void
379 stm_gpio_conf(struct stm_gpio *gpio, int pin, uint8_t mode, uint8_t cnf)
380 {
381         uint8_t         cr = STM_GPIO_CR(pin);
382         uint32_t        v = gpio->cr[cr];
383
384         v &= ~((STM_GPIO_CR_CNF_MASK << STM_GPIO_CR_CNF(pin)) |
385                (STM_GPIO_CR_MODE_MASK << STM_GPIO_CR_MODE(pin)));
386         v |= (mode << STM_GPIO_CR_MODE(pin)) | (cnf << STM_GPIO_CR_CNF(pin));
387         gpio->cr[cr] = v;
388 }
389
390 static inline void
391 stm_gpio_set(struct stm_gpio *gpio, int pin, uint8_t value) {
392         /* Use the bit set/reset register to do this atomically */
393         gpio->bsrr = ((uint32_t) (value ^ 1) << (pin + 16)) | ((uint32_t) value << pin);
394 }
395
396 static inline void
397 stm_gpio_set_mask(struct stm_gpio *gpio, uint16_t bits, uint16_t mask) {
398         /* Use the bit set/reset register to do this atomically */
399         gpio->bsrr = ((uint32_t) (~bits & mask) << 16) | ((uint32_t) (bits & mask));
400 }
401
402 static inline void
403 stm_gpio_set_bits(struct stm_gpio *gpio, uint16_t bits) {
404         gpio->bsrr = bits;
405 }
406
407 static inline void
408 stm_gpio_clr_bits(struct stm_gpio *gpio, uint16_t bits) {
409         gpio->bsrr = ((uint32_t) bits) << 16;
410 }
411
412 static inline uint8_t
413 stm_gpio_get(struct stm_gpio *gpio, int pin) {
414         return (gpio->idr >> pin) & 1;
415 }
416
417 static inline uint16_t
418 stm_gpio_get_all(struct stm_gpio *gpio) {
419         return (uint16_t) gpio->idr;
420 }
421
422 extern struct stm_gpio stm_gpioa;
423 extern struct stm_gpio stm_gpiob;
424 extern struct stm_gpio stm_gpioc;
425 extern struct stm_gpio stm_gpiod;
426 extern struct stm_gpio stm_gpioe;
427
428 #define stm_gpioe  (*((struct stm_gpio *) 0x40011800))
429 #define stm_gpiod  (*((struct stm_gpio *) 0x40011400))
430 #define stm_gpioc  (*((struct stm_gpio *) 0x40011000))
431 #define stm_gpiob  (*((struct stm_gpio *) 0x40010c00))
432 #define stm_gpioa  (*((struct stm_gpio *) 0x40010800))
433
434 struct stm_afio {
435         vuint32_t       evcr;
436         vuint32_t       mapr;
437         vuint32_t       exticr[4];
438         vuint32_t       mapr2;
439 };
440
441 extern struct stm_afio stm_afio;
442
443 #define stm_afio        (*((struct stm_afio *) 0x40010000))
444
445 #define isr_decl(name) void stm_ ## name ## _isr(void)
446
447 isr_decl(halt);
448 isr_decl(ignore);
449
450 isr_decl(nmi);
451 isr_decl(hardfault);
452 isr_decl(memmanage);
453 isr_decl(busfault);
454 isr_decl(usagefault);
455 isr_decl(svc);
456 isr_decl(debugmon);
457 isr_decl(pendsv);
458 isr_decl(systick);
459 isr_decl(wwdg);
460 isr_decl(pvd);
461 isr_decl(tamper_stamp);
462 isr_decl(rtc_wkup);
463 isr_decl(flash);
464 isr_decl(rcc);
465 isr_decl(exti0);
466 isr_decl(exti1);
467 isr_decl(exti2);
468 isr_decl(exti3);
469 isr_decl(exti4);
470 isr_decl(dma1_channel1);
471 isr_decl(dma1_channel2);
472 isr_decl(dma1_channel3);
473 isr_decl(dma1_channel4);
474 isr_decl(dma1_channel5);
475 isr_decl(dma1_channel6);
476 isr_decl(dma1_channel7);
477 isr_decl(adc1_2);
478 isr_decl(usb_hp);
479 isr_decl(usb_lp);
480 isr_decl(can_rx1);
481 isr_decl(can_sce);
482 isr_decl(exti9_5);
483 isr_decl(tim1_brk);
484 isr_decl(tim1_up);
485 isr_decl(tim1_trg_com);
486 isr_decl(tim1_cc);
487 isr_decl(tim2);
488 isr_decl(tim3);
489 isr_decl(tim4);
490 isr_decl(i2c1_ev);
491 isr_decl(i2c1_er);
492 isr_decl(i2c2_ev);
493 isr_decl(i2c2_er);
494 isr_decl(spi1);
495 isr_decl(spi2);
496 isr_decl(usart1);
497 isr_decl(usart2);
498 isr_decl(usart3);
499 isr_decl(exti15_10);
500 isr_decl(rtc_alarm);
501 isr_decl(usb_wakeup);
502 isr_decl(tim8_brk);
503 isr_decl(tim8_up);
504 isr_decl(tim8_trg_com);
505 isr_decl(tim8_cc);
506 isr_decl(adc3);
507 isr_decl(fsmc);
508 isr_decl(sdio);
509 isr_decl(tim5);
510 isr_decl(spi3);
511 isr_decl(uart4);
512 isr_decl(uart5);
513 isr_decl(tim6);
514 isr_decl(tim7);
515 isr_decl(dma2_channel1);
516 isr_decl(dma2_channel2);
517 isr_decl(dma2_channel3);
518 isr_decl(dma2_channel4_5);
519
520 #undef isr_decl
521
522 #endif