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)
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/>.
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
;
51 #error "Unknown CPU defined"
62 TIM_USE_TRANSPONDER
= 0x20,
63 TIM_USE_BEEPER
= 0x40,
64 TIM_USE_CAMERA_CONTROL
= 0x80,
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
{
88 typedef struct timerHardware_s
{
92 timerUsageFlag_e usageFlags
;
94 #if defined(STM32F3) || defined(STM32F4) || defined(STM32F7) || defined(STM32H7) || defined(STM32G4)
95 uint8_t alternateFunction
;
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
;
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)
110 #endif // USE_DMA_SPEC
111 dmaResource_t
*dmaTimUPRef
;
112 #if defined(STM32F4) || defined(STM32F7) || defined(STM32H7) || defined(STM32G4)
113 uint32_t dmaTimUPChannel
;
115 uint8_t dmaTimUPIrqHandler
;
120 TIMER_OUTPUT_NONE
= 0,
121 TIMER_OUTPUT_INVERTED
= (1 << 0),
122 TIMER_OUTPUT_N_CHANNEL
= (1 << 1),
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
131 #define HARDWARE_TIMER_DEFINITION_COUNT 4
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))
149 #define MHZ_TO_HZ(x) ((x) * 1000000)
151 #if !defined(USE_UNIFIED_TARGET)
152 extern const timerHardware_t timerHardware
[];
156 #if defined(USE_TIMER_MGMT)
159 #define FULL_TIMER_CHANNEL_COUNT 88
161 #elif defined(STM32F4)
163 #if defined(STM32F411xE)
164 #define FULL_TIMER_CHANNEL_COUNT 59
166 #define FULL_TIMER_CHANNEL_COUNT 78
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
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) )
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) )
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) )
213 #error "No timer / channel tag definition found for CPU"
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
[];
229 TYPE_PWMOUTPUT_MOTOR
,
231 TYPE_PWMOUTPUT_SERVO
,
234 TYPE_SOFTSERIAL_RXTX
, // bidirectional pin for softserial
235 TYPE_SOFTSERIAL_AUXTIMER
, // timer channel is used for softserial. No IO function on pin
246 void timerConfigure(const timerHardware_t
*timHw
, uint16_t period
, uint32_t hz
);
251 void timerInit(void);
252 void timerStart(void);
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
);
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
);
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
);
313 void timerOCInit(TIM_TypeDef
*tim
, uint8_t channel
, TIM_OCInitTypeDef
*init
);
314 void timerOCPreloadConfig(TIM_TypeDef
*tim
, uint8_t channel
, uint16_t preload
);
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
);