Paparazzi UAS  v5.8.2_stable-0-g6260b7c
Paparazzi is a free software Unmanned Aircraft System.
 All Data Structures Namespaces 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 /* untested, should go into libopencm3 */
44 const clock_scale_t hse_24mhz_3v3[CLOCK_3V3_END] = {
45  { /* 48MHz */
46  .pllm = 24,
47  .plln = 96,
48  .pllp = 2,
49  .pllq = 2,
50  .hpre = RCC_CFGR_HPRE_DIV_NONE,
51  .ppre1 = RCC_CFGR_PPRE_DIV_4,
52  .ppre2 = RCC_CFGR_PPRE_DIV_2,
53  .power_save = 1,
54  .flash_config = FLASH_ACR_ICE | FLASH_ACR_DCE |
55  FLASH_ACR_LATENCY_3WS,
56  .apb1_frequency = 12000000,
57  .apb2_frequency = 24000000,
58  },
59  { /* 120MHz */
60  .pllm = 24,
61  .plln = 240,
62  .pllp = 2,
63  .pllq = 5,
64  .hpre = RCC_CFGR_HPRE_DIV_NONE,
65  .ppre1 = RCC_CFGR_PPRE_DIV_4,
66  .ppre2 = RCC_CFGR_PPRE_DIV_2,
67  .power_save = 1,
68  .flash_config = FLASH_ACR_ICE | FLASH_ACR_DCE |
69  FLASH_ACR_LATENCY_3WS,
70  .apb1_frequency = 30000000,
71  .apb2_frequency = 60000000,
72  },
73  { /* 168MHz */
74  .pllm = 24,
75  .plln = 336,
76  .pllp = 2,
77  .pllq = 7,
78  .hpre = RCC_CFGR_HPRE_DIV_NONE,
79  .ppre1 = RCC_CFGR_PPRE_DIV_4,
80  .ppre2 = RCC_CFGR_PPRE_DIV_2,
81  .flash_config = FLASH_ACR_ICE | FLASH_ACR_DCE |
82  FLASH_ACR_LATENCY_5WS,
83  .apb1_frequency = 42000000,
84  .apb2_frequency = 84000000,
85  },
86 };
87 #endif
88 
89 void mcu_arch_init(void)
90 {
91 #if LUFTBOOT
92  PRINT_CONFIG_MSG("We are running luftboot, the interrupt vector is being relocated.")
93 #if defined STM32F4
94  SCB_VTOR = 0x00004000;
95 #else
96  SCB_VTOR = 0x00002000;
97 #endif
98 #endif
99 #if EXT_CLK == 8000000
100 #if defined(STM32F1)
101  PRINT_CONFIG_MSG("Using 8MHz external clock to PLL it to 72MHz.")
102  rcc_clock_setup_in_hse_8mhz_out_72mhz();
103 #elif defined(STM32F4)
104  PRINT_CONFIG_MSG("Using 8MHz external clock to PLL it to 168MHz.")
105  rcc_clock_setup_hse_3v3(&hse_8mhz_3v3[CLOCK_3V3_168MHZ]);
106 #endif
107 #elif EXT_CLK == 12000000
108 #if defined(STM32F1)
109  PRINT_CONFIG_MSG("Using 12MHz external clock to PLL it to 72MHz.")
110  rcc_clock_setup_in_hse_12mhz_out_72mhz();
111 #elif defined(STM32F4)
112  PRINT_CONFIG_MSG("Using 12MHz external clock to PLL it to 168MHz.")
113  rcc_clock_setup_hse_3v3(&hse_12mhz_3v3[CLOCK_3V3_168MHZ]);
114 #endif
115 #elif EXT_CLK == 16000000
116 #if defined(STM32F4)
117  PRINT_CONFIG_MSG("Using 16MHz external clock to PLL it to 168MHz.")
118  rcc_clock_setup_hse_3v3(&hse_16mhz_3v3[CLOCK_3V3_168MHZ]);
119 #endif
120 #elif EXT_CLK == 24000000
121 #if defined(STM32F4)
122  PRINT_CONFIG_MSG("Using 24MHz external clock to PLL it to 168MHz.")
123  rcc_clock_setup_hse_3v3(&hse_24mhz_3v3[CLOCK_3V3_168MHZ]);
124 #endif
125 #elif EXT_CLK == 25000000
126 #if defined(STM32F4)
127  PRINT_CONFIG_MSG("Using 25MHz external clock to PLL it to 168MHz.")
128  rcc_clock_setup_hse_3v3(&hse_25mhz_3v3[CLOCK_3V3_168MHZ]);
129 #endif
130 #else
131 #error EXT_CLK is either set to an unsupported frequency or not defined at all. Please check!
132 #endif
133 
134  /* Configure priority grouping 0 bits for pre-emption priority and 4 bits for sub-priority.
135  * this was previously in i2c driver
136  * FIXME is it really needed ?
137  */
138 #ifndef RTOS_IS_CHIBIOS
139  scb_set_priority_grouping(SCB_AIRCR_PRIGROUP_NOGROUP_SUB16);
140 #endif
141 
142 }
143 
144 #if defined(STM32F1)
145 #define RCC_CFGR_PPRE2_SHIFT 11
146 #define RCC_CFGR_PPRE2 (7 << RCC_CFGR_PPRE2_SHIFT)
147 
148 #define RCC_CFGR_PPRE1_SHIFT 8
149 #define RCC_CFGR_PPRE1 (7 << RCC_CFGR_PPRE1_SHIFT)
150 
151 static inline uint32_t rcc_get_ppre1(void)
152 {
153  return RCC_CFGR & RCC_CFGR_PPRE1;
154 }
155 
156 static inline uint32_t rcc_get_ppre2(void)
157 {
158  return RCC_CFGR & RCC_CFGR_PPRE2;
159 }
160 #elif defined(STM32F4)
161 static inline uint32_t rcc_get_ppre1(void)
162 {
163  return RCC_CFGR & ((1 << 10) | (1 << 11) | (1 << 12));
164 }
165 
166 static inline uint32_t rcc_get_ppre2(void)
167 {
168  return RCC_CFGR & ((1 << 13) | (1 << 14) | (1 << 15));
169 }
170 #endif
171 
180 {
181  switch (timer_peripheral) {
182  // Timers on high speed APB2
183  case TIM1:
184  case TIM8:
185 #ifdef TIM9
186  case TIM9:
187 #endif
188 #ifdef TIM10
189  case TIM10:
190 #endif
191 #ifdef TIM11
192  case TIM11:
193 #endif
194  if (!rcc_get_ppre2())
195  {
196  /* without APB2 prescaler, runs at APB2 freq */
197  return rcc_apb2_frequency;
198  } else {
199  /* with any ABP2 prescaler, runs at 2 * APB2 freq */
200  return rcc_apb2_frequency * 2;
201  }
202 
203  // timers on low speed APB1
204  case TIM2:
205  case TIM3:
206  case TIM4:
207  case TIM5:
208  case TIM6:
209  case TIM7:
210 #ifdef TIM12
211  case TIM12:
212 #endif
213 #ifdef TIM13
214  case TIM13:
215 #endif
216 #ifdef TIM14
217  case TIM14:
218 #endif
219  if (!rcc_get_ppre1())
220  {
221  /* without APB1 prescaler, runs at APB1 freq */
222  return rcc_apb1_frequency;
223  } else {
224  /* with any ABP1 prescaler, runs at 2 * APB1 freq */
225  return rcc_apb1_frequency * 2;
226  }
227  default:
228  // other timers currently not supported
229  break;
230  }
231  return 0;
232 }
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:179
void mcu_arch_init(void)
Definition: mcu_arch.c:77
unsigned long uint32_t
Definition: types.h:18
PRINT_CONFIG_MSG("USE_INS_NAV_INIT defaulting to TRUE")
Arch independent mcu ( Micro Controller Unit ) utilities.