#include "project.h" int time_known; #if 0 void exti15_10_isr (void) { nvic_disable_irq (NVIC_EXTI15_10_IRQ); if (exti_get_flag_status (EXTI10)) exti10_isr(); if (exti_get_flag_status (EXTI11)) exti11_isr(); nvic_enable_irq (NVIC_EXTI15_10_IRQ); } #endif static void cmd_dispatch (void) { uint8_t c; while (!ring_read_byte (&rx2_ring, &c)) { printf ("KEY> %c\r\n", c); switch (c) { case 'R': scb_reset_system(); break; case 'G': gps_reset(); break; case 'I': gps_bs(); break; case 'A': //gps_almanac(); gps_dump_almanac(); break; } } } #if 0 static void pd_port (uint32_t p) { unsigned c; for (c = 0; c < 32; ++c) { if ((p == GPIOA) && ((c == 13) || (c == 14))) continue; gpio_mode_setup (p, GPIO_MODE_INPUT, GPIO_PUPD_NONE, 1UL << c); } } static void pd_clear (uint32_t g, uint32_t b) { gpio_mode_setup (g, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, b); gpio_set_output_options (g, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, b); gpio_clear (g, b); } static void pd_set (uint32_t g, uint32_t b) { gpio_mode_setup (g, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, b); gpio_set_output_options (g, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, b); gpio_set (g, b); } static void pd(void) { pd_port (GPIOA); pd_port (GPIOB); pd_port (GPIOC); pd_port (GPIOD); pd_port (GPIOE); pd_port (GPIOF); pd_port (GPIOG); pd_set (GPIOB, GPIO10); pd_set (GPIOG, GPIO4); pd_set (GPIOD, GPIO10); pd_set (GPIOD, GPIO1); pd_set (GPIOB, GPIO13); pd_set (GPIOE, GPIO3); pd_set (GPIOE, GPIO4); rcc_periph_clock_disable (RCC_ETHMACPTP); rcc_periph_clock_disable (RCC_ETHMACRX); rcc_periph_clock_disable (RCC_ETHMACTX); rcc_periph_clock_disable (RCC_ETHMAC); rcc_periph_clock_disable (RCC_USART2); rcc_periph_clock_disable (RCC_USART1); rcc_periph_clock_disable (RCC_GPIOG); rcc_periph_clock_disable (RCC_GPIOF); rcc_periph_clock_disable (RCC_GPIOE); rcc_periph_clock_disable (RCC_GPIOD); rcc_periph_clock_disable (RCC_GPIOC); rcc_periph_clock_disable (RCC_GPIOB); rcc_periph_clock_disable (RCC_GPIOA); rcc_periph_clock_disable (RCC_SYSCFG); for (;;); } #endif static const clock_scale_t hse_10mhz_3v3_168 = { /* 168MHz */ .pllm = 10, .plln = 336, .pllp = 2, .pllq = 7, .hpre = RCC_CFGR_HPRE_DIV_NONE, .ppre1 = RCC_CFGR_PPRE_DIV_4, .ppre2 = RCC_CFGR_PPRE_DIV_2, .flash_config = FLASH_ACR_ICE | FLASH_ACR_DCE | FLASH_ACR_LATENCY_5WS, .apb1_frequency = 42000000, .apb2_frequency = 84000000, }; static const clock_scale_t hse_10mhz_3v3_120 = { /* 120 */ .pllm = 10, .plln = 240, .pllp = 2, .pllq = 5, .hpre = RCC_CFGR_HPRE_DIV_NONE, .ppre1 = RCC_CFGR_PPRE_DIV_4, .ppre2 = RCC_CFGR_PPRE_DIV_2, .power_save = 1, .flash_config = FLASH_ACR_ICE | FLASH_ACR_DCE | FLASH_ACR_LATENCY_3WS, .apb1_frequency = 30000000, .apb2_frequency = 60000000, }; static const clock_scale_t hse_10mhz_3v3_84 = { .pllm = 10, .plln = 336, .pllp = 4, .pllq = 7, .hpre = RCC_CFGR_HPRE_DIV_NONE, .ppre1 = RCC_CFGR_PPRE_DIV_2, .ppre2 = RCC_CFGR_PPRE_DIV_NONE, .flash_config = FLASH_ACR_ICE | FLASH_ACR_DCE | FLASH_ACR_LATENCY_2WS, .apb1_frequency = 42000000, .apb2_frequency = 84000000, }; static const clock_scale_t hse_10mhz_3v3_48 = { .pllm = 10, .plln = 96, .pllp = 2, .pllq = 2, .hpre = RCC_CFGR_HPRE_DIV_NONE, .ppre1 = RCC_CFGR_PPRE_DIV_4, .ppre2 = RCC_CFGR_PPRE_DIV_2, .power_save = 1, .flash_config = FLASH_ACR_ICE | FLASH_ACR_DCE | FLASH_ACR_LATENCY_3WS, .apb1_frequency = 12000000, .apb2_frequency = 24000000, }; static const clock_scale_t hse_10mhz_3v3_10 = { /* 10 */ .pllm = 10, .plln = 336, .pllp = 2, .pllq = 7, .hpre = RCC_CFGR_HPRE_DIV_NONE, .ppre1 = RCC_CFGR_PPRE_DIV_NONE, .ppre2 = RCC_CFGR_PPRE_DIV_NONE, .flash_config = FLASH_ACR_ICE | FLASH_ACR_DCE | FLASH_ACR_LATENCY_0WS, // .ahb_frequency = 10000000, .apb1_frequency = 10000000, .apb2_frequency = 10000000, }; /* * Erugh the STM32F4's PLL is shite, we need * to drive the entire clock tree from the 10MHz * input, we use the PLL only to drive the 48MHz * clock tree. * * So PTP, AHB, APB1, APB2 all are directly from * the HSE input */ void rcc_clock_setup_hse_3v3_no_pll(const clock_scale_t *clock) { /* Enable internal high-speed oscillator. */ rcc_osc_on(HSI); rcc_wait_for_osc_ready(HSI); /* Select HSI as SYSCLK source. */ rcc_set_sysclk_source(RCC_CFGR_SW_HSI); /* Enable external high-speed oscillator 8MHz. */ rcc_osc_on(HSE); rcc_wait_for_osc_ready(HSE); /* Enable/disable high performance mode */ if (!clock->power_save) { pwr_set_vos_scale(SCALE1); } else { pwr_set_vos_scale(SCALE2); } /* * Set prescalers for AHB, ADC, ABP1, ABP2. * Do this before touching the PLL (TODO: why?). */ rcc_set_hpre(clock->hpre); rcc_set_ppre1(clock->ppre1); rcc_set_ppre2(clock->ppre2); rcc_set_main_pll_hse(clock->pllm, clock->plln, clock->pllp, clock->pllq); /* Enable PLL oscillator and wait for it to stabilize. */ rcc_osc_on(PLL); rcc_wait_for_osc_ready(PLL); /* Configure flash settings. */ flash_set_ws(clock->flash_config); /* Select PLL as SYSCLK source. */ rcc_set_sysclk_source(RCC_CFGR_SW_HSE); /* Wait for PLL clock to be selected. */ rcc_wait_for_sysclk_status(HSE); /* Set the peripheral clock frequencies used. */ rcc_apb1_frequency = clock->apb1_frequency; rcc_apb2_frequency = clock->apb2_frequency; /* Disable internal high-speed oscillator. */ rcc_osc_off(HSI); } static void board_setup (void) { rcc_osc_bypass_enable (HSE); RCC_SSCGR = 0; // rcc_clock_setup_hse_3v3 (&hse_10mhz_3v3_168); rcc_clock_setup_hse_3v3_no_pll (&hse_10mhz_3v3_10); rcc_periph_clock_enable (RCC_SYSCFG); rcc_periph_clock_enable (RCC_GPIOA); rcc_periph_clock_enable (RCC_GPIOB); rcc_periph_clock_enable (RCC_GPIOC); rcc_periph_clock_enable (RCC_GPIOD); rcc_periph_clock_enable (RCC_GPIOE); rcc_periph_clock_enable (RCC_GPIOF); rcc_periph_clock_enable (RCC_GPIOG); rcc_periph_clock_enable (RCC_USART1); rcc_periph_clock_enable (RCC_USART2); rcc_periph_clock_enable (RCC_ETHMAC); rcc_periph_clock_enable (RCC_ETHMACTX); rcc_periph_clock_enable (RCC_ETHMACRX); rcc_periph_clock_enable (RCC_ETHMACPTP); nvic_set_priority (NVIC_EXTI9_5_IRQ, 0x00); nvic_set_priority (NVIC_EXTI3_IRQ, 0x10); nvic_set_priority (NVIC_EXTI4_IRQ, 0x20); nvic_set_priority (NVIC_USART1_IRQ, 0x30); nvic_set_priority (NVIC_USART2_IRQ, 0x30); nvic_set_priority (NVIC_ETH_IRQ, 0x40); nvic_set_priority (NVIC_SYSTICK_IRQ, 0x50); // nvic_enable_irq (NVIC_EXTI15_10_IRQ); } static void system_init (void) { board_setup(); led_init(); ticker_init(); usart_init(); msf_init(); dcf77_init(); printf ("LWIP\r\n"); start_lwip(); printf ("STETH\r\n"); steth_init(); max7219_init (1); gps_init(); ntp_init(); } int main (void) { system_init(); printf ("Boot\r\n"); #if 0 while (1) { uint32_t now = SCS_DWT_CYCCNT; uint64_t abs = abs_extend (now); EPOCH e = pll_decompose (abs); time_print_epoch ("TEST: ", e); delay_ms (100); } #endif while (1) { #if 0 { uint32_t now = SCS_DWT_CYCCNT; uint64_t abs = abs_extend (now); EPOCH e = pll_decompose (abs); time_print_epoch ("TEST: ", e); delay_ms (100); } abs_meh(); #endif msf_dispatch(); dcf77_dispatch(); gps_dispatch(); cmd_dispatch(); dispatch_lwip(); max7219_dispatch(); } return 0; }