#include "Timer.h" #include "stm32f1xx_ll_bus.h" // Pour l'activation des horloges #include "stm32f1xx_ll_tim.h" // Pour les timers /**************************************************************************** * INTERRUPTIONS ***************************************************************************/ // variable pointeur de fonction permettant de mémoriser le callback à appeler depuis // le handler d'IT void (*it_callback_TIM1)(void); void (*it_callback_TIM2)(void); void (*it_callback_TIM3)(void); void (*it_callback_TIM4)(void); void TIM1_UP_IRQHandler(void) { // rabaisser le flag d'IT LL_TIM_ClearFlag_UPDATE(TIM1); (*it_callback_TIM1)(); } void TIM2_IRQHandler(void) { // rabaisser le flag d'IT LL_TIM_ClearFlag_UPDATE(TIM2); (*it_callback_TIM2)(); } void TIM3_IRQHandler(void) { // rabaisser le flag d'IT LL_TIM_ClearFlag_UPDATE(TIM3); (*it_callback_TIM3)(); } void TIM4_IRQHandler(void) { // rabaisser le flag d'IT LL_TIM_ClearFlag_UPDATE(TIM4); (*it_callback_TIM4)(); } /** * @brief Autorise les interruptions * @note * @param TIM_TypeDef Timer : indique le timer à utiliser par le chronomètre, TIM1, TIM2, TIM3 ou TIM4 * @retval None */ void Timer_IT_enable(TIM_TypeDef * timer) { LL_TIM_EnableIT_UPDATE(timer); } /** * @brief Interdit les interruptions * @note * @param TIM_TypeDef Timer : indique le timer à utiliser par le chronomètre, TIM1, TIM2, TIM3 ou TIM4 * @retval None */ void Timer_IT_disable(TIM_TypeDef * timer) { LL_TIM_DisableIT_UPDATE(timer); } /** * @brief Configure le Timer considéré en interruption sur débordement. * @note A ce stade, les interruptions ne sont pas validés (voir MyTimer_IT_Enable ) * @param TIM_TypeDef Timer : indique le timer à utiliser par le chronomètre, TIM1, TIM2, TIM3 ou TIM4 * void (*IT_function) (void) : nom (adresse) de la fonction à lancer sur interruption * int Prio : priorité associée à l'interruption * @retval None */ void Timer_IT_conf(TIM_TypeDef * timer, void (*it_callback) (void), int prio) { // affectation de la fonction if (timer == TIM1) it_callback_TIM1 = it_callback; else if (timer == TIM2) it_callback_TIM2 = it_callback; else if (timer == TIM3) it_callback_TIM3 = it_callback; else it_callback_TIM4 = it_callback; // Blocage IT (il faudra la débloquer voir fct suivante) LL_TIM_DisableIT_UPDATE(timer); // validation du canal NVIC IRQn_Type TIM_irq; if (timer == TIM1) TIM_irq = TIM1_UP_IRQn; else if (timer == TIM2) TIM_irq = TIM2_IRQn; else if (timer == TIM3) TIM_irq = TIM3_IRQn; else TIM_irq = TIM4_IRQn; NVIC_SetPriority(TIM_irq, prio); NVIC_EnableIRQ(TIM_irq); } /**************************************************************************** * TIMER ***************************************************************************/ /** * @brief Démarre le timer considéré et active les interruptions * @note * @param TIM_TypeDef Timer : indique le timer à utiliser par le chronomètre, TIM1, TIM2, TIM3 ou TIM4 * @retval None */ void Timer_start(TIM_TypeDef * timer) { LL_TIM_EnableCounter(timer); } /** * @brief Arrêt le timer considéré et désactive les interruptions * @note * @param TIM_TypeDef Timer : indique le timer à utiliser par le chronomètre, TIM1, TIM2, TIM3 ou TIM4 * @retval None */ void Timer_stop(TIM_TypeDef * timer) { LL_TIM_DisableCounter(timer); } /** * @brief Active l'horloge et règle l'ARR et le PSC du timer visé. * @note Fonction à lancer avant toute autre. Le timer n'est pas encore lancé (voir Timer_start) * @param TIM_TypeDef Timer : indique le timer à utiliser par le chronomètre, TIM1, TIM2, TIM3 ou TIM4 * int Arr : valeur à placer dans ARR * int Psc : valeur à placer dans PSC * @retval None */ void Timer_conf(TIM_TypeDef * timer, int arr, int psc) { LL_TIM_InitTypeDef init_struct; // Validation horloge locale if (timer == TIM1) LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_TIM1); else if (timer == TIM2) LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2); else if (timer == TIM3) LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM3); else LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM4); // chargement structure Arr, Psc, Up Count init_struct.Autoreload = arr; init_struct.Prescaler = psc; init_struct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1; init_struct.CounterMode = LL_TIM_COUNTERMODE_UP; init_struct.RepetitionCounter = 0; LL_TIM_Init(timer,&init_struct); // Blocage interruptions Timer_IT_disable(timer); // Blocage Timer Timer_stop(timer); } /**************************************************************************** * PWM INPUT ***************************************************************************/ /**************************************************************************** * PWM OUTPUT ***************************************************************************/ int getArrFromFreq(float freq_khz) { return (72000 / freq_khz) - 1; } void PWMo_conf(TIM_TypeDef * timer, int channel, float freq_khz, float dutyCycle) { const int arr = getArrFromFreq(freq_khz); Timer_conf(timer, arr, 0); LL_TIM_OC_InitTypeDef init_struct; LL_TIM_OC_StructInit(&init_struct); init_struct.OCMode = LL_TIM_OCMODE_PWM1; init_struct.OCState = LL_TIM_OCSTATE_ENABLE; init_struct.CompareValue= dutyCycle * arr; LL_TIM_OC_Init(timer, channel, &init_struct); } void PWMo_setDutyCycle(TIM_TypeDef * timer, int channel, float freq_khz, float dutyCycle) { int compare = dutyCycle * getArrFromFreq(freq_khz); if (channel == LL_TIM_CHANNEL_CH1) LL_TIM_OC_SetCompareCH1(timer, compare); else if (channel == LL_TIM_CHANNEL_CH2) LL_TIM_OC_SetCompareCH2(timer, compare); else if (channel == LL_TIM_CHANNEL_CH3) LL_TIM_OC_SetCompareCH3(timer, compare); else LL_TIM_OC_SetCompareCH4(timer, compare); } /**************************************************************************** * ENCODER ***************************************************************************/ void Timer_encoder_conf(TIM_TypeDef * timer, int arr, int psc) { } int Timer_encoder_get(TIM_TypeDef * timer) { return 0; }