Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions Documentation/applications/examples/pulsecount/index.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
====================================
``pulsecount`` Pulse Count Example
====================================

This example starts a finite pulse train on a pulsecount device and
waits for completion when the device is opened in blocking mode.

Required configuration:

- ``CONFIG_PULSECOUNT`` – Enables pulsecount support.
- ``CONFIG_NSH_BUILTIN_APPS`` – Builds the example as an NSH built-in.

Specific configuration options:

- ``CONFIG_EXAMPLES_PULSECOUNT_DEVPATH`` – The default pulsecount device.
Default: ``/dev/pulsecount0``.
- ``CONFIG_EXAMPLES_PULSECOUNT_HIGH_NS`` – The pulse high time. Default:
``5000000`` ns.
- ``CONFIG_EXAMPLES_PULSECOUNT_LOW_NS`` – The pulse low time. Default:
``5000000`` ns.
- ``CONFIG_EXAMPLES_PULSECOUNT_COUNT`` – The finite pulse count.
8 changes: 1 addition & 7 deletions Documentation/applications/examples/pwm/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ This test depends on these specific PWM/NSH configurations settings (your
specific PWM settings might require additional settings).

- ``CONFIG_PWM`` – Enables PWM support.
- ``CONFIG_PWM_PULSECOUNT`` – Enables PWM pulse count support (if the hardware
supports it).
- ``CONFIG_NSH_BUILTIN_APPS`` – Build the PWM test as an NSH built-in function.

Specific configuration options for this example include:
Expand All @@ -22,8 +20,4 @@ Specific configuration options for this example include:
- ``CONFIG_EXAMPLES_PWM_DUTYPCT`` – The initial PWM duty as a percentage. Default:
``50%``.
- ``CONFIG_EXAMPLES_PWM_DURATION`` – The initial PWM pulse train duration in
seconds. Used only if the current pulse count is zero (pulse count is only
supported if ``CONFIG_PWM_PULSECOUNT`` is defined). Default: ``5`` seconds.
- ``CONFIG_EXAMPLES_PWM_PULSECOUNT`` – The initial PWM pulse count. This option is
only available if ``CONFIG_PWM_PULSECOUNT`` is non-zero. Default: ``0`` (i.e., use
the duration, not the count).
seconds. Default: ``5`` seconds.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Timers Drivers
timer.rst
oneshot.rst
pwm.rst
pulsecount.rst
watchdog.rst
rtc.rst
capture.rst
Expand Down
97 changes: 97 additions & 0 deletions Documentation/components/drivers/character/timers/pulsecount.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
===================
Pulsecount Drivers
===================

The pulsecount driver generates a finite pulse train and reports completion
after the requested number of pulses has been produced. It is intended for
hardware that can generate pulse output with a fixed repetition count, often
using PWM/timer peripherals internally.

This interface is separate from the PWM driver. PWM describes a continuous
periodic output using frequency and duty cycle. Pulsecount describes a finite
waveform using explicit high time, low time, and pulse count.

Driver Model
============

The NuttX pulsecount driver is split into two parts:

#. An upper-half character driver that provides the common application
interface.
#. A lower-half platform driver that programs the hardware timer/PWM
peripheral and calls ``pulsecount_expired()`` when the finite pulse train
completes.

Files supporting pulsecount can be found in the following locations:

- ``include/nuttx/timers/pulsecount.h`` - public interface and lower-half
callbacks.
- ``drivers/timers/pulsecount.c`` - generic upper-half driver.
- ``arch/<architecture>/src/<chip>/*pulsecount*.c`` - platform lower-half
drivers.

Application Interface
=====================

Applications use the pulsecount driver through a character device such as
``/dev/pulsecount0``. Include the pulsecount header:

.. code-block:: c

#include <nuttx/timers/pulsecount.h>

The driver is controlled through ``ioctl`` commands:

- ``PULSECOUNTIOC_SETCHARACTERISTICS``
- ``PULSECOUNTIOC_GETCHARACTERISTICS``
- ``PULSECOUNTIOC_START``
- ``PULSECOUNTIOC_STOP``

Pulse Characteristics
=====================

``PULSECOUNTIOC_SETCHARACTERISTICS`` takes a pointer to
``struct pulsecount_info_s``:

.. code-block:: c

struct pulsecount_info_s
{
uint32_t high_ns; /* Pulse high time in nanoseconds */
uint32_t low_ns; /* Pulse low time in nanoseconds */
uint32_t count; /* Number of pulses to generate */
};

``high_ns`` and ``low_ns`` must both be non-zero. Their sum is the pulse
period. ``count`` is the number of complete high/low pulses to generate.

This API previously followed the PWM-style ``frequency`` plus ``duty``
model. It now uses explicit high/low nanosecond timing because that is more
user-friendly for finite pulse trains: applications can describe the waveform
directly and do not need to convert timing requirements into fixed-point duty
cycle values.

The lower-half driver may quantize the requested timings to the nearest values
that the hardware timer can represent. Very long periods or very short
pulses can be rejected if they are outside the timer's clock and counter
range.

Starting And Stopping
=====================

After setting the pulse characteristics, start the pulse train with
``PULSECOUNTIOC_START``. By default, this call blocks until the requested
pulse count completes. Open the device with ``O_NONBLOCK`` to start the
pulse train and return immediately.

``PULSECOUNTIOC_STOP`` stops pulse generation before the count completes.
TODO: support cancelling a blocking ``PULSECOUNTIOC_START``.

Example
=======

The ``apps/examples/pulsecount`` example starts a finite pulse train from
NSH. It can be built with ``CONFIG_EXAMPLES_PULSECOUNT`` and configured with
``CONFIG_EXAMPLES_PULSECOUNT_HIGH_NS``,
``CONFIG_EXAMPLES_PULSECOUNT_LOW_NS``, and
``CONFIG_EXAMPLES_PULSECOUNT_COUNT``.
8 changes: 6 additions & 2 deletions Documentation/components/drivers/character/timers/pwm.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ PWM Drivers
For the purposes of this driver, a PWM device is any device that
generates periodic output pulses of controlled frequency and pulse
width. Such a device might be used, for example, to perform
pulse-width modulated output or frequency/pulse-count modulated
output (such as might be needed to control a stepper motor).
pulse-width modulated output. Finite pulse-count output is provided
through the separate pulsecount driver interface.

The NuttX PWM driver is split into two parts:

Expand Down Expand Up @@ -209,3 +209,7 @@ wait for an end of cycle.

The ``CONFIG_PWM_DEADTIME`` option brings the possibility to introduce
dead time values between complementary PWM outputs.

Finite pulse trains are not configured through ``pwm_info_s``. Use the
:doc:`pulsecount <pulsecount>` driver for hardware that supports a fixed pulse
count.
116 changes: 107 additions & 9 deletions arch/arm/src/at32/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -1052,7 +1052,6 @@ config AT32_TIM
config AT32_PWM
bool
default n
select ARCH_HAVE_PWM_PULSECOUNT

config AT32_CAP
bool
Expand Down Expand Up @@ -1108,7 +1107,6 @@ config ARCH_BOARD_AT32_CUSTOM_CLOCKCONFIG
---help---
Enables special, board-specific AT32 clock configuration.


config AT32_DMACAPABLE
bool "Workaround non-DMA capable memory"
depends on ARCH_DMA
Expand Down Expand Up @@ -3662,6 +3660,113 @@ config AT32_PWM_TRGO
---help---
Enable TRGO support for PWM driver

config AT32_PULSECOUNT
bool
default n
select ARCH_HAVE_PULSECOUNT
select PULSECOUNT

config AT32_TIM1_PULSECOUNT
bool "TIM1 pulse count"
default n
depends on AT32_TIM1
select AT32_PULSECOUNT
---help---
Reserve timer 1 for pulse count output.

if AT32_TIM1_PULSECOUNT

config AT32_TIM1_PULSECOUNT_TDTS
int "TIM1 pulse count clock division"
default 0
range 0 2

config AT32_TIM1_PULSECOUNT_CHANNEL
int "TIM1 pulse count channel"
default 1
range 1 4
---help---
Specifies the timer channel {1,..,4}.

config AT32_TIM1_PULSECOUNT_POL
int "TIM1 pulse count output polarity"
default 0
range 0 1

config AT32_TIM1_PULSECOUNT_IDLE
int "TIM1 pulse count idle state"
default 0
range 0 1

endif # AT32_TIM1_PULSECOUNT

config AT32_TIM8_PULSECOUNT
bool "TIM8 pulse count"
default n
depends on AT32_TIM8
select AT32_PULSECOUNT
---help---
Reserve timer 8 for pulse count output.

if AT32_TIM8_PULSECOUNT

config AT32_TIM8_PULSECOUNT_TDTS
int "TIM8 pulse count clock division"
default 0
range 0 2

config AT32_TIM8_PULSECOUNT_CHANNEL
int "TIM8 pulse count channel"
default 1
range 1 4
---help---
Specifies the timer channel {1,..,4}.

config AT32_TIM8_PULSECOUNT_POL
int "TIM8 pulse count output polarity"
default 0
range 0 1

config AT32_TIM8_PULSECOUNT_IDLE
int "TIM8 pulse count idle state"
default 0
range 0 1

endif # AT32_TIM8_PULSECOUNT

config AT32_TIM20_PULSECOUNT
bool "TIM20 pulse count"
default n
depends on AT32_TIM20
select AT32_PULSECOUNT
---help---
Reserve timer 20 for pulse count output.

if AT32_TIM20_PULSECOUNT

config AT32_TIM20_PULSECOUNT_TDTS
int "TIM20 pulse count clock division"
default 0
range 0 2

config AT32_TIM20_PULSECOUNT_CHANNEL
int "TIM20 pulse count channel"
default 1
range 1 4
---help---
Specifies the timer channel {1,..,4}.

config AT32_TIM20_PULSECOUNT_POL
int "TIM20 pulse count output polarity"
default 0
range 0 1

config AT32_TIM20_PULSECOUNT_IDLE
int "TIM20 pulse count idle state"
default 0
range 0 1

endif # AT32_TIM20_PULSECOUNT
config AT32_TIM1_ADC
bool "TIM1 ADC"
default n
Expand Down Expand Up @@ -6008,7 +6113,6 @@ config AT32_ADC5_JEXTSEL

endmenu


config AT32_USART
bool
default n
Expand Down Expand Up @@ -6807,7 +6911,6 @@ config AT32_HCIUART_RXDMAPRIO
---help---
Select HCI UART DMA priority.


config AT32_HCIUART_SW_RXFLOW
bool "Use Software UART RTS flow control"
default n
Expand Down Expand Up @@ -6940,7 +7043,6 @@ config AT32_SPI4_DMA_BUFFER

endmenu # SPI Configuration


menu "I2C Configuration"
depends on AT32_I2C

Expand Down Expand Up @@ -7027,7 +7129,6 @@ config AT32_SDIO_DMAPRIO
For AT32 , options are: 0x00000000 low, 0x00001000 medium,
0x00002000 high, 0x00003000 very high. Default: medium.


config AT32_SDIO_WIDTH_D1_ONLY
bool "Use D1 only"
default n
Expand All @@ -7036,7 +7137,6 @@ config AT32_SDIO_WIDTH_D1_ONLY

endmenu


config AT32_HAVE_RTC_COUNTER
bool
default n
Expand Down Expand Up @@ -7433,7 +7533,6 @@ config OTG_ID_GPIO_DISABLE

endmenu


menu "CAN driver configuration"
depends on AT32_CAN

Expand Down Expand Up @@ -7488,7 +7587,6 @@ config AT32_CAN_REGDEBUG

endmenu # "CAN driver configuration"


menu "AT32 QEncoder Driver"
depends on SENSORS_QENCODER
depends on AT32_TIM1 || AT32_TIM2 || AT32_TIM3 || AT32_TIM4 || AT32_TIM5 || AT32_TIM8
Expand Down
5 changes: 4 additions & 1 deletion arch/arm/src/at32/Make.defs
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,10 @@ ifeq ($(CONFIG_AT32_PWM),y)
CHIP_CSRCS += at32_pwm.c
endif

ifeq ($(CONFIG_AT32_PULSECOUNT),y)
CHIP_CSRCS += at32_pulsecount.c
endif

ifeq ($(CONFIG_AT32_CAP),y)
CHIP_CSRCS += at32_capture_lowerhalf.c
endif
Expand Down Expand Up @@ -180,4 +184,3 @@ ifeq ($(CONFIG_AT32_FOC),y)
CHIP_CSRCS += at32_foc.c
endif


Loading
Loading