2 * Copyright © 2023 Keith Packard <keithp@keithp.com>
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.
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.
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.
24 typedef volatile uint32_t vuint32_t;
25 typedef volatile uint16_t vuint16_t;
26 typedef volatile void * vvoid_t;
45 extern struct stm_rcc stm_rcc;
47 //#define stm_rcc (*((struct stm_rcc *) 0x40021000))
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
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)
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
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
87 #define STM_RCC_CFGR_USBPRE (22)
88 #define STM_RCC_CFGR_USBPRE_1_5 0
89 #define STM_RCC_CFGR_USBPRE_1 1
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
109 #define STM_RCC_CFGR_PLLXTPRE (17)
110 #define STM_RCC_CFGR_PLLXTPRE_1 0
111 #define STM_RCC_CFGR_PLLXTPRE_2 1
113 #define STM_RCC_CFGR_PLLSRC (16)
114 #define STM_RCC_CFGR_PLLSRC_HSI_2 0
115 #define STM_RCC_CFGR_PLLSRC_HSE 1
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
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
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
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
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
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
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
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
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
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)
220 extern struct stm_systick stm_systick;
222 #define stm_systick (*((struct stm_systick *) 0xe000e010))
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
231 /* The NVIC starts at 0xe000e100, so add that to the offsets to find the absolute address */
234 vuint32_t iser[8]; /* 0x000 0xe000e100 Set Enable Register */
236 uint8_t _unused020[0x080 - 0x020];
238 vuint32_t icer[8]; /* 0x080 0xe000e180 Clear Enable Register */
240 uint8_t _unused0a0[0x100 - 0x0a0];
242 vuint32_t ispr[8]; /* 0x100 0xe000e200 Set Pending Register */
244 uint8_t _unused120[0x180 - 0x120];
246 vuint32_t icpr[8]; /* 0x180 0xe000e280 Clear Pending Register */
248 uint8_t _unused1a0[0x200 - 0x1a0];
250 vuint32_t iabr[8]; /* 0x200 0xe000e300 Active Bit Register */
252 uint8_t _unused220[0x300 - 0x220];
254 vuint32_t ipr[60]; /* 0x300 0xe000e400 Priority Register */
256 uint8_t _unused3f0[0xc00 - 0x3f0];
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 */
265 vuint32_t shpr7_4; /* 0xc18 0xe000ed18 System Hander Priority Registers */
266 vuint32_t shpr11_8; /* 0xc1c */
267 vuint32_t shpr15_12; /* 0xc20 */
269 uint8_t _unusedc18[0xe00 - 0xc24];
271 vuint32_t stir; /* 0xe00 */
274 extern struct stm_nvic stm_nvic;
276 #define stm_nvic (*((struct stm_nvic *) 0xe000e100))
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)
284 stm_nvic_set_enable(int irq) {
285 stm_nvic.iser[IRQ_REG(irq)] = IRQ_MASK(irq);
289 stm_nvic_clear_enable(int irq) {
290 stm_nvic.icer[IRQ_REG(irq)] = IRQ_MASK(irq);
294 stm_nvic_enabled(int irq) {
295 return IRQ_BOOL(stm_nvic.iser[IRQ_REG(irq)], irq);
299 stm_nvic_set_pending(int irq) {
300 stm_nvic.ispr[IRQ_REG(irq)] = IRQ_MASK(irq);
304 stm_nvic_clear_pending(int irq) {
305 stm_nvic.icpr[IRQ_REG(irq)] = IRQ_MASK(irq);
309 stm_nvic_pending(int irq) {
310 return IRQ_BOOL(stm_nvic.ispr[IRQ_REG(irq)], irq);
314 stm_nvic_active(int irq) {
315 return IRQ_BOOL(stm_nvic.iabr[IRQ_REG(irq)], irq);
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))
323 stm_nvic_set_priority(int irq, uint8_t prio) {
324 int n = IRQ_PRIO_REG(irq);
328 v &= (uint32_t) ~IRQ_PRIO_MASK(irq);
329 v |= (prio) << IRQ_PRIO_BIT(irq);
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);
338 struct stm_flash_data {
342 vuint32_t device_id[3];
345 extern struct stm_flash_data stm_flash_data;
347 static inline uint32_t stm_flash_size(void) { return (uint32_t) stm_flash_data.f_size * 1024; }
349 #define stm_flash_data (*((struct stm_flash_data *) 0x1ffff7e0))
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
379 stm_gpio_conf(struct stm_gpio *gpio, int pin, uint8_t mode, uint8_t cnf)
381 uint8_t cr = STM_GPIO_CR(pin);
382 uint32_t v = gpio->cr[cr];
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));
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);
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));
403 stm_gpio_set_bits(struct stm_gpio *gpio, uint16_t bits) {
408 stm_gpio_clr_bits(struct stm_gpio *gpio, uint16_t bits) {
409 gpio->bsrr = ((uint32_t) bits) << 16;
412 static inline uint8_t
413 stm_gpio_get(struct stm_gpio *gpio, int pin) {
414 return (gpio->idr >> pin) & 1;
417 static inline uint16_t
418 stm_gpio_get_all(struct stm_gpio *gpio) {
419 return (uint16_t) gpio->idr;
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;
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))
441 extern struct stm_afio stm_afio;
443 #define stm_afio (*((struct stm_afio *) 0x40010000))
445 #define isr_decl(name) void stm_ ## name ## _isr(void)
454 isr_decl(usagefault);
461 isr_decl(tamper_stamp);
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);
485 isr_decl(tim1_trg_com);
501 isr_decl(usb_wakeup);
504 isr_decl(tim8_trg_com);
515 isr_decl(dma2_channel1);
516 isr_decl(dma2_channel2);
517 isr_decl(dma2_channel3);
518 isr_decl(dma2_channel4_5);