297 lines
8.1 KiB
C
297 lines
8.1 KiB
C
/*==============================================================================
|
||
* Инициализация таймеров с использованием бибилотеки PLIB035
|
||
*------------------------------------------------------------------------------
|
||
* ЦНИИ СЭТ, Разваляев Алексей <wot890089@mail.ru>
|
||
*==============================================================================
|
||
* ЦНИИ СЭТ
|
||
*==============================================================================
|
||
*/
|
||
|
||
//-- Includes ------------------------------------------------------------------
|
||
#include "periph_config.h"
|
||
|
||
TMR_HandleTypeDef htmr0;
|
||
TMR_HandleTypeDef htmr1;
|
||
TMR_HandleTypeDef htmr2;
|
||
TMR_HandleTypeDef htmr3;
|
||
//-- Defines -------------------------------------------------------------------
|
||
|
||
//-- Peripheral init functions -------------------------------------------------
|
||
void tmr_init_first(void)
|
||
{
|
||
#if (USE_TMR0==1)
|
||
RCU_APBClkCmd(RCU_APBClk_TMR0, ENABLE);
|
||
RCU_APBRstCmd(RCU_APBRst_TMR0, ENABLE);
|
||
|
||
htmr0.TMR = TMR0;
|
||
tmr_init(&htmr0, &tmr0_config);
|
||
if(htmr0.Config->IT == ENABLE)
|
||
{
|
||
NVIC_EnableIRQ(TMR0_IRQn);
|
||
}
|
||
#endif
|
||
|
||
#if (USE_TMR1==1)
|
||
RCU_APBClkCmd(RCU_APBClk_TMR1, ENABLE);
|
||
RCU_APBRstCmd(RCU_APBRst_TMR1, ENABLE);
|
||
|
||
htmr1.TMR = TMR1;
|
||
tmr_init(&htmr1, &tmr1_config);
|
||
if(htmr1.Config->IT == ENABLE)
|
||
{
|
||
NVIC_EnableIRQ(TMR1_IRQn);
|
||
}
|
||
#endif
|
||
|
||
#if (USE_TMR2==1)
|
||
RCU_APBClkCmd(RCU_APBClk_TMR2, ENABLE);
|
||
RCU_APBRstCmd(RCU_APBRst_TMR2, ENABLE);
|
||
|
||
htmr2.TMR = TMR2;
|
||
tmr_init(&htmr2, &tmr2_config);
|
||
if(htmr2.Config->IT == ENABLE)
|
||
{
|
||
NVIC_EnableIRQ(TMR2_IRQn);
|
||
}
|
||
#endif
|
||
|
||
#if (USE_TMR3==1)
|
||
RCU_APBClkCmd(RCU_APBClk_TMR3, ENABLE);
|
||
RCU_APBRstCmd(RCU_APBRst_TMR3, ENABLE);
|
||
|
||
htmr3.TMR = TMR3;
|
||
tmr_init(&htmr3, &tmr3_config);
|
||
if(htmr3.Config->IT == ENABLE)
|
||
{
|
||
NVIC_EnableIRQ(TMR3_IRQn);
|
||
}
|
||
#endif
|
||
}
|
||
|
||
/**
|
||
* @brief Инициализация таймера
|
||
* @param htmr указатель на хендл таймера
|
||
* @param NewConfig указатель на новую конфигурацию UART, иначе используется та, что в структуре
|
||
* @retval OperationStatus OK - если всё хорошо, ERROR - если ошибка
|
||
*/
|
||
OperationStatus tmr_init(TMR_HandleTypeDef *htmr, TMR_Init_TypeDef *NewConfig)
|
||
{
|
||
if(htmr->TMR == NULL)
|
||
{
|
||
return ERROR;
|
||
}
|
||
if(NewConfig != NULL)
|
||
{
|
||
htmr->Config = NewConfig;
|
||
}
|
||
if(htmr->Config == NULL)
|
||
{
|
||
return ERROR;
|
||
}
|
||
|
||
TMR_Init(htmr->TMR, htmr->Config);
|
||
|
||
return OK;
|
||
}
|
||
|
||
|
||
/**
|
||
* @brief Установка коллбека таймера
|
||
* @param htmr указатель на хендл таймера
|
||
* @param cb_type Тип коллбека
|
||
* @param Callback Функция коллбека
|
||
* @retval void
|
||
*/
|
||
OperationStatus tmr_set_callback(TMR_HandleTypeDef* htmr, int cb_type, void (*Callback)(void))
|
||
{
|
||
if((htmr->TMR == NULL) || (htmr->Config == NULL))
|
||
{
|
||
return ERROR;
|
||
}
|
||
htmr->Config->Callback = Callback;
|
||
return OK;
|
||
}
|
||
|
||
/**
|
||
* @brief Запуск таймера
|
||
* @param htmr указатель на хендл таймера
|
||
* @retval OperationStatus OK - если всё хорошо, ERROR - если ошибка
|
||
*/
|
||
OperationStatus tmr_start(TMR_HandleTypeDef *htmr)
|
||
{
|
||
if(htmr->TMR == NULL)
|
||
{
|
||
return ERROR;
|
||
}
|
||
|
||
TMR_Cmd(htmr->TMR, ENABLE);
|
||
|
||
return OK;
|
||
}
|
||
|
||
/**
|
||
* @brief Остановка таймера
|
||
* @param htmr указатель на хендл таймера
|
||
* @retval OperationStatus OK - если всё хорошо, ERROR - если ошибка
|
||
*/
|
||
OperationStatus tmr_stop(TMR_HandleTypeDef *htmr)
|
||
{
|
||
if(htmr->TMR == NULL)
|
||
{
|
||
return ERROR;
|
||
}
|
||
|
||
TMR_Cmd(htmr->TMR, DISABLE);
|
||
|
||
return OK;
|
||
}
|
||
/**
|
||
* @brief Задержка в тиках таймера (блокирующая).
|
||
* @param htmr Указатель на хендл таймера.
|
||
* @param delay Задержка в тиках таймера.
|
||
* @return OperationStatus.
|
||
* @details Формирует задержку с блокировкой программы.
|
||
*/
|
||
OperationStatus tmr_delay(TMR_HandleTypeDef *htmr, uint32_t delay)
|
||
{
|
||
if(!htmr || !htmr->TMR)
|
||
return ERROR;
|
||
|
||
uint32_t presc = htmr->Config->Prescaler+1;
|
||
uint64_t delay_load = delay*presc;
|
||
if(delay_load > 0xFFFFFFFF)
|
||
{
|
||
delay_load = 0xFFFFFFFF;
|
||
}
|
||
|
||
if(delay_load >= htmr->TMR->LOAD)
|
||
{
|
||
return ERROR;
|
||
}
|
||
uint32_t starttick = htmr->TMR->VALUE;
|
||
while(1)
|
||
{
|
||
if((starttick - htmr->TMR->VALUE) >= delay_load)
|
||
{
|
||
return OK;
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @brief Начать отсчет неблокирующей задержки.
|
||
* @param htmr Указатель на хендл таймера.
|
||
* @param var Указатель на переменную куда положить значение тиков.
|
||
* @return OperationStatus.
|
||
* @details Запоминает счетчик для начала отсчета неблокирующей задержки.
|
||
* @ref tmr_delay_done для проверки статуса задержки
|
||
*/
|
||
OperationStatus tmr_delay_start(TMR_HandleTypeDef *htmr, uint32_t *var)
|
||
{
|
||
if(!htmr || !htmr->TMR)
|
||
return ERROR;
|
||
|
||
*var = htmr->TMR->VALUE;
|
||
|
||
return OK;
|
||
}
|
||
|
||
/**
|
||
* @brief Задержка в тиках таймера (неблокирующая).
|
||
* @param htmr Указатель на хендл таймера.
|
||
* @param delay Задержка в тиках таймера.
|
||
* @param var Указатель на переменную где хранится тики в момент начала задержки.
|
||
* @return 1 - задержка прошла. 0 - задержка в процессе.
|
||
* @details Формирует задержку с блокировкой программы.
|
||
* Перед ожиданием задержки надо инициализировать задержку @ref tmr_delay_start
|
||
*/
|
||
int tmr_delay_done(TMR_HandleTypeDef *htmr, uint32_t delay, uint32_t *var)
|
||
{
|
||
if(!htmr || !htmr->TMR)
|
||
return 0;
|
||
|
||
uint32_t presc = htmr->Config->Prescaler+1;
|
||
uint64_t delay_load = delay*presc;
|
||
if(delay_load > 0xFFFFFFFF)
|
||
{
|
||
delay_load = 0xFFFFFFFF;
|
||
}
|
||
|
||
if(delay_load >= htmr->TMR->LOAD)
|
||
{
|
||
return 0;
|
||
}
|
||
|
||
if((*var - htmr->TMR->VALUE) >= delay_load)
|
||
{
|
||
return 1; // Задержка прошла
|
||
}
|
||
else
|
||
{
|
||
return 0;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
/**
|
||
* @brief Обработчик прерывания таймера
|
||
* @param htmr указатель на хендл таймера
|
||
* @retval void
|
||
*/
|
||
void tmr_handler(TMR_HandleTypeDef* htmr)
|
||
{
|
||
if((htmr->TMR == NULL) || (htmr->Config == NULL))
|
||
{
|
||
return;
|
||
}
|
||
|
||
/* Проверка флага прерывания таймера */
|
||
if (TMR_ITStatus(htmr->TMR) == SET)
|
||
{
|
||
/* Если есть коллбек вызываем его */
|
||
if(htmr->Config->Callback)
|
||
htmr->Config->Callback();
|
||
|
||
/* Очистка флага прерывания */
|
||
TMR_ITStatusClear(htmr->TMR);
|
||
}
|
||
}
|
||
|
||
|
||
/* Расширение библиотеки plib */
|
||
/**
|
||
* @brief Инициализирует модуль TMRx согласно параметрам структуры InitStruct.
|
||
* @param TMRx Выбор таймера, где x=A|B
|
||
* @param InitStruct Указатель на структуру типа @ref TMR_Init_TypeDef,
|
||
* которая содержит конфигурационную информацию
|
||
* @retval void
|
||
*/
|
||
void TMR_Init(TMR_TypeDef* TMRx, TMR_Init_TypeDef* InitStruct)
|
||
{
|
||
uint32_t tim_clk = InitStruct->ClkFreq*__MHZ;
|
||
uint32_t presc = InitStruct->Prescaler+1;
|
||
if(InitStruct->PeriodUs)
|
||
{
|
||
TMR_PeriodConfig(TMRx, tim_clk, InitStruct->PeriodUs);
|
||
}
|
||
else if(InitStruct->FreqHz)
|
||
{
|
||
TMR_FreqConfig(TMRx, tim_clk, InitStruct->FreqHz);
|
||
}
|
||
else
|
||
{
|
||
uint64_t load = (uint64_t)InitStruct->Load*presc;
|
||
if(load > 0xFFFFFFFF)
|
||
load = 0xFFFFFFFF;
|
||
TMR_SetLoad(TMRx, load);
|
||
}
|
||
|
||
TMR_ITCmd(TMRx, InitStruct->IT);
|
||
|
||
TMR_DMAReqCmd(TMRx, InitStruct->DMAReq);
|
||
TMR_ADCSOCCmd(TMRx, InitStruct->ADCSOC);
|
||
TMR_ExtInputConfig(TMRx, InitStruct->ExtInput);
|
||
}
|
||
|