This runs AltOS and talks over the serial port.
Signed-off-by: Keith Packard <keithp@keithp.com>
--- /dev/null
+stm-demo
+ao_product.h
--- /dev/null
+#
+# AltOS build
+#
+#
+vpath % ..:../core:../product:../drivers:../stm
+vpath make-altitude ..
+vpath make-kalman ..
+vpath kalman.5c ../kalman
+vpath kalman_filter.5c ../kalman
+vpath load_csv.5c ../kalman
+vpath matrix.5c ../kalman
+vpath ao-make-product.5c ../util
+
+#PROGRAMMER=stk500v2 -P usb
+#PROGRAMMER=usbtiny
+#LOADCMD=avrdude
+#LOADARG=-p $(DUDECPUTYPE) -c $(PROGRAMMER) -e -U flash:w:
+CC=arm-none-eabi-gcc
+#OBJCOPY=avr-objcopy
+
+ifndef VERSION
+include ../Version
+endif
+
+INC = \
+ ao.h \
+ ao_pins.h \
+ altitude.h \
+ ao_kalman.h
+
+#
+# Common AltOS sources
+#
+ALTOS_SRC = \
+ ao_interrupt.c \
+ ao_product.c \
+ ao_romconfig.c \
+ ao_cmd.c \
+ ao_task.c \
+ ao_stdio.c \
+ ao_panic.c \
+ ao_timer.c \
+ ao_serial_stm.c
+
+PRODUCT=StmDemo-v0.0
+PRODUCT_DEF=-DSTM_DEMO
+IDPRODUCT=0x000a
+CPU=cortex-m3
+CFLAGS = $(PRODUCT_DEF) -I. -I../stm -I../core -I..
+CFLAGS += -g -std=gnu99 -Os -mlittle-endian -mcpu=cortex-m3 -mthumb -ffreestanding -nostdlib -I../stm $(CINC)
+
+NICKLE=nickle
+
+PROG=stm-demo
+
+SRC=$(ALTOS_SRC) ao_demo.c
+OBJ=$(SRC:.c=.o)
+
+V=0
+# The user has explicitly enabled quiet compilation.
+ifeq ($(V),0)
+quiet = @printf " $1 $2 $@\n"; $($1)
+endif
+# Otherwise, print the full command line.
+quiet ?= $($1)
+
+all: $(PROG)
+
+CLIB=/home/keithp/sat/lib/pdclib.a
+CINC=-I/home/keithp/sat/include
+LDFLAGS=-L../stm -Wl,-Taltos.ld
+
+$(PROG): Makefile $(OBJ)
+ $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(CLIB) -lgcc
+
+../altitude.h: make-altitude
+ nickle $< > $@
+
+ao_product.h: ao-make-product.5c ../Version
+ $(call quiet,NICKLE,$<) $< -m altusmetrum.org -i $(IDPRODUCT) -p $(PRODUCT) -v $(VERSION) > $@
+
+ao_product.rel: ao_product.c ao_product.h
+ $(call quiet,CC) -c $(CFLAGS) -D PRODUCT_DEFS='\"ao_product.h\"' -o$@ $<
+
+distclean: clean
+
+clean:
+ rm -f $(OBJ)
+ rm -f ao_product.h
+
+install:
+
+uninstall:
+
+$(OBJ): ao.h ao_product.h
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright © 2011 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "ao.h"
+
+struct ao_task demo_task;
+
+void
+ao_demo(void)
+{
+ int i = 0;
+ for (;;) {
+ printf ("hello %d\n", i++);
+ }
+}
+
+void _close() { }
+void _sbrk() { }
+void _isatty() { }
+void _lseek() { }
+void _exit () { }
+void _read () { }
+void _fstat() { }
+int
+main(void)
+{
+ ao_clock_init();
+
+ ao_serial_init();
+ ao_timer_init();
+ ao_cmd_init();
+
+ ao_demo();
+ return 0;
+}
--- /dev/null
+/*
+ * Copyright © 2012 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#ifndef _AO_PINS_H_
+#define _AO_PINS_H_
+
+#define HAS_SERIAL_1 1
+#define USE_SERIAL_STDIN 1
+#define HAS_USB 0
+#define HAS_BEEP 0
+#define PACKET_HAS_SLAVE 0
+
+#endif /* _AO_PINS_H_ */
uint16_t adc[AO_ARM_NUM_ADC]; /* samples */
};
+/*
+ * For now, we're running at a weird frequency
+ */
+#define STM_APB1 (16000000 * 6 / 4)
#endif /* _AO_ARCH_H_ */
--- /dev/null
+/*
+ * Copyright © 2011 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "ao.h"
+
+const uint16_t ao_serial_number = 0;
{
if (c == '\n')
ao_debug_out('\r');
- while (!(STM_USART1->usart_sr & (1 << STM_USART_SR_TXE)));
- STM_USART1->usart_dr = c;
+ while (!(stm_usart1.sr & (1 << STM_USART_SR_TXE)));
+ stm_usart1.dr = c;
+}
+
+void
+outbyte(char c)
+{
+ putchar(c);
}
-#if 0
static __xdata uint8_t ao_serial_tx1_started;
static void
!ao_serial_tx1_started)
{
ao_serial_tx1_started = 1;
- ao_fifo_remove(ao_usart1_tx_fifo, STM_USART1->usart_dr);
+ ao_fifo_remove(ao_usart1_tx_fifo, stm_usart1.dr);
}
}
-void usart1_isr(void)
+void stm_usart1_isr(void)
{
- if (STM_USART1->usart_sr & (1 << STM_USART_SR_RXNE)) {
+ uint32_t sr;
+ cli();
+ sr = stm_usart1.sr;
+ stm_usart1.sr = 0;
+ sei();
+ if (sr & (1 << STM_USART_SR_RXNE)) {
if (!ao_fifo_full(ao_usart1_rx_fifo))
- ao_fifo_insert(ao_usart1_rx_fifo, STM_USART1->usart_dr);
+ ao_fifo_insert(ao_usart1_rx_fifo, stm_usart1.dr);
ao_wakeup(&ao_usart1_rx_fifo);
#if USE_SERIAL_STDIN
ao_wakeup(&ao_stdin_ready);
#endif
}
- if (STM_USART1->usart_sr & (1 << STM_USART_SR_TXE)) {
+ if (sr & (1 << STM_USART_SR_TXE)) {
ao_serial_tx1_started = 0;
ao_serial_tx1_start();
ao_wakeup(&ao_usart1_tx_fifo);
sei();
}
-#endif
-
int _write(int file, char *ptr, int len)
{
int l = len;
return len;
}
-#define F_CPU 24000000
-
static const struct {
- uint32_t usart_brr;
+ uint32_t brr;
} ao_serial_speeds[] = {
[AO_SERIAL_SPEED_4800] = {
- (F_CPU * 16) / (16 * 4800)
+ STM_APB1 / 4800
},
[AO_SERIAL_SPEED_9600] = {
- (F_CPU * 16) / (16 * 9600)
+ STM_APB1 / 9600
},
[AO_SERIAL_SPEED_19200] = {
- (F_CPU * 16) / (16 * 19200)
+ STM_APB1 / 19200
},
[AO_SERIAL_SPEED_57600] = {
- (F_CPU * 16) / (16 * 57600)
+ STM_APB1 / 57600
},
};
#endif
if (speed > AO_SERIAL_SPEED_57600)
return;
- STM_USART1->usart_brr = ao_serial_speeds[speed].usart_brr;
+ stm_usart1.brr = ao_serial_speeds[speed].brr;
}
void
ao_serial_init(void)
{
- STM_USART1->usart_cr1 = ((0 << STM_USART_CR1_OVER8) |
- (1 << STM_USART_CR1_UE) |
- (0 << STM_USART_CR1_M) |
- (0 << STM_USART_CR1_WAKE) |
- (0 << STM_USART_CR1_PCE) |
- (0 << STM_USART_CR1_PS) |
- (0 << STM_USART_CR1_PEIE) |
- (0 << STM_USART_CR1_TXEIE) | /* XXX enable */
- (0 << STM_USART_CR1_TCIE) |
- (0 << STM_USART_CR1_RXNEIE) | /* XXX enable */
- (0 << STM_USART_CR1_IDLEIE) |
- (1 << STM_USART_CR1_TE) |
- (1 << STM_USART_CR1_RE) |
- (0 << STM_USART_CR1_RWU) |
- (0 << STM_USART_CR1_SBK));
-
- STM_USART1->usart_cr2 = 0;
- STM_USART1->usart_cr3 = 0;
+ stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIOAEN);
+
+ stm_moder_set(&stm_gpioa, 9, STM_MODER_ALTERNATE);
+ stm_moder_set(&stm_gpioa, 10, STM_MODER_ALTERNATE);
+ stm_afr_set(&stm_gpioa, 9, STM_AFR_AF7);
+ stm_afr_set(&stm_gpioa, 10, STM_AFR_AF7);
+
+ /* Enable USART1 */
+ stm_rcc.apb2enr |= (1 << STM_RCC_APB2ENR_USART1EN);
+
+ stm_usart1.cr1 = ((0 << STM_USART_CR1_OVER8) |
+ (1 << STM_USART_CR1_UE) |
+ (0 << STM_USART_CR1_M) |
+ (0 << STM_USART_CR1_WAKE) |
+ (0 << STM_USART_CR1_PCE) |
+ (0 << STM_USART_CR1_PS) |
+ (0 << STM_USART_CR1_PEIE) |
+ (1 << STM_USART_CR1_TXEIE) |
+ (0 << STM_USART_CR1_TCIE) |
+ (1 << STM_USART_CR1_RXNEIE) |
+ (0 << STM_USART_CR1_IDLEIE) |
+ (1 << STM_USART_CR1_TE) |
+ (1 << STM_USART_CR1_RE) |
+ (0 << STM_USART_CR1_RWU) |
+ (0 << STM_USART_CR1_SBK));
+
+ stm_usart1.cr2 = ((0 << STM_USART_CR2_LINEN) |
+ (STM_USART_CR2_STOP_1 << STM_USART_CR2_STOP) |
+ (0 << STM_USART_CR2_CLKEN) |
+ (0 << STM_USART_CR2_CPOL) |
+ (0 << STM_USART_CR2_CPHA) |
+ (0 << STM_USART_CR2_LBCL) |
+ (0 << STM_USART_CR2_LBDIE) |
+ (0 << STM_USART_CR2_LBDL) |
+ (0 << STM_USART_CR2_ADD));
+
+ stm_usart1.cr3 = ((0 << STM_USART_CR3_ONEBITE) |
+ (0 << STM_USART_CR3_CTSIE) |
+ (0 << STM_USART_CR3_CTSE) |
+ (0 << STM_USART_CR3_RTSE) |
+ (0 << STM_USART_CR3_DMAT) |
+ (0 << STM_USART_CR3_DMAR) |
+ (0 << STM_USART_CR3_SCEN) |
+ (0 << STM_USART_CR3_NACK) |
+ (0 << STM_USART_CR3_HDSEL) |
+ (0 << STM_USART_CR3_IRLP) |
+ (0 << STM_USART_CR3_IREN) |
+ (0 << STM_USART_CR3_EIE));
/* Pick a 9600 baud rate */
ao_serial_set_speed(AO_SERIAL_SPEED_9600);
NULL);
#endif
#endif
+
+ stm_nvic_set_enable(STM_ISR_USART1_POS);
+ stm_nvic_set_priority(STM_ISR_USART1_POS, 4);
}
ao_sleep(&ao_forever);
}
-#define T2_CLOCK_DIVISOR 8 /* 24e6/8 = 3e6 */
-#define T2_SAMPLE_TIME 30000 /* 3e6/30000 = 100 */
-
#if HAS_ADC
volatile __data uint8_t ao_adc_interval = 1;
volatile __data uint8_t ao_adc_count;
ao_debug_out(char c);
-void tim2_isr(void)
+void stm_tim6_isr(void)
{
++ao_tick_count;
#if HAS_ADC
}
#endif
+#define TIMER_10kHz (STM_APB1 / 10000)
+
void
ao_timer_init(void)
{
+ stm_nvic_set_enable(STM_ISR_TIM6_POS);
+ stm_nvic_set_priority(STM_ISR_TIM6_POS, 1);
+
+ /* Turn on timer 6 */
+ stm_rcc.apb1enr |= (1 << STM_RCC_APB1ENR_TIM6EN);
+
+ stm_tim6.psc = TIMER_10kHz;
+ stm_tim6.arr = 100;
+ stm_tim6.cnt = 0;
+
+ /* Enable update interrupt */
+ stm_tim6.dier = (1 << STM_TIM67_DIER_UIE);
+
+ /* Poke timer to reload values */
+ stm_tim6.egr |= (1 << STM_TIM67_EGR_UG);
+
+ stm_tim6.cr2 = (STM_TIM67_CR2_MMS_RESET << STM_TIM67_CR2_MMS);
+
+ /* And turn it on */
+ stm_tim6.cr1 = ((0 << STM_TIM67_CR1_ARPE) |
+ (0 << STM_TIM67_CR1_OPM) |
+ (1 << STM_TIM67_CR1_URS) |
+ (0 << STM_TIM67_CR1_UDIS) |
+ (1 << STM_TIM67_CR1_CEN));
}
void
ao_clock_init(void)
{
uint32_t cfgr;
+ uint32_t cr;
/* Set flash latency to tolerate 32MHz SYSCLK -> 1 wait state */
- uint32_t acr = STM_FLASH->acr;
+ uint32_t acr = stm_flash.acr;
/* Enable 64-bit access and prefetch */
acr |= (1 << STM_FLASH_ACR_ACC64) | (1 << STM_FLASH_ACR_PRFEN);
- STM_FLASH->acr = acr;
+ stm_flash.acr = acr;
/* Enable 1 wait state so the CPU can run at 32MHz */
+ /* (haven't managed to run the CPU at 32MHz yet, it's at 16MHz) */
acr |= (1 << STM_FLASH_ACR_LATENCY);
- STM_FLASH->acr = acr;
+ stm_flash.acr = acr;
+
+ /* HCLK to 16MHz -> AHB prescaler = /1 */
+ cfgr = stm_rcc.cfgr;
+ cfgr &= ~(STM_RCC_CFGR_HPRE_MASK << STM_RCC_CFGR_HPRE);
+ cfgr |= (STM_RCC_CFGR_HPRE_DIV_1 << STM_RCC_CFGR_HPRE);
+ stm_rcc.cfgr = cfgr;
+ while ((stm_rcc.cfgr & (STM_RCC_CFGR_HPRE_MASK << STM_RCC_CFGR_HPRE)) !=
+ (STM_RCC_CFGR_HPRE_DIV_1 << STM_RCC_CFGR_HPRE))
+ asm ("nop");
+#define STM_AHB_PRESCALER 1
+
+ /* PCLK1 to 16MHz -> APB1 Prescaler = 1 */
+ cfgr = stm_rcc.cfgr;
+ cfgr &= ~(STM_RCC_CFGR_PPRE1_MASK << STM_RCC_CFGR_PPRE1);
+ cfgr |= (STM_RCC_CFGR_PPRE1_DIV_1 << STM_RCC_CFGR_PPRE1);
+ stm_rcc.cfgr = cfgr;
+#define STM_APB1_PRESCALER 1
+
+ /* PCLK2 to 16MHz -> APB2 Prescaler = 1 */
+ cfgr = stm_rcc.cfgr;
+ cfgr &= ~(STM_RCC_CFGR_PPRE2_MASK << STM_RCC_CFGR_PPRE2);
+ cfgr |= (STM_RCC_CFGR_PPRE2_DIV_1 << STM_RCC_CFGR_PPRE2);
+ stm_rcc.cfgr = cfgr;
+#define STM_APB2_PRESCALER 1
+
+ /* Enable power interface clock */
+ stm_rcc.apb1enr |= (1 << STM_RCC_APB1ENR_PWREN);
+
+ /* Set voltage range to 1.8V */
+
+ /* poll VOSF bit in PWR_CSR. Wait until it is reset to 0 */
+ while ((stm_pwr.csr & (1 << STM_PWR_CSR_VOSF)) != 0)
+ asm("nop");
+
+ /* Configure voltage scaling range */
+ cr = stm_pwr.cr;
+ cr &= ~(STM_PWR_CR_VOS_MASK << STM_PWR_CR_VOS);
+ cr |= (STM_PWR_CR_VOS_1_8 << STM_PWR_CR_VOS);
+ stm_pwr.cr = cr;
+
+ /* poll VOSF bit in PWR_CSR. Wait until it is reset to 0 */
+ while ((stm_pwr.csr & (1 << STM_PWR_CSR_VOSF)) != 0)
+ asm("nop");
/* Enable HSI RC clock 16MHz */
- if (!(STM_RCC->cr & (1 << STM_RCC_CR_HSIRDY))) {
- STM_RCC->cr |= (1 << STM_RCC_CR_HSION);
- while (!(STM_RCC->cr & (1 << STM_RCC_CR_HSIRDY)))
+ if (!(stm_rcc.cr & (1 << STM_RCC_CR_HSIRDY))) {
+ stm_rcc.cr |= (1 << STM_RCC_CR_HSION);
+ while (!(stm_rcc.cr & (1 << STM_RCC_CR_HSIRDY)))
asm("nop");
}
+#define STM_HSI 16000000
/* Switch to direct HSI for SYSCLK */
- if ((STM_RCC->cfgr & (STM_RCC_CFGR_SWS_MASK << STM_RCC_CFGR_SWS)) !=
+ if ((stm_rcc.cfgr & (STM_RCC_CFGR_SWS_MASK << STM_RCC_CFGR_SWS)) !=
(STM_RCC_CFGR_SWS_HSI << STM_RCC_CFGR_SWS)) {
- cfgr = STM_RCC->cfgr;
+ cfgr = stm_rcc.cfgr;
cfgr &= ~(STM_RCC_CFGR_SW_MASK << STM_RCC_CFGR_SW);
cfgr |= (STM_RCC_CFGR_SW_HSI << STM_RCC_CFGR_SW);
- STM_RCC->cfgr = cfgr;
- while ((STM_RCC->cfgr & (STM_RCC_CFGR_SWS_MASK << STM_RCC_CFGR_SWS)) !=
+ stm_rcc.cfgr = cfgr;
+ while ((stm_rcc.cfgr & (STM_RCC_CFGR_SWS_MASK << STM_RCC_CFGR_SWS)) !=
(STM_RCC_CFGR_SWS_HSI << STM_RCC_CFGR_SWS))
asm("nop");
}
/* Disable the PLL */
- STM_RCC->cr &= ~(1 << STM_RCC_CR_PLLON);
- while (STM_RCC->cr & (1 << STM_RCC_CR_PLLRDY))
+ stm_rcc.cr &= ~(1 << STM_RCC_CR_PLLON);
+ while (stm_rcc.cr & (1 << STM_RCC_CR_PLLRDY))
asm("nop");
- /* PLLVCO to 96MHz (for USB) -> PLLMUL = 6 */
- cfgr = STM_RCC->cfgr;
+ /* PLLVCO to 96MHz (for USB) -> PLLMUL = 6, PLLDIV = 4 */
+ cfgr = stm_rcc.cfgr;
cfgr &= ~(STM_RCC_CFGR_PLLMUL_MASK << STM_RCC_CFGR_PLLMUL);
- cfgr |= (STM_RCC_CFGR_PLLMUL_6 << STM_RCC_CFGR_PLLMUL);
-
- /* SYSCLK to 32MHz from PLL clock -> PLLDIV = /3 */
cfgr &= ~(STM_RCC_CFGR_PLLDIV_MASK << STM_RCC_CFGR_PLLDIV);
- cfgr |= (STM_RCC_CFGR_PLLDIV_3 << STM_RCC_CFGR_PLLDIV);
+
+// cfgr |= (STM_RCC_CFGR_PLLMUL_6 << STM_RCC_CFGR_PLLMUL);
+// cfgr |= (STM_RCC_CFGR_PLLDIV_3 << STM_RCC_CFGR_PLLDIV);
+
+ cfgr |= (STM_RCC_CFGR_PLLMUL_6 << STM_RCC_CFGR_PLLMUL);
+ cfgr |= (STM_RCC_CFGR_PLLDIV_4 << STM_RCC_CFGR_PLLDIV);
+
+#define STM_PLLMUL 6
+#define STM_PLLDIV 4
/* PLL source to HSI */
cfgr &= ~(1 << STM_RCC_CFGR_PLLSRC);
- STM_RCC->cfgr = cfgr;
+#define STM_PLLSRC STM_HSI
+
+ stm_rcc.cfgr = cfgr;
/* Enable the PLL and wait for it */
- STM_RCC->cr |= (1 << STM_RCC_CR_PLLON);
- while (!(STM_RCC->cr & (1 << STM_RCC_CR_PLLRDY)))
+ stm_rcc.cr |= (1 << STM_RCC_CR_PLLON);
+ while (!(stm_rcc.cr & (1 << STM_RCC_CR_PLLRDY)))
asm("nop");
/* Switch to the PLL for the system clock */
- cfgr = STM_RCC->cfgr;
+ cfgr = stm_rcc.cfgr;
cfgr &= ~(STM_RCC_CFGR_SW_MASK << STM_RCC_CFGR_SW);
cfgr |= (STM_RCC_CFGR_SW_PLL << STM_RCC_CFGR_SW);
- STM_RCC->cfgr = cfgr;
- while ((STM_RCC->cfgr & (STM_RCC_CFGR_SWS_MASK << STM_RCC_CFGR_SWS)) !=
- (STM_RCC_CFGR_SWS_PLL << STM_RCC_CFGR_SWS))
- asm("nop");
-
- /* HCLK to 32MHz -> AHB prescaler = /1 */
- cfgr = STM_RCC->cfgr;
- cfgr &= ~(STM_RCC_CFGR_HPRE_MASK << STM_RCC_CFGR_HPRE);
- cfgr |= (STM_RCC_CFGR_HPRE_DIV_1 << STM_RCC_CFGR_HPRE);
- STM_RCC->cfgr = cfgr;
- while ((STM_RCC->cfgr & (STM_RCC_CFGR_HPRE_MASK << STM_RCC_CFGR_HPRE)) !=
- (STM_RCC_CFGR_HPRE_DIV_1 << STM_RCC_CFGR_HPRE))
- asm ("nop");
-
- /* PCLK1 to 16MHz -> APB1 Prescaler = 2 */
- cfgr = STM_RCC->cfgr;
- cfgr &= ~(STM_RCC_CFGR_PPRE1_MASK << STM_RCC_CFGR_PPRE1);
- cfgr |= (STM_RCC_CFGR_PPRE1_DIV_2 << STM_RCC_CFGR_PPRE1);
- STM_RCC->cfgr = cfgr;
-
- /* PCLK2 to 16MHz -> APB2 Prescaler = 2 */
- cfgr = STM_RCC->cfgr;
- cfgr &= ~(STM_RCC_CFGR_PPRE2_MASK << STM_RCC_CFGR_PPRE2);
- cfgr |= (STM_RCC_CFGR_PPRE2_DIV_2 << STM_RCC_CFGR_PPRE2);
- STM_RCC->cfgr = cfgr;
-
+ stm_rcc.cfgr = cfgr;
+ for (;;) {
+ uint32_t c, part, mask, val;
+
+ c = stm_rcc.cfgr;
+ mask = (STM_RCC_CFGR_SWS_MASK << STM_RCC_CFGR_SWS);
+ val = (STM_RCC_CFGR_SWS_PLL << STM_RCC_CFGR_SWS);
+ part = c & mask;
+ if (part == val)
+ break;
+ }
}
isr(tim6)
isr(tim7)
+#define STM_ISR_TIM9_POS 25
+#define STM_ISR_TIM10_POS 26
+#define STM_ISR_TIM11_POS 27
+#define STM_ISR_TIM2_POS 28
+#define STM_ISR_TIM3_POS 29
+#define STM_ISR_TIM4_POS 30
+
+#define STM_ISR_SPI1_POS 35
+#define STM_ISR_SPI2_POS 36
+#define STM_ISR_USART1_POS 37
+#define STM_ISR_USART2_POS 38
+#define STM_ISR_USART3_POS 39
#define STM_ISR_TIM6_POS 43
+#define STM_ISR_TIM7_POS 44
#undef isr