X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fstmf0%2Fao_timer.c;h=58e52995cf32f35cbb4146b092f60e6217771972;hb=c4b8aff07d5366cef2c7209729f6cd22fa67de0c;hp=e5bf04a3ccb8eecfe56593ad446b177d57fb2af6;hpb=f95c781bc16d332ea5442590521074396d6981ae;p=fw%2Faltos diff --git a/src/stmf0/ao_timer.c b/src/stmf0/ao_timer.c index e5bf04a3..58e52995 100644 --- a/src/stmf0/ao_timer.c +++ b/src/stmf0/ao_timer.c @@ -3,7 +3,8 @@ * * 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. + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of @@ -34,9 +35,25 @@ ao_time(void) return ao_tick_count; } +uint64_t +ao_time_ns(void) +{ + AO_TICK_TYPE before, after; + uint32_t cvr; + + do { + before = ao_tick_count; + cvr = stm_systick.cvr; + after = ao_tick_count; + } while (before != after); + + return (uint64_t) after * (1000000000ULL / AO_HERTZ) + + (uint64_t) cvr * (1000000000ULL / AO_SYSTICK); +} + #if AO_DATA_ALL -volatile __data uint8_t ao_data_interval = 1; -volatile __data uint8_t ao_data_count; +volatile uint8_t ao_data_interval = 1; +volatile uint8_t ao_data_count; #endif void stm_systick_isr(void) @@ -85,6 +102,7 @@ ao_timer_set_adc_interval(uint8_t interval) void ao_timer_init(void) { + stm_systick.csr = 0; stm_systick.rvr = SYSTICK_RELOAD; stm_systick.cvr = 0; stm_systick.csr = ((1 << STM_SYSTICK_CSR_ENABLE) | @@ -175,13 +193,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); @@ -191,8 +208,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); @@ -201,9 +218,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 @@ -225,6 +239,8 @@ ao_clock_normal_start(void) #define STM_PLLSRC STM_HSI #define STM_RCC_CFGR_PLLSRC_TARGET_CLOCK 0 #endif + + } static void @@ -302,14 +318,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);