Blackbox device type 'file' (SITL) considered working when file handler is available
[inav.git] / src / main / drivers / timer.h
blobd87e0400d5297c53d3ee00381dc001ee14a910cb
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 "drivers/dma.h"
25 #include "drivers/rcc_types.h"
26 #include "drivers/timer_def.h"
28 #include "platform.h"
30 #define CC_CHANNELS_PER_TIMER 4 // TIM_Channel_1..4
32 typedef uint16_t captureCompare_t; // 16 bit on both 103 and 303, just register access must be 32bit sometimes (use timCCR_t)
34 #if defined(STM32F4) || defined(STM32F7) || defined(STM32H7)|| defined(AT32F43x)
35 typedef uint32_t timCCR_t;
36 typedef uint32_t timCCER_t;
37 typedef uint32_t timSR_t;
38 typedef uint32_t timCNT_t;
39 #elif defined(UNIT_TEST)
40 typedef uint32_t timCCR_t;
41 typedef uint32_t timCCER_t;
42 typedef uint32_t timSR_t;
43 typedef uint32_t timCNT_t;
44 #elif defined(SITL_BUILD)
45 typedef uint32_t timCCR_t;
46 typedef uint32_t timCCER_t;
47 typedef uint32_t timSR_t;
48 typedef uint32_t timCNT_t;
49 #else
50 #error "Unknown CPU defined"
51 #endif
53 #if defined(STM32F4)
54 #define HARDWARE_TIMER_DEFINITION_COUNT 14
55 #elif defined(STM32F7)
56 #define HARDWARE_TIMER_DEFINITION_COUNT 14
57 #elif defined(STM32H7)
58 #define HARDWARE_TIMER_DEFINITION_COUNT 14
59 #elif defined(AT32F43x)
60 #define HARDWARE_TIMER_DEFINITION_COUNT 15
61 #elif defined(SITL_BUILD)
62 #define HARDWARE_TIMER_DEFINITION_COUNT 0
63 #else
64 #error "Unknown CPU defined"
65 #endif
66 // tmr_type instead in AT32
67 #if defined(AT32F43x)
68 typedef tmr_type HAL_Timer_t;
69 typedef struct timerDef_s {
70 HAL_Timer_t * tim;
71 rccPeriphTag_t rcc;
72 uint8_t irq;
73 uint8_t secondIrq;
74 } timerDef_t;
75 // TCH hardware definition (listed in target.c)
76 typedef struct timerHardware_s {
77 tmr_type *tim;
78 ioTag_t tag;
79 uint8_t channelIndex;
80 uint8_t output;
81 ioConfig_t ioMode;
82 uint8_t alternateFunction;
83 uint32_t usageFlags;
84 dmaTag_t dmaTag;
85 uint32_t dmaMuxid; //DMAMUX ID
86 } timerHardware_t;
87 #else
88 typedef TIM_TypeDef HAL_Timer_t;
89 typedef struct timerDef_s {
90 HAL_Timer_t * tim;
91 rccPeriphTag_t rcc;
92 uint8_t irq;
93 uint8_t secondIrq;
94 } timerDef_t;
96 // TCH hardware definition (listed in target.c)
97 typedef struct timerHardware_s {
98 TIM_TypeDef *tim;
99 ioTag_t tag;
100 uint8_t channelIndex;
101 uint8_t output;
102 ioConfig_t ioMode;
103 uint8_t alternateFunction;
104 uint32_t usageFlags;
105 dmaTag_t dmaTag;
106 } timerHardware_t;
108 #endif
109 typedef enum {
110 TIM_USE_ANY = 0,
111 TIM_USE_PPM = (1 << 0),
112 TIM_USE_PWM = (1 << 1),
113 TIM_USE_MOTOR = (1 << 2), // Motor output
114 TIM_USE_SERVO = (1 << 3), // Servo output
115 TIM_USE_MC_CHNFW = (1 << 4), // Deprecated and not used after removal of CHANNEL_FORWARDING feature
116 //TIM_USE_FW_MOTOR = (1 << 5), // We no longer differentiate mc from fw on pwm allocation
117 //TIM_USE_FW_SERVO = (1 << 6),
118 TIM_USE_LED = (1 << 24), // Remapping needs to be in the lower 8 bits.
119 TIM_USE_BEEPER = (1 << 25),
120 } timerUsageFlag_e;
122 #define TIM_USE_OUTPUT_AUTO (TIM_USE_MOTOR | TIM_USE_SERVO)
124 #define TIM_IS_MOTOR(flags) ((flags) & TIM_USE_MOTOR)
125 #define TIM_IS_SERVO(flags) ((flags) & TIM_USE_SERVO)
126 #define TIM_IS_LED(flags) ((flags) & TIM_USE_LED)
128 #define TIM_IS_MOTOR_ONLY(flags) (TIM_IS_MOTOR(flags) && !TIM_IS_SERVO(flags))
129 #define TIM_IS_SERVO_ONLY(flags) (!TIM_IS_MOTOR(flags) && TIM_IS_SERVO(flags))
131 enum {
132 TIMER_OUTPUT_NONE = 0x00,
133 TIMER_OUTPUT_INVERTED = 0x02,
134 TIMER_OUTPUT_N_CHANNEL= 0x04
137 typedef enum {
138 TCH_DMA_IDLE = 0,
139 TCH_DMA_READY,
140 TCH_DMA_ACTIVE,
141 } tchDmaState_e;
143 // Some forward declarations for types
144 struct TCH_s;
145 struct timHardwareContext_s;
147 // Timer generic callback
148 typedef void timerCallbackFn(struct TCH_s * tch, uint32_t value);
150 typedef struct timerCallbacks_s {
151 void * callbackParam;
152 timerCallbackFn * callbackEdge;
153 timerCallbackFn * callbackOvr;
154 } timerCallbacks_t;
156 // Run-time TCH (Timer CHannel) context
157 typedef struct TCH_s {
158 struct timHardwareContext_s * timCtx; // Run-time initialized to parent timer
159 const timerHardware_t * timHw; // Link to timerHardware_t definition (target-specific)
160 const timerCallbacks_t * cb;
161 DMA_t dma; // Timer channel DMA handle
162 volatile tchDmaState_e dmaState;
163 void * dmaBuffer;
164 } TCH_t;
166 // Run-time timer context (dynamically allocated), includes 4x TCH
167 typedef struct timHardwareContext_s {
168 const timerDef_t * timDef;
169 #ifdef USE_HAL_DRIVER
170 TIM_HandleTypeDef * timHandle;
171 #endif
172 TCH_t ch[CC_CHANNELS_PER_TIMER];
173 #ifdef USE_DSHOT_DMAR
174 DMA_t dmaBurstRef;
175 uint16_t DMASource;
176 #endif
177 } timHardwareContext_t;
179 // Per MCU timer definitions
180 extern timHardwareContext_t * timerCtx[HARDWARE_TIMER_DEFINITION_COUNT];
181 extern const timerDef_t timerDefinitions[HARDWARE_TIMER_DEFINITION_COUNT];
183 // Per target timer output definitions
184 extern timerHardware_t timerHardware[];
185 extern const int timerHardwareCount;
187 #ifdef USE_DSHOT_DMAR
188 typedef struct {
189 TIM_TypeDef *timer;
190 #ifdef USE_HAL_DRIVER
191 DMA_TypeDef *dma;
192 uint32_t streamLL;
193 #else
194 DMA_Stream_TypeDef *dmaBurstStream;
195 #endif
196 timerDMASafeType_t *dmaBurstBuffer;
197 uint16_t burstRequestSource;
198 } burstDmaTimer_t;
199 #endif
201 typedef enum {
202 TYPE_FREE,
203 TYPE_PWMINPUT,
204 TYPE_PPMINPUT,
205 TYPE_PWMOUTPUT_MOTOR,
206 TYPE_PWMOUTPUT_FAST,
207 TYPE_PWMOUTPUT_SERVO,
208 TYPE_SOFTSERIAL_RX,
209 TYPE_SOFTSERIAL_TX,
210 TYPE_SOFTSERIAL_RXTX, // bidirectional pin for softserial
211 TYPE_SOFTSERIAL_AUXTIMER, // timer channel is used for softserial. No IO function on pin
212 TYPE_ADC,
213 TYPE_SERIAL_RX,
214 TYPE_SERIAL_TX,
215 TYPE_SERIAL_RXTX,
216 TYPE_TIMER
217 } channelType_t;
219 #if defined(AT32F43x)
220 uint32_t timerClock(tmr_type *tim);
221 uint16_t timerGetPrescalerByDesiredMhz(tmr_type *tim, uint16_t mhz);
222 #else
223 uint32_t timerClock(TIM_TypeDef *tim);
224 uint16_t timerGetPrescalerByDesiredMhz(TIM_TypeDef *tim, uint16_t mhz);
225 #endif
227 uint32_t timerGetBaseClockHW(const timerHardware_t * timHw);
229 const timerHardware_t * timerGetByUsageFlag(timerUsageFlag_e flag);
230 const timerHardware_t * timerGetByTag(ioTag_t tag, timerUsageFlag_e flag);
231 TCH_t * timerGetTCH(const timerHardware_t * timHw);
233 uint32_t timerGetBaseClock(TCH_t * tch);
234 void timerConfigure(TCH_t * tch, uint16_t period, uint32_t hz); // This interface should be replaced.
236 void timerChInitCallbacks(timerCallbacks_t * cb, void * callbackParam, timerCallbackFn * edgeCallback, timerCallbackFn * overflowCallback);
237 void timerChConfigIC(TCH_t * tch, bool polarityRising, unsigned inputFilterSamples);
238 void timerChConfigCallbacks(TCH_t * tch, timerCallbacks_t * cb);
239 void timerChCaptureEnable(TCH_t * tch);
240 void timerChCaptureDisable(TCH_t * tch);
242 void timerInit(void);
243 void timerStart(void);
245 void timerConfigBase(TCH_t * tch, uint16_t period, uint32_t hz); // TODO - just for migration
246 uint16_t timerGetPeriod(TCH_t * tch);
248 void timerEnable(TCH_t * tch);
249 void timerPWMConfigChannel(TCH_t * tch, uint16_t value);
250 void timerPWMStart(TCH_t * tch);
252 // dmaBufferElementSize is the size in bytes of each element in the memory
253 // buffer. 1, 2 or 4 are the only valid values.
254 // dmaBufferElementCount is the number of elements in the buffer
255 bool timerPWMConfigChannelDMA(TCH_t * tch, void * dmaBuffer, uint8_t dmaBufferElementSize, uint32_t dmaBufferElementCount);
256 void timerPWMPrepareDMA(TCH_t * tch, uint32_t dmaBufferElementCount);
257 void timerPWMStartDMA(TCH_t * tch);
258 void timerPWMStopDMA(TCH_t * tch);
259 bool timerPWMDMAInProgress(TCH_t * tch);
261 volatile timCCR_t *timerCCR(TCH_t * tch);
263 uint8_t timer2id(const HAL_Timer_t *tim);
265 #ifdef USE_DSHOT_DMAR
266 bool timerPWMConfigDMABurst(burstDmaTimer_t *burstDmaTimer, TCH_t * tch, void * dmaBuffer, uint8_t dmaBufferElementSize, uint32_t dmaBufferElementCount);
267 void pwmBurstDMAStart(burstDmaTimer_t * burstDmaTimer, uint32_t BurstLength);
268 #endif