PWM output calculations dynamic based on clock speed
[betaflight.git] / src / main / drivers / timer.h
blob00cf4d8bc1768737eae37d55d8b63319909f2f13
1 /*
2 * This file is part of Cleanflight.
4 * Cleanflight 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 * Cleanflight 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 Cleanflight. If not, see <http://www.gnu.org/licenses/>.
18 #pragma once
20 #include <stdbool.h>
21 #include <stdint.h>
23 #include "drivers/io_types.h"
24 #include "rcc_types.h"
26 typedef uint16_t captureCompare_t; // 16 bit on both 103 and 303, just register access must be 32bit sometimes (use timCCR_t)
28 #if defined(STM32F4)
29 typedef uint32_t timCCR_t;
30 typedef uint32_t timCCER_t;
31 typedef uint32_t timSR_t;
32 typedef uint32_t timCNT_t;
33 #elif defined(STM32F7)
34 typedef uint32_t timCCR_t;
35 typedef uint32_t timCCER_t;
36 typedef uint32_t timSR_t;
37 typedef uint32_t timCNT_t;
38 #elif defined(STM32F3)
39 typedef uint32_t timCCR_t;
40 typedef uint32_t timCCER_t;
41 typedef uint32_t timSR_t;
42 typedef uint32_t timCNT_t;
43 #elif defined(STM32F1)
44 typedef uint16_t timCCR_t;
45 typedef uint16_t timCCER_t;
46 typedef uint16_t timSR_t;
47 typedef uint16_t timCNT_t;
48 #elif defined(UNIT_TEST) || defined(SIMULATOR_BUILD)
49 typedef uint32_t timCCR_t;
50 typedef uint32_t timCCER_t;
51 typedef uint32_t timSR_t;
52 typedef uint32_t timCNT_t;
53 #else
54 #error "Unknown CPU defined"
55 #endif
57 typedef enum {
58 TIM_USE_ANY = 0x0,
59 TIM_USE_NONE = 0x0,
60 TIM_USE_PPM = 0x1,
61 TIM_USE_PWM = 0x2,
62 TIM_USE_MOTOR = 0x4,
63 TIM_USE_SERVO = 0x8,
64 TIM_USE_LED = 0x10,
65 TIM_USE_TRANSPONDER = 0x20,
66 TIM_USE_BEEPER = 0x40
67 } timerUsageFlag_e;
69 // use different types from capture and overflow - multiple overflow handlers are implemented as linked list
70 struct timerCCHandlerRec_s;
71 struct timerOvrHandlerRec_s;
72 typedef void timerCCHandlerCallback(struct timerCCHandlerRec_s* self, uint16_t capture);
73 typedef void timerOvrHandlerCallback(struct timerOvrHandlerRec_s* self, uint16_t capture);
75 typedef struct timerCCHandlerRec_s {
76 timerCCHandlerCallback* fn;
77 } timerCCHandlerRec_t;
79 typedef struct timerOvrHandlerRec_s {
80 timerOvrHandlerCallback* fn;
81 struct timerOvrHandlerRec_s* next;
82 } timerOvrHandlerRec_t;
84 typedef struct timerDef_s {
85 TIM_TypeDef *TIMx;
86 rccPeriphTag_t rcc;
87 uint8_t inputIrq;
88 } timerDef_t;
90 typedef struct timerHardware_s {
91 TIM_TypeDef *tim;
92 ioTag_t tag;
93 uint8_t channel;
94 timerUsageFlag_e usageFlags;
95 uint8_t output;
96 #if defined(STM32F3) || defined(STM32F4) || defined(STM32F7)
97 uint8_t alternateFunction;
98 #endif
99 #if defined(USE_DSHOT) || defined(LED_STRIP) || defined(TRANSPONDER)
100 #if defined(STM32F4) || defined(STM32F7)
101 DMA_Stream_TypeDef *dmaRef;
102 uint32_t dmaChannel;
103 #elif defined(STM32F3) || defined(STM32F1)
104 DMA_Channel_TypeDef *dmaRef;
105 #endif
106 uint8_t dmaIrqHandler;
107 #endif
108 } timerHardware_t;
110 typedef enum {
111 TIMER_OUTPUT_NONE = 0x00,
112 TIMER_INPUT_ENABLED = 0x01, /* TODO: remove this */
113 TIMER_OUTPUT_ENABLED = 0x01, /* TODO: remove this */
114 TIMER_OUTPUT_STANDARD = 0x01,
115 TIMER_OUTPUT_INVERTED = 0x02,
116 TIMER_OUTPUT_N_CHANNEL = 0x04
117 } timerFlag_e;
119 #ifdef STM32F1
120 #if defined(STM32F10X_XL) || defined(STM32F10X_HD_VL)
121 #define HARDWARE_TIMER_DEFINITION_COUNT 14
122 #elif defined(STM32F10X_HD) || defined(STM32F10X_CL)
123 #define HARDWARE_TIMER_DEFINITION_COUNT 7
124 #else
125 #define HARDWARE_TIMER_DEFINITION_COUNT 4
126 #endif
127 #elif defined(STM32F3)
128 #define HARDWARE_TIMER_DEFINITION_COUNT 10
129 #elif defined(STM32F411xE)
130 #define HARDWARE_TIMER_DEFINITION_COUNT 10
131 #elif defined(STM32F4)
132 #define HARDWARE_TIMER_DEFINITION_COUNT 14
133 #elif defined(STM32F7)
134 #define HARDWARE_TIMER_DEFINITION_COUNT 14
135 #endif
137 #define MHZ_TO_HZ(x) (x * 1000000)
139 extern const timerHardware_t timerHardware[];
140 extern const timerDef_t timerDefinitions[];
142 typedef enum {
143 TYPE_FREE,
144 TYPE_PWMINPUT,
145 TYPE_PPMINPUT,
146 TYPE_PWMOUTPUT_MOTOR,
147 TYPE_PWMOUTPUT_FAST,
148 TYPE_PWMOUTPUT_SERVO,
149 TYPE_SOFTSERIAL_RX,
150 TYPE_SOFTSERIAL_TX,
151 TYPE_SOFTSERIAL_RXTX, // bidirectional pin for softserial
152 TYPE_SOFTSERIAL_AUXTIMER, // timer channel is used for softserial. No IO function on pin
153 TYPE_ADC,
154 TYPE_SERIAL_RX,
155 TYPE_SERIAL_TX,
156 TYPE_SERIAL_RXTX,
157 TYPE_TIMER
158 } channelType_t;
160 void timerConfigure(const timerHardware_t *timHw, uint16_t period, uint32_t hz); // This interface should be replaced.
162 void timerChConfigIC(const timerHardware_t *timHw, bool polarityRising, unsigned inputFilterSamples);
163 void timerChConfigICDual(const timerHardware_t* timHw, bool polarityRising, unsigned inputFilterSamples);
164 void timerChICPolarity(const timerHardware_t *timHw, bool polarityRising);
165 volatile timCCR_t* timerChCCR(const timerHardware_t* timHw);
166 volatile timCCR_t* timerChCCRLo(const timerHardware_t* timHw);
167 volatile timCCR_t* timerChCCRHi(const timerHardware_t* timHw);
168 void timerChConfigOC(const timerHardware_t* timHw, bool outEnable, bool stateHigh);
169 void timerChConfigGPIO(const timerHardware_t* timHw, ioConfig_t mode);
171 void timerChCCHandlerInit(timerCCHandlerRec_t *self, timerCCHandlerCallback *fn);
172 void timerChOvrHandlerInit(timerOvrHandlerRec_t *self, timerOvrHandlerCallback *fn);
173 void timerChConfigCallbacks(const timerHardware_t *channel, timerCCHandlerRec_t *edgeCallback, timerOvrHandlerRec_t *overflowCallback);
174 void timerChConfigCallbacksDual(const timerHardware_t *channel, timerCCHandlerRec_t *edgeCallbackLo, timerCCHandlerRec_t *edgeCallbackHi, timerOvrHandlerRec_t *overflowCallback);
175 void timerChITConfigDualLo(const timerHardware_t* timHw, FunctionalState newState);
176 void timerChITConfig(const timerHardware_t* timHw, FunctionalState newState);
177 void timerChClearCCFlag(const timerHardware_t* timHw);
179 void timerChInit(const timerHardware_t *timHw, channelType_t type, int irqPriority, uint8_t irq);
181 void timerInit(void);
182 void timerStart(void);
183 void timerForceOverflow(TIM_TypeDef *tim);
185 uint8_t timerClockDivisor(TIM_TypeDef *tim);
186 uint32_t timerClock(TIM_TypeDef *tim);
188 void configTimeBase(TIM_TypeDef *tim, uint16_t period, uint32_t hz); // TODO - just for migration
190 rccPeriphTag_t timerRCC(TIM_TypeDef *tim);
191 uint8_t timerInputIrq(TIM_TypeDef *tim);
193 const timerHardware_t *timerGetByTag(ioTag_t tag, timerUsageFlag_e flag);
195 #if defined(USE_HAL_DRIVER)
196 TIM_HandleTypeDef* timerFindTimerHandle(TIM_TypeDef *tim);
197 #else
198 void timerOCInit(TIM_TypeDef *tim, uint8_t channel, TIM_OCInitTypeDef *init);
199 void timerOCPreloadConfig(TIM_TypeDef *tim, uint8_t channel, uint16_t preload);
200 #endif
202 volatile timCCR_t *timerCCR(TIM_TypeDef *tim, uint8_t channel);
203 uint16_t timerDmaSource(uint8_t channel);
205 uint16_t timerGetPrescalerByDesiredHertz(TIM_TypeDef *tim, uint32_t hz);
206 uint16_t timerGetPrescalerByDesiredMhz(TIM_TypeDef *tim, uint16_t mhz);
207 uint16_t timerGetPeriodByPrescaler(TIM_TypeDef *tim, uint16_t prescaler, uint32_t hz);