Page MenuHomec4science

callback_timers.c
No OneTemporary

File Metadata

Created
Sat, May 11, 15:10

callback_timers.c

#include "callback_timers.h"
#include "../controller.h"
#include "../lib/utils.h"
cbt_PeriodicTaskFunc cbt_tim1Task, cbt_tim6Task, cbt_tim7Task;
volatile float32_t cbt_ucLoad; // Processor load (%).
void tim1InitFunc(void);
void tim67InitFunc(void);
/**
* @brief Initialize the timers to call an interrupt routine periodically.
*/
void cbt_Init(void)
{
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA|RCC_AHB1Periph_GPIOB|RCC_AHB1Periph_GPIOC|RCC_AHB1Periph_GPIOD|RCC_AHB1Periph_GPIOE, ENABLE);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); // ???
// Initialize the timers.
tim1InitFunc();
tim67InitFunc();
// Initialize the function pointers to NULL, in order to be able to test
// if they are already affected or not.
cbt_tim1Task = NULL;
cbt_tim6Task = NULL;
cbt_tim7Task = NULL;
}
/**
* @brief Set the function to call periodically by the timer 1.
* @param f: the function to call periodically.
* @param period: the period between each call of f [us].
*/
void cbt_SetCurrentLoopTimer(cbt_PeriodicTaskFunc f, uint32_t period)
{
cbt_tim1Task = f;
utils_SaturateU(&period, TE_LOOP_MIN_VALUE, TE_LOOP_MAX_VALUE);
TIM1->ARR = (uint16_t) period;
}
/**
* @brief Set the function to call periodically by the timer 6.
* @param f: the function to call periodically.
* @param period: the period between each call of f [us].
*/
void cbt_SetPositionLoopTimer(cbt_PeriodicTaskFunc f, uint32_t period)
{
cbt_tim6Task = f;
utils_SaturateU(&period, TE_LOOP_MIN_VALUE, TE_LOOP_MAX_VALUE);
TIM6->ARR = (uint16_t) period;
}
/**
* @brief Set the function to call periodically by the timer 7.
* @param f: the function to call periodically.
* @param period: the period between each call of f [us].
*/
void cbt_SetCommLoopTimer(cbt_PeriodicTaskFunc f, uint32_t period)
{
cbt_tim7Task = f;
utils_SaturateU(&period, TE_LOOP_MIN_VALUE, TE_LOOP_MAX_VALUE);
TIM7->ARR = (uint16_t) period;
}
/**
* @brief Initialize TIM1 used for timing the current loop (resolution 1us).
*/
void tim1InitFunc(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct;
//TIM_OCInitTypeDef TIM_OCInitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
NVIC_InitStruct.NVIC_IRQChannel = TIM1_UP_TIM10_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = CURRENT_LOOP_IRQ_PRIORITY;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
TIM_TimeBaseStruct.TIM_Period = (uint16_t)(TE_CURRENT_LOOP_DEFAULT_VAL-1);
TIM_TimeBaseStruct.TIM_Prescaler = TIM1_PRESCALER;
TIM_TimeBaseStruct.TIM_ClockDivision = 0; // TIM_CKD_DIV2;
TIM_TimeBaseStruct.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStruct);
TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE);
TIM_Cmd(TIM1, ENABLE);
}
/**
* @brief Initialize TIM6, for timing the main control loop (resolution 1us)
* Initialize TIM7, for timing the data transmission loop (resolution 1us)
*/
void tim67InitFunc(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct;
NVIC_InitTypeDef NVIC_InitStruct;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6|RCC_APB1Periph_TIM7, ENABLE);
NVIC_InitStruct.NVIC_IRQChannel = TIM6_DAC_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = CONTROL_LOOP_IRQ_PRIORITY;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
NVIC_InitStruct.NVIC_IRQChannel = TIM7_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = DATA_LOOP_IRQ_PRIORITY;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
NVIC_Init(&NVIC_InitStruct);
TIM_TimeBaseStructInit(&TIM_TimeBaseStruct);
TIM_TimeBaseStruct.TIM_Prescaler = TIM6_PRESCALER;
TIM_TimeBaseStruct.TIM_Period = (uint16_t)(TE_CONTROL_LOOP_DEFAULT_VAL-1);
TIM_TimeBaseStruct.TIM_ClockDivision = 0;
TIM_TimeBaseStruct.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStruct);
TIM_TimeBaseStructInit(&TIM_TimeBaseStruct);
TIM_TimeBaseStruct.TIM_Prescaler = TIM7_PRESCALER;
TIM_TimeBaseStruct.TIM_Period = (uint16_t)(TE_DATA_LOOP_DEFAULT_VAL-1);
TIM_TimeBaseStruct.TIM_ClockDivision = 0;
TIM_TimeBaseStruct.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM7, &TIM_TimeBaseStruct);
TIM_ITConfig(TIM6, TIM_IT_Update, ENABLE);
TIM_ITConfig(TIM7, TIM_IT_Update, ENABLE);
TIM_Cmd(TIM6, ENABLE);
TIM_Cmd(TIM7, DISABLE);
}
/**
* @brief Interrupt from current control loop timer (TIM1)
*/
void TIM1_UP_TIM10_IRQHandler(void)
{
if(TIM_GetITStatus(TIM1, TIM_IT_Update) != RESET)
{
if(cbt_tim1Task != NULL)
cbt_tim1Task();
TIM_ClearITPendingBit(TIM1, TIM_IT_Update);
}
}
/**
* @brief Interrupt from main control loop timer (TIM6)
*/
void TIM6_DAC_IRQHandler(void)
{
if(TIM_GetITStatus(TIM6, TIM_IT_Update) != RESET)
{
if(cbt_tim6Task != NULL)
cbt_tim6Task();
// Percentage of time consumed by the control task 0..100%.
cbt_ucLoad = (((float32_t)(TIM6->CNT))*100)/((float32_t)(TIM6->ARR));
TIM_ClearITPendingBit(TIM6, TIM_IT_Update);
}
}
/**
* @brief Interrupt from data transmission loop timer (TIM7) (data loop)
*/
void TIM7_IRQHandler(void)
{
if(TIM_GetITStatus(TIM7, TIM_IT_Update) != RESET)
{
if(cbt_tim7Task != NULL)
cbt_tim7Task();
TIM_ClearITPendingBit(TIM7, TIM_IT_Update);
}
}
/**
* @brief Set the period of the position loop.
* @param period: the new period of the position loop [us].
*/
void cbt_SetPositionLoopPeriod(uint32_t period)
{
utils_SaturateU(&period, TE_LOOP_MIN_VALUE, TE_LOOP_MAX_VALUE);
TIM6->ARR = period;
}
/**
* @brief Set the period of the communication loop.
* @param period: the new period of the communication loop [us].
*/
void cbt_SetCommLoopPeriod(uint32_t period)
{
utils_SaturateU(&period, TE_LOOP_MIN_VALUE, TE_LOOP_MAX_VALUE);
TIM7->ARR = period;
}
/**
* @brief Get the period of the current loop.
* @return the period of the current loop [us].
*/
uint32_t cbt_GetCurrentLoopPeriod(void)
{
return TIM1->ARR;
}
/**
* @brief Get the period of the position loop.
* @return the period of the position loop [us].
*/
uint32_t cbt_GetPositionLoopPeriod(void)
{
return TIM6->ARR;
}
/**
* @brief Get the period of the communication loop.
* @return the period of the communication loop [us].
*/
uint32_t cbt_GetCommLoopPeriod(void)
{
return TIM7->ARR;
}

Event Timeline