CAPTURE USER GUIDE
REVISION HISTORY¶
| Revision No. | Description |
Date |
|---|---|---|
| 1.0 | 04/09/2025 |
1. OVERVIEW¶
1.1. Capture¶
Capture can capture PWM waveform information, including period, duty cycle and number of pulses. The principle of Capture is to obtain the PWM waveform information by capturing the rising and falling edges of the PWM waveform and their time intervals. It should be noted that the captured waveform duty cycle range should be 0% < duty < 100%, because when the duty cycle is 0% or 100%, there is no rising and falling edge, and the jump cannot be captured to obtain the input PWM waveform information.
The clock frequency of Capture is 24Mhz, and switching is not supported.
1.2. channel¶
Capture has 8 groups, of which the first 4 groups have 2 channels each, and the last 4 groups have 1 channel each, there are 12 channels to support capture in total.
Capture supports up to 12 channels to capture PWM period and duty cycle at the same time, but each group has only 1 channel to capture the number of pulses, so it supports up to 8 channels to capture the number of pulses at the same time.
2. Key Words¶
dts/dtsi:
Linux Device Tree File, commonly used to describe the peripherals supported by the CPU. The attribute values contained in the peripheral nodes can be used for the configuration of the peripherals.
padmux:
Pin Multiplexing, used to connect the functional pins of a module to specific external pins, thereby establishing signal connections.
deglitch:
Glitch filtering: waveforms shorter than the deglitch value (in ns) will be ignored. The setting of deglitch affects the upper limit of the captured PWM frequency
3. Function Description¶
Support three modes of pulse number capture: normal mode, direction mode, quad mode.the captured frequency range is 1Hz ~ 6MHz.
3.1. Pulse Counting Mode--Normal Mode¶
All 8 capture groups support normal mode. After capturing two rising edges, the count increases by 1. The maximum value is 0xFFFF, and overflow is cleared to 0.
3.2. Pulse Counting Mode--Direction Mode¶
Only the first 4 groups Capture0-Capture3 support direction mode. Each group has two channels, one for pulse counting and the other for direction judgment.
When the channel as the direction captures a high level, the pulse count starts to increase, the maximum value is 0xFFFF, and overflow is cleared to 0.
When the channel as the direction captures a low level, the pulse count starts to decrease, the maximum value is 0xFFFF, gradually decreases to 0 and then jumps to 0xFFFF, repeating the cycle.
3.3. Pulse Counting Mode--Quad Mode¶
The quad mode is also called orthogonal encoding counting mode. It is only supported by the first 4 groups Capture0-Capture3, with two channels in each group.
By capturing PWM signals with the same signal and a phase difference of 90 degrees (i.e. orthogonal signals), the number and direction of pulses are calculated.
As shown in the figure, quad mode means 4 times counting. The number of pulses will be increased by 1 only when the counting at the 4 moments in the figure is met, so it has a higher counting accuracy.

As shown in the figure, pulses count on both edges of TI1 and TI2, among which,
Moment 1: TI2 is at a low level, TI1 has an upward edge transition, the counter counts up
Moment 2: TI1 is at a high level, TI2 has an upward edge transition, the counter continues to count up
Moment 3: TI2 is at a high level, TI1 has a downward edge transition, the counter continues to count up
Moment 4: TI1 is at a low level, TI2 has a downward edge transition, the counter continues to count up
4. KERNEL USAGE INTRODUCTION¶
Driver Path: kernel/drivers/sstar/capture
4.1. Kernel Config Configuration¶
The configurations you need to select when compiling the kernel are as follows:
Device Drivers-->
[*] SStar SoC platform drivers-->
[*] Sigmastar Capture driver
4.2. Configure DTS¶
The DTS configuration of Capture only needs to configure the following information in the corresponding chipname.dtsi:
capture0: capture@1f2ce000 {
compatible = "sstar,capture";
reg = <0x0 0x1F2CE000 0x0 0x80>;
interrupts=<GIC_SPI INT_IRQ_CAPTURE IRQ_TYPE_LEVEL_HIGH>;
group = <0>;
channel = <0 1>;
//0: normal mode, 1: quad mode, 2: dir mode
pulse-cal-mode = <0>;
pulse-cal-chan = <0>;
deglitch = <0>;
clocks = <&CLK_pwm_capture>;
status = "ok";
};
.......
capture4: capture@1f2cf800 {
compatible = "sstar,capture";
reg = <0x0 0x1F2CF800 0x0 0x80>;
interrupts=<GIC_SPI INT_IRQ_CAPTURE IRQ_TYPE_LEVEL_HIGH>;
group = <4>;
channel = <8>;
//only support 0: normal mode
pulse-cal-mode = <0>;
pulse-cal-chan = <8>;
deglitch = <0>;
clocks = <&CLK_pwm_capture>;
status = "ok";
};
Capture DTS configuration description:
| Attribute | Description | Setting Value | Remark |
|---|---|---|---|
| compatible | Match the driver for registration, which must be consistent with the code | "sstar,capture" | Modification prohibited |
| reg | Set the address of the register bank | / | Modification prohibited |
| interrupts | Specify the hardware interrupt number and attributes to be used | INT_IRQ_CAPTURE | Modification prohibited |
| group | The group ID to which each channel belongs | / | Modification prohibited |
| channel | The channel ID under each group | / | Modification prohibited |
| pulse-cal-mode | Select different pulse counting modes, please refer to Pulse Counting Mode Description | Capture0~3 supports 0~2, Capture4~7 only supports 0 | Can be modified as needed |
| pulse-cal-chan | Select the channel for capturing the number of pulses | Capture0~3 supports 2-choose-1, Capture4~7 only supports 1 channel | Can be modified as needed |
| deglitch | Set the pulse to be filtered | In ns, for example, if the setting value is 7, then pulses with a high level duration shorter than 24M * 7 = 291.67ns cannot be captured | Can be modified as needed |
| clocks | Specify the clock source to be used | CLK_pwm_capture | Modification prohibited |
| status | Select whether to enable the Capture driver | "ok" or "disable" | Can be modified as needed |
4.3. PADMUX CONFIGURATION¶
The padmux configuration of Capture needs to add the following code to the corresponding arch/arm64/boot/dts/sstar/chipname-xxx-padmux.dtsi according to the selected pin:
<PAD_OUTP_CH0 PINMUX_FOR_PWMIN0_MODE_1 MDRV_PUSE_PWMIN0>, <PAD_OUTN_CH0 PINMUX_FOR_PWMIN1_MODE_1 MDRV_PUSE_PWMIN1>, <PAD_OUTP_CH1 PINMUX_FOR_PWMIN2_MODE_1 MDRV_PUSE_PWMIN2>, <PAD_OUTN_CH1 PINMUX_FOR_PWMIN3_MODE_1 MDRV_PUSE_PWMIN3>, <PAD_OUTP_CH2 PINMUX_FOR_PWMIN4_MODE_1 MDRV_PUSE_PWMIN4>, <PAD_OUTN_CH2 PINMUX_FOR_PWMIN5_MODE_1 MDRV_PUSE_PWMIN5>, <PAD_OUTP_CH3 PINMUX_FOR_PWMIN6_MODE_1 MDRV_PUSE_PWMIN6>, <PAD_OUTN_CH3 PINMUX_FOR_PWMIN7_MODE_1 MDRV_PUSE_PWMIN7>, <PAD_GPIOE_10 PINMUX_FOR_PWMIN8_MODE_3 MDRV_PUSE_PWMIN8>, <PAD_GPIOD_00 PINMUX_FOR_PWMIN9_MODE_2 MDRV_PUSE_PWMIN9>, <PAD_GPIOE_14 PINMUX_FOR_PWMIN10_MODE_3 MDRV_PUSE_PWMIN10>, <PAD_GPIOE_16 PINMUX_FOR_PWMIN11_MODE_3 MDRV_PUSE_PWMIN11>,
The first column is the pin index number, which can be found in /drivers/sstar/inlcude/{chipname}/gpio.h;
The second column is the mode definition. The hal_gpio_st_padmux_info array in /drivers/sstar/gpio/{chipname}/hal_pinmux.c lists the multiplexing relationship of all pins, which can be used to query which multiplexing functions the pin supports;
The third column is the index name of the pin and the matching mode, which can be found in /drivers/sstar/include/drv_puse.h.
4.4. Module Usage Introduction¶
4.4.1 sys/class/sstar/capture¶
The directory structure of sys/class/sstar/capture is as follows:
-
First-level directory
Create different groups according to the status of DTS Capture.

-
Second-level directory
Each group of Capture attribute settings.

Each File Interface Usage Introduction:
| Name | Description | Parameter | Remark |
|---|---|---|---|
| capture | Get the captured frequency and duty cycle | echo [channel id] > capture;cat capture | |
| cap_edge | Set the edge sampling mode when capturing period and duty cycle | echo [channel id] [edge mode] > cap_edge | edge mode: 0 -> rising edge, 1 -> falling edge, 2 -> dual edges |
| cap_enable | Enable capture | echo [enable] > cap_enable | 0->disable 1->enable |
| pulse | Get the number of captured pulses | cat pulse | The channel to be captured is determined by DTS |
| pulse_edge | Set the edge sampling mode when capturing the number of pulses | echo [edge mode] > pulse_edge | edge mode: 0 -> rising edge, 1 -> falling edge, 2 -> dual edges, note that the number of pulses captured by a single edge is a multiple of that by a double edge. |
| pulse_enable | Enable capture | echo [enable] > pulse_enable | 0->disable 1->enable |
| pulse_bound | Set the upper and lower limits of capture in quad mode | echo [max] [min]> pulse_bound | Only supports quad mode. When the direction is positive, reaching max will trigger an interrupt and clear the captured pulse value to 0. When the direction is negative, reaching min will trigger an interrupt and clear the captured pulse value to 0. |
| direction | Get the direction of the captured pulse | cat direction | 0->negative 1->positive |
| timeout | Set the capture timeout | echo [channel id] [time ns] > time_out | If the capture result does not change within the specified time, the software determines that the input source has been disconnected and the capture fails. It can be used for capturing at a lower frequency. |
For example: Use channel0 of Capture0 to capture frequency, duty cycle and number of pulses.
1. #Jump to Capture0 path 2. cd sys/class/sstar/capture0/ 3. 4. #Set Capture related attributes 5. echo 0 2 > cap_edge 6. echo 1 > cap_enable 7. echo 1 > pulse_edge 8. echo 1 > pulse_enable 9. 10. #Get capture results 11. echo 0 > capture; 12. cat capture; 13. cat pulse; 14. cat direction;
4.5 Demo code¶
Besides sysfs, capture also provides an ioctl interface
#include <stdio.h> #include <errno.h> #include <fcntl.h> #include <stdlib.h> #include <unistd.h> #include <signal.h> #include <string.h> #include <sys/stat.h> #include <sys/types.h> #include <sys/ioctl.h> #include <drv_capture.h> void capture_warn(int num) { printf("capture pulse exceeding the threshold\n"); } int main(int argc, char **argv) { u8 id; char cmd; int flags; int fd = -1; char path_name[24]; struct capture_info info; struct capture_config cap_cfg; if (argc != 5) { printf("format: ut_capture [channel] [cap_edge] [pul_edge] [enable]\n"); return -1; } info.channel = atoi(argv[1]); cap_cfg.channel = atoi(argv[1]); cap_cfg.cap_edge = atoi(argv[2]); cap_cfg.pul_edge = atoi(argv[3]); cap_cfg.cap_enable = atoi(argv[4]); cap_cfg.pul_enable = atoi(argv[4]); cap_cfg.quad_pul_up = 20000; cap_cfg.quad_pul_dn = 20000; cap_cfg.timeout = 10000000000; if (cap_cfg.channel >= 0 && cap_cfg.channel <= 1) { id = 0; } else if (cap_cfg.channel >= 2 && cap_cfg.channel <= 3) { id = 1; } else if (cap_cfg.channel >= 4 && cap_cfg.channel <= 5) { id = 2; } else if (cap_cfg.channel >= 6 && cap_cfg.channel <= 7) { id = 3; } else if (cap_cfg.channel == 8) { id = 4; } else if (cap_cfg.channel == 9) { id = 5; } else if (cap_cfg.channel == 10) { id = 6; } else if (cap_cfg.channel == 11) { id = 7; } else { printf("unsupport channel\n"); return -1; } snprintf(path_name, sizeof(path_name), "/dev/capture%hhu", id); fd = open((const char *)(char *)path_name, O_RDWR); if (fd < 0) { printf("open /dev/capture%hhu fail errno:[%d]\n", id, fd); return -1; } if (ioctl(fd, IOCTL_CAPTURE_SET_CONFIG, &cap_cfg)) { printf("capture[%hhu] config fail\n", cap_cfg.channel); close(fd); return -1; } signal(SIGIO, capture_warn); //Trigger when quad mode reaches the upper and lower limits fcntl(fd, F_SETOWN, getpid()); flags = fcntl(fd, F_GETFL); fcntl(fd, F_SETFL, flags | FASYNC); while (1) { cmd = getchar(); if (cmd == 'q' || cmd == 'Q') { break; } if (ioctl(fd, IOCTL_CAPTURE_RD_PERIOD, &info)) { printf("capture[%hhu] read period fail\n", info.channel); close(fd); return -1; } printf("capture period [%llu]ns , duty [%llu.%02llu]%% \n", info.period, info.duty_i, info.duty_d); if (ioctl(fd, IOCTL_CAPTURE_RD_PULSE, &info)) { printf("capture[%hhu] read pulse fail\n", info.channel); } else { printf("capture pulse [%u] dir[%hhu]\n", info.pulse, info.dir); } } close(fd); return 0; }
5. API Reference¶
| Cmd | Function |
|---|---|
| IOCTL_CAPTURE_SET_CONFIG | Set the capture attributes for the specified channel |
| IOCTL_CAPTURE_GET_CONFIG | Get the current capture attributes for the channel |
| IOCTL_CAPTURE_RD_PERIOD | Get the current period |
| IOCTL_CAPTURE_RD_PULSE | Get the current pulse count |
Before using, include the header file /driver/sstar/capture/drv_capture.h, where the data structures are defined as follows:
struct capture_config { u8 channel; // Specify the capture channel u64 timeout; // Set the timeout period in nanoseconds (ns) u8 cap_edge; // Set the edge mode for capturing period and duty cycle u8 pul_edge; // Set the edge mode for capturing pulse count u8 cap_enable; u8 pul_enable; u16 quad_pul_up; // Set the upper limit for pulse capture in quad mode u16 quad_pul_dn; // Set the lower limit for pulse capture in quad mode }; struct capture_info { u8 dir; // Direction during pulse capture u32 pulse; // Number of captured pulses u64 period; // Captured period u64 duty_i; // Integer part of the captured duty cycle u64 duty_d; // Decimal part of the captured duty cycle u8 channel; };
5.1. IOCTL_CAPTURE_SET_CONFIG¶
-
Function
Set the capture attributes for the corresponding device from the cfg file。
-
Declaration
ioctl(struct file *file, IOCTL_CAPTURE_SET_CONFIG,struct capture_config *cfg);
-
Parameters
Parameter Name Description file Device node IOCTL_CAPTURE_SET_CONFIG Command cfg Structure for storing configurations -
Return Value
Return Value Description 0 Success other Failure
5.2. IOCTL_CAPTURE_GET_CONFIG¶
-
Function
Get the capture attributes for the device corresponding to the file and return them to cfg.
-
Declaration
ioctl(struct file *file, IOCTL_CAPTURE_GET_CONFIG,struct capture_config *cfg);
-
Parameters
Parameter Name Description file Device node IOCTL_CAPTURE_GET_CONFIG Command cfg Structure for storing configurations -
Return Value
Return Value Description 0 Success other Failure
5.3. IOCTL_CAPTURE_RD_PERIOD¶
-
Function
Get the current period for the device corresponding to the file and return it to info.
-
Declaration
ioctl(struct file *file, IOCTL_CAPTURE_RD_PERIOD,struct capture_info *info);
-
Parameters
Parameter Name Description file Device node IOCTL_CAPTURE_RD_PERIOD Command info Structure for storing capture information -
Return Value
Return Value Description 0 Success other Failure
5.4. IOCTL_CAPTURE_RD_PULSE¶
-
Function
Get the current pulse count for the device corresponding to the file and return it to info.
-
Declaration
ioctl(struct file *file, IOCTL_CAPTURE_RD_PULSE, struct capture_info *info);
-
Parameters
Parameter Name Description file Device node IOCTL_CAPTURE_RD_PULSE Command info Structure for storing capture information -
Return Value
Return Value Description 0 Success other Failure
6. FAQ¶
6.1. Each Capture Interface Does Not Exist¶
-
Check whether the
statusof the DTS Capture node isok. -
Check whether the kernel config is configured, see Kernel Config Configuration.
6.2. Capture Results Are Abnormal or Timed out After Configuration¶
Step 1: First confirm whether the measured pin is correct: open the corresponding schematic to confirm, if there is no error, proceed to the next step.
Step 2: Confirm whether the corresponding Capture pad mode is effective. There are two main reasons for pin multiplexing failure:
Reason 1: The pin is not set to Capture mode. For details on the setting method, see PADMUX Configuration.
Reason 2: A padmux mode with a higher priority than Capture mode is enabled. You can turn on the padmux readback mechanism CONFIG: CONFIG_MSYS_PADMUX during compilation. Its function is to confirm whether the padmux used has been successfully set. After turning it on, enter the following command in user space to check:
echo [pad index] [pinmux index] > /sys/class/sstar/msys/mux_verify cat /sys/class/sstar/msys/mux_verify
Step 3: Check whether the relevant parameters are set successfully.
Please refer to Sysfs Interface Usage Instructions for standard usage.