3 #ifdef PIOS_INCLUDE_TIM
5 #include "pios_tim_priv.h"
7 enum pios_tim_dev_magic
{
8 PIOS_TIM_DEV_MAGIC
= 0x87654098,
12 enum pios_tim_dev_magic magic
;
14 const struct pios_tim_channel
*channels
;
17 const struct pios_tim_callbacks
*callbacks
;
22 static bool PIOS_TIM_validate(struct pios_tim_dev
*tim_dev
)
24 return tim_dev
->magic
== PIOS_TIM_DEV_MAGIC
;
28 #if defined(PIOS_INCLUDE_FREERTOS) && 0
29 static struct pios_tim_dev
*PIOS_TIM_alloc(void)
31 struct pios_tim_dev
*tim_dev
;
33 tim_dev
= (struct pios_tim_dev
*)malloc(sizeof(*tim_dev
));
38 tim_dev
->magic
= PIOS_TIM_DEV_MAGIC
;
42 static struct pios_tim_dev pios_tim_devs
[PIOS_TIM_MAX_DEVS
];
43 static uint8_t pios_tim_num_devs
;
44 static struct pios_tim_dev
*PIOS_TIM_alloc(void)
46 struct pios_tim_dev
*tim_dev
;
48 if (pios_tim_num_devs
>= PIOS_TIM_MAX_DEVS
) {
52 tim_dev
= &pios_tim_devs
[pios_tim_num_devs
++];
53 tim_dev
->magic
= PIOS_TIM_DEV_MAGIC
;
57 #endif /* if defined(PIOS_INCLUDE_FREERTOS) && 0 */
60 int32_t PIOS_TIM_InitClock(const struct pios_tim_clock_cfg
*cfg
)
62 PIOS_DEBUG_Assert(cfg
);
64 /* Enable appropriate clock to timer module */
65 switch ((uint32_t)cfg
->timer
) {
67 RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1
, ENABLE
);
70 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2
, ENABLE
);
73 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3
, ENABLE
);
76 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4
, ENABLE
);
80 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5
, ENABLE
);
83 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6
, ENABLE
);
86 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM7
, ENABLE
);
89 RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8
, ENABLE
);
94 /* Configure the dividers for this timer */
95 TIM_TimeBaseInit(cfg
->timer
, cfg
->time_base_init
);
97 /* Configure internal timer clocks */
98 TIM_InternalClockConfig(cfg
->timer
);
101 TIM_Cmd(cfg
->timer
, ENABLE
);
103 /* Enable Interrupts */
104 NVIC_Init(&cfg
->irq
.init
);
109 int32_t PIOS_TIM_InitChannels(uint32_t *tim_id
, const struct pios_tim_channel
*channels
, uint8_t num_channels
, const struct pios_tim_callbacks
*callbacks
, uint32_t context
)
111 PIOS_Assert(channels
);
112 PIOS_Assert(num_channels
);
114 struct pios_tim_dev
*tim_dev
;
115 tim_dev
= (struct pios_tim_dev
*)PIOS_TIM_alloc();
120 /* Bind the configuration to the device instance */
121 tim_dev
->channels
= channels
;
122 tim_dev
->num_channels
= num_channels
;
123 tim_dev
->callbacks
= callbacks
;
124 tim_dev
->context
= context
;
126 /* Configure the pins */
127 for (uint8_t i
= 0; i
< num_channels
; i
++) {
128 const struct pios_tim_channel
*chan
= &(channels
[i
]);
130 /* Enable the peripheral clock for the GPIO */
131 switch ((uint32_t)chan
->pin
.gpio
) {
132 case (uint32_t)GPIOA
:
133 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA
, ENABLE
);
135 case (uint32_t)GPIOB
:
136 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB
, ENABLE
);
138 case (uint32_t)GPIOC
:
139 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC
, ENABLE
);
145 GPIO_Init(chan
->pin
.gpio
, &chan
->pin
.init
);
148 GPIO_PinRemapConfig(chan
->remap
, ENABLE
);
152 *tim_id
= (uint32_t)tim_dev
;
160 static void PIOS_TIM_generic_irq_handler(TIM_TypeDef
*timer
)
162 /* Iterate over all registered clients of the TIM layer to find channels on this timer */
163 for (uint8_t i
= 0; i
< pios_tim_num_devs
; i
++) {
164 const struct pios_tim_dev
*tim_dev
= &pios_tim_devs
[i
];
166 if (!tim_dev
->channels
|| tim_dev
->num_channels
== 0) {
167 /* No channels to process on this client */
171 /* Check for an overflow event on this timer */
173 uint16_t overflow_count
;
174 if (TIM_GetITStatus(timer
, TIM_IT_Update
) == SET
) {
175 TIM_ClearITPendingBit(timer
, TIM_IT_Update
);
176 overflow_count
= timer
->ARR
;
177 overflow_event
= true;
180 overflow_event
= false;
183 for (uint8_t j
= 0; j
< tim_dev
->num_channels
; j
++) {
184 const struct pios_tim_channel
*chan
= &tim_dev
->channels
[j
];
186 if (chan
->timer
!= timer
) {
187 /* channel is not on this timer */
191 /* Figure out which interrupt bit we should be looking at */
193 switch (chan
->timer_chan
) {
195 timer_it
= TIM_IT_CC1
;
198 timer_it
= TIM_IT_CC2
;
201 timer_it
= TIM_IT_CC3
;
204 timer_it
= TIM_IT_CC4
;
213 if (TIM_GetITStatus(chan
->timer
, timer_it
) == SET
) {
214 TIM_ClearITPendingBit(chan
->timer
, timer_it
);
216 /* Read the current counter */
217 switch (chan
->timer_chan
) {
219 edge_count
= TIM_GetCapture1(chan
->timer
);
222 edge_count
= TIM_GetCapture2(chan
->timer
);
225 edge_count
= TIM_GetCapture3(chan
->timer
);
228 edge_count
= TIM_GetCapture4(chan
->timer
);
240 if (!tim_dev
->callbacks
) {
241 /* No callbacks registered, we're done with this channel */
245 /* Generate the appropriate callbacks */
246 if (overflow_event
& edge_event
) {
248 * When both edge and overflow happen in the same interrupt, we
249 * need a heuristic to determine the order of the edge and overflow
250 * events so that the callbacks happen in the right order. If we
251 * get the order wrong, our pulse width calculations could be off by up
252 * to ARR ticks. That could be bad.
254 * Heuristic: If the edge_count is < 16 ticks above zero then we assume the
255 * edge happened just after the overflow.
258 if (edge_count
< 16) {
259 /* Call the overflow callback first */
260 if (tim_dev
->callbacks
->overflow
) {
261 (*tim_dev
->callbacks
->overflow
)((uint32_t)tim_dev
,
266 /* Call the edge callback second */
267 if (tim_dev
->callbacks
->edge
) {
268 (*tim_dev
->callbacks
->edge
)((uint32_t)tim_dev
,
274 /* Call the edge callback first */
275 if (tim_dev
->callbacks
->edge
) {
276 (*tim_dev
->callbacks
->edge
)((uint32_t)tim_dev
,
281 /* Call the overflow callback second */
282 if (tim_dev
->callbacks
->overflow
) {
283 (*tim_dev
->callbacks
->overflow
)((uint32_t)tim_dev
,
289 } else if (overflow_event
&& tim_dev
->callbacks
->overflow
) {
290 (*tim_dev
->callbacks
->overflow
)((uint32_t)tim_dev
,
294 } else if (edge_event
&& tim_dev
->callbacks
->edge
) {
295 (*tim_dev
->callbacks
->edge
)((uint32_t)tim_dev
,
305 for (uint8_t i
= 0; i
< pios_pwm_cfg
.num_channels
; i
++) {
306 struct pios_pwm_channel channel
= pios_pwm_cfg
.channels
[i
];
307 if ((channel
.timer
== timer
) && (TIM_GetITStatus(channel
.timer
, channel
.ccr
) == SET
)) {
308 TIM_ClearITPendingBit(channel
.timer
, channel
.ccr
);
310 switch (channel
.channel
) {
312 val
= TIM_GetCapture1(channel
.timer
);
315 val
= TIM_GetCapture2(channel
.timer
);
318 val
= TIM_GetCapture3(channel
.timer
);
321 val
= TIM_GetCapture4(channel
.timer
);
325 if (CaptureState
[i
] == 0) {
331 // flip state machine and capture value here
332 /* Simple rise or fall state machine */
333 TIM_ICInitTypeDef TIM_ICInitStructure
= pios_pwm_cfg
.tim_ic_init
;
334 if (CaptureState
[i
] == 0) {
338 /* Switch polarity of input capture */
339 TIM_ICInitStructure
.TIM_ICPolarity
= TIM_ICPolarity_Falling
;
340 TIM_ICInitStructure
.TIM_Channel
= channel
.channel
;
341 TIM_ICInit(channel
.timer
, &TIM_ICInitStructure
);
343 /* Capture computation */
344 if (FallValue
[i
] > RiseValue
[i
]) {
345 CaptureValue
[i
] = (FallValue
[i
] - RiseValue
[i
]);
347 CaptureValue
[i
] = ((channel
.timer
->ARR
- RiseValue
[i
]) + FallValue
[i
]);
353 /* Increase supervisor counter */
356 /* Switch polarity of input capture */
357 TIM_ICInitStructure
.TIM_ICPolarity
= TIM_ICPolarity_Rising
;
358 TIM_ICInitStructure
.TIM_Channel
= channel
.channel
;
359 TIM_ICInit(channel
.timer
, &TIM_ICInitStructure
);
365 /* Bind Interrupt Handlers
367 * Map all valid TIM IRQs to the common interrupt handler
368 * and give it enough context to properly demux the various timers
370 void TIM1_UP_IRQHandler(void) __attribute__((alias("PIOS_TIM_1_UP_irq_handler")));
371 static void PIOS_TIM_1_UP_irq_handler(void)
373 PIOS_TIM_generic_irq_handler(TIM1
);
376 void TIM1_CC_IRQHandler(void) __attribute__((alias("PIOS_TIM_1_CC_irq_handler")));
377 static void PIOS_TIM_1_CC_irq_handler(void)
379 PIOS_TIM_generic_irq_handler(TIM1
);
382 void TIM2_IRQHandler(void) __attribute__((alias("PIOS_TIM_2_irq_handler")));
383 static void PIOS_TIM_2_irq_handler(void)
385 PIOS_TIM_generic_irq_handler(TIM2
);
388 void TIM3_IRQHandler(void) __attribute__((alias("PIOS_TIM_3_irq_handler")));
389 static void PIOS_TIM_3_irq_handler(void)
391 PIOS_TIM_generic_irq_handler(TIM3
);
394 void TIM4_IRQHandler(void) __attribute__((alias("PIOS_TIM_4_irq_handler")));
395 static void PIOS_TIM_4_irq_handler(void)
397 PIOS_TIM_generic_irq_handler(TIM4
);
400 void TIM5_IRQHandler(void) __attribute__((alias("PIOS_TIM_5_irq_handler")));
401 static void PIOS_TIM_5_irq_handler(void)
403 PIOS_TIM_generic_irq_handler(TIM5
);
406 void TIM6_IRQHandler(void) __attribute__((alias("PIOS_TIM_6_irq_handler")));
407 static void PIOS_TIM_6_irq_handler(void)
409 PIOS_TIM_generic_irq_handler(TIM6
);
412 void TIM7_IRQHandler(void) __attribute__((alias("PIOS_TIM_7_irq_handler")));
413 static void PIOS_TIM_7_irq_handler(void)
415 PIOS_TIM_generic_irq_handler(TIM7
);
418 void TIM8_UP_IRQHandler(void) __attribute__((alias("PIOS_TIM_8_UP_irq_handler")));
419 static void PIOS_TIM_8_UP_irq_handler(void)
421 PIOS_TIM_generic_irq_handler(TIM8
);
424 void TIM8_CC_IRQHandler(void) __attribute__((alias("PIOS_TIM_8_CC_irq_handler")));
425 static void PIOS_TIM_8_CC_irq_handler(void)
427 PIOS_TIM_generic_irq_handler(TIM8
);
430 #endif /* PIOS_INCLUDE_TIM */