altos/stmf0: Hook up clock output support
authorKeith Packard <keithp@keithp.com>
Tue, 2 Aug 2016 23:32:43 +0000 (16:32 -0700)
committerKeith Packard <keithp@keithp.com>
Tue, 2 Aug 2016 23:55:11 +0000 (16:55 -0700)
This was used to try and not have two xtals on telemini, but failed
because the provided clock has too much noise.

Signed-off-by: Keith Packard <keithp@keithp.com>
src/stmf0/ao_timer.c
src/stmf0/stm32f0.h

index 2cb994c35df6408ff1c4ee14b546e880ce97376c..5c05e4f187c09017876b1dfd476ed6a9259e7e9d 100644 (file)
@@ -176,13 +176,12 @@ ao_clock_normal_start(void)
        while (!(stm_rcc.cr & (1 << STM_RCC_CR_HSERDY)))
                asm("nop");
 
-#ifdef STM_PLLSRC
        /* Disable the PLL */
        stm_rcc.cr &= ~(1 << STM_RCC_CR_PLLON);
        while (stm_rcc.cr & (1 << STM_RCC_CR_PLLRDY))
                asm("nop");
 
-       /* PLLVCO to 48MHz (for USB) -> PLLMUL = 3 */
+       /* Set multiplier */
        cfgr = stm_rcc.cfgr;
        cfgr &= ~(STM_RCC_CFGR_PLLMUL_MASK << STM_RCC_CFGR_PLLMUL);
        cfgr |= (AO_RCC_CFGR_PLLMUL << STM_RCC_CFGR_PLLMUL);
@@ -192,8 +191,8 @@ ao_clock_normal_start(void)
        cfgr |= (STM_RCC_CFGR_PLLSRC_TARGET_CLOCK  << STM_RCC_CFGR_PLLSRC);
        stm_rcc.cfgr = cfgr;
 
-       /* Disable pre divider */
-       stm_rcc.cfgr2 = (STM_RCC_CFGR2_PREDIV_1 << STM_RCC_CFGR2_PREDIV);
+       /* Set pre divider */
+       stm_rcc.cfgr2 = (AO_RCC_CFGR2_PLLDIV << STM_RCC_CFGR2_PREDIV);
 
        /* Enable the PLL and wait for it */
        stm_rcc.cr |= (1 << STM_RCC_CR_PLLON);
@@ -202,9 +201,6 @@ ao_clock_normal_start(void)
 
 #endif
 
-#endif
-
-
 #if AO_HSI48
 #define STM_RCC_CFGR_SWS_TARGET_CLOCK          STM_RCC_CFGR_SWS_HSI48
 #define STM_RCC_CFGR_SW_TARGET_CLOCK           STM_RCC_CFGR_SW_HSI48
@@ -226,6 +222,8 @@ ao_clock_normal_start(void)
 #define STM_PLLSRC                             STM_HSI
 #define STM_RCC_CFGR_PLLSRC_TARGET_CLOCK       0
 #endif
+
+
 }
 
 static void
@@ -303,14 +301,34 @@ ao_clock_init(void)
        /* Clear reset flags */
        stm_rcc.csr |= (1 << STM_RCC_CSR_RMVF);
 
+#ifdef AO_MCO_PORT
+       cfgr = stm_rcc.cfgr;
+
+       /* Send PLL clock to MCO */
+       cfgr &= ~(STM_RCC_CFGR_MCO_MASK << STM_RCC_CFGR_MCO);
+       cfgr |= (STM_RCC_CFGR_MCO_PLLCLK << STM_RCC_CFGR_MCO);
+
+       /* Divide by 1 */
+       cfgr &= ~(STM_RCC_CFGR_MCOPRE_DIV_MASK << STM_RCC_CFGR_MCOPRE);
+       cfgr |= (STM_RCC_CFGR_MCOPRE_DIV_1 << STM_RCC_CFGR_MCOPRE);
+
+       /* Don't divide PLL */
+       cfgr |= (1 << STM_RCC_CFGR_PLL_NODIV);
+
+       stm_rcc.cfgr = cfgr;
+
+       ao_enable_port(AO_MCO_PORT);
+       stm_ospeedr_set(AO_MCO_PORT, AO_MCO_PIN, STM_OSPEEDR_HIGH);
+       stm_afr_set(AO_MCO_PORT, AO_MCO_PIN, AO_MCO_AF);
+#endif
+
 #if DEBUG_THE_CLOCK
        /* Output SYSCLK on PA8 for measurments */
 
        stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIOAEN);
 
        stm_afr_set(&stm_gpioa, 8, STM_AFR_AF0);
-       stm_moder_set(&stm_gpioa, 8, STM_MODER_ALTERNATE);
-       stm_ospeedr_set(&stm_gpioa, 8, STM_OSPEEDR_40MHz);
+       stm_ospeedr_set(&stm_gpioa, 8, STM_OSPEEDR_HIGH);
 
        stm_rcc.cfgr |= (STM_RCC_CFGR_MCOPRE_DIV_1 << STM_RCC_CFGR_MCOPRE);
        stm_rcc.cfgr |= (STM_RCC_CFGR_MCOSEL_HSE << STM_RCC_CFGR_MCOSEL);
index d528e492127657f4bf5de4d6d85e860e8fe8c05e..054200e0c7ce03d2d7f36f2ca6652ff4caf1ffec 100644 (file)
@@ -313,6 +313,15 @@ extern struct stm_rcc stm_rcc;
 
 #define STM_RCC_CFGR_MCO       (24)
 # define STM_RCC_CFGR_MCO_DISABLE      0
+# define STM_RCC_CFGR_MCO_RC           1
+# define STM_RCC_CFGR_MCO_LSI          2
+# define STM_RCC_CFGR_MCO_LSE          3
+# define STM_RCC_CFGR_MCO_SYSCLK       4
+# define STM_RCC_CFGR_MCO_HSI          5
+# define STM_RCC_CFGR_MCO_HSE          6
+# define STM_RCC_CFGR_MCO_PLLCLK       7
+# define STM_RCC_CFGR_MCO_HSI48                8
+# define STM_RCC_CFGR_MCO_MASK         (0xf)
 
 #define STM_RCC_CFGR_PLLMUL    (18)
 #define  STM_RCC_CFGR_PLLMUL_2         0