Added support for F411, F446, F745, F765.
[betaflight.git] / src / main / drivers / timer.h
blob553128c77ee4f4903d5b2054744c853f707d9ba0
1 /*
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)
8 * any later version.
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/>.
21 #pragma once
23 #include <stdbool.h>
24 #include <stdint.h>
26 #include "drivers/io_types.h"
27 #include "drivers/rcc_types.h"
28 #include "drivers/timer_def.h"
30 #include "pg/timerio.h"
32 #define CC_CHANNELS_PER_TIMER 4 // TIM_Channel_1..4
33 #define CC_INDEX_FROM_CHANNEL(x) ((uint8_t)((x) >> 2))
34 #define CC_CHANNEL_FROM_INDEX(x) ((uint16_t)(x) << 2)
36 typedef uint16_t captureCompare_t; // 16 bit on both 103 and 303, just register access must be 32bit sometimes (use timCCR_t)
38 #if defined(STM32F4)
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(STM32F7)
44 typedef uint32_t timCCR_t;
45 typedef uint32_t timCCER_t;
46 typedef uint32_t timSR_t;
47 typedef uint32_t timCNT_t;
48 #elif defined(STM32F3)
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 #elif defined(STM32F1)
54 typedef uint16_t timCCR_t;
55 typedef uint16_t timCCER_t;
56 typedef uint16_t timSR_t;
57 typedef uint16_t timCNT_t;
58 #elif defined(UNIT_TEST) || defined(SIMULATOR_BUILD)
59 typedef uint32_t timCCR_t;
60 typedef uint32_t timCCER_t;
61 typedef uint32_t timSR_t;
62 typedef uint32_t timCNT_t;
63 #else
64 #error "Unknown CPU defined"
65 #endif
67 typedef enum {
68 TIM_USE_ANY = 0x0,
69 TIM_USE_NONE = 0x0,
70 TIM_USE_PPM = 0x1,
71 TIM_USE_PWM = 0x2,
72 TIM_USE_MOTOR = 0x4,
73 TIM_USE_SERVO = 0x8,
74 TIM_USE_LED = 0x10,
75 TIM_USE_TRANSPONDER = 0x20,
76 TIM_USE_BEEPER = 0x40,
77 TIM_USE_CAMERA_CONTROL = 0x80,
78 } timerUsageFlag_e;
80 // use different types from capture and overflow - multiple overflow handlers are implemented as linked list
81 struct timerCCHandlerRec_s;
82 struct timerOvrHandlerRec_s;
83 typedef void timerCCHandlerCallback(struct timerCCHandlerRec_s* self, uint16_t capture);
84 typedef void timerOvrHandlerCallback(struct timerOvrHandlerRec_s* self, uint16_t capture);
86 typedef struct timerCCHandlerRec_s {
87 timerCCHandlerCallback* fn;
88 } timerCCHandlerRec_t;
90 typedef struct timerOvrHandlerRec_s {
91 timerOvrHandlerCallback* fn;
92 struct timerOvrHandlerRec_s* next;
93 } timerOvrHandlerRec_t;
95 typedef struct timerDef_s {
96 TIM_TypeDef *TIMx;
97 rccPeriphTag_t rcc;
98 uint8_t inputIrq;
99 } timerDef_t;
101 typedef struct timerHardware_s {
102 TIM_TypeDef *tim;
103 ioTag_t tag;
104 uint8_t channel;
105 timerUsageFlag_e usageFlags;
106 uint8_t output;
107 #if defined(STM32F3) || defined(STM32F4) || defined(STM32F7)
108 uint8_t alternateFunction;
109 #endif
110 #if defined(USE_DSHOT) || defined(USE_LED_STRIP) || defined(USE_TRANSPONDER)
111 #if defined(USE_DMA_SPEC)
112 #if defined(STM32F4) || defined(STM32F7)
113 DMA_Stream_TypeDef *dmaRefConfigured;
114 uint32_t dmaChannelConfigured;
115 #else
116 DMA_Channel_TypeDef *dmaRefConfigured;
117 #endif
118 #else
119 #if defined(STM32F4) || defined(STM32F7)
120 DMA_Stream_TypeDef *dmaRef;
121 uint32_t dmaChannel;
122 #else
123 DMA_Channel_TypeDef *dmaRef;
124 #endif
125 #endif
126 #if defined(STM32F3) || defined(STM32F4) || defined(STM32F7)
127 // TIMUP
128 #ifdef STM32F3
129 DMA_Channel_TypeDef *dmaTimUPRef;
130 #else
131 DMA_Stream_TypeDef *dmaTimUPRef;
132 uint32_t dmaTimUPChannel;
133 #endif
134 uint8_t dmaTimUPIrqHandler;
135 #endif
136 #endif
137 } timerHardware_t;
139 typedef enum {
140 TIMER_OUTPUT_NONE = 0,
141 TIMER_OUTPUT_INVERTED = (1 << 0),
142 TIMER_OUTPUT_N_CHANNEL = (1 << 1),
143 } timerFlag_e;
145 #ifdef STM32F1
146 #if defined(STM32F10X_XL) || defined(STM32F10X_HD_VL)
147 #define HARDWARE_TIMER_DEFINITION_COUNT 14
148 #elif defined(STM32F10X_HD) || defined(STM32F10X_CL)
149 #define HARDWARE_TIMER_DEFINITION_COUNT 7
150 #else
151 #define HARDWARE_TIMER_DEFINITION_COUNT 4
152 #endif
153 #elif defined(STM32F3)
154 #define HARDWARE_TIMER_DEFINITION_COUNT 10
155 #elif defined(STM32F411xE)
156 #define HARDWARE_TIMER_DEFINITION_COUNT 10
157 #elif defined(STM32F4)
158 #define HARDWARE_TIMER_DEFINITION_COUNT 14
159 #elif defined(STM32F7)
160 #define HARDWARE_TIMER_DEFINITION_COUNT 14
161 #endif
163 #define MHZ_TO_HZ(x) ((x) * 1000000)
165 #if !defined(USE_UNIFIED_TARGET)
166 extern const timerHardware_t timerHardware[];
167 #endif
169 #if defined(USE_TIMER_MGMT)
170 #if defined(STM32F4)
172 #define FULL_TIMER_CHANNEL_COUNT 70
174 #elif defined(STM32F7)
176 #define FULL_TIMER_CHANNEL_COUNT 70
178 #endif
180 extern const timerHardware_t fullTimerHardware[];
182 #define TIMER_CHANNEL_COUNT FULL_TIMER_CHANNEL_COUNT
183 #define TIMER_HARDWARE fullTimerHardware
185 #if defined(STM32F7) || defined(STM32F4)
187 #define USED_TIMERS ( TIM_N(1) | TIM_N(2) | TIM_N(3) | TIM_N(4) | TIM_N(5) | TIM_N(6) | TIM_N(7) | TIM_N(8) | TIM_N(9) | TIM_N(10) | TIM_N(11) | TIM_N(12) | TIM_N(13) | TIM_N(14) )
189 #elif defined(STM32F3)
191 #define USED_TIMERS ( TIM_N(1) | TIM_N(2) | TIM_N(3) | TIM_N(4) | TIM_N(5) | TIM_N(6) | TIM_N(7) | TIM_N(8) | TIM_N(15) | TIM_N(16) | TIM_N(17) )
193 #elif defined(STM32F1)
195 #define USED_TIMERS ( TIM_N(1) | TIM_N(2) | TIM_N(3) | TIM_N(4) )
197 #else
198 #error "No timer / channel tag definition found for CPU"
199 #endif
201 #else
203 #define TIMER_CHANNEL_COUNT USABLE_TIMER_CHANNEL_COUNT
204 #define TIMER_HARDWARE timerHardware
206 #endif // USE_TIMER_MGMT
208 extern const timerDef_t timerDefinitions[];
210 typedef enum {
211 TYPE_FREE,
212 TYPE_PWMINPUT,
213 TYPE_PPMINPUT,
214 TYPE_PWMOUTPUT_MOTOR,
215 TYPE_PWMOUTPUT_FAST,
216 TYPE_PWMOUTPUT_SERVO,
217 TYPE_SOFTSERIAL_RX,
218 TYPE_SOFTSERIAL_TX,
219 TYPE_SOFTSERIAL_RXTX, // bidirectional pin for softserial
220 TYPE_SOFTSERIAL_AUXTIMER, // timer channel is used for softserial. No IO function on pin
221 TYPE_ADC,
222 TYPE_SERIAL_RX,
223 TYPE_SERIAL_TX,
224 TYPE_SERIAL_RXTX,
225 TYPE_TIMER
226 } channelType_t;
228 void timerConfigure(const timerHardware_t *timHw, uint16_t period, uint32_t hz); // This interface should be replaced.
230 void timerChConfigIC(const timerHardware_t *timHw, bool polarityRising, unsigned inputFilterSamples);
231 void timerChConfigICDual(const timerHardware_t* timHw, bool polarityRising, unsigned inputFilterSamples);
232 void timerChICPolarity(const timerHardware_t *timHw, bool polarityRising);
233 volatile timCCR_t* timerChCCR(const timerHardware_t* timHw);
234 volatile timCCR_t* timerChCCRLo(const timerHardware_t* timHw);
235 volatile timCCR_t* timerChCCRHi(const timerHardware_t* timHw);
236 void timerChConfigOC(const timerHardware_t* timHw, bool outEnable, bool stateHigh);
237 void timerChConfigGPIO(const timerHardware_t* timHw, ioConfig_t mode);
239 void timerChCCHandlerInit(timerCCHandlerRec_t *self, timerCCHandlerCallback *fn);
240 void timerChOvrHandlerInit(timerOvrHandlerRec_t *self, timerOvrHandlerCallback *fn);
241 void timerChConfigCallbacks(const timerHardware_t *channel, timerCCHandlerRec_t *edgeCallback, timerOvrHandlerRec_t *overflowCallback);
242 void timerChConfigCallbacksDual(const timerHardware_t *channel, timerCCHandlerRec_t *edgeCallbackLo, timerCCHandlerRec_t *edgeCallbackHi, timerOvrHandlerRec_t *overflowCallback);
243 void timerChITConfigDualLo(const timerHardware_t* timHw, FunctionalState newState);
244 void timerChITConfig(const timerHardware_t* timHw, FunctionalState newState);
245 void timerChClearCCFlag(const timerHardware_t* timHw);
247 void timerChInit(const timerHardware_t *timHw, channelType_t type, int irqPriority, uint8_t irq);
249 void timerInit(void);
250 void timerStart(void);
251 void timerForceOverflow(TIM_TypeDef *tim);
253 uint32_t timerClock(TIM_TypeDef *tim);
255 void configTimeBase(TIM_TypeDef *tim, uint16_t period, uint32_t hz); // TODO - just for migration
257 rccPeriphTag_t timerRCC(TIM_TypeDef *tim);
258 uint8_t timerInputIrq(TIM_TypeDef *tim);
260 #if defined(USE_TIMER_MGMT)
261 timerIOConfig_t *timerIoConfigByTag(ioTag_t ioTag);
262 #endif
263 const timerHardware_t *timerGetByTag(ioTag_t ioTag);
264 ioTag_t timerioTagGetByUsage(timerUsageFlag_e usageFlag, uint8_t index);
266 #if defined(USE_HAL_DRIVER)
267 TIM_HandleTypeDef* timerFindTimerHandle(TIM_TypeDef *tim);
268 HAL_StatusTypeDef TIM_DMACmd(TIM_HandleTypeDef *htim, uint32_t Channel, FunctionalState NewState);
269 HAL_StatusTypeDef DMA_SetCurrDataCounter(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData, uint16_t Length);
270 uint16_t timerDmaIndex(uint8_t channel);
271 #else
272 void timerOCInit(TIM_TypeDef *tim, uint8_t channel, TIM_OCInitTypeDef *init);
273 void timerOCPreloadConfig(TIM_TypeDef *tim, uint8_t channel, uint16_t preload);
274 #endif
276 volatile timCCR_t *timerCCR(TIM_TypeDef *tim, uint8_t channel);
277 uint16_t timerDmaSource(uint8_t channel);
279 uint16_t timerGetPrescalerByDesiredHertz(TIM_TypeDef *tim, uint32_t hz);
280 uint16_t timerGetPrescalerByDesiredMhz(TIM_TypeDef *tim, uint16_t mhz);
281 uint16_t timerGetPeriodByPrescaler(TIM_TypeDef *tim, uint16_t prescaler, uint32_t hz);
283 int8_t timerGetTIMNumber(const TIM_TypeDef *tim);
284 uint8_t timerLookupChannelIndex(const uint16_t channel);