Merge remote-tracking branch 'mjb/master'
[fw/altos] / src / stm / ao_timer.c
index 387df184c7747bb3f595c1c6d00d86a80d09993c..adec7aad950f617fc3effe7055db3749167ebaa5 100644 (file)
@@ -17,7 +17,7 @@
 
 #include "ao.h"
 
-static volatile __data uint16_t ao_tick_count;
+volatile __data AO_TICK_TYPE ao_tick_count;
 
 uint16_t ao_time(void)
 {
@@ -69,13 +69,25 @@ ao_timer_set_adc_interval(uint8_t interval) __critical
 }
 #endif
 
-#define TIMER_10kHz    (STM_APB1 / 10000)
+/*
+ * According to the STM clock-configuration, timers run
+ * twice as fast as the APB1 clock *if* the APB1 prescaler
+ * is greater than 1.
+ */
+
+#if AO_APB1_PRESCALER > 1
+#define TIMER_23467_SCALER 2
+#else
+#define TIMER_23467_SCALER 1
+#endif
+
+#define TIMER_10kHz    ((AO_PCLK1 * TIMER_23467_SCALER) / 10000)
 
 void
 ao_timer_init(void)
 {
        stm_nvic_set_enable(STM_ISR_TIM6_POS);
-       stm_nvic_set_priority(STM_ISR_TIM6_POS, 1);
+       stm_nvic_set_priority(STM_ISR_TIM6_POS, AO_STM_NVIC_CLOCK_PRIORITY);
 
        /* Turn on timer 6 */
        stm_rcc.apb1enr |= (1 << STM_RCC_APB1ENR_TIM6EN);
@@ -106,41 +118,62 @@ ao_clock_init(void)
        uint32_t        cfgr;
        uint32_t        cr;
        
+       /* Switch to MSI while messing about */
+       stm_rcc.cr |= (1 << STM_RCC_CR_MSION);
+       while (!(stm_rcc.cr & (1 << STM_RCC_CR_MSIRDY)))
+               asm("nop");
+
+       /* reset SW, HPRE, PPRE1, PPRE2, MCOSEL and MCOPRE */
+       stm_rcc.cfgr &= (uint32_t)0x88FFC00C;
+
+       /* reset HSION, HSEON, CSSON and PLLON bits */
+       stm_rcc.cr &= 0xeefefffe;
+       
+       /* reset PLLSRC, PLLMUL and PLLDIV bits */
+       stm_rcc.cfgr &= 0xff02ffff;
+       
+       /* Disable all interrupts */
+       stm_rcc.cir = 0;
+
+#if AO_HSE
+#if AO_HSE_BYPASS
+       stm_rcc.cr |= (1 << STM_RCC_CR_HSEBYP);
+#else
+       stm_rcc.cr &= ~(1 << STM_RCC_CR_HSEBYP);
+#endif
+       /* Enable HSE clock */
+       stm_rcc.cr |= (1 << STM_RCC_CR_HSEON);
+       while (!(stm_rcc.cr & (1 << STM_RCC_CR_HSERDY)))
+               asm("nop");
+
+#define STM_RCC_CFGR_SWS_TARGET_CLOCK          (STM_RCC_CFGR_SWS_HSE << STM_RCC_CFGR_SWS)
+#define STM_RCC_CFGR_SW_TARGET_CLOCK           (STM_RCC_CFGR_SW_HSE)
+#define STM_PLLSRC                             AO_HSE
+#define STM_RCC_CFGR_PLLSRC_TARGET_CLOCK       (1 << STM_RCC_CFGR_PLLSRC)
+#else
+#define STM_HSI                                16000000
+#define STM_RCC_CFGR_SWS_TARGET_CLOCK          (STM_RCC_CFGR_SWS_HSI << STM_RCC_CFGR_SWS)
+#define STM_RCC_CFGR_SW_TARGET_CLOCK           (STM_RCC_CFGR_SW_HSI)
+#define STM_PLLSRC                             STM_HSI
+#define STM_RCC_CFGR_PLLSRC_TARGET_CLOCK       (0 << STM_RCC_CFGR_PLLSRC)
+#endif
+
+#if !AO_HSE || HAS_ADC
+       /* Enable HSI RC clock 16MHz */
+       stm_rcc.cr |= (1 << STM_RCC_CR_HSION);
+       while (!(stm_rcc.cr & (1 << STM_RCC_CR_HSIRDY)))
+               asm("nop");
+#endif
+
        /* Set flash latency to tolerate 32MHz SYSCLK  -> 1 wait state */
-       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 |= (1 << STM_FLASH_ACR_ACC64);
+       stm_flash.acr |= (1 << STM_FLASH_ACR_PRFEN);
 
        /* 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;
-
-       /* 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
+       stm_flash.acr |= (1 << STM_FLASH_ACR_LATENCY);
 
        /* Enable power interface clock */
        stm_rcc.apb1enr |= (1 << STM_RCC_APB1ENR_PWREN);
@@ -161,25 +194,26 @@ ao_clock_init(void)
        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)))
-                       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)) !=
-           (STM_RCC_CFGR_SWS_HSI << STM_RCC_CFGR_SWS)) {
-               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_SWS_HSI << STM_RCC_CFGR_SWS))
-                       asm("nop");
-       }
+       /* HCLK to 16MHz -> AHB prescaler = /1 */
+       cfgr = stm_rcc.cfgr;
+       cfgr &= ~(STM_RCC_CFGR_HPRE_MASK << STM_RCC_CFGR_HPRE);
+       cfgr |= (AO_RCC_CFGR_HPRE_DIV << STM_RCC_CFGR_HPRE);
+       stm_rcc.cfgr = cfgr;
+       while ((stm_rcc.cfgr & (STM_RCC_CFGR_HPRE_MASK << STM_RCC_CFGR_HPRE)) !=
+              (AO_RCC_CFGR_HPRE_DIV << STM_RCC_CFGR_HPRE))
+               asm ("nop");
+
+       /* APB1 Prescaler = AO_APB1_PRESCALER */
+       cfgr = stm_rcc.cfgr;
+       cfgr &= ~(STM_RCC_CFGR_PPRE1_MASK << STM_RCC_CFGR_PPRE1);
+       cfgr |= (AO_RCC_CFGR_PPRE1_DIV << STM_RCC_CFGR_PPRE1);
+       stm_rcc.cfgr = cfgr;
+
+       /* APB2 Prescaler = AO_APB2_PRESCALER */
+       cfgr = stm_rcc.cfgr;
+       cfgr &= ~(STM_RCC_CFGR_PPRE2_MASK << STM_RCC_CFGR_PPRE2);
+       cfgr |= (AO_RCC_CFGR_PPRE2_DIV << STM_RCC_CFGR_PPRE2);
+       stm_rcc.cfgr = cfgr;
 
        /* Disable the PLL */
        stm_rcc.cr &= ~(1 << STM_RCC_CR_PLLON);
@@ -191,19 +225,12 @@ ao_clock_init(void)
        cfgr &= ~(STM_RCC_CFGR_PLLMUL_MASK << STM_RCC_CFGR_PLLMUL);
        cfgr &= ~(STM_RCC_CFGR_PLLDIV_MASK << 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 |= (AO_RCC_CFGR_PLLMUL << STM_RCC_CFGR_PLLMUL);
+       cfgr |= (AO_RCC_CFGR_PLLDIV << 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 */
+       /* PLL source */
        cfgr &= ~(1 << STM_RCC_CFGR_PLLSRC);
-
-#define STM_PLLSRC     STM_HSI
+       cfgr |= STM_RCC_CFGR_PLLSRC_TARGET_CLOCK;
 
        stm_rcc.cfgr = cfgr;
 
@@ -228,4 +255,31 @@ ao_clock_init(void)
                if (part == val)
                        break;
        }
+
+#if 0
+       stm_rcc.apb2rstr = 0xffff;
+       stm_rcc.apb1rstr = 0xffff;
+       stm_rcc.ahbrstr = 0x3f;
+       stm_rcc.ahbenr = (1 << STM_RCC_AHBENR_FLITFEN);
+       stm_rcc.apb2enr = 0;
+       stm_rcc.apb1enr = 0;
+       stm_rcc.ahbrstr = 0;
+       stm_rcc.apb1rstr = 0;
+       stm_rcc.apb2rstr = 0;
+#endif
+
+       /* Clear reset flags */
+       stm_rcc.csr |= (1 << STM_RCC_CSR_RMVF);
+
+
+       /* 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_rcc.cfgr |= (STM_RCC_CFGR_MCOPRE_DIV_1 << STM_RCC_CFGR_MCOPRE);
+       stm_rcc.cfgr |= (STM_RCC_CFGR_MCOSEL_HSE << STM_RCC_CFGR_MCOSEL);
 }