X-Git-Url: https://git.gag.com/?p=fw%2Faltos;a=blobdiff_plain;f=src%2Fstm%2Fao_timer.c;h=8db62e76a806b6ff51e49ecb3e23d0cc087aab72;hp=e7f1ddfe231cfe4db879a64108fbc35b14cf1937;hb=c674a20432c2cb97e5bc2a3de891f78b9e172fe9;hpb=51aef5d4fc29986353ad887f4a67ed2fe35f8c8e diff --git a/src/stm/ao_timer.c b/src/stm/ao_timer.c index e7f1ddfe..8db62e76 100644 --- a/src/stm/ao_timer.c +++ b/src/stm/ao_timer.c @@ -16,96 +16,143 @@ */ #include "ao.h" +#include +#if HAS_FAKE_FLIGHT +#include +#endif -static volatile __data uint16_t ao_tick_count; - -uint16_t ao_time(void) -{ - uint16_t v; - ao_arch_critical( - v = ao_tick_count; - ); - return v; -} +#ifndef HAS_TICK +#define HAS_TICK 1 +#endif -static __xdata uint8_t ao_forever; +#if HAS_TICK +volatile AO_TICK_TYPE ao_tick_count; -void -ao_delay(uint16_t ticks) +AO_TICK_TYPE +ao_time(void) { - ao_alarm(ticks); - ao_sleep(&ao_forever); + return ao_tick_count; } -#if HAS_ADC -volatile __data uint8_t ao_adc_interval = 1; -volatile __data uint8_t ao_adc_count; +#if AO_DATA_ALL +volatile __data uint8_t ao_data_interval = 1; +volatile __data uint8_t ao_data_count; #endif -void -ao_debug_out(char c); - - -void stm_tim6_isr(void) +void stm_systick_isr(void) { - if (stm_tim6.sr & (1 << STM_TIM67_SR_UIF)) { - stm_tim6.sr = 0; + if (stm_systick.csr & (1 << STM_SYSTICK_CSR_COUNTFLAG)) { ++ao_tick_count; -#if HAS_ADC - if (++ao_adc_count == ao_adc_interval) { - ao_adc_count = 0; - ao_adc_poll(); +#if HAS_TASK_QUEUE + if (ao_task_alarm_tick && (int16_t) (ao_tick_count - ao_task_alarm_tick) >= 0) + ao_task_check_alarm((uint16_t) ao_tick_count); +#endif +#if AO_DATA_ALL + if (++ao_data_count == ao_data_interval) { + ao_data_count = 0; +#if HAS_FAKE_FLIGHT + if (ao_fake_flight_active) + ao_fake_flight_poll(); + else +#endif + ao_adc_poll(); +#if (AO_DATA_ALL & ~(AO_DATA_ADC)) + ao_wakeup((void *) &ao_data_count); +#endif } +#endif +#ifdef AO_TIMER_HOOK + AO_TIMER_HOOK; #endif } } #if HAS_ADC void -ao_timer_set_adc_interval(uint8_t interval) __critical +ao_timer_set_adc_interval(uint8_t interval) { - ao_adc_interval = interval; - ao_adc_count = 0; + ao_arch_critical( + ao_data_interval = interval; + ao_data_count = 0; + ); } #endif -#define TIMER_10kHz (AO_PCLK1 / 10000) +#define SYSTICK_RELOAD (AO_SYSTICK / 100 - 1) 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)); + stm_systick.rvr = SYSTICK_RELOAD; + stm_systick.cvr = 0; + stm_systick.csr = ((1 << STM_SYSTICK_CSR_ENABLE) | + (1 << STM_SYSTICK_CSR_TICKINT) | + (STM_SYSTICK_CSR_CLKSOURCE_HCLK_8 << STM_SYSTICK_CSR_CLKSOURCE)); } +#endif + void 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))) + ao_arch_nop(); + + stm_rcc.cfgr = (stm_rcc.cfgr & ~(STM_RCC_CFGR_SW_MASK << STM_RCC_CFGR_SW)) | + (STM_RCC_CFGR_SW_MSI << STM_RCC_CFGR_SW); + + /* wait for system to switch to MSI */ + while ((stm_rcc.cfgr & (STM_RCC_CFGR_SWS_MASK << STM_RCC_CFGR_SWS)) != + (STM_RCC_CFGR_SWS_MSI << STM_RCC_CFGR_SWS)) + ao_arch_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 */ /* Enable 64-bit access and prefetch */ @@ -113,9 +160,26 @@ ao_clock_init(void) 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) */ stm_flash.acr |= (1 << STM_FLASH_ACR_LATENCY); + /* 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"); /* HCLK to 16MHz -> AHB prescaler = /1 */ cfgr = stm_rcc.cfgr; @@ -138,65 +202,6 @@ ao_clock_init(void) cfgr |= (AO_RCC_CFGR_PPRE2_DIV << STM_RCC_CFGR_PPRE2); stm_rcc.cfgr = cfgr; - /* 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"); - -#if AO_HSE - /* Enable HSE clock */ - if (!(stm_rcc.cr & (1 << STM_RCC_CR_HSERDY))) { - 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 */ - 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"); - } -#endif - /* Switch to direct high speed clock for SYSCLK */ - if ((stm_rcc.cfgr & (STM_RCC_CFGR_SWS_MASK << STM_RCC_CFGR_SWS)) != - STM_RCC_CFGR_SWS_TARGET_CLOCK) { - cfgr = stm_rcc.cfgr; - cfgr &= ~(STM_RCC_CFGR_SW_MASK << STM_RCC_CFGR_SW); - cfgr |= STM_RCC_CFGR_SW_TARGET_CLOCK; - stm_rcc.cfgr = cfgr; - while ((stm_rcc.cfgr & (STM_RCC_CFGR_SWS_MASK << STM_RCC_CFGR_SWS)) != - STM_RCC_CFGR_SWS_TARGET_CLOCK); - asm("nop"); - } - /* Disable the PLL */ stm_rcc.cr &= ~(1 << STM_RCC_CR_PLLON); while (stm_rcc.cr & (1 << STM_RCC_CR_PLLRDY)) @@ -237,4 +242,33 @@ 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); + + +#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_rcc.cfgr |= (STM_RCC_CFGR_MCOPRE_DIV_1 << STM_RCC_CFGR_MCOPRE); + stm_rcc.cfgr |= (STM_RCC_CFGR_MCOSEL_HSE << STM_RCC_CFGR_MCOSEL); +#endif }