@@ -72,17 +72,58 @@ Supported ``ioctl`` Commands
7272
7373 **Argument: ** ``int `` (value to watch for).
7474
75+ .. c :macro :: CAPIOC_REGISTER
76+
77+ Register for capture edge event notifications. This allows applications
78+ to receive asynchronous signal notifications when capture edge events
79+ occur, instead of polling for events.
80+
81+ **Argument: ** ``struct cap_notify_s * `` (pointer to notification structure).
82+
83+ The ``struct cap_notify_s `` contains:
84+
85+ * ``event `` - The signal event configuration (``struct sigevent ``)
86+ * ``chan `` - Capture channel number
87+ * ``type `` - Edge type (``CAP_TYPE_RISING ``, ``CAP_TYPE_FALLING ``, or ``CAP_TYPE_BOTH ``)
88+ * ``ptr `` - User data pointer
89+
90+ **Returns: **
91+
92+ * ``OK `` on success
93+ * ``-EINVAL `` for invalid channel
94+ * ``-EBUSY `` if channel already registered by another task
95+
96+ .. c :macro :: CAPIOC_UNREGISTER
97+
98+ Unregister capture edge event notifications.
99+
100+ **Argument: ** ``int `` (channel number).
101+
102+ **Returns: ** ``OK `` on success.
103+
75104Configuration
76105-------------
77106
78107To enable the capture driver, enable the following configuration options:
79108
80- * ``CONFIG_CAPTURE ``
81- * ``CONFIG_STM32H7_TIM4_CAP `` (for STM32H7 Timer 4)
109+ * ``CONFIG_CAPTURE `` - Enable the capture driver framework
110+ * ``CONFIG_CAPTURE_NOTIFY `` - Enable signal notification support for edge events
111+ * ``CONFIG_FAKE_CAPTURE `` - Enable fake capture driver for testing (generates 10Hz signal with 50% duty cycle)
112+ * ``CONFIG_STM32H7_TIM4_CAP `` (for STM32H7 Timer 4, platform-specific)
82113
83114The ``CONFIG_CAPTURE `` option enables the lower-half driver and registers
84115the ``/dev/capture `` device.
85116
117+ The ``CONFIG_CAPTURE_NOTIFY `` option enables the signal notification feature,
118+ allowing applications to receive asynchronous notifications when capture
119+ edge events occur. This requires hardware support for edge interrupts and
120+ depends on ``CONFIG_CAPTURE ``.
121+
122+ The ``CONFIG_FAKE_CAPTURE `` option enables a software-based fake capture
123+ driver that simulates a 10Hz square wave with 50% duty cycle. This is
124+ useful for development and testing without requiring actual hardware.
125+ It depends on ``CONFIG_CAPTURE `` and ``CONFIG_CAPTURE_NSIGNALS > 0 ``.
126+
86127Without it, capture is still possible manually by including the appropriate
87128header (e.g., ``arch/arm/src/stm32h7/stm32_capture.h ``) and performing a
88129manual initialization.
@@ -125,6 +166,129 @@ frequency:
125166 return 0;
126167 }
127168
169+ Signal Notification Example
170+ ----------------------------
171+
172+ Here is an example using signal notifications for event-driven capture
173+ (requires ``CONFIG_CAPTURE_NOTIFY ``):
174+
175+ .. code-block :: c
176+
177+ #include <stdio.h>
178+ #include <signal.h>
179+ #include <fcntl.h>
180+ #include <sys/ioctl.h>
181+ #include <nuttx/timers/capture.h>
182+
183+ static volatile int edge_count = 0;
184+
185+ static void capture_handler(int signo, siginfo_t *info, void *context)
186+ {
187+ edge_count++;
188+ }
189+
190+ int main(int argc, char *argv[])
191+ {
192+ int fd;
193+ struct cap_notify_s notify;
194+ struct sigaction sa;
195+ uint32_t frequency;
196+ uint8_t duty;
197+
198+ /* Set up signal handler */
199+ sa.sa_sigaction = capture_handler;
200+ sa.sa_flags = SA_SIGINFO;
201+ sigemptyset(&sa.sa_mask);
202+ sigaction(SIGUSR1, &sa, NULL);
203+
204+ /* Open capture device */
205+ fd = open("/dev/capture0", O_RDONLY);
206+ if (fd < 0)
207+ {
208+ perror("Failed to open capture device");
209+ return 1;
210+ }
211+
212+ /* Configure notification for both edges on channel 0 */
213+ notify.chan = 0;
214+ notify.type = CAP_TYPE_BOTH;
215+ notify.event.sigev_notify = SIGEV_SIGNAL;
216+ notify.event.sigev_signo = SIGUSR1;
217+ notify.event.sigev_value.sival_ptr = NULL;
218+
219+ if (ioctl(fd, CAPIOC_REGISTER, (unsigned long)¬ify) < 0)
220+ {
221+ perror("Failed to register notification");
222+ close(fd);
223+ return 1;
224+ }
225+
226+ printf("Waiting for capture events...\n");
227+
228+ /* Wait for some events */
229+ sleep(2);
230+
231+ /* Get frequency and duty cycle */
232+ ioctl(fd, CAPIOC_FREQUENCE, (unsigned long)&frequency);
233+ ioctl(fd, CAPIOC_DUTYCYCLE, (unsigned long)&duty);
234+
235+ printf("Captured %d edges\n", edge_count);
236+ printf("Frequency: %u Hz, Duty: %u%%\n", frequency, duty);
237+
238+ /* Unregister notification */
239+ ioctl(fd, CAPIOC_UNREGISTER, 0);
240+
241+ close(fd);
242+ return 0;
243+ }
244+
245+ Fake Capture Testing Example
246+ -----------------------------
247+
248+ The fake capture driver can be used for testing without hardware
249+ (requires ``CONFIG_FAKE_CAPTURE ``):
250+
251+ .. code-block :: c
252+
253+ #include <stdio.h>
254+ #include <fcntl.h>
255+ #include <sys/ioctl.h>
256+ #include <nuttx/timers/capture.h>
257+
258+ int main(int argc, char *argv[])
259+ {
260+ int fd;
261+ uint32_t frequency;
262+ uint8_t duty;
263+
264+ /* Open fake capture device */
265+ fd = open("/dev/fake_capture0", O_RDONLY);
266+ if (fd < 0)
267+ {
268+ perror("Failed to open fake capture device");
269+ return 1;
270+ }
271+
272+ /* Start capture */
273+ ioctl(fd, CAPIOC_START, 0);
274+
275+ /* Wait for capture to stabilize */
276+ sleep(1);
277+
278+ /* Read values (should be 10Hz, 50% duty) */
279+ ioctl(fd, CAPIOC_FREQUENCE, (unsigned long)&frequency);
280+ ioctl(fd, CAPIOC_DUTYCYCLE, (unsigned long)&duty);
281+
282+ printf("Fake Capture - Frequency: %u Hz, Duty: %u%%\n",
283+ frequency, duty);
284+
285+ /* Stop capture */
286+ ioctl(fd, CAPIOC_STOP, 0);
287+
288+ close(fd);
289+ return 0;
290+ }
291+
128292 Notes
129293-----
130294
@@ -136,3 +300,38 @@ Notes
136300* **Important: ** In debug builds of NuttX, calling an unsupported
137301 ``ioctl `` command will trigger a ``DEBUGASSERT `` in the driver,
138302 which will halt or crash the system.
303+
304+ Signal Notification Features
305+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
306+
307+ When ``CONFIG_CAPTURE_NOTIFY `` is enabled:
308+
309+ * Applications can register for asynchronous edge event notifications
310+ * Supports per-channel registration with independent configurations
311+ * Edge types supported: rising edge (``CAP_TYPE_RISING ``), falling edge
312+ (``CAP_TYPE_FALLING ``), or both (``CAP_TYPE_BOTH ``)
313+ * Only one task can register per channel at a time
314+ * Signal notifications use standard POSIX ``sigevent `` mechanism
315+ * Lower-half drivers must implement ``bind() `` and ``unbind() `` operations
316+ * Ideal for event-driven applications like tachometers, encoders, and
317+ frequency counters
318+
319+ Fake Capture Driver
320+ ~~~~~~~~~~~~~~~~~~~
321+
322+ The fake capture driver (``CONFIG_FAKE_CAPTURE ``) provides:
323+
324+ * Software simulation of capture events using watchdog timers
325+ * Fixed 10Hz frequency with 50% duty cycle
326+ * Edge toggles every 50ms (rising and falling)
327+ * Supports all standard capture operations including notifications
328+ * Available at ``/dev/fake_capture0 ``, ``/dev/fake_capture1 ``, etc.
329+ * Useful for development, testing, and CI/CD without hardware
330+ * Platform-independent implementation
331+ * Automatically initialized at boot (2 channels by default)
332+
333+ Limitations:
334+
335+ * Fixed timing parameters (not configurable at runtime)
336+ * Software timing accuracy (not hardware-precise)
337+ * Suitable for functional testing, not timing precision validation
0 commit comments