Merge pull request #11494 from haslinghuis/dshot_gpio
[betaflight.git] / src / main / drivers / timer.h
blob16de57a7f3a2bafb6d70e9ced7271125978135d3
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/dma.h"
27 #include "drivers/io_types.h"
28 #include "drivers/rcc_types.h"
29 #include "drivers/resource.h"
30 #include "drivers/timer_def.h"
32 #include "pg/timerio.h"
34 #define CC_CHANNELS_PER_TIMER 4 // TIM_Channel_1..4
35 #define CC_INDEX_FROM_CHANNEL(x) ((uint8_t)((x) >> 2))
36 #define CC_CHANNEL_FROM_INDEX(x) ((uint16_t)(x) << 2)
38 typedef uint16_t captureCompare_t; // 16 bit on both 103 and 303, just register access must be 32bit sometimes (use timCCR_t)
40 #if defined(STM32F3) || defined(STM32F4) || defined(STM32F7) || defined(STM32H7) || defined(STM32G4) || defined(UNIT_TEST) || defined(SIMULATOR_BUILD)
41 typedef uint32_t timCCR_t;
42 typedef uint32_t timCCER_t;
43 typedef uint32_t timSR_t;
44 typedef uint32_t timCNT_t;
45 #elif defined(STM32F1)
46 typedef uint16_t timCCR_t;
47 typedef uint16_t timCCER_t;
48 typedef uint16_t timSR_t;
49 typedef uint16_t timCNT_t;
50 #else
51 #error "Unknown CPU defined"
52 #endif
54 typedef enum {
55 TIM_USE_ANY = 0x0,
56 TIM_USE_NONE = 0x0,
57 TIM_USE_PPM = 0x1,
58 TIM_USE_PWM = 0x2,
59 TIM_USE_MOTOR = 0x4,
60 TIM_USE_SERVO = 0x8,
61 TIM_USE_LED = 0x10,
62 TIM_USE_TRANSPONDER = 0x20,
63 TIM_USE_BEEPER = 0x40,
64 TIM_USE_CAMERA_CONTROL = 0x80,
65 } timerUsageFlag_e;
67 // use different types from capture and overflow - multiple overflow handlers are implemented as linked list
68 struct timerCCHandlerRec_s;
69 struct timerOvrHandlerRec_s;
70 typedef void timerCCHandlerCallback(struct timerCCHandlerRec_s* self, uint16_t capture);
71 typedef void timerOvrHandlerCallback(struct timerOvrHandlerRec_s* self, uint16_t capture);
73 typedef struct timerCCHandlerRec_s {
74 timerCCHandlerCallback* fn;
75 } timerCCHandlerRec_t;
77 typedef struct timerOvrHandlerRec_s {
78 timerOvrHandlerCallback* fn;
79 struct timerOvrHandlerRec_s* next;
80 } timerOvrHandlerRec_t;
82 typedef struct timerDef_s {
83 TIM_TypeDef *TIMx;
84 rccPeriphTag_t rcc;
85 uint8_t inputIrq;
86 } timerDef_t;
88 typedef struct timerHardware_s {
89 TIM_TypeDef *tim;
90 ioTag_t tag;
91 uint8_t channel;
92 timerUsageFlag_e usageFlags;
93 uint8_t output;
94 #if defined(STM32F3) || defined(STM32F4) || defined(STM32F7) || defined(STM32H7) || defined(STM32G4)
95 uint8_t alternateFunction;
96 #endif
98 #if defined(USE_TIMER_DMA)
100 #if defined(USE_DMA_SPEC)
101 #if defined(STM32F4) || defined(STM32F7) || defined(STM32H7) || defined(STM32G4)
102 dmaResource_t *dmaRefConfigured;
103 uint32_t dmaChannelConfigured;
104 #endif
105 #else // USE_DMA_SPEC
106 dmaResource_t *dmaRef;
107 #if defined(STM32F4) || defined(STM32F7) || defined(STM32H7) || defined(STM32G4)
108 uint32_t dmaChannel; // XXX Can be much smaller (e.g. uint8_t)
109 #endif
110 #endif // USE_DMA_SPEC
111 dmaResource_t *dmaTimUPRef;
112 #if defined(STM32F4) || defined(STM32F7) || defined(STM32H7) || defined(STM32G4)
113 uint32_t dmaTimUPChannel;
114 #endif
115 uint8_t dmaTimUPIrqHandler;
116 #endif
117 } timerHardware_t;
119 typedef enum {
120 TIMER_OUTPUT_NONE = 0,
121 TIMER_OUTPUT_INVERTED = (1 << 0),
122 TIMER_OUTPUT_N_CHANNEL = (1 << 1),
123 } timerFlag_e;
125 #ifdef STM32F1
126 #if defined(STM32F10X_XL) || defined(STM32F10X_HD_VL)
127 #define HARDWARE_TIMER_DEFINITION_COUNT 14
128 #elif defined(STM32F10X_HD) || defined(STM32F10X_CL)
129 #define HARDWARE_TIMER_DEFINITION_COUNT 7
130 #else
131 #define HARDWARE_TIMER_DEFINITION_COUNT 4
132 #endif
133 #elif defined(STM32F3)
134 #define HARDWARE_TIMER_DEFINITION_COUNT 10
135 #elif defined(STM32F411xE)
136 #define HARDWARE_TIMER_DEFINITION_COUNT 10
137 #elif defined(STM32F4)
138 #define HARDWARE_TIMER_DEFINITION_COUNT 14
139 #elif defined(STM32F7)
140 #define HARDWARE_TIMER_DEFINITION_COUNT 14
141 #elif defined(STM32H7)
142 #define HARDWARE_TIMER_DEFINITION_COUNT 17
143 #define TIMUP_TIMERS ( BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | BIT(6) | BIT(7) | BIT(8) | BIT(15) | BIT(16) | BIT(17) )
144 #elif defined(STM32G4)
145 #define HARDWARE_TIMER_DEFINITION_COUNT 12
146 #define TIMUP_TIMERS ( BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | BIT(6) | BIT(7) | BIT(8) | BIT(15) | BIT(16) | BIT(17) | BIT(20))
147 #endif
149 #define MHZ_TO_HZ(x) ((x) * 1000000)
151 #if !defined(USE_UNIFIED_TARGET)
152 extern const timerHardware_t timerHardware[];
153 #endif
156 #if defined(USE_TIMER_MGMT)
157 #if defined(STM32F3)
159 #define FULL_TIMER_CHANNEL_COUNT 88
161 #elif defined(STM32F4)
163 #if defined(STM32F411xE)
164 #define FULL_TIMER_CHANNEL_COUNT 59
165 #else
166 #define FULL_TIMER_CHANNEL_COUNT 78
167 #endif
169 #elif defined(STM32F7)
171 #define FULL_TIMER_CHANNEL_COUNT 78
173 #elif defined(STM32H7)
175 #define FULL_TIMER_CHANNEL_COUNT 87
177 #elif defined(STM32G4)
179 #define FULL_TIMER_CHANNEL_COUNT 93 // XXX Need review
181 #endif
183 extern const timerHardware_t fullTimerHardware[];
185 #define TIMER_CHANNEL_COUNT FULL_TIMER_CHANNEL_COUNT
186 #define TIMER_HARDWARE fullTimerHardware
188 #if defined(STM32F7) || defined(STM32F4)
190 #if defined(STM32F411xE)
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(9) | TIM_N(10) | TIM_N(11) )
192 #else
193 #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) )
194 #endif
196 #elif defined(STM32F3)
198 #define USED_TIMERS ( TIM_N(1) | TIM_N(2) | TIM_N(3) | TIM_N(4) | TIM_N(6) | TIM_N(7) | TIM_N(8) | TIM_N(15) | TIM_N(16) | TIM_N(17) )
200 #elif defined(STM32F1)
202 #define USED_TIMERS ( TIM_N(1) | TIM_N(2) | TIM_N(3) | TIM_N(4) )
204 #elif defined(STM32H7)
206 #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(12) | TIM_N(13) | TIM_N(14) | TIM_N(15) | TIM_N(16) | TIM_N(17) )
208 #elif defined(STM32G4)
210 #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) | TIM_N(20) )
212 #else
213 #error "No timer / channel tag definition found for CPU"
214 #endif
216 #else
218 #define TIMER_CHANNEL_COUNT USABLE_TIMER_CHANNEL_COUNT
219 #define TIMER_HARDWARE timerHardware
221 #endif // USE_TIMER_MGMT
223 extern const timerDef_t timerDefinitions[];
225 typedef enum {
226 TYPE_FREE,
227 TYPE_PWMINPUT,
228 TYPE_PPMINPUT,
229 TYPE_PWMOUTPUT_MOTOR,
230 TYPE_PWMOUTPUT_FAST,
231 TYPE_PWMOUTPUT_SERVO,
232 TYPE_SOFTSERIAL_RX,
233 TYPE_SOFTSERIAL_TX,
234 TYPE_SOFTSERIAL_RXTX, // bidirectional pin for softserial
235 TYPE_SOFTSERIAL_AUXTIMER, // timer channel is used for softserial. No IO function on pin
236 TYPE_ADC,
237 TYPE_SERIAL_RX,
238 TYPE_SERIAL_TX,
239 TYPE_SERIAL_RXTX,
240 TYPE_TIMER
241 } channelType_t;
244 // Legacy API
246 void timerConfigure(const timerHardware_t *timHw, uint16_t period, uint32_t hz);
249 // Initialisation
251 void timerInit(void);
252 void timerStart(void);
255 // per-channel
258 void timerChConfigIC(const timerHardware_t *timHw, bool polarityRising, unsigned inputFilterSamples);
259 void timerChConfigICDual(const timerHardware_t* timHw, bool polarityRising, unsigned inputFilterSamples);
260 void timerChICPolarity(const timerHardware_t *timHw, bool polarityRising);
261 volatile timCCR_t* timerChCCR(const timerHardware_t* timHw);
262 volatile timCCR_t* timerChCCRLo(const timerHardware_t* timHw);
263 volatile timCCR_t* timerChCCRHi(const timerHardware_t* timHw);
264 void timerChConfigOC(const timerHardware_t* timHw, bool outEnable, bool stateHigh);
265 void timerChConfigGPIO(const timerHardware_t* timHw, ioConfig_t mode);
267 void timerChCCHandlerInit(timerCCHandlerRec_t *self, timerCCHandlerCallback *fn);
268 void timerChOvrHandlerInit(timerOvrHandlerRec_t *self, timerOvrHandlerCallback *fn);
269 void timerChConfigCallbacks(const timerHardware_t *channel, timerCCHandlerRec_t *edgeCallback, timerOvrHandlerRec_t *overflowCallback);
270 void timerChConfigCallbacksDual(const timerHardware_t *channel, timerCCHandlerRec_t *edgeCallbackLo, timerCCHandlerRec_t *edgeCallbackHi, timerOvrHandlerRec_t *overflowCallback);
271 void timerChITConfigDualLo(const timerHardware_t* timHw, FunctionalState newState);
272 void timerChITConfig(const timerHardware_t* timHw, FunctionalState newState);
273 void timerChClearCCFlag(const timerHardware_t* timHw);
275 void timerChInit(const timerHardware_t *timHw, channelType_t type, int irqPriority, uint8_t irq);
278 // per-timer
281 void timerForceOverflow(TIM_TypeDef *tim);
283 void timerConfigUpdateCallback(const TIM_TypeDef *tim, timerOvrHandlerRec_t *updateCallback);
285 uint32_t timerClock(TIM_TypeDef *tim);
287 void configTimeBase(TIM_TypeDef *tim, uint16_t period, uint32_t hz); // TODO - just for migration
288 void timerReconfigureTimeBase(TIM_TypeDef *tim, uint16_t period, uint32_t hz);
290 rccPeriphTag_t timerRCC(TIM_TypeDef *tim);
291 uint8_t timerInputIrq(TIM_TypeDef *tim);
293 #if defined(USE_TIMER_MGMT)
294 extern const resourceOwner_t freeOwner;
296 struct timerIOConfig_s;
298 struct timerIOConfig_s *timerIoConfigByTag(ioTag_t ioTag);
299 const timerHardware_t *timerGetAllocatedByNumberAndChannel(int8_t timerNumber, uint16_t timerChannel);
300 const resourceOwner_t *timerGetOwner(const timerHardware_t *timer);
301 #endif
302 const timerHardware_t *timerGetConfiguredByTag(ioTag_t ioTag);
303 const timerHardware_t *timerAllocate(ioTag_t ioTag, resourceOwner_e owner, uint8_t resourceIndex);
304 const timerHardware_t *timerGetByTagAndIndex(ioTag_t ioTag, unsigned timerIndex);
305 ioTag_t timerioTagGetByUsage(timerUsageFlag_e usageFlag, uint8_t index);
307 #if defined(USE_HAL_DRIVER)
308 TIM_HandleTypeDef* timerFindTimerHandle(TIM_TypeDef *tim);
309 HAL_StatusTypeDef TIM_DMACmd(TIM_HandleTypeDef *htim, uint32_t Channel, FunctionalState NewState);
310 HAL_StatusTypeDef DMA_SetCurrDataCounter(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData, uint16_t Length);
311 uint16_t timerDmaIndex(uint8_t channel);
312 #else
313 void timerOCInit(TIM_TypeDef *tim, uint8_t channel, TIM_OCInitTypeDef *init);
314 void timerOCPreloadConfig(TIM_TypeDef *tim, uint8_t channel, uint16_t preload);
315 #endif
317 volatile timCCR_t *timerCCR(TIM_TypeDef *tim, uint8_t channel);
318 uint16_t timerDmaSource(uint8_t channel);
320 uint16_t timerGetPrescalerByDesiredHertz(TIM_TypeDef *tim, uint32_t hz);
321 uint16_t timerGetPrescalerByDesiredMhz(TIM_TypeDef *tim, uint16_t mhz);
322 uint16_t timerGetPeriodByPrescaler(TIM_TypeDef *tim, uint16_t prescaler, uint32_t hz);
324 int8_t timerGetNumberByIndex(uint8_t index);
325 int8_t timerGetTIMNumber(const TIM_TypeDef *tim);
326 uint8_t timerLookupChannelIndex(const uint16_t channel);