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
*)pios_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
);
106 /* Advanced TIM1 has additional IRQ */
107 if (cfg
->timer
== TIM1
) {
108 NVIC_InitTypeDef init
= cfg
->irq
.init
;
109 init
.NVIC_IRQChannel
= TIM1_UP_IRQn
;
116 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
)
118 PIOS_Assert(channels
);
119 PIOS_Assert(num_channels
);
121 struct pios_tim_dev
*tim_dev
;
122 tim_dev
= (struct pios_tim_dev
*)PIOS_TIM_alloc();
127 /* Bind the configuration to the device instance */
128 tim_dev
->channels
= channels
;
129 tim_dev
->num_channels
= num_channels
;
130 tim_dev
->callbacks
= callbacks
;
131 tim_dev
->context
= context
;
133 /* Configure the pins */
134 for (uint8_t i
= 0; i
< num_channels
; i
++) {
135 const struct pios_tim_channel
*chan
= &(channels
[i
]);
137 /* Enable the peripheral clock for the GPIO */
138 switch ((uint32_t)chan
->pin
.gpio
) {
139 case (uint32_t)GPIOA
:
140 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA
, ENABLE
);
142 case (uint32_t)GPIOB
:
143 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB
, ENABLE
);
145 case (uint32_t)GPIOC
:
146 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC
, ENABLE
);
152 GPIO_Init(chan
->pin
.gpio
, &chan
->pin
.init
);
155 GPIO_PinRemapConfig(chan
->remap
, ENABLE
);
159 *tim_id
= (uint32_t)tim_dev
;
167 static void PIOS_TIM_generic_irq_handler(TIM_TypeDef
*timer
)
169 /* Check for an overflow event on this timer */
170 bool overflow_event
= 0;
171 uint16_t overflow_count
= false;
173 if (TIM_GetITStatus(timer
, TIM_IT_Update
) == SET
) {
174 TIM_ClearITPendingBit(timer
, TIM_IT_Update
);
175 overflow_count
= timer
->ARR
;
176 overflow_event
= true;
179 /* Iterate over all registered clients of the TIM layer to find channels on this timer */
180 for (uint8_t i
= 0; i
< pios_tim_num_devs
; i
++) {
181 const struct pios_tim_dev
*tim_dev
= &pios_tim_devs
[i
];
183 if (!tim_dev
->channels
|| tim_dev
->num_channels
== 0) {
184 /* No channels to process on this client */
188 for (uint8_t j
= 0; j
< tim_dev
->num_channels
; j
++) {
189 const struct pios_tim_channel
*chan
= &tim_dev
->channels
[j
];
191 if (chan
->timer
!= timer
) {
192 /* channel is not on this timer */
196 /* Figure out which interrupt bit we should be looking at */
198 switch (chan
->timer_chan
) {
200 timer_it
= TIM_IT_CC1
;
203 timer_it
= TIM_IT_CC2
;
206 timer_it
= TIM_IT_CC3
;
209 timer_it
= TIM_IT_CC4
;
218 if (TIM_GetITStatus(chan
->timer
, timer_it
) == SET
) {
219 TIM_ClearITPendingBit(chan
->timer
, timer_it
);
221 /* Read the current counter */
222 switch (chan
->timer_chan
) {
224 edge_count
= TIM_GetCapture1(chan
->timer
);
227 edge_count
= TIM_GetCapture2(chan
->timer
);
230 edge_count
= TIM_GetCapture3(chan
->timer
);
233 edge_count
= TIM_GetCapture4(chan
->timer
);
245 if (!tim_dev
->callbacks
) {
246 /* No callbacks registered, we're done with this channel */
250 /* Generate the appropriate callbacks */
251 if (overflow_event
& edge_event
) {
253 * When both edge and overflow happen in the same interrupt, we
254 * need a heuristic to determine the order of the edge and overflow
255 * events so that the callbacks happen in the right order. If we
256 * get the order wrong, our pulse width calculations could be off by up
257 * to ARR ticks. That could be bad.
259 * Heuristic: If the edge_count is < 32 ticks above zero then we assume the
260 * edge happened just after the overflow.
263 if (edge_count
< 32) {
264 /* Call the overflow callback first */
265 if (tim_dev
->callbacks
->overflow
) {
266 (*tim_dev
->callbacks
->overflow
)((uint32_t)tim_dev
,
271 /* Call the edge callback second */
272 if (tim_dev
->callbacks
->edge
) {
273 (*tim_dev
->callbacks
->edge
)((uint32_t)tim_dev
,
279 /* Call the edge callback first */
280 if (tim_dev
->callbacks
->edge
) {
281 (*tim_dev
->callbacks
->edge
)((uint32_t)tim_dev
,
286 /* Call the overflow callback second */
287 if (tim_dev
->callbacks
->overflow
) {
288 (*tim_dev
->callbacks
->overflow
)((uint32_t)tim_dev
,
294 } else if (overflow_event
&& tim_dev
->callbacks
->overflow
) {
295 (*tim_dev
->callbacks
->overflow
)((uint32_t)tim_dev
,
299 } else if (edge_event
&& tim_dev
->callbacks
->edge
) {
300 (*tim_dev
->callbacks
->edge
)((uint32_t)tim_dev
,
309 /* Bind Interrupt Handlers
311 * Map all valid TIM IRQs to the common interrupt handler
312 * and give it enough context to properly demux the various timers
314 void TIM1_UP_IRQHandler(void) __attribute__((alias("PIOS_TIM_1_UP_irq_handler")));
315 static void PIOS_TIM_1_UP_irq_handler(void)
317 PIOS_TIM_generic_irq_handler(TIM1
);
320 void TIM1_CC_IRQHandler(void) __attribute__((alias("PIOS_TIM_1_CC_irq_handler")));
321 static void PIOS_TIM_1_CC_irq_handler(void)
323 PIOS_TIM_generic_irq_handler(TIM1
);
326 void TIM2_IRQHandler(void) __attribute__((alias("PIOS_TIM_2_irq_handler")));
327 static void PIOS_TIM_2_irq_handler(void)
329 PIOS_TIM_generic_irq_handler(TIM2
);
332 void TIM3_IRQHandler(void) __attribute__((alias("PIOS_TIM_3_irq_handler")));
333 static void PIOS_TIM_3_irq_handler(void)
335 PIOS_TIM_generic_irq_handler(TIM3
);
338 void TIM4_IRQHandler(void) __attribute__((alias("PIOS_TIM_4_irq_handler")));
339 static void PIOS_TIM_4_irq_handler(void)
341 PIOS_TIM_generic_irq_handler(TIM4
);
344 void TIM5_IRQHandler(void) __attribute__((alias("PIOS_TIM_5_irq_handler")));
345 static void PIOS_TIM_5_irq_handler(void)
347 PIOS_TIM_generic_irq_handler(TIM5
);
350 void TIM6_IRQHandler(void) __attribute__((alias("PIOS_TIM_6_irq_handler")));
351 static void PIOS_TIM_6_irq_handler(void)
353 PIOS_TIM_generic_irq_handler(TIM6
);
356 void TIM7_IRQHandler(void) __attribute__((alias("PIOS_TIM_7_irq_handler")));
357 static void PIOS_TIM_7_irq_handler(void)
359 PIOS_TIM_generic_irq_handler(TIM7
);
362 void TIM8_UP_IRQHandler(void) __attribute__((alias("PIOS_TIM_8_UP_irq_handler")));
363 static void PIOS_TIM_8_UP_irq_handler(void)
365 PIOS_TIM_generic_irq_handler(TIM8
);
368 void TIM8_CC_IRQHandler(void) __attribute__((alias("PIOS_TIM_8_CC_irq_handler")));
369 static void PIOS_TIM_8_CC_irq_handler(void)
371 PIOS_TIM_generic_irq_handler(TIM8
);
374 #endif /* PIOS_INCLUDE_TIM */