Paparazzi UAS  v5.2.2_stable-0-gd6b9f29
Paparazzi is a free software Unmanned Aircraft System.
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
mcu_arch.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2010-2012 The Paparazzi team
3  *
4  * This file is part of Paparazzi.
5  *
6  * Paparazzi is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2, or (at your option)
9  * any later version.
10  *
11  * Paparazzi is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Paparazzi; see the file COPYING. If not, write to
18  * the Free Software Foundation, 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  *
21  */
22 
29 #include "mcu.h"
30 
31 #include BOARD_CONFIG
32 
33 #include <inttypes.h>
34 #include <libopencm3/stm32/gpio.h>
35 #include <libopencm3/stm32/rcc.h>
36 #include <libopencm3/stm32/timer.h>
37 #include <libopencm3/stm32/flash.h>
38 #include <libopencm3/cm3/scb.h>
39 
40 #include "std.h"
41 
42 #if defined(STM32F4)
43 
44 const clock_scale_t hse_25mhz_3v3_168mhz = { /* 168MHz */
45  .pllm = 25,
46  .plln = 336,
47  .pllp = 2,
48  .pllq = 7,
49  .hpre = RCC_CFGR_HPRE_DIV_NONE,
50  .ppre1 = RCC_CFGR_PPRE_DIV_4,
51  .ppre2 = RCC_CFGR_PPRE_DIV_2,
52  .flash_config = FLASH_ACR_ICE | FLASH_ACR_DCE |
53  FLASH_ACR_LATENCY_5WS,
54  .apb1_frequency = 42000000,
55  .apb2_frequency = 84000000,
56 };
57 #endif
58 
59 void mcu_arch_init(void) {
60 #if LUFTBOOT
61 PRINT_CONFIG_MSG("We are running luftboot, the interrupt vector is being relocated.")
62  SCB_VTOR = 0x00002000;
63 #endif
64 #if EXT_CLK == 8000000
65 #if defined(STM32F1)
66 PRINT_CONFIG_MSG("Using 8MHz external clock to PLL it to 72MHz.")
67  rcc_clock_setup_in_hse_8mhz_out_72mhz();
68 #elif defined(STM32F4)
69 PRINT_CONFIG_MSG("Using 8MHz external clock to PLL it to 168MHz.")
70  rcc_clock_setup_hse_3v3(&hse_8mhz_3v3[CLOCK_3V3_168MHZ]);
71 #endif
72 #elif EXT_CLK == 12000000
73 #if defined(STM32F1)
74 PRINT_CONFIG_MSG("Using 12MHz external clock to PLL it to 72MHz.")
75  rcc_clock_setup_in_hse_12mhz_out_72mhz();
76 #elif defined(STM32F4)
77 PRINT_CONFIG_MSG("Using 12MHz external clock to PLL it to 168MHz.")
78  rcc_clock_setup_hse_3v3(&hse_12mhz_3v3[CLOCK_3V3_168MHZ]);
79 #endif
80 #elif EXT_CLK == 16000000
81 #if defined(STM32F4)
82 PRINT_CONFIG_MSG("Using 16MHz external clock to PLL it to 168MHz.")
83  rcc_clock_setup_hse_3v3(&hse_16mhz_3v3[CLOCK_3V3_168MHZ]);
84 #endif
85 #elif EXT_CLK == 25000000
86 #if defined(STM32F4)
87 PRINT_CONFIG_MSG("Using 25MHz external clock to PLL it to 168MHz.")
88  rcc_clock_setup_hse_3v3(&hse_25mhz_3v3_168mhz);
89 #endif
90 #else
91 #error EXT_CLK is either set to an unsupported frequency or not defined at all. Please check!
92 #endif
93 
94  /* Configure priority grouping 0 bits for pre-emption priority and 4 bits for sub-priority.
95  * this was previously in i2c driver
96  * FIXME is it really needed ?
97  */
98 #ifndef RTOS_IS_CHIBIOS
99  scb_set_priority_grouping(SCB_AIRCR_PRIGROUP_NOGROUP_SUB16);
100 #endif
101 
102 }
103 
104 #if defined(STM32F1)
105 #define RCC_CFGR_PPRE2_SHIFT 11
106 #define RCC_CFGR_PPRE2 (7 << RCC_CFGR_PPRE2_SHIFT)
107 
108 #define RCC_CFGR_PPRE1_SHIFT 8
109 #define RCC_CFGR_PPRE1 (7 << RCC_CFGR_PPRE1_SHIFT)
110 
111 static inline uint32_t rcc_get_ppre1(void)
112 {
113  return RCC_CFGR & RCC_CFGR_PPRE1;
114 }
115 
116 static inline uint32_t rcc_get_ppre2(void)
117 {
118  return RCC_CFGR & RCC_CFGR_PPRE2;
119 }
120 #elif defined(STM32F4)
121 static inline uint32_t rcc_get_ppre1(void)
122 {
123  return RCC_CFGR &((1 << 10) | (1 << 11) | (1 << 12));
124 }
125 
126 static inline uint32_t rcc_get_ppre2(void)
127 {
128  return RCC_CFGR &((1 << 13) | (1 << 14) | (1 << 15));
129 }
130 #endif
131 
140 {
141  switch (timer_peripheral) {
142  // Timers on APB1
143  case TIM1:
144  case TIM8:
145 #ifdef TIM9
146  case TIM9:
147 #endif
148 #ifdef TIM10
149  case TIM10:
150 #endif
151 #ifdef TIM11
152  case TIM11:
153 #endif
154  if (!rcc_get_ppre2())
155  // no APB2 prescaler
156  return rcc_ppre2_frequency;
157  else
158  return rcc_ppre2_frequency * 2;
159 
160  // timers on APB2
161  case TIM2:
162  case TIM3:
163  case TIM4:
164  case TIM5:
165  case TIM6:
166  case TIM7:
167 #ifdef TIM12
168  case TIM12:
169 #endif
170 #ifdef TIM13
171  case TIM13:
172 #endif
173 #ifdef TIM14
174  case TIM14:
175 #endif
176  if (!rcc_get_ppre1())
177  // no APB2 prescaler
178  return rcc_ppre1_frequency;
179  else
180  return rcc_ppre1_frequency * 2;
181  default:
182  // other timers currently not supported
183  break;
184  }
185  return 0;
186 }
uint32_t timer_get_frequency(uint32_t timer_peripheral)
Get Timer clock frequency (before prescaling) Only valid if using the internal clock for the timer...
Definition: mcu_arch.c:139
unsigned long uint32_t
Definition: types.h:18
Arch independent mcu ( Micro Controller Unit ) utilities.
void mcu_arch_init(void)
Definition: mcu_arch.c:40