Merge branch 'master' of ssh://git.gag.com/scm/git/fw/altos
[fw/altos] / src / stmf0 / ao_interrupt.c
1 /*
2  * Copyright © 2012 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 #include <ao.h>
20 #include "stm32f0.h"
21 #include <string.h>
22 #include <ao_boot.h>
23
24 #ifndef IS_FLASH_LOADER
25 #error Should define IS_FLASH_LOADER
26 #define IS_FLASH_LOADER 0
27 #endif
28
29 #ifndef RELOCATE_INTERRUPT
30 #if !IS_FLASH_LOADER
31 #define RELOCATE_INTERRUPT      1
32 #endif
33 #endif
34
35 extern void main(void);
36 extern char __stack__;
37 extern char __text_start__, __text_end__;
38 extern char _start__, _end__;
39 extern char __bss_start__, __bss_end__;
40 #if RELOCATE_INTERRUPT
41 extern char __interrupt_rom__, __interrupt_start__, __interrupt_end__;
42 #endif
43
44 /* Interrupt functions */
45
46 void stm_halt_isr(void)
47 {
48         ao_panic(AO_PANIC_CRASH);
49 }
50
51 void stm_ignore_isr(void)
52 {
53 }
54
55 const void *stm_interrupt_vector[];
56
57 uint32_t
58 stm_flash_size(void) {
59         uint16_t        dev_id = stm_dev_id();
60         uint16_t        kbytes = 0;
61
62         switch (dev_id) {
63         case 0x445:
64                 kbytes = stm_flash_size_04x.f_size;
65                 break;
66         }
67         return (uint32_t) kbytes * 1024;
68 }
69
70 void start(void)
71 {
72 #if AO_BOOT_CHAIN
73         if (ao_boot_check_chain()) {
74 #if AO_BOOT_PIN
75                 ao_boot_check_pin();
76 #endif
77         }
78 #endif
79         /* Turn on syscfg */
80         stm_rcc.apb2enr |= (1 << STM_RCC_APB2ENR_SYSCFGCOMPEN);
81
82 #if RELOCATE_INTERRUPT
83         memcpy(&__interrupt_start__, &__interrupt_rom__, &__interrupt_end__ - &__interrupt_start__);
84         stm_syscfg.cfgr1 = (stm_syscfg.cfgr1 & ~(STM_SYSCFG_CFGR1_MEM_MODE_MASK << STM_SYSCFG_CFGR1_MEM_MODE)) |
85                 (STM_SYSCFG_CFGR1_MEM_MODE_SRAM << STM_SYSCFG_CFGR1_MEM_MODE);
86 #else
87         /* Switch to Main Flash mode (DFU loader leaves us in System mode) */
88         stm_syscfg.cfgr1 = (stm_syscfg.cfgr1 & ~(STM_SYSCFG_CFGR1_MEM_MODE_MASK << STM_SYSCFG_CFGR1_MEM_MODE)) |
89                 (STM_SYSCFG_CFGR1_MEM_MODE_MAIN_FLASH << STM_SYSCFG_CFGR1_MEM_MODE);
90 #endif
91         memcpy(&_start__, &__text_end__, &_end__ - &_start__);
92         memset(&__bss_start__, '\0', &__bss_end__ - &__bss_start__);
93         main();
94 }
95
96 #define STRINGIFY(x) #x
97
98 #define isr(name) \
99         void __attribute__ ((weak)) stm_ ## name ## _isr(void); \
100         _Pragma(STRINGIFY(weak stm_ ## name ## _isr = stm_ignore_isr))
101
102 #define isr_halt(name) \
103         void __attribute__ ((weak)) stm_ ## name ## _isr(void); \
104         _Pragma(STRINGIFY(weak stm_ ## name ## _isr = stm_halt_isr))
105
106 isr(nmi)
107 isr_halt(hardfault)
108 isr_halt(memmanage)
109 isr_halt(busfault)
110 isr_halt(usagefault)
111 isr(svc)
112 isr(debugmon)
113 isr(pendsv)
114 isr(systick)
115 isr(wwdg)
116 isr(pvd)
117 isr(rtc)
118 isr(flash)
119 isr(rcc_crs)
120 isr(exti0_1)
121 isr(exti2_3)
122 isr(exti4_15)
123 isr(tsc)
124 isr(dma_ch1)
125 isr(dma_ch2_3)
126 isr(dma_ch4_5_6)
127 isr(adc_comp)
128 isr(tim1_brk_up_trg_com)
129 isr(tim1_cc)
130 isr(tim2)
131 isr(tim3)
132 isr(tim6_dac)
133 isr(tim7)
134 isr(tim14)
135 isr(tim15)
136 isr(tim16)
137 isr(tim17)
138 isr(i2c1)
139 isr(i2c2)
140 isr(spi1)
141 isr(spi2)
142 isr(usart1)
143 isr(usart2)
144 isr(usart3_4_5_6_7_8)
145 isr(cec_can)
146 isr(usb)
147
148 #define i(addr,name)    [(addr)/4] = stm_ ## name ## _isr
149
150 __attribute__ ((section(".interrupt")))
151 const void *stm_interrupt_vector[] = {
152         [0] = &__stack__,
153         [1] = start,
154         i(0x08, nmi),
155         i(0x0c, hardfault),
156         i(0x2c, svc),
157         i(0x30, debugmon),
158         i(0x38, pendsv),
159         i(0x3c, systick),
160         i(0x40, wwdg),          /* IRQ0 */
161         i(0x44, pvd),
162         i(0x48, rtc),
163         i(0x4c, flash),
164         i(0x50, rcc_crs),
165         i(0x54, exti0_1),
166         i(0x58, exti2_3),
167         i(0x5c, exti4_15),
168         i(0x60, tsc),
169         i(0x64, dma_ch1),
170         i(0x68, dma_ch2_3),
171         i(0x6c, dma_ch4_5_6),
172         i(0x70, adc_comp),
173         i(0x74, tim1_brk_up_trg_com),
174         i(0x78, tim1_cc),
175         i(0x7c, tim2),
176         i(0x80, tim3),
177         i(0x84, tim6_dac),
178         i(0x88, tim7),
179         i(0x8c, tim14),
180         i(0x90, tim15),
181         i(0x94, tim16),
182         i(0x98, tim17),
183         i(0x9c, i2c1),
184         i(0xa0, i2c2),
185         i(0xa4, spi1),
186         i(0xa8, spi2),
187         i(0xac, usart1),
188         i(0xb0, usart2),
189         i(0xb4, usart3_4_5_6_7_8),
190         i(0xb8, cec_can),
191         i(0xbc, usb),
192 };