You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
214 lines
6.8 KiB
214 lines
6.8 KiB
/**
|
|
* \file
|
|
* \brief Timer driver
|
|
* \author Erich Styger, erich.styger@hslu.ch
|
|
* \license SPDX-License-Identifier: BSD-3-Clause
|
|
* This module implements the driver for all our timers.
|
|
*/
|
|
|
|
#include "platform.h"
|
|
#include "Timer.h"
|
|
#if PL_CONFIG_USE_EVENTS
|
|
#include "Event.h"
|
|
#endif
|
|
#include "Trigger.h"
|
|
#include "fsl_ftm.h"
|
|
#if PL_CONFIG_USE_QUADRATURE
|
|
#include "fsl_pit.h"
|
|
#include "QuadCounter.h"
|
|
#endif
|
|
#include "Tacho.h"
|
|
|
|
void TMR_OnInterrupt(void) { /* called from RTOS tick hook */
|
|
/* this one gets called from an interrupt!!!! */
|
|
#if PL_CONFIG_USE_EVENTS
|
|
static unsigned int cntr = 0;
|
|
#define BLINK_PERIOD_MS 2000
|
|
/* this one gets called from an interrupt!!!! */
|
|
cntr++;
|
|
if ((cntr%(BLINK_PERIOD_MS/TMR_TICK_MS))==0) { /* every two seconds */
|
|
EVNT_SetEvent(EVNT_LED_HEARTBEAT);
|
|
}
|
|
#endif
|
|
TRG_AddTick();
|
|
TACHO_Sample();
|
|
}
|
|
|
|
#if PL_CONFIG_USE_LINE_SENSOR
|
|
/*------------------------------------------------------------------------------------------- */
|
|
/* Reflectance Sensor free running timer */
|
|
/*------------------------------------------------------------------------------------------- */
|
|
#define REFLECTANCE_FTM_BASEADDR FTM1 /* FTM0 and FTM1 works, but FTM2 crashes? */
|
|
#define REFLECTANCE_FTM_CLOCK_SRC kFTM_SystemClock
|
|
#define REFLECTANCE_FTM_IRQ_NUM FTM1_IRQn
|
|
#define REFLECTANCE_FTM_IRQ_HANDLER FTM1_IRQHandler
|
|
#define REFLECTANCE_FTM_SOURCE_CLOCK (CLOCK_GetFreq(kCLOCK_BusClk))
|
|
|
|
#if 0
|
|
void REFLECTANCE_FTM_IRQ_HANDLER(void) { /* called every 1 ms */
|
|
/* Clear interrupt flag.*/
|
|
FTM_ClearStatusFlags(REFLECTANCE_FTM_BASEADDR, kFTM_TimeOverflowFlag);
|
|
__DSB();
|
|
}
|
|
#endif
|
|
|
|
void TMR_StartReflectanceTimer(void) {
|
|
FTM_StartTimer(REFLECTANCE_FTM_BASEADDR, REFLECTANCE_FTM_CLOCK_SRC);
|
|
}
|
|
|
|
void TMR_StopReflectanceTimer(void) {
|
|
FTM_StopTimer(REFLECTANCE_FTM_BASEADDR);
|
|
}
|
|
|
|
void TMR_ResetReflectanceTimerCounter(void) {
|
|
REFLECTANCE_FTM_BASEADDR->CNT = 0; /* there is no SDK function for this */
|
|
}
|
|
|
|
uint32_t TMR_GetReflectanceTimerCounter(void) {
|
|
return FTM_GetCurrentTimerCount(REFLECTANCE_FTM_BASEADDR);
|
|
}
|
|
|
|
uint32_t TMR_GetRefelectanceTimerFrequencyHz(void) {
|
|
return REFLECTANCE_FTM_SOURCE_CLOCK;
|
|
}
|
|
|
|
static void InitReflectanceTimer(void) {
|
|
ftm_config_t ftmInfo;
|
|
|
|
FTM_GetDefaultConfig(&ftmInfo);
|
|
/* Divide FTM clock by 4 */
|
|
ftmInfo.prescale = kFTM_Prescale_Divide_1;
|
|
|
|
/* Initialize FTM module */
|
|
FTM_Init(REFLECTANCE_FTM_BASEADDR, &ftmInfo);
|
|
FTM_SetTimerPeriod(REFLECTANCE_FTM_BASEADDR, 0xFFFF /*USEC_TO_COUNT(10000U), REFLECTANCE_FTM_SOURCE_CLOCK)*/);
|
|
|
|
// FTM_EnableInterrupts(REFLECTANCE_FTM_BASEADDR, kFTM_TimeOverflowInterruptEnable);
|
|
// EnableIRQ(REFLECTANCE_FTM_IRQ_NUM);
|
|
|
|
FTM_StartTimer(REFLECTANCE_FTM_BASEADDR, REFLECTANCE_FTM_CLOCK_SRC);
|
|
}
|
|
#endif /* PL_CONFIG_USE_LINE_SENSOR */
|
|
/*------------------------------------------------------------------------------------------- */
|
|
#if PL_CONFIG_USE_MOTORS
|
|
/*
|
|
* Left motor: PTC5, FTM0, Ch2
|
|
* Right motor: PTC4, FTM0, Ch3
|
|
*/
|
|
#define MOTOR_PWM_FTM_BASEADDR FTM0
|
|
#define MOTOR_FTM_SOURCE_CLOCK CLOCK_GetFreq(kCLOCK_BusClk)
|
|
#define MOTOR_PWM_LEFT_FTM_CHANNEL 2U
|
|
#define MOTOR_PWM_RIGHT_FTM_CHANNEL 3U
|
|
|
|
void TMR_SetLeftMotorPWMDutyPercent(uint8_t percent) {
|
|
FTM_UpdatePwmDutycycle(MOTOR_PWM_FTM_BASEADDR, (ftm_chnl_t)MOTOR_PWM_LEFT_FTM_CHANNEL, kFTM_EdgeAlignedPwm, 100-percent);
|
|
/* Software trigger to update registers */
|
|
FTM_SetSoftwareTrigger(MOTOR_PWM_FTM_BASEADDR, true);
|
|
}
|
|
|
|
void TMR_SetRightMotorPWMDutyPercent(uint8_t percent) {
|
|
FTM_UpdatePwmDutycycle(MOTOR_PWM_FTM_BASEADDR, (ftm_chnl_t)MOTOR_PWM_RIGHT_FTM_CHANNEL, kFTM_EdgeAlignedPwm, 100-percent);
|
|
/* Software trigger to update registers */
|
|
FTM_SetSoftwareTrigger(MOTOR_PWM_FTM_BASEADDR, true);
|
|
}
|
|
|
|
void TMR_SetLeftMotorPWMRatio(uint16_t val) {
|
|
TMR_SetLeftMotorPWMDutyPercent(val>>8);
|
|
}
|
|
|
|
void TMR_SetRightMotorPWMRatio(uint16_t val) {
|
|
TMR_SetRightMotorPWMDutyPercent(val>>8);
|
|
}
|
|
|
|
void TMR_MotorPWMStart(void) {
|
|
FTM_StartTimer(MOTOR_PWM_FTM_BASEADDR, kFTM_SystemClock);
|
|
}
|
|
|
|
void TMR_MotorPWMStop(void) {
|
|
FTM_StopTimer(MOTOR_PWM_FTM_BASEADDR);
|
|
}
|
|
|
|
static void InitMotorPWMTimer(void) {
|
|
ftm_chnl_pwm_signal_param_t ftmParam[2];
|
|
ftm_config_t ftmInfo;
|
|
|
|
/* Configure ftm params with frequency 24kHZ */
|
|
ftmParam[0].chnlNumber = (ftm_chnl_t)MOTOR_PWM_LEFT_FTM_CHANNEL;
|
|
ftmParam[0].level = kFTM_LowTrue;
|
|
ftmParam[0].dutyCyclePercent = 0U;
|
|
ftmParam[0].firstEdgeDelayPercent = 0U;
|
|
|
|
ftmParam[1].chnlNumber = (ftm_chnl_t)MOTOR_PWM_RIGHT_FTM_CHANNEL;
|
|
ftmParam[1].level = kFTM_LowTrue;
|
|
ftmParam[1].dutyCyclePercent = 0U;
|
|
ftmParam[1].firstEdgeDelayPercent = 0U;
|
|
|
|
/*
|
|
* ftmInfo.prescale = kFTM_Prescale_Divide_1;
|
|
* ftmInfo.bdmMode = kFTM_BdmMode_0;
|
|
* ftmInfo.pwmSyncMode = kFTM_SoftwareTrigger;
|
|
* ftmInfo.reloadPoints = 0;
|
|
* ftmInfo.faultMode = kFTM_Fault_Disable;
|
|
* ftmInfo.faultFilterValue = 0;
|
|
* ftmInfo.deadTimePrescale = kFTM_Deadtime_Prescale_1;
|
|
* ftmInfo.deadTimeValue = 0;
|
|
* ftmInfo.extTriggers = 0;
|
|
* ftmInfo.chnlInitState = 0;
|
|
* ftmInfo.chnlPolarity = 0;
|
|
* ftmInfo.useGlobalTimeBase = false;
|
|
*/
|
|
FTM_GetDefaultConfig(&ftmInfo);
|
|
/* Initialize FTM module */
|
|
FTM_Init(MOTOR_PWM_FTM_BASEADDR, &ftmInfo);
|
|
|
|
FTM_SetupPwm(MOTOR_PWM_FTM_BASEADDR, ftmParam, 2U, kFTM_EdgeAlignedPwm, 24000U, MOTOR_FTM_SOURCE_CLOCK);
|
|
TMR_SetLeftMotorPWMDutyPercent(0);
|
|
TMR_SetRightMotorPWMDutyPercent(0);
|
|
// FTM_StartTimer(MOTOR_PWM_FTM_BASEADDR, kFTM_SystemClock);
|
|
}
|
|
#endif /* PL_CONFIG_USE_MOTORS */
|
|
/*------------------------------------------------------------------------------------------- */
|
|
#if PL_CONFIG_USE_QUADRATURE
|
|
|
|
#define QUADRATURE_PIT_BASEADDR PIT
|
|
#define QUADRATURE_PIT_SOURCE_CLOCK CLOCK_GetFreq(kCLOCK_BusClk)
|
|
#define QUADRATURE_PIT_CHANNEL kPIT_Chnl_0
|
|
#define QUADRATURE_PIT_HANDLER PIT0_IRQHandler
|
|
#define QUADRATURE_PIT_IRQ_ID PIT0_IRQn
|
|
|
|
void QUADRATURE_PIT_HANDLER(void) {
|
|
PIT_ClearStatusFlags(QUADRATURE_PIT_BASEADDR, QUADRATURE_PIT_CHANNEL, kPIT_TimerFlag);
|
|
QuadCounter_Sample();
|
|
__DSB();
|
|
}
|
|
|
|
static void InitQuadratureTimer(void) {
|
|
pit_config_t config;
|
|
|
|
PIT_GetDefaultConfig(&config);
|
|
config.enableRunInDebug = false;
|
|
PIT_Init(QUADRATURE_PIT_BASEADDR, &config);
|
|
PIT_SetTimerPeriod(QUADRATURE_PIT_BASEADDR, QUADRATURE_PIT_CHANNEL, USEC_TO_COUNT(200U, QUADRATURE_PIT_SOURCE_CLOCK));
|
|
PIT_EnableInterrupts(QUADRATURE_PIT_BASEADDR, QUADRATURE_PIT_CHANNEL, kPIT_TimerInterruptEnable);
|
|
NVIC_SetPriority(QUADRATURE_PIT_IRQ_ID, 0);
|
|
EnableIRQ(QUADRATURE_PIT_IRQ_ID);
|
|
PIT_StartTimer(QUADRATURE_PIT_BASEADDR, QUADRATURE_PIT_CHANNEL);
|
|
}
|
|
#endif /* PL_CONFIG_USE_QUADRATURE */
|
|
|
|
/*------------------------------------------------------------------------------------------- */
|
|
void TMR_Init(void) {
|
|
#if PL_CONFIG_USE_LINE_SENSOR
|
|
InitReflectanceTimer();
|
|
#endif
|
|
#if PL_CONFIG_USE_MOTORS
|
|
InitMotorPWMTimer();
|
|
#endif
|
|
#if PL_CONFIG_USE_QUADRATURE
|
|
InitQuadratureTimer();
|
|
#endif
|
|
}
|
|
|
|
void TMR_Deinit(void) {
|
|
}
|
|
|
|
|