Article directory
- MCAL – ICU (NXP – S32K14x)
-
- 1 Overview
-
- 1.1 Introduction to FlexTimer module ICU
-
- 1.1.1 How input capture works
- 1.1.2 Filter
- 1.1.3 Working principle of double edge capture
- 2.API
- 3. Configuration introduction
-
- 3.1 IcuChannel
-
- 3.1.1 General
- 3.1.2 IcuSignalEdgeDetection
- 3.1.3 IcuSignalMeasurement
- 3.1.4 IcuTimestampMeasurement
- 3.2 IcuFtm
-
- 3.2.1 FTM Modules
- 3.2.2 IcuFtmChannels
- 3.3 IcuHwInterruptConfigList
- 3.4 Introduction to capture mode
-
- 3.4.1 Timestamp
- 3.4.2 Signal measurement (ICU_DUTY_CYCLE)
- 3.5 Remaining issues
MCAL – ICU (NXP – S32K14x)
MCAL – Summary
- Configuration tool: EB Tresos Studio
- Chip type: S32K146
1. Overview
The function of ICU (Input Capture Unit) input capture is to monitor the edge transition of the input signal to measure the frequency, duty cycle, and high/low level duration of the input signal.
1.1 Introduction to FlexTimer module ICU
1.1.1 How input capture works
The input capture module monitors the input signal (channel input), and compares the captured signal with the set monitoring edge (rising edge/falling edge) through the edge monitoring module. If it matches, the current FTM Counter
The value is stored in Cnv
and triggers an interrupt. At this time, the user can read and record the Cnv
value.
For example, I set rising edge capture, the FTM clock frequency is 1MHz, the program records the Cnv
value as 1000 when triggered for the first time, and records the Cnv
value as when triggered for the second time. 2000, at this time the signal period can be calculated period = (2000-1000) * 1000 / 1000000 = 1ms = 1KHz
.
The capture edge can be set to upper edge/lower edge/double edge
by setting ELSB/ELSA
. Double edge
means that triggering any one will record and trigger an interrupt. In this case, the duty cycle of the input signal can be calculated.
1.1.2 Filter
The input capture module is equipped with a filter (enabled by the user). The stabilization time of the input signal needs to meet the specified sampling time before the signal is transmitted to the edge, otherwise the signal will be filtered. The sampling time of the filter is shown below:
Please refer to the figure below for the sampling time of the filter:
1.1.3 Working principle of double edge capture
Dual Edge Capture Mode – Dual edge capture. In this mode, there is only one input, but there are 2 channels for capturing, and one more channel for recording data, which can easily monitor the duty cycle and period of the signal. For example, channel 0 is configured as rising edge capture and channel 1 is configured as falling edge capture. When the rising edge is detected, the data is recorded in C0V, and when the falling edge is captured, the data is recorded in C1V. We can enable the interrupt of channel 1. When the channel 1 interrupt is triggered, the duty cycle can be obtained through C1V-C0V. When triggered again, the current value and historical value are used to calculate the cycle (NXP processing method)).
Note that this mode can only be used for even channels: 0, 2, 4, 6
There is a description of the configuration in S32K-RM:
In dual-edge monitoring capture mode, the channel needs to be configured for rising edge or falling edge capture (I did not see it allowed to be configured as 1:1 here) ). When the two channels are configured differently, one rising edge and one falling edge, the duty cycle can be monitored. When both channels are configured identically, the period can be monitored.
For the reading of CnV and C(n + 1)V, it is introduced in the Read coherency mechanism
of the S32K reference manual: Note that C(n)V must be read first when reading data. Then read C(n + 1)V
2. API
Function | Description |
---|---|
Icu_Init | ICU module initialization |
Icu_DeInit | ICU module returns to default state |
Icu_SetActivationCondition | Set trigger edge |
Icu_EnableNotification | Enable interrupt callback |
Icu_DisableNotification | Disable interrupt callback |
Icu_StartTimestamp | Start Timestamp mode |
Icu_StopTimestamp | Stop timestamp mode |
Icu_GetTimestampIndex | Get the current timestamp serial number |
Icu_StartSignalMeasurement | Start signal measurement |
Icu_StopSignalMeasurement | Stop signal measurement |
Icu_GetDutyCycleValues | Get duty cycle and cycle values |
3. Configuration introduction
3.1 IcuChannel
3.1.1 General
IcuHwIP:
Hardware module selection
IcuFtmChannelRef:
The hardware module selects FTM. Here you need to open and select the corresponding FTM channel (LPIT/PORT/LPTMR is the same)
IcuDefaultStartEdge:
Start capturing the edge by default (for example, if you select the upper edge, then the measurement will only start when the upper edge is detected, and the ELSB/ELSA register is configured)
IcuMeasurementMode:
Measurement mode
IcuOverflowNotification:
Overflow interrupt callback
3.1.2 IcuSignalEdgeDetection
It needs to be turned on when the measurement mode is selected ICU_MODE_SIGNAL_EDGE_DETECT
.
IcuSignalNotification:
Interrupt callback
3.1.3 IcuSignalMeasurement
It needs to be turned on when the measurement mode is selected ICU_MODE_SIGNAL_MEASUREMENT
.
IcuSignalMeasurementProperty:
Signal measurement method (duty cycle, period, high level time, low level time)
3.1.4 IcuTimestampMeasurement
It needs to be turned on when the measurement mode is selected ICU_MODE_TIMESTAMP
.
IcuTimestampMeasurementProperty:
Time stamp measurement method (loopback, linear)
IcuTimestampNotification:
Interrupt callback
3.2 IcuFtm
3.2.1 Ftm Modules
Ftm Hardware Module:
FTM module selection
ICU FlexTimer Prescaler:
FTM clock division coefficient
IcuFlexTimer Clock source:
Clock source selection
3.2.2 IcuFtmChannels
Ftm Channel:
FTM channel selection
3.3 IcuHwInterruptConfigList
Interrupt enable configuration, select the corresponding interrupt according to the corresponding channel configuration.
3.4 Introduction to capture mode
3.4.1 Timestamp
Time stamp measurement method:
- ICU_CIRCULAR_BUFFER: Loopback, continue to store data from 0 after it is full
- ICU_LINEAR_BUFFER: Linear, the measurement stops when the data is full.
The NotifuInterval
parameter can be set in timestamp mode. The meaning of this parameter is to store the specified number of data before notifying the user. For example, I set NotifuInterval to 2. When two interrupts are triggered and two data are stored, a callback notification will be triggered. At this time, through Icu_GetTimestampIndex
The function can obtain that the current storage location is 2 (you may have questions here. After storing two pieces of data, shouldn’t the current serial number be 1? Because after storing the data, the Index will first increase by 1. Then call the callback function, so it is 2), so after each trigger, the index-1 obtained is the current storage location. Therefore, there will be a problem here. For example, when the callback is triggered for the third time in the above picture, the cache position is 5, but the obtained index exceeds the maximum cache range and the obtained index is 0, so zero point processing is required here. .
void icu_test_init(void) {<!-- --> Icu_Init( & amp;Icu_Config); INT_SYS_EnableIRQ(FTM0_Ch0_Ch1_IRQn); Icu_EnableNotification(0); Icu_StartTimestamp(0, icu_buffer, sizeof(icu_buffer) / sizeof(icu_buffer[0]), 2); } void Icu_channel0_notify(void) {<!-- --> uint16_t index = 0; index = Icu_GetTimestampIndex(0); if(index == 0 ) {<!-- --> index = sizeof(icu_buffer) / sizeof(icu_buffer[0]); return; } index -= 1; if(icu_buffer[index] > icu_buffer[index - 1]) {<!-- --> printf("%d%\r\ ", (icu_buffer[index] - icu_buffer[index - 1]) * 100 / 10000); } else {<!-- --> printf("%d%\r\ ", (65535 - icu_buffer[index - 1] + icu_buffer[index]) * 100 / 10000); } }
3.4.2 Signal measurement (ICU_DUTY_CYCLE)
This mode is implemented through FTM dual edge capture mode.
NXP’s implementation logic for this measurement method is shown in the figure below. When starting measurement, enable channel n and trigger an interrupt to save the value of CnV ① (Note that it is assumed that the rising edge is captured at this time
). Reconfigure the channel (channel n is set to falling edge capture, channel n + 1 is set to rising edge capture) and turn off the channel n interrupt, open the channel n + 1 interrupt, when the channel n + 1 interrupt is triggered, obtain the value of Cnv at the same time ② and the value of C(n + 1)V ③, then get the duty cycle value through ②-①, get the period value through ③-①, and then update the value of ③ to the historical value. When channel n + 1 is triggered again, it will be at the ⑤ position and repeat the above operation.
void icu_test_init(void) {<!-- --> Icu_Init( & amp;Icu_Config); INT_SYS_EnableIRQ(FTM0_Ch0_Ch1_IRQn); Icu_EnableNotification(0); Icu_StartSignalMeasurement(0); } // This function is called in periodic tasks void Icu_get_duty_period(void) {<!-- --> float duty = 0; Icu_DutyCycleType data = {<!-- -->0}; Icu_GetDutyCycleValues(0, & amp;data); printf("duty:%f%% period:%f(ms)\r\ ", ((float)data.ActiveTime * 100 / data.PeriodTime), ((float)data.PeriodTime * 1000 / 1000000)); }
3.5 Remaining Issues
It can be seen from the manual that in dual-edge mode, the trigger edges of the two channel configurations should be opposite, so when EB is configured in IcuSignalMeasurement mode, the edge trigger should select rising edge or falling edge
, double edge should not be selected (personal understanding), but when I select double edge, the triggering mode of both channels is (ELSA:ELSB = 1:1), it can still work normally, and the working phenomenon is the same as (Channel n: rising edge trigger / Channel n + 1: falling edge trigger) Same, So I didn’t understand here, in dual edge capture mode, both channels are configured as (ELSA:ELSB = 1:1) In this case, how does it work internally? Won't the two capture input signals conflict?
.
The duty cycle I set here is 30%, and the actual test phenomenon is consistent with rising edge trigger
.
References:
S32K-RM.pdf-NXP
AUTOSAR_MCAL_ICU_UM[1].pdf – NXP