2 * This file is part of Cleanflight and Betaflight.
4 * Cleanflight and Betaflight are free software. You can redistribute
5 * this software and/or modify this software under the terms of the
6 * GNU General Public License as published by the Free Software
7 * Foundation, either version 3 of the License, or (at your option)
10 * Cleanflight and Betaflight are distributed in the hope that they
11 * will be useful, but WITHOUT ANY WARRANTY; without even the implied
12 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 * See the GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this software.
18 * If not, see <http://www.gnu.org/licenses/>.
25 #include "common/utils.h"
27 #include "drivers/dma.h"
28 #include "drivers/io.h"
29 #include "drivers/timer_def.h"
31 #include "stm32f4xx.h"
36 const timerDef_t timerDefinitions
[HARDWARE_TIMER_DEFINITION_COUNT
] = {
37 { .TIMx
= TIM1
, .rcc
= RCC_APB2(TIM1
), .inputIrq
= TIM1_CC_IRQn
},
38 { .TIMx
= TIM2
, .rcc
= RCC_APB1(TIM2
), .inputIrq
= TIM2_IRQn
},
39 { .TIMx
= TIM3
, .rcc
= RCC_APB1(TIM3
), .inputIrq
= TIM3_IRQn
},
40 { .TIMx
= TIM4
, .rcc
= RCC_APB1(TIM4
), .inputIrq
= TIM4_IRQn
},
41 { .TIMx
= TIM5
, .rcc
= RCC_APB1(TIM5
), .inputIrq
= TIM5_IRQn
},
42 { .TIMx
= TIM6
, .rcc
= RCC_APB1(TIM6
), .inputIrq
= 0},
43 { .TIMx
= TIM7
, .rcc
= RCC_APB1(TIM7
), .inputIrq
= 0},
44 #if defined(STM32F446xx)
45 { .TIMx
= TIM8
, .rcc
= RCC_APB2(TIM8
), .inputIrq
= 0},
46 #elif !defined(STM32F411xE)
47 { .TIMx
= TIM8
, .rcc
= RCC_APB2(TIM8
), .inputIrq
= TIM8_CC_IRQn
},
49 { .TIMx
= TIM9
, .rcc
= RCC_APB2(TIM9
), .inputIrq
= TIM1_BRK_TIM9_IRQn
},
50 { .TIMx
= TIM10
, .rcc
= RCC_APB2(TIM10
), .inputIrq
= TIM1_UP_TIM10_IRQn
},
51 { .TIMx
= TIM11
, .rcc
= RCC_APB2(TIM11
), .inputIrq
= TIM1_TRG_COM_TIM11_IRQn
},
53 { .TIMx
= TIM12
, .rcc
= RCC_APB1(TIM12
), .inputIrq
= TIM8_BRK_TIM12_IRQn
},
54 { .TIMx
= TIM13
, .rcc
= RCC_APB1(TIM13
), .inputIrq
= TIM8_UP_TIM13_IRQn
},
55 { .TIMx
= TIM14
, .rcc
= RCC_APB1(TIM14
), .inputIrq
= TIM8_TRG_COM_TIM14_IRQn
},
59 #if defined(USE_TIMER_MGMT)
60 const timerHardware_t fullTimerHardware
[FULL_TIMER_CHANNEL_COUNT
] = {
61 // Auto-generated from 'timer_def.h'
63 DEF_TIM(TIM2
, CH1
, PA0
, TIM_USE_ANY
, 0, 0),
64 DEF_TIM(TIM2
, CH2
, PA1
, TIM_USE_ANY
, 0, 0),
65 DEF_TIM(TIM2
, CH3
, PA2
, TIM_USE_ANY
, 0, 0),
66 DEF_TIM(TIM2
, CH4
, PA3
, TIM_USE_ANY
, 0, 0),
67 DEF_TIM(TIM2
, CH1
, PA5
, TIM_USE_ANY
, 0, 0),
68 DEF_TIM(TIM1
, CH1N
, PA7
, TIM_USE_ANY
, 0, 0),
69 DEF_TIM(TIM1
, CH1
, PA8
, TIM_USE_ANY
, 0, 0),
70 DEF_TIM(TIM1
, CH2
, PA9
, TIM_USE_ANY
, 0, 0),
71 DEF_TIM(TIM1
, CH3
, PA10
, TIM_USE_ANY
, 0, 0),
72 DEF_TIM(TIM1
, CH1N
, PA11
, TIM_USE_ANY
, 0, 0),
73 DEF_TIM(TIM2
, CH1
, PA15
, TIM_USE_ANY
, 0, 0),
75 DEF_TIM(TIM5
, CH1
, PA0
, TIM_USE_ANY
, 0, 0),
76 DEF_TIM(TIM5
, CH2
, PA1
, TIM_USE_ANY
, 0, 0),
77 DEF_TIM(TIM5
, CH3
, PA2
, TIM_USE_ANY
, 0, 0),
78 DEF_TIM(TIM5
, CH4
, PA3
, TIM_USE_ANY
, 0, 0),
79 DEF_TIM(TIM3
, CH1
, PA6
, TIM_USE_ANY
, 0, 0),
80 DEF_TIM(TIM3
, CH2
, PA7
, TIM_USE_ANY
, 0, 0),
82 DEF_TIM(TIM9
, CH1
, PA2
, TIM_USE_ANY
, 0, 0),
83 DEF_TIM(TIM9
, CH2
, PA3
, TIM_USE_ANY
, 0, 0),
84 #if !defined(STM32F411xE)
85 DEF_TIM(TIM8
, CH1N
, PA5
, TIM_USE_ANY
, 0, 0),
86 DEF_TIM(TIM8
, CH1N
, PA7
, TIM_USE_ANY
, 0, 0),
88 DEF_TIM(TIM13
, CH1
, PA6
, TIM_USE_ANY
, 0, 0),
89 DEF_TIM(TIM14
, CH1
, PA7
, TIM_USE_ANY
, 0, 0),
93 DEF_TIM(TIM1
, CH2N
, PB0
, TIM_USE_ANY
, 0, 0),
94 DEF_TIM(TIM1
, CH3N
, PB1
, TIM_USE_ANY
, 0, 0),
95 DEF_TIM(TIM2
, CH2
, PB3
, TIM_USE_ANY
, 0, 0),
96 DEF_TIM(TIM2
, CH3
, PB10
, TIM_USE_ANY
, 0, 0),
97 DEF_TIM(TIM2
, CH4
, PB11
, TIM_USE_ANY
, 0, 0),
98 DEF_TIM(TIM1
, CH1N
, PB13
, TIM_USE_ANY
, 0, 0),
99 DEF_TIM(TIM1
, CH2N
, PB14
, TIM_USE_ANY
, 0, 0),
100 DEF_TIM(TIM1
, CH3N
, PB15
, TIM_USE_ANY
, 0, 0),
102 DEF_TIM(TIM3
, CH3
, PB0
, TIM_USE_ANY
, 0, 0),
103 DEF_TIM(TIM3
, CH4
, PB1
, TIM_USE_ANY
, 0, 0),
104 DEF_TIM(TIM3
, CH1
, PB4
, TIM_USE_ANY
, 0, 0),
105 DEF_TIM(TIM3
, CH2
, PB5
, TIM_USE_ANY
, 0, 0),
106 DEF_TIM(TIM4
, CH1
, PB6
, TIM_USE_ANY
, 0, 0),
107 DEF_TIM(TIM4
, CH2
, PB7
, TIM_USE_ANY
, 0, 0),
108 DEF_TIM(TIM4
, CH3
, PB8
, TIM_USE_ANY
, 0, 0),
109 DEF_TIM(TIM4
, CH4
, PB9
, TIM_USE_ANY
, 0, 0),
111 #if !defined(STM32F411xE)
112 DEF_TIM(TIM8
, CH2N
, PB0
, TIM_USE_ANY
, 0, 0),
113 DEF_TIM(TIM8
, CH3N
, PB1
, TIM_USE_ANY
, 0, 0),
115 DEF_TIM(TIM10
, CH1
, PB8
, TIM_USE_ANY
, 0, 0),
116 DEF_TIM(TIM11
, CH1
, PB9
, TIM_USE_ANY
, 0, 0),
117 #if !defined(STM32F411xE)
118 DEF_TIM(TIM8
, CH2N
, PB14
, TIM_USE_ANY
, 0, 0),
119 DEF_TIM(TIM8
, CH3N
, PB15
, TIM_USE_ANY
, 0, 0),
121 DEF_TIM(TIM12
, CH1
, PB14
, TIM_USE_ANY
, 0, 0),
122 DEF_TIM(TIM12
, CH2
, PB15
, TIM_USE_ANY
, 0, 0),
126 DEF_TIM(TIM3
, CH1
, PC6
, TIM_USE_ANY
, 0, 0),
127 DEF_TIM(TIM3
, CH2
, PC7
, TIM_USE_ANY
, 0, 0),
128 DEF_TIM(TIM3
, CH3
, PC8
, TIM_USE_ANY
, 0, 0),
129 DEF_TIM(TIM3
, CH4
, PC9
, TIM_USE_ANY
, 0, 0),
131 #if !defined(STM32F411xE)
132 DEF_TIM(TIM8
, CH1
, PC6
, TIM_USE_ANY
, 0, 0),
133 DEF_TIM(TIM8
, CH2
, PC7
, TIM_USE_ANY
, 0, 0),
134 DEF_TIM(TIM8
, CH3
, PC8
, TIM_USE_ANY
, 0, 0),
135 DEF_TIM(TIM8
, CH4
, PC9
, TIM_USE_ANY
, 0, 0),
139 DEF_TIM(TIM4
, CH1
, PD12
, TIM_USE_ANY
, 0, 0),
140 DEF_TIM(TIM4
, CH2
, PD13
, TIM_USE_ANY
, 0, 0),
141 DEF_TIM(TIM4
, CH3
, PD14
, TIM_USE_ANY
, 0, 0),
142 DEF_TIM(TIM4
, CH4
, PD15
, TIM_USE_ANY
, 0, 0),
145 DEF_TIM(TIM1
, CH1N
, PE8
, TIM_USE_ANY
, 0, 0),
146 DEF_TIM(TIM1
, CH1
, PE9
, TIM_USE_ANY
, 0, 0),
147 DEF_TIM(TIM1
, CH2N
, PE10
, TIM_USE_ANY
, 0, 0),
148 DEF_TIM(TIM1
, CH2
, PE11
, TIM_USE_ANY
, 0, 0),
149 DEF_TIM(TIM1
, CH3N
, PE12
, TIM_USE_ANY
, 0, 0),
150 DEF_TIM(TIM1
, CH3
, PE13
, TIM_USE_ANY
, 0, 0),
151 DEF_TIM(TIM1
, CH4
, PE14
, TIM_USE_ANY
, 0, 0),
153 DEF_TIM(TIM9
, CH1
, PE5
, TIM_USE_ANY
, 0, 0),
154 DEF_TIM(TIM9
, CH2
, PE6
, TIM_USE_ANY
, 0, 0),
157 #if !defined(STM32F411xE)
158 DEF_TIM(TIM10
, CH1
, PF6
, TIM_USE_ANY
, 0, 0),
159 DEF_TIM(TIM11
, CH1
, PF7
, TIM_USE_ANY
, 0, 0),
163 // Port H is not available for LPQFP-100 or 144 package
164 // DEF_TIM(TIM5, CH1, PH10, TIM_USE_ANY, 0, 0),
165 // DEF_TIM(TIM5, CH2, PH11, TIM_USE_ANY, 0, 0),
166 // DEF_TIM(TIM5, CH3, PH12, TIM_USE_ANY, 0, 0),
168 //#if !defined(STM32F411xE)
169 // DEF_TIM(TIM8, CH1N, PH13, TIM_USE_ANY, 0, 0),
170 // DEF_TIM(TIM8, CH2N, PH14, TIM_USE_ANY, 0, 0),
171 // DEF_TIM(TIM8, CH3N, PH15, TIM_USE_ANY, 0, 0),
173 // DEF_TIM(TIM12, CH1, PH6, TIM_USE_ANY, 0, 0),
174 // DEF_TIM(TIM12, CH2, PH9, TIM_USE_ANY, 0, 0),
178 // Port I is not available for LPQFP-100 or 144 package
179 // DEF_TIM(TIM5, CH4, PI0, TIM_USE_ANY, 0, 0),
181 //#if !defined(STM32F411xE)
182 // DEF_TIM(TIM8, CH4, PI2, TIM_USE_ANY, 0, 0),
183 // DEF_TIM(TIM8, CH1, PI5, TIM_USE_ANY, 0, 0),
184 // DEF_TIM(TIM8, CH2, PI6, TIM_USE_ANY, 0, 0),
185 // DEF_TIM(TIM8, CH3, PI7, TIM_USE_ANY, 0, 0),
192 need a mapping from dma and timers to pins, and the values should all be set here to the dmaMotors array.
193 this mapping could be used for both these motors and for led strip.
195 only certain pins have OC output (already used in normal PWM et al) but then
196 there are only certain DMA streams/channels available for certain timers and channels.
197 *** (this may highlight some hardware limitations on some targets) ***
201 Channel Stream0 Stream1 Stream2 Stream3 Stream4 Stream5 Stream6 Stream7
204 2 TIM4_CH1 TIM4_CH2 TIM4_CH3
205 3 TIM2_CH3 TIM2_CH1 TIM2_CH1 TIM2_CH4
208 5 TIM3_CH4 TIM3_CH1 TIM3_CH2 TIM3_CH3
209 6 TIM5_CH3 TIM5_CH4 TIM5_CH1 TIM5_CH4 TIM5_CH2
214 Channel Stream0 Stream1 Stream2 Stream3 Stream4 Stream5 Stream6 Stream7
223 6 TIM1_CH1 TIM1_CH2 TIM1_CH1 TIM1_CH4 TIM1_CH3
224 7 TIM8_CH1 TIM8_CH2 TIM8_CH3 TIM8_CH4
227 uint32_t timerClock(TIM_TypeDef
*tim
)
229 #if defined (STM32F411xE)
231 return SystemCoreClock
;
232 #elif defined (STM32F40_41xxx) || defined (STM32F446xx)
233 if (tim
== TIM8
|| tim
== TIM1
|| tim
== TIM9
|| tim
== TIM10
|| tim
== TIM11
) {
234 return SystemCoreClock
;
236 return SystemCoreClock
/ 2;
239 #error "No timer clock defined correctly for MCU"