Timer code simplification in preparation of led strip being assignable.
[betaflight.git] / src / main / drivers / timer_stm32f4xx.c
blobda13ae77f3af7d76e88fc064a60e4cec0e10b435
1 /*
2 modified version of StdPeriph function is located here.
3 TODO - what license does apply here?
4 original file was lincesed under MCD-ST Liberty SW License Agreement V2
5 http://www.st.com/software_license_agreement_liberty_v2
6 */
8 #include <stdbool.h>
9 #include <stdint.h>
11 #include "platform.h"
13 #include "common/utils.h"
15 #include "stm32f4xx.h"
16 #include "rcc.h"
17 #include "timer.h"
19 /**
20 * @brief Selects the TIM Output Compare Mode.
21 * @note This function does NOT disable the selected channel before changing the Output
22 * Compare Mode.
23 * @param TIMx: where x can be 1 to 17 except 6 and 7 to select the TIM peripheral.
24 * @param TIM_Channel: specifies the TIM Channel
25 * This parameter can be one of the following values:
26 * @arg TIM_Channel_1: TIM Channel 1
27 * @arg TIM_Channel_2: TIM Channel 2
28 * @arg TIM_Channel_3: TIM Channel 3
29 * @arg TIM_Channel_4: TIM Channel 4
30 * @param TIM_OCMode: specifies the TIM Output Compare Mode.
31 * This parameter can be one of the following values:
32 * @arg TIM_OCMode_Timing
33 * @arg TIM_OCMode_Active
34 * @arg TIM_OCMode_Toggle
35 * @arg TIM_OCMode_PWM1
36 * @arg TIM_OCMode_PWM2
37 * @arg TIM_ForcedAction_Active
38 * @arg TIM_ForcedAction_InActive
39 * @retval None
42 #define CCMR_Offset ((uint16_t)0x0018)
44 const timerDef_t timerDefinitions[HARDWARE_TIMER_DEFINITION_COUNT] = {
45 { .TIMx = TIM1, .rcc = RCC_APB2(TIM1) },
46 { .TIMx = TIM2, .rcc = RCC_APB1(TIM2) },
47 { .TIMx = TIM3, .rcc = RCC_APB1(TIM3) },
48 { .TIMx = TIM4, .rcc = RCC_APB1(TIM4) },
49 { .TIMx = TIM5, .rcc = RCC_APB1(TIM5) },
50 { .TIMx = TIM6, .rcc = RCC_APB1(TIM6) },
51 { .TIMx = TIM7, .rcc = RCC_APB1(TIM7) },
52 { .TIMx = TIM8, .rcc = RCC_APB2(TIM8) },
53 { .TIMx = TIM9, .rcc = RCC_APB2(TIM9) },
54 { .TIMx = TIM10, .rcc = RCC_APB2(TIM10) },
55 { .TIMx = TIM11, .rcc = RCC_APB2(TIM11) },
56 { .TIMx = TIM12, .rcc = RCC_APB1(TIM12) },
57 { .TIMx = TIM13, .rcc = RCC_APB1(TIM13) },
58 { .TIMx = TIM14, .rcc = RCC_APB1(TIM14) },
61 /*
62 need a mapping from dma and timers to pins, and the values should all be set here to the dmaMotors array.
63 this mapping could be used for both these motors and for led strip.
65 only certain pins have OC output (already used in normal PWM et al) but then
66 there are only certain DMA streams/channels available for certain timers and channels.
67 *** (this may highlight some hardware limitations on some targets) ***
69 DMA1
71 Channel Stream0 Stream1 Stream2 Stream3 Stream4 Stream5 Stream6 Stream7
74 2 TIM4_CH1 TIM4_CH2 TIM4_CH3
75 3 TIM2_CH3 TIM2_CH1 TIM2_CH1 TIM2_CH4
76 TIM2_CH4
78 5 TIM3_CH4 TIM3_CH1 TIM3_CH2 TIM3_CH3
79 6 TIM5_CH3 TIM5_CH4 TIM5_CH1 TIM5_CH4 TIM5_CH2
82 DMA2
84 Channel Stream0 Stream1 Stream2 Stream3 Stream4 Stream5 Stream6 Stream7
85 0 TIM8_CH1 TIM1_CH1
86 TIM8_CH2 TIM1_CH2
87 TIM8_CH3 TIM1_CH3
93 6 TIM1_CH1 TIM1_CH2 TIM1_CH1 TIM1_CH4 TIM1_CH3
94 7 TIM8_CH1 TIM8_CH2 TIM8_CH3 TIM8_CH4
97 uint8_t timerClockDivisor(TIM_TypeDef *tim)
99 #if defined (STM32F40_41xxx)
100 if (tim == TIM8) return 1;
101 #endif
102 if (tim == TIM1 || tim == TIM9 || tim == TIM10 || tim == TIM11) {
103 return 1;
104 } else {
105 return 2;
109 void TIM_SelectOCxM_NoDisable(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_OCMode)
111 uint32_t tmp = 0;
113 /* Check the parameters */
114 assert_param(IS_TIM_LIST8_PERIPH(TIMx));
115 assert_param(IS_TIM_CHANNEL(TIM_Channel));
116 assert_param(IS_TIM_OCM(TIM_OCMode));
118 tmp = (uint32_t) TIMx;
119 tmp += CCMR_Offset;
121 if((TIM_Channel == TIM_Channel_1) ||(TIM_Channel == TIM_Channel_3)) {
122 tmp += (TIM_Channel>>1);
124 /* Reset the OCxM bits in the CCMRx register */
125 *(__IO uint32_t *) tmp &= (uint32_t)~((uint32_t)TIM_CCMR1_OC1M);
127 /* Configure the OCxM bits in the CCMRx register */
128 *(__IO uint32_t *) tmp |= TIM_OCMode;
129 } else {
130 tmp += (uint16_t)(TIM_Channel - (uint16_t)4)>> (uint16_t)1;
132 /* Reset the OCxM bits in the CCMRx register */
133 *(__IO uint32_t *) tmp &= (uint32_t)~((uint32_t)TIM_CCMR1_OC2M);
135 /* Configure the OCxM bits in the CCMRx register */
136 *(__IO uint32_t *) tmp |= (uint16_t)(TIM_OCMode << 8);