samd21: Shrink default stack to 512 bytes
[fw/altos] / src / samd21 / ao_arch.h
1 /*
2  * Copyright © 2019 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 _AO_ARCH_H_
20 #define _AO_ARCH_H_
21
22 #include <stdio.h>
23 #include <samd21.h>
24
25 /*
26  * Samd21 definitions and code fragments for AltOS
27  */
28
29 #define AO_PORT_TYPE    uint32_t
30
31 #define AO_LED_TYPE     AO_PORT_TYPE
32
33 #define ao_arch_naked_declare   __attribute__((naked))
34 #define ao_arch_naked_define
35
36 #define ao_arch_reboot() \
37         (samd21_scb.aircr = ((SAMD21_SCB_AIRCR_VECTKEY_KEY << SAMD21_SCB_AIRCR_VECTKEY) | \
38                           (1 << SAMD21_SCB_AIRCR_SYSRESETREQ)))
39
40 #define ao_arch_nop()           asm("nop")
41 #define ao_arch_interrupt(n)    /* nothing */
42 #define ao_arch_block_interrupts()      asm("cpsid i")
43 #define ao_arch_release_interrupts()    asm("cpsie i")
44
45 /* ao_romconfig.c */
46 #define AO_ROMCONFIG_SYMBOL __attribute__((section(".init.1"))) const
47 #define AO_USBCONFIG_SYMBOL __attribute__((section(".init.2"))) const
48
49 /*
50  * ao_timer.c
51  *
52  * For the samd21, we want to use the DFLL48 clock
53  */
54
55 /* GCLK 0 is always the system clock source */
56
57 #define AO_GCLK_SYSCLK  0
58
59 /* If there's a 32kHz xtal, use that for the 32kHz oscillator */
60 #ifdef AO_XOSC32K
61 # ifndef AO_GCLK_XOSC32K
62 #  define AO_GCLK_XOSC32K       1
63 # endif
64 #endif
65
66 /* If there's a high-freq xtal, use that */
67 #ifdef AO_XOSC
68 # ifndef AO_GCLK_XOSC
69 #  define AO_GCLK_XOSC  1
70 # endif
71
72 # ifndef AO_XOSC_GCLK_DIV
73 #  define AO_XOSC_GCLK_DIV 1
74 # endif
75
76 # define AO_FDPLL96M    ((AO_XOSC_FREQ / AO_XOSC_DIV * AO_XOSC_MUL) / AO_XOSC_GCLK_DIV)
77
78 /* By default, use the xosc for the system, but allow the dfll48m to
79  * drive USB if desired.
80  */
81
82 # ifndef AO_GCLK_FDPLL96M
83 #  define AO_SYSCLK             AO_FDPLL96M
84 #  define AO_GCLK_FDPLL96M      AO_GCLK_SYSCLK
85 #  define AO_GCLK_DFLL48M       2
86 # endif
87
88 #endif  /* AO_XOSC */
89
90 #if AO_DFLL48M
91 # ifndef AO_GCLK_DFLL48M
92 #  define AO_SYSCLK     AO_DFLL48M
93 #  define AO_GCLK_DFLL48M AO_GCLK_SYSCLK
94 # endif
95 #endif
96
97 #ifndef AO_GCLK_USB
98 # if AO_DFLL48M
99 #  define AO_GCLK_USB AO_GCLK_DFLL48M
100 # else
101 #  define AO_GCLK_USB AO_GCLK_SYSCLK
102 # endif
103 #endif
104
105 /*
106  * ao_timer.c
107  *
108  * For the samd21, we want to use the DFLL48 clock
109  */
110
111 /* GCLK 0 is always the system clock source */
112
113 #define AO_GCLK_SYSCLK  0
114
115 /* If there's a 32kHz xtal, use that for the 32kHz oscillator */
116 #ifdef AO_XOSC32K
117 # ifndef AO_GCLK_XOSC32K
118 #  define AO_GCLK_XOSC32K       1
119 # endif
120 #endif
121
122 /* If there's a high-freq xtal, use that */
123 #ifdef AO_XOSC
124 # ifndef AO_GCLK_XOSC
125 #  define AO_GCLK_XOSC  1
126 # endif
127
128 # ifndef AO_XOSC_GCLK_DIV
129 #  define AO_XOSC_GCLK_DIV 1
130 # endif
131
132 # define AO_FDPLL96M    ((AO_XOSC_FREQ / AO_XOSC_DIV * AO_XOSC_MUL) / AO_XOSC_GCLK_DIV)
133
134 /* By default, use the xosc for the system, but allow the dfll48m to
135  * drive USB if desired.
136  */
137
138 # ifndef AO_GCLK_FDPLL96M
139 #  define AO_SYSCLK             AO_FDPLL96M
140 #  define AO_GCLK_FDPLL96M      AO_GCLK_SYSCLK
141 #  define AO_GCLK_DFLL48M       2
142 # endif
143
144 #endif  /* AO_XOSC */
145
146 #if AO_DFLL48M
147 # ifndef AO_GCLK_DFLL48M
148 #  define AO_SYSCLK     AO_DFLL48M
149 #  define AO_GCLK_DFLL48M AO_GCLK_SYSCLK
150 # endif
151 #endif
152
153 #ifndef AO_GCLK_USB
154 # if AO_DFLL48M
155 #  define AO_GCLK_USB AO_GCLK_DFLL48M
156 # else
157 #  define AO_GCLK_USB AO_GCLK_SYSCLK
158 # endif
159 #endif
160
161 #define AO_HCLK         (AO_SYSCLK / AO_AHB_PRESCALER)
162
163 #define AO_HCLK         (AO_SYSCLK / AO_AHB_PRESCALER)
164 #define AO_PCLK         (AO_HCLK / AO_APB_PRESCALER)
165 #define AO_SYSTICK      (AO_HCLK)
166 #define AO_PANIC_DELAY_SCALE  (AO_SYSCLK / 12000000)
167
168 #define AO_SAMD21_NVIC_HIGH_PRIORITY    (0 << 6)
169 #define AO_SAMD21_NVIC_CLOCK_PRIORITY   (1 << 6)
170 #define AO_SAMD21_NVIC_MED_PRIORITY     (2 << 6)
171 #define AO_SAMD21_NVIC_LOW_PRIORITY     (3 << 6)
172
173 /* ADC maximum reported value */
174 #define AO_ADC_MAX                      4095
175
176 #define AO_SAMD21_NVIC_HIGH_PRIORITY    (0 << 6)
177 #define AO_SAMD21_NVIC_CLOCK_PRIORITY   (1 << 6)
178 #define AO_SAMD21_NVIC_MED_PRIORITY     (2 << 6)
179 #define AO_SAMD21_NVIC_LOW_PRIORITY     (3 << 6)
180
181 /* ADC maximum reported value */
182 #define AO_ADC_MAX                      4095
183
184 /* This has to be 65536 so that TCC and TC match; TC isn't configurable */
185 #define AO_TCC_PERIOD           65536
186 #define SNEK_PWM_MAX            (AO_TCC_PERIOD-1)
187
188 #define AO_TICK_TYPE            uint32_t
189 #define AO_TICK_SIGNED          int32_t
190
191 bool
192 ao_usb_waiting(void);
193
194 #define AO_CMD_LEN              128
195
196 #ifndef AO_STACK_SIZE
197 #define AO_STACK_SIZE           512
198 #endif
199
200 #ifndef HAS_BOOT_LOADER
201 #define HAS_BOOT_LOADER                 1
202 #endif
203
204 #if HAS_BOOT_LOADER
205 #define AO_BOOT_APPLICATION_BASE        ((uint32_t *) 0x00001000)
206 #ifndef AO_BOOT_APPLICATION_BOUND
207 #define AO_BOOT_APPLICATION_BOUND       ((uint32_t *) (0x00000000 + samd21_flash_size()))
208 #endif
209 #define AO_BOOT_LOADER_BASE             ((uint32_t *) 0x00000000)
210 #endif
211
212 #endif /* _AO_ARCH_H_ */