altos: Always start application if boot pin isn't in use
[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                 if (ao_boot_check_pin())
76 #endif
77                 {
78                         ao_boot_chain(AO_BOOT_APPLICATION_BASE);
79                 }
80         }
81 #endif
82         /* Turn on syscfg */
83         stm_rcc.apb2enr |= (1 << STM_RCC_APB2ENR_SYSCFGCOMPEN);
84
85 #if RELOCATE_INTERRUPT
86         memcpy(&__interrupt_start__, &__interrupt_rom__, &__interrupt_end__ - &__interrupt_start__);
87         stm_syscfg.cfgr1 = (stm_syscfg.cfgr1 & ~(STM_SYSCFG_CFGR1_MEM_MODE_MASK << STM_SYSCFG_CFGR1_MEM_MODE)) |
88                 (STM_SYSCFG_CFGR1_MEM_MODE_SRAM << STM_SYSCFG_CFGR1_MEM_MODE);
89 #else
90         /* Switch to Main Flash mode (DFU loader leaves us in System mode) */
91         stm_syscfg.cfgr1 = (stm_syscfg.cfgr1 & ~(STM_SYSCFG_CFGR1_MEM_MODE_MASK << STM_SYSCFG_CFGR1_MEM_MODE)) |
92                 (STM_SYSCFG_CFGR1_MEM_MODE_MAIN_FLASH << STM_SYSCFG_CFGR1_MEM_MODE);
93 #endif
94         memcpy(&_start__, &__text_end__, &_end__ - &_start__);
95         memset(&__bss_start__, '\0', &__bss_end__ - &__bss_start__);
96         main();
97 }
98
99 #define STRINGIFY(x) #x
100
101 #define isr(name) \
102         void __attribute__ ((weak)) stm_ ## name ## _isr(void); \
103         _Pragma(STRINGIFY(weak stm_ ## name ## _isr = stm_ignore_isr))
104
105 #define isr_halt(name) \
106         void __attribute__ ((weak)) stm_ ## name ## _isr(void); \
107         _Pragma(STRINGIFY(weak stm_ ## name ## _isr = stm_halt_isr))
108
109 isr(nmi)
110 isr_halt(hardfault)
111 isr_halt(memmanage)
112 isr_halt(busfault)
113 isr_halt(usagefault)
114 isr(svc)
115 isr(debugmon)
116 isr(pendsv)
117 isr(systick)
118 isr(wwdg)
119 isr(pvd)
120 isr(rtc)
121 isr(flash)
122 isr(rcc_crs)
123 isr(exti0_1)
124 isr(exti2_3)
125 isr(exti4_15)
126 isr(tsc)
127 isr(dma_ch1)
128 isr(dma_ch2_3)
129 isr(dma_ch4_5_6)
130 isr(adc_comp)
131 isr(tim1_brk_up_trg_com)
132 isr(tim1_cc)
133 isr(tim2)
134 isr(tim3)
135 isr(tim6_dac)
136 isr(tim7)
137 isr(tim14)
138 isr(tim15)
139 isr(tim16)
140 isr(tim17)
141 isr(i2c1)
142 isr(i2c2)
143 isr(spi1)
144 isr(spi2)
145 isr(usart1)
146 isr(usart2)
147 isr(usart3_4_5_6_7_8)
148 isr(cec_can)
149 isr(usb)
150
151 #undef isr
152 #undef isr_halt
153
154 #define i(addr,name)    [(addr)/4] = stm_ ## name ## _isr
155
156 __attribute__ ((section(".interrupt")))
157 const void *stm_interrupt_vector[] = {
158         [0] = &__stack__,
159         [1] = start,
160         i(0x08, nmi),
161         i(0x0c, hardfault),
162         i(0x2c, svc),
163         i(0x30, debugmon),
164         i(0x38, pendsv),
165         i(0x3c, systick),
166         i(0x40, wwdg),          /* IRQ0 */
167         i(0x44, pvd),
168         i(0x48, rtc),
169         i(0x4c, flash),
170         i(0x50, rcc_crs),
171         i(0x54, exti0_1),
172         i(0x58, exti2_3),
173         i(0x5c, exti4_15),
174         i(0x60, tsc),
175         i(0x64, dma_ch1),
176         i(0x68, dma_ch2_3),
177         i(0x6c, dma_ch4_5_6),
178         i(0x70, adc_comp),
179         i(0x74, tim1_brk_up_trg_com),
180         i(0x78, tim1_cc),
181         i(0x7c, tim2),
182         i(0x80, tim3),
183         i(0x84, tim6_dac),
184         i(0x88, tim7),
185         i(0x8c, tim14),
186         i(0x90, tim15),
187         i(0x94, tim16),
188         i(0x98, tim17),
189         i(0x9c, i2c1),
190         i(0xa0, i2c2),
191         i(0xa4, spi1),
192         i(0xa8, spi2),
193         i(0xac, usart1),
194         i(0xb0, usart2),
195         i(0xb4, usart3_4_5_6_7_8),
196         i(0xb8, cec_can),
197         i(0xbc, usb),
198 };