Blackbox device type 'file' (SITL) considered working when file handler is available
[inav.git] / src / main / drivers / timer_stm32h7xx.c
blobb01c8647e4189222ae895dee0bc532e8ab7eaca4
1 /*
2 * This file is part of INAV.
4 * INAV is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * INAV is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with INAV. If not, see <http://www.gnu.org/licenses/>.
18 #include <stdbool.h>
19 #include <stdint.h>
21 #include "platform.h"
23 #include "common/utils.h"
25 #include "drivers/io.h"
26 #include "drivers/rcc.h"
27 #include "drivers/time.h"
28 #include "drivers/nvic.h"
29 #include "drivers/timer.h"
30 #include "drivers/timer_impl.h"
32 #include "stm32h7xx.h"
34 const timerDef_t timerDefinitions[HARDWARE_TIMER_DEFINITION_COUNT] = {
35 [0] = { .tim = TIM1, .rcc = RCC_APB2(TIM1), .irq = TIM1_CC_IRQn},
36 [1] = { .tim = TIM2, .rcc = RCC_APB1L(TIM2), .irq = TIM2_IRQn},
37 [2] = { .tim = TIM3, .rcc = RCC_APB1L(TIM3), .irq = TIM3_IRQn},
38 [3] = { .tim = TIM4, .rcc = RCC_APB1L(TIM4), .irq = TIM4_IRQn},
39 [4] = { .tim = TIM5, .rcc = RCC_APB1L(TIM5), .irq = TIM5_IRQn},
40 [5] = { .tim = TIM6, .rcc = RCC_APB1L(TIM6), .irq = 0},
41 [6] = { .tim = TIM7, .rcc = RCC_APB1L(TIM7), .irq = 0},
42 [7] = { .tim = TIM8, .rcc = RCC_APB2(TIM8), .irq = TIM8_CC_IRQn},
43 [8] = { .tim = TIM12, .rcc = RCC_APB1L(TIM12), .irq = TIM8_BRK_TIM12_IRQn},
44 [9] = { .tim = TIM13, .rcc = RCC_APB1L(TIM13), .irq = TIM8_UP_TIM13_IRQn},
45 [10] = { .tim = TIM14, .rcc = RCC_APB1L(TIM14), .irq = TIM8_TRG_COM_TIM14_IRQn},
46 [11] = { .tim = TIM15, .rcc = RCC_APB2(TIM15), .irq = TIM15_IRQn},
47 [12] = { .tim = TIM16, .rcc = RCC_APB2(TIM16), .irq = TIM16_IRQn},
48 [13] = { .tim = TIM17, .rcc = RCC_APB2(TIM17), .irq = TIM17_IRQn},
51 uint32_t timerClock(TIM_TypeDef *tim)
53 int timpre;
54 uint32_t pclk;
55 uint32_t ppre;
57 // Implement the table:
58 // RM0433 (Rev 6) Table 52.
59 // RM0455 (Rev 3) Table 55.
60 // "Ratio between clock timer and pclk"
61 // (Tables are the same, just D2 or CD difference)
63 #if defined(STM32H743xx) || defined(STM32H750xx) || defined(STM32H723xx) || defined(STM32H725xx)
64 #define PERIPH_PRESCALER(bus) ((RCC->D2CFGR & RCC_D2CFGR_D2PPRE ## bus) >> RCC_D2CFGR_D2PPRE ## bus ## _Pos)
65 #elif defined(STM32H7A3xx) || defined(STM32H7A3xxQ)
66 #define PERIPH_PRESCALER(bus) ((RCC->CDCFGR2 & RCC_CDCFGR2_CDPPRE ## bus) >> RCC_CDCFGR2_CDPPRE ## bus ## _Pos)
67 #else
68 #error Unknown MCU type
69 #endif
71 if (tim == TIM1 || tim == TIM8 || tim == TIM15 || tim == TIM16 || tim == TIM17) {
72 // Timers on APB2
73 pclk = HAL_RCC_GetPCLK2Freq();
74 ppre = PERIPH_PRESCALER(2);
75 } else {
76 // Timers on APB1
77 pclk = HAL_RCC_GetPCLK1Freq();
78 ppre = PERIPH_PRESCALER(1);
81 timpre = (RCC->CFGR & RCC_CFGR_TIMPRE) ? 1 : 0;
83 int index = (timpre << 3) | ppre;
85 static uint8_t periphToKernel[16] = { // The mutiplier table
86 1, 1, 1, 1, 2, 2, 2, 2, // TIMPRE = 0
87 1, 1, 1, 1, 2, 4, 4, 4 // TIMPRE = 1
90 return pclk * periphToKernel[index];
92 #undef PERIPH_PRESCALER
95 _TIM_IRQ_HANDLER(TIM1_CC_IRQHandler, 1);
96 _TIM_IRQ_HANDLER(TIM2_IRQHandler, 2);
97 _TIM_IRQ_HANDLER(TIM3_IRQHandler, 3);
98 _TIM_IRQ_HANDLER(TIM4_IRQHandler, 4);
99 _TIM_IRQ_HANDLER(TIM5_IRQHandler, 5);
100 _TIM_IRQ_HANDLER(TIM8_CC_IRQHandler, 8);
101 _TIM_IRQ_HANDLER(TIM8_BRK_TIM12_IRQHandler, 12);
102 _TIM_IRQ_HANDLER(TIM15_IRQHandler, 15);
103 _TIM_IRQ_HANDLER(TIM16_IRQHandler, 16);
104 _TIM_IRQ_HANDLER(TIM17_IRQHandler, 17);
105 _TIM_IRQ_HANDLER2(TIM8_UP_TIM13_IRQHandler, 8, 13);
106 _TIM_IRQ_HANDLER2(TIM8_TRG_COM_TIM14_IRQHandler, 8, 14);