-------------------------------------------------------------------------------- #define INST_FTM_MEASURE 2U #define FTM_MEASURE_BASE FTM2 #define FTM_IN_CAP_CH0 0 #define FTM_IN_CAP_CH0 2 #define INPUT_1_PORT PTE #define INPUT_1_PIN 8 #define INPUT_2_PORT PTB #define INPUT_2_PIN 5 #define INPUT_3_PORT PTB #define INPUT_3_PIN 4 #define FTM_IN_CAP_CH0_PORT PORTD #define FTM_IN_CAP_CH0_PIN 0 #define FTM_IN_CAP_CH2_PORT PORTE #define FTM_IN_CAP_CH2_PIN 4 static ftm_state_t ftmMeasureState; enum SensorType_t{ SENSOR1, SENSOR2 }; static ftm_user_config_t ftmMeasureConfig = { { true, /* Software trigger state */ false, /* Hardware trigger 1 state */ false, /* Hardware trigger 2 state */ false, /* Hardware trigger 3 state */ false, /* Max loading point state */ false, /* Min loading point state */ FTM_SYSTEM_CLOCK, /* Update mode for INVCTRL register */ FTM_SYSTEM_CLOCK, /* Update mode for SWOCTRL register */ FTM_SYSTEM_CLOCK, /* Update mode for OUTMASK register */ FTM_SYSTEM_CLOCK, /* Update mode for CNTIN register */ false, /* Automatic clear of the trigger */ FTM_UPDATE_NOW, /* Synchronization point */ }, FTM_MODE_INPUT_CAPTURE, /* Mode of operation for FTM */ FTM_CLOCK_DIVID_BY_1, /* FTM clock prescaler */ FTM_CLOCK_SOURCE_SYSTEMCLK, /* FTM clock source */ FTM_BDM_MODE_11, /* FTM debug mode */ true, /* Interrupt state */ false /* Initialization trigger */ }; static ftm_input_ch_param_t ftmMeasureInputCaptureChannelConfig[2] = { (ftm_input_ch_param_t){ FTM_IN_CAP_CH0, // Channel 0 (ESS Sensor) FTM_SIGNAL_MEASUREMENT, // Input capture operation mode FTM_RISING_EDGE, // Edge alignment mode FTM_FALLING_EDGE_PERIOD_MEASUREMENT, // Signal measurement operation type 0U, // Filter value false, // Filter state (enabled/disabled) true, // Continuous measurement NULL, // Callback parameters NULL // Callback function }, (ftm_input_ch_param_t){ FTM_IN_CAP_CH2, // Channel 0 (ESS Sensor) FTM_SIGNAL_MEASUREMENT, // Input capture operation mode FTM_RISING_EDGE, // Edge alignment mode FTM_FALLING_EDGE_PERIOD_MEASUREMENT, // Signal measurement operation type 0U, // Filter value false, // Filter state (enabled/disabled) true, // Continuous measurement NULL, // Callback parameters NULL // Callback function } }; static ftm_input_param_t ftmMeasureInputCaptureConfig = { 2U, // Number of channels 65535U, // Maximum count value ftmMeasureInputCaptureChannelConfig // Channels configuration }; static pin_settings_config_t g_pin_mux_inputcapture[] = { { .base = FTM_IN_CAP_CH0_PORT, // FTM2_CH0 -> PTD0 .pinPortIdx = FTM_IN_CAP_CH0_PIN, .mux = PORT_MUX_ALT4 }, { .base = FTM_IN_CAP_CH2_PORT, // FTM2_CH2 -> PTE4 .pinPortIdx = FTM_IN_CAP_CH2_PIN, // PTE4 .mux = PORT_MUX_ALT4, // ALT4 -> FTM2_CH2 function } }; static volatile uint16_t ch0_count = 0; static volatile uint16_t ch2_count = 0; static SensorType_t SensorType; void FTM_Callback(void); /** * @brief Initialisierung des Leitwert-Moduls * @param[in] - * @param[out] - * @return - */ void CaptureInit(void) { PORTE->PCR[INPUT_1_PIN] = PORT_PCR_MUX(1); PORTB->PCR[INPUT_2_PIN] = PORT_PCR_MUX(1); PORTB->PCR[INPUT_3_PIN] = PORT_PCR_MUX(1); PINS_DRV_Init( sizeof(g_pin_mux_inputcapture) / sizeof(g_pin_mux_inputcapture[0]), g_pin_mux_inputcapture); FTM_DRV_Init(INST_FTM_MEASURE, &ftmMeasureConfig, &ftmMeasureState); FTM_DRV_InitInputCapture(INST_FTM_MEASURE, &ftmMeasureInputCaptureConfig); INT_SYS_InstallHandler(FTM2_Ch0_Ch1_IRQn, FTM_Callback, NULL); INT_SYS_InstallHandler(FTM2_Ch2_Ch3_IRQn, FTM_Callback, NULL); INT_SYS_EnableIRQ(FTM2_Ch0_Ch1_IRQn); INT_SYS_EnableIRQ(FTM2_Ch2_Ch3_IRQn); } void CaptureExit(void) { FTM_DRV_CounterStop(INST_FTM_MEASURE); FTM_DRV_DeinitInputCapture(INST_FTM_MEASURE, &ftmMeasureInputCaptureConfig); FTM_DRV_Deinit(INST_FTM_MEASURE); } void CaptureStart(MEASURE_T type) { ch0_count = 0; ch2_count = 0; PINS_DRV_WritePin(INPUT_3_PORT, INPUT_3_PIN, S_ON); if (type == MEASURE_COUNT) { FTM_IC_DRV_SetChannelMode(INST_FTM_MEASURE, FTM_IN_CAP_CH0, FTM_TIMESTAMP_RISING_EDGE, true); FTM_IC_DRV_SetChannelMode(INST_FTM_MEASURE, FTM_IN_CAP_CH2, FTM_TIMESTAMP_RISING_EDGE, true); } else if (type == MEASURE_PULSE) { FTM_IC_DRV_SetChannelMode(INST_FTM_MEASURE, FTM_IN_CAP_CH0, FTM_MEASURE_PULSE_HIGH, true); FTM_IC_DRV_SetChannelMode(INST_FTM_MEASURE, FTM_IN_CAP_CH2, FTM_MEASURE_PULSE_HIGH, true); } FTM_DRV_CounterStart(INST_FTM_MEASURE); } uint32_t CaptureGetSample(SensorType_t senType) { return (senType == SENSOR1) ? (uint32_t)ch0_count : (uint32_t)ch2_count; } void FTM_Callback(void) { if (FTM_DRV_GetChnEventStatus(FTM_MEASURE_BASE, FTM_IN_CAP_CH0)) { ch0_count = FTM_DRV_GetInputCaptureMeasurement(INST_FTM_MEASURE, FTM_IN_CAP_CH0); FTM_DRV_ClearChnEventStatus(FTM_MEASURE_BASE, FTM_IN_CAP_CH0); } if (FTM_DRV_GetChnEventStatus(FTM_MEASURE_BASE, FTM_IN_CAP_CH2)) { ch2_count = FTM_DRV_GetInputCaptureMeasurement(INST_FTM_MEASURE, FTM_IN_CAP_CH2); FTM_DRV_ClearChnEventStatus(FTM_MEASURE_BASE, FTM_IN_CAP_CH2); } } ------------------------------------------------------------------------------- //main.c void delay(volatile int cycles) { while (cycles--) ; } void TestCapture() { CaptureInit(); CaptureStart(MEASURE_COUNT); uint32_t count1 = 0; uint32_t count2 = 0; while (1) { delay(1000); count1 = CaptureGetSample(SENSOR1); delay(1000); count2 = CaptureGetSample(SENSOR2); } CaptureExit(); } int main() { SystemClockInit(); TestCapture() for (;;) { } return 0; } ---------------------------------------------------------------------------- //clock cofig #include "ClockConfig.h" #define CLOCK_MANAGER_CONFIG_CNT 1U #define CLOCK_MANAGER_CALLBACK_CNT 0U #define NUM_OF_PERIPHERAL_CLOCKS_0 30U /** @brief peripheral clock configuration 0 */ peripheral_clock_config_t peripheralClockConfig0[NUM_OF_PERIPHERAL_CLOCKS_0] = { { .clockName = ADC0_CLK, .clkGate = true, .clkSrc = CLK_SRC_FIRC_DIV1, .frac = MULTIPLY_BY_ONE, .divider = DIVIDE_BY_ONE, }, { .clockName = ADC1_CLK, .clkGate = true, .clkSrc = CLK_SRC_FIRC_DIV1, .frac = MULTIPLY_BY_ONE, .divider = DIVIDE_BY_ONE, }, { .clockName = LPSPI0_CLK, .clkGate = true, .clkSrc = CLK_SRC_FIRC_DIV1, .frac = MULTIPLY_BY_ONE, .divider = DIVIDE_BY_ONE, }, { .clockName = LPSPI1_CLK, .clkGate = true, .clkSrc = CLK_SRC_FIRC_DIV1, .frac = MULTIPLY_BY_ONE, .divider = DIVIDE_BY_ONE, }, { .clockName = LPUART0_CLK, .clkGate = true, .clkSrc = CLK_SRC_SOSC_DIV1, .frac = MULTIPLY_BY_ONE, .divider = DIVIDE_BY_ONE, }, { .clockName = LPUART1_CLK, .clkGate = true, .clkSrc = CLK_SRC_SOSC_DIV1, .frac = MULTIPLY_BY_ONE, .divider = DIVIDE_BY_ONE, }, { .clockName = LPI2C0_CLK, .clkGate = true, .clkSrc = CLK_SRC_FIRC_DIV1, .frac = MULTIPLY_BY_ONE, .divider = DIVIDE_BY_ONE, }, { .clockName = LPIT0_CLK, .clkGate = true, .clkSrc = CLK_SRC_FIRC_DIV1, .frac = MULTIPLY_BY_ONE, .divider = DIVIDE_BY_ONE, }, { .clockName = LPTMR0_CLK, .clkGate = true, .clkSrc = CLK_SRC_FIRC_DIV1, .frac = MULTIPLY_BY_ONE, .divider = DIVIDE_BY_ONE, }, { .clockName = FTM0_CLK, .clkGate = true, .clkSrc = CLK_SRC_SPLL_DIV2, .frac = MULTIPLY_BY_ONE, .divider = DIVIDE_BY_ONE, }, { .clockName = FTM1_CLK, .clkGate = true, .clkSrc = CLK_SRC_SPLL_DIV2, .frac = MULTIPLY_BY_ONE, .divider = DIVIDE_BY_ONE, }, { .clockName = FTM2_CLK, .clkGate = true, .clkSrc = CLK_SRC_SPLL_DIV2, .frac = MULTIPLY_BY_ONE, .divider = DIVIDE_BY_ONE, }, { .clockName = FTM3_CLK, .clkGate = true, .clkSrc = CLK_SRC_SPLL_DIV2, //SPLL_CLK = 160 MHz -> SPLL_DIV2_CLK = 80 MHz .frac = MULTIPLY_BY_ONE, .divider = DIVIDE_BY_ONE, }, { .clockName = FLEXIO0_CLK, .clkGate = true, .clkSrc = CLK_SRC_SIRC_DIV2, .frac = MULTIPLY_BY_ONE, .divider = DIVIDE_BY_ONE, }, { .clockName = CMP0_CLK, .clkGate = true, .clkSrc = CLK_SRC_OFF, .frac = MULTIPLY_BY_ONE, .divider = DIVIDE_BY_ONE, }, { .clockName = CRC0_CLK, .clkGate = true, .clkSrc = CLK_SRC_OFF, .frac = MULTIPLY_BY_ONE, .divider = DIVIDE_BY_ONE, }, { .clockName = DMAMUX0_CLK, .clkGate = true, .clkSrc = CLK_SRC_OFF, .frac = MULTIPLY_BY_ONE, .divider = DIVIDE_BY_ONE, }, { .clockName = EWM0_CLK, .clkGate = true, .clkSrc = CLK_SRC_OFF, .frac = MULTIPLY_BY_ONE, .divider = DIVIDE_BY_ONE, }, { .clockName = FTFC0_CLK, .clkGate = true, .clkSrc = CLK_SRC_OFF, .frac = MULTIPLY_BY_ONE, .divider = DIVIDE_BY_ONE, }, { .clockName = PDB0_CLK, .clkGate = true, .clkSrc = CLK_SRC_OFF, .frac = MULTIPLY_BY_ONE, .divider = DIVIDE_BY_ONE, }, { .clockName = PDB1_CLK, .clkGate = true, .clkSrc = CLK_SRC_OFF, .frac = MULTIPLY_BY_ONE, .divider = DIVIDE_BY_ONE, }, { .clockName = RTC0_CLK, .clkGate = true, .clkSrc = CLK_SRC_OFF, .frac = MULTIPLY_BY_ONE, .divider = DIVIDE_BY_ONE, }, { .clockName = FlexCAN0_CLK, .clkGate = true, .clkSrc = CLK_SRC_OFF, .frac = MULTIPLY_BY_ONE, .divider = DIVIDE_BY_ONE, }, { .clockName = FlexCAN1_CLK, .clkGate = true, .clkSrc = CLK_SRC_OFF, .frac = MULTIPLY_BY_ONE, .divider = DIVIDE_BY_ONE, }, { .clockName = PORTA_CLK, .clkGate = true, .clkSrc = CLK_SRC_FIRC_DIV1, .frac = MULTIPLY_BY_ONE, .divider = DIVIDE_BY_ONE, }, { .clockName = PORTB_CLK, .clkGate = true, .clkSrc = CLK_SRC_FIRC_DIV1, .frac = MULTIPLY_BY_ONE, .divider = DIVIDE_BY_ONE, }, { .clockName = PORTC_CLK, .clkGate = true, .clkSrc = CLK_SRC_FIRC_DIV1, .frac = MULTIPLY_BY_ONE, .divider = DIVIDE_BY_ONE, }, { .clockName = PORTD_CLK, .clkGate = true, .clkSrc = CLK_SRC_FIRC_DIV1, .frac = MULTIPLY_BY_ONE, .divider = DIVIDE_BY_ONE, }, { .clockName = PORTE_CLK, .clkGate = true, .clkSrc = CLK_SRC_FIRC_DIV1, .frac = MULTIPLY_BY_ONE, .divider = DIVIDE_BY_ONE, }, { .clockName = FTFC0_CLK, .clkGate = true, .clkSrc = CLK_SRC_FIRC_DIV1, .frac = MULTIPLY_BY_ONE, .divider = DIVIDE_BY_ONE, }, }; /** @brief User Configuration structure clock_managerCfg_0 */ clock_manager_user_config_t clockMan1_InitConfig0 = { .scgConfig = { .sircConfig = { .initialize = true, .enableInStop = true, .enableInLowPower = true, .locked = false, .range = SCG_SIRC_RANGE_HIGH, // Slow IRC high range clock (8 MHz) .div1 = SCG_ASYNC_CLOCK_DIV_BY_1, // Slow IRC Clock Divider 1: divided by 1 .div2 = SCG_ASYNC_CLOCK_DIV_BY_1, // Slow IRC Clock Divider 3: divided by 1 }, .fircConfig = { .initialize = true, .regulator = true, // FIRC regulator is enabled .locked = false, // unlocked .range = SCG_FIRC_RANGE_48M, // RANGE .div1 = SCG_ASYNC_CLOCK_DIV_BY_1, // Fast IRC Clock Divider 1: divided by 1 .div2 = SCG_ASYNC_CLOCK_DIV_BY_1, // Fast IRC Clock Divider 3: divided by 1 }, .rtcConfig = { .initialize = false, }, .soscConfig = { .initialize = true, .freq = 8000000U, // System Oscillator frequency: 8000000Hz .monitorMode = SCG_SOSC_MONITOR_DISABLE,// Monitor disabled .locked = false, // SOSC disabled .extRef = SCG_SOSC_REF_OSC, // Internal oscillator of OSC requested. .gain = SCG_SOSC_GAIN_LOW, // Configure crystal oscillator for low-gain operation .range = SCG_SOSC_RANGE_HIGH, // High frequency range selected for the crystal oscillator of 8 MHz to 40 MHz. .div1 = SCG_ASYNC_CLOCK_DIV_BY_1, // System OSC Clock Divider 1: divided by 1 .div2 = SCG_ASYNC_CLOCK_DIV_BY_1, // System OSC Clock Divider 3: divided by 1 }, .spllConfig = { .initialize = true, .monitorMode = SCG_SPLL_MONITOR_DISABLE, // Monitor disabled .locked = false, //unlocked .prediv = (uint8_t)SCG_SPLL_CLOCK_PREDIV_BY_1, // Divided by 1 .mult = (uint8_t)SCG_SPLL_CLOCK_MULTIPLY_BY_20,// Multiply Factor is 20 -> SPLL_CLK = 8 MHz * 20 = 160 MHz .src = 0U, .div1 = SCG_ASYNC_CLOCK_DIV_BY_2, // System PLL Clock Divider 1: divided by 2 -> SPLL_DIV2_CLK = 80 MHz .div2 = SCG_ASYNC_CLOCK_DIV_BY_4, // System PLL Clock Divider 3: divided by 4 }, .clockOutConfig = { .initialize = true, .source = SCG_CLOCKOUT_SRC_FIRC, // Fast IRC. }, .clockModeConfig = { .initialize = true, .rccrConfig = { .src = SCG_SYSTEM_CLOCK_SRC_SYS_PLL,// Use System PLL (160 MHz) .divCore = SCG_SYSTEM_CLOCK_DIV_BY_2,// Core Clock = 160/2 = 80 MHz .divBus = SCG_SYSTEM_CLOCK_DIV_BY_4,// Bus Clock = 160/4 = 40 MHz .divSlow = SCG_SYSTEM_CLOCK_DIV_BY_6,// Flash Clock = 160/6 ≈ 26.67 MHz }, .vccrConfig = { .src = SCG_SYSTEM_CLOCK_SRC_SIRC, //Slow SIRC .divCore = SCG_SYSTEM_CLOCK_DIV_BY_2, // Core Clock Divider: divided by 2 .divBus = SCG_SYSTEM_CLOCK_DIV_BY_1, // Bus Clock Divider: divided by 1 .divSlow = SCG_SYSTEM_CLOCK_DIV_BY_4, // Slow Clock Divider: divided by 4 }, .hccrConfig = { .src = SCG_SYSTEM_CLOCK_SRC_SYS_PLL,//System PLL .divCore = SCG_SYSTEM_CLOCK_DIV_BY_1,// Core Clock Divider: divided by 1 .divBus = SCG_SYSTEM_CLOCK_DIV_BY_2,//Bus Clock Divider: divided by 2 .divSlow = SCG_SYSTEM_CLOCK_DIV_BY_4,// Slow Clock Divider: divided by 4 }, }, }, .pccConfig = { .peripheralClocks = peripheralClockConfig0, //Peripheral clock control configurations .count = NUM_OF_PERIPHERAL_CLOCKS_0, //Number of the peripheral clock control configurations }, .simConfig = { .clockOutConfig = { .initialize = true, .enable = true, .source = SIM_CLKOUT_SEL_SYSTEM_SCG_CLKOUT, .divider = SIM_CLKOUT_DIV_BY_1, }, .lpoClockConfig = { .initialize = true, .enableLpo1k = true, .enableLpo32k = true, .sourceLpoClk = SIM_LPO_CLK_SEL_LPO_128K, .sourceRtcClk = SIM_RTCCLK_SEL_FIRCDIV1_CLK, }, .platGateConfig = { .initialize = true, .enableEim = true, .enableErm = true, .enableDma = true, .enableMpu = true, .enableMscm = true, }, .tclkConfig = { .initialize = false, }, .traceClockConfig = { .initialize = true, .divEnable = true, .source = CLOCK_TRACE_SRC_CORE_CLK, .divider = 0U, .divFraction = false, }, }, .pmcConfig = { .lpoClockConfig = { .initialize = true, .enable = true, .trimValue = 0, }, }, }; /** @brief Array of pointers to User configuration structures */ clock_manager_user_config_t const *g_clockManConfigsArr[] = { &clockMan1_InitConfig0 }; /** @brief Array of pointers to User defined Callbacks configuration structures The tool do not support generate Callbacks configuration. It's always empty. */ clock_manager_callback_user_config_t *g_clockManCallbacksArr[] = { (void *)0 }; void SystemClockInit() { CLOCK_SYS_Init( g_clockManConfigsArr, CLOCK_MANAGER_CONFIG_CNT, g_clockManCallbacksArr, CLOCK_MANAGER_CALLBACK_CNT); CLOCK_SYS_UpdateConfiguration(0U, CLOCK_MANAGER_POLICY_AGREEMENT); }