Zephyr API Documentation  2.7.0-rc2
A Scalable Open Source RTOS
pwm.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2016 Intel Corporation.
3 * Copyright (c) 2020-2021 Vestas Wind Systems A/S
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
13#ifndef ZEPHYR_INCLUDE_DRIVERS_PWM_H_
14#define ZEPHYR_INCLUDE_DRIVERS_PWM_H_
15
23#include <errno.h>
24#include <zephyr/types.h>
25#include <stddef.h>
26#include <sys/math_extras.h>
27#include <device.h>
28#include <dt-bindings/pwm/pwm.h>
29
30#ifdef __cplusplus
31extern "C" {
32#endif
33
40/* Bit 0 is used for PWM_POLARITY_NORMAL/PWM_POLARITY_INVERTED */
41#define PWM_CAPTURE_TYPE_SHIFT 1U
42#define PWM_CAPTURE_TYPE_MASK (3U << PWM_CAPTURE_TYPE_SHIFT)
43#define PWM_CAPTURE_MODE_SHIFT 3U
44#define PWM_CAPTURE_MODE_MASK (1U << PWM_CAPTURE_MODE_SHIFT)
48#define PWM_CAPTURE_TYPE_PERIOD (1U << PWM_CAPTURE_TYPE_SHIFT)
49
51#define PWM_CAPTURE_TYPE_PULSE (2U << PWM_CAPTURE_TYPE_SHIFT)
52
54#define PWM_CAPTURE_TYPE_BOTH (PWM_CAPTURE_TYPE_PERIOD | \
55 PWM_CAPTURE_TYPE_PULSE)
56
58#define PWM_CAPTURE_MODE_SINGLE (0U << PWM_CAPTURE_MODE_SHIFT)
59
61#define PWM_CAPTURE_MODE_CONTINUOUS (1U << PWM_CAPTURE_MODE_SHIFT)
62
69
75typedef int (*pwm_pin_set_t)(const struct device *dev, uint32_t pwm,
76 uint32_t period_cycles, uint32_t pulse_cycles,
78
99typedef void (*pwm_capture_callback_handler_t)(const struct device *dev,
100 uint32_t pwm,
101 uint32_t period_cycles,
102 uint32_t pulse_cycles,
103 int status,
104 void *user_data);
105
111typedef int (*pwm_pin_configure_capture_t)(const struct device *dev,
112 uint32_t pwm,
115 void *user_data);
121typedef int (*pwm_pin_enable_capture_t)(const struct device *dev,
122 uint32_t pwm);
123
129typedef int (*pwm_pin_disable_capture_t)(const struct device *dev,
130 uint32_t pwm);
131
137typedef int (*pwm_get_cycles_per_sec_t)(const struct device *dev,
138 uint32_t pwm,
139 uint64_t *cycles);
140
142__subsystem struct pwm_driver_api {
144#ifdef CONFIG_PWM_CAPTURE
148#endif /* CONFIG_PWM_CAPTURE */
150};
151
181__syscall int pwm_pin_set_cycles(const struct device *dev, uint32_t pwm,
182 uint32_t period, uint32_t pulse, pwm_flags_t flags);
183
184static inline int z_impl_pwm_pin_set_cycles(const struct device *dev,
185 uint32_t pwm,
186 uint32_t period, uint32_t pulse,
188{
189 struct pwm_driver_api *api;
190
191 api = (struct pwm_driver_api *)dev->api;
192 return api->pin_set(dev, pwm, period, pulse, flags);
193}
194
223#ifdef CONFIG_PWM_CAPTURE
224static inline int pwm_pin_configure_capture(const struct device *dev,
225 uint32_t pwm,
228 void *user_data)
229{
230 const struct pwm_driver_api *api = (struct pwm_driver_api *)dev->api;
231
232 if (api->pin_configure_capture == NULL) {
233 return -ENOSYS;
234 }
235
236 return api->pin_configure_capture(dev, pwm, flags, cb, user_data);
237}
238#endif /* CONFIG_PWM_CAPTURE */
239
258__syscall int pwm_pin_enable_capture(const struct device *dev, uint32_t pwm);
259
260#ifdef CONFIG_PWM_CAPTURE
261static inline int z_impl_pwm_pin_enable_capture(const struct device *dev,
262 uint32_t pwm)
263{
264 const struct pwm_driver_api *api = (struct pwm_driver_api *)dev->api;
265
266 if (api->pin_enable_capture == NULL) {
267 return -ENOSYS;
268 }
269
270 return api->pin_enable_capture(dev, pwm);
271}
272#endif /* CONFIG_PWM_CAPTURE */
273
289__syscall int pwm_pin_disable_capture(const struct device *dev, uint32_t pwm);
290
291#ifdef CONFIG_PWM_CAPTURE
292static inline int z_impl_pwm_pin_disable_capture(const struct device *dev,
293 uint32_t pwm)
294{
295 const struct pwm_driver_api *api = (struct pwm_driver_api *)dev->api;
296
297 if (api->pin_disable_capture == NULL) {
298 return -ENOSYS;
299 }
300
301 return api->pin_disable_capture(dev, pwm);
302}
303#endif /* CONFIG_PWM_CAPTURE */
304
332__syscall int pwm_pin_capture_cycles(const struct device *dev, uint32_t pwm,
334 uint32_t *period,
335 uint32_t *pulse,
337
349__syscall int pwm_get_cycles_per_sec(const struct device *dev, uint32_t pwm,
350 uint64_t *cycles);
351
352static inline int z_impl_pwm_get_cycles_per_sec(const struct device *dev,
353 uint32_t pwm,
354 uint64_t *cycles)
355{
356 struct pwm_driver_api *api;
357
358 api = (struct pwm_driver_api *)dev->api;
359 return api->get_cycles_per_sec(dev, pwm, cycles);
360}
361
374static inline int pwm_pin_set_usec(const struct device *dev, uint32_t pwm,
375 uint32_t period, uint32_t pulse,
377{
378 uint64_t period_cycles, pulse_cycles, cycles_per_sec;
379
380 if (pwm_get_cycles_per_sec(dev, pwm, &cycles_per_sec) != 0) {
381 return -EIO;
382 }
383
384 period_cycles = (period * cycles_per_sec) / USEC_PER_SEC;
385 if (period_cycles >= ((uint64_t)1 << 32)) {
386 return -ENOTSUP;
387 }
388
389 pulse_cycles = (pulse * cycles_per_sec) / USEC_PER_SEC;
390 if (pulse_cycles >= ((uint64_t)1 << 32)) {
391 return -ENOTSUP;
392 }
393
394 return pwm_pin_set_cycles(dev, pwm, (uint32_t)period_cycles,
395 (uint32_t)pulse_cycles, flags);
396}
397
410static inline int pwm_pin_set_nsec(const struct device *dev, uint32_t pwm,
411 uint32_t period, uint32_t pulse,
413{
414 uint64_t period_cycles, pulse_cycles, cycles_per_sec;
415
416 if (pwm_get_cycles_per_sec(dev, pwm, &cycles_per_sec) != 0) {
417 return -EIO;
418 }
419
420 period_cycles = (period * cycles_per_sec) / NSEC_PER_SEC;
421 if (period_cycles >= ((uint64_t)1 << 32)) {
422 return -ENOTSUP;
423 }
424
425 pulse_cycles = (pulse * cycles_per_sec) / NSEC_PER_SEC;
426 if (pulse_cycles >= ((uint64_t)1 << 32)) {
427 return -ENOTSUP;
428 }
429
430 return pwm_pin_set_cycles(dev, pwm, (uint32_t)period_cycles,
431 (uint32_t)pulse_cycles, flags);
432}
433
446static inline int pwm_pin_cycles_to_usec(const struct device *dev, uint32_t pwm,
447 uint32_t cycles, uint64_t *usec)
448{
449 uint64_t cycles_per_sec;
450 uint64_t temp;
451
452 if (pwm_get_cycles_per_sec(dev, pwm, &cycles_per_sec) != 0) {
453 return -EIO;
454 }
455
456 if (u64_mul_overflow(cycles, (uint64_t)USEC_PER_SEC, &temp)) {
457 return -ERANGE;
458 }
459
460 *usec = temp / cycles_per_sec;
461
462 return 0;
463}
464
477static inline int pwm_pin_cycles_to_nsec(const struct device *dev, uint32_t pwm,
478 uint32_t cycles, uint64_t *nsec)
479{
480 uint64_t cycles_per_sec;
481 uint64_t temp;
482
483 if (pwm_get_cycles_per_sec(dev, pwm, &cycles_per_sec) != 0) {
484 return -EIO;
485 }
486
487 if (u64_mul_overflow(cycles, (uint64_t)NSEC_PER_SEC, &temp)) {
488 return -ERANGE;
489 }
490
491 *nsec = temp / cycles_per_sec;
492
493 return 0;
494}
495
523static inline int pwm_pin_capture_usec(const struct device *dev, uint32_t pwm,
525 uint64_t *period,
526 uint64_t *pulse,
528{
529 uint32_t period_cycles;
530 uint32_t pulse_cycles;
531 int err;
532
533 err = pwm_pin_capture_cycles(dev, pwm, flags, &period_cycles,
534 &pulse_cycles, timeout);
535 if (err) {
536 return err;
537 }
538
539 err = pwm_pin_cycles_to_usec(dev, pwm, period_cycles, period);
540 if (err) {
541 return err;
542 }
543
544 err = pwm_pin_cycles_to_usec(dev, pwm, pulse_cycles, pulse);
545 if (err) {
546 return err;
547 }
548
549 return 0;
550}
551
579static inline int pwm_pin_capture_nsec(const struct device *dev, uint32_t pwm,
581 uint64_t *period,
582 uint64_t *pulse,
584{
585 uint32_t period_cycles;
586 uint32_t pulse_cycles;
587 int err;
588
589 err = pwm_pin_capture_cycles(dev, pwm, flags, &period_cycles,
590 &pulse_cycles, timeout);
591 if (err) {
592 return err;
593 }
594
595 err = pwm_pin_cycles_to_nsec(dev, pwm, period_cycles, period);
596 if (err) {
597 return err;
598 }
599
600 err = pwm_pin_cycles_to_nsec(dev, pwm, pulse_cycles, pulse);
601 if (err) {
602 return err;
603 }
604
605 return 0;
606}
607
608#ifdef __cplusplus
609}
610#endif
611
616#include <syscalls/pwm.h>
617
618#endif /* ZEPHYR_INCLUDE_DRIVERS_PWM_H_ */
ZTEST_BMEM int timeout
Definition: main.c:31
System error numbers.
void
Definition: eswifi_shell.c:15
int pwm_get_cycles_per_sec(const struct device *dev, uint32_t pwm, uint64_t *cycles)
Get the clock rate (cycles per second) for a single PWM output.
uint8_t pwm_flags_t
Provides a type to hold PWM configuration flags.
Definition: pwm.h:68
int pwm_pin_capture_cycles(const struct device *dev, uint32_t pwm, pwm_flags_t flags, uint32_t *period, uint32_t *pulse, k_timeout_t timeout)
Capture a single PWM period/pulse width in clock cycles for a single PWM input.
static int pwm_pin_capture_nsec(const struct device *dev, uint32_t pwm, pwm_flags_t flags, uint64_t *period, uint64_t *pulse, k_timeout_t timeout)
Capture a single PWM period/pulse width in nanoseconds for a single PWM input.
Definition: pwm.h:579
static int pwm_pin_cycles_to_nsec(const struct device *dev, uint32_t pwm, uint32_t cycles, uint64_t *nsec)
Convert from PWM cycles to nanoseconds.
Definition: pwm.h:477
int(* pwm_get_cycles_per_sec_t)(const struct device *dev, uint32_t pwm, uint64_t *cycles)
Callback API upon getting cycles per second See pwm_get_cycles_per_sec() for argument description.
Definition: pwm.h:137
static int pwm_pin_configure_capture(const struct device *dev, uint32_t pwm, pwm_flags_t flags, pwm_capture_callback_handler_t cb, void *user_data)
Configure PWM period/pulse width capture for a single PWM input.
Definition: pwm.h:224
static int pwm_pin_set_usec(const struct device *dev, uint32_t pwm, uint32_t period, uint32_t pulse, pwm_flags_t flags)
Set the period and pulse width for a single PWM output.
Definition: pwm.h:374
int(* pwm_pin_enable_capture_t)(const struct device *dev, uint32_t pwm)
Callback API upon enabling PWM pin capture See pwm_pin_enable_capture() for argument description.
Definition: pwm.h:121
int pwm_pin_set_cycles(const struct device *dev, uint32_t pwm, uint32_t period, uint32_t pulse, pwm_flags_t flags)
Set the period and pulse width for a single PWM output.
int pwm_pin_enable_capture(const struct device *dev, uint32_t pwm)
Enable PWM period/pulse width capture for a single PWM input.
static int pwm_pin_capture_usec(const struct device *dev, uint32_t pwm, pwm_flags_t flags, uint64_t *period, uint64_t *pulse, k_timeout_t timeout)
Capture a single PWM period/pulse width in microseconds for a single PWM input.
Definition: pwm.h:523
void(* pwm_capture_callback_handler_t)(const struct device *dev, uint32_t pwm, uint32_t period_cycles, uint32_t pulse_cycles, int status, void *user_data)
PWM capture callback handler function signature.
Definition: pwm.h:99
static int pwm_pin_cycles_to_usec(const struct device *dev, uint32_t pwm, uint32_t cycles, uint64_t *usec)
Convert from PWM cycles to microseconds.
Definition: pwm.h:446
int(* pwm_pin_set_t)(const struct device *dev, uint32_t pwm, uint32_t period_cycles, uint32_t pulse_cycles, pwm_flags_t flags)
Callback API upon setting the pin See pwm_pin_set_cycles() for argument description.
Definition: pwm.h:75
int pwm_pin_disable_capture(const struct device *dev, uint32_t pwm)
Disable PWM period/pulse width capture for a single PWM input.
int(* pwm_pin_configure_capture_t)(const struct device *dev, uint32_t pwm, pwm_flags_t flags, pwm_capture_callback_handler_t cb, void *user_data)
Callback API upon configuring PWM pin capture See pwm_pin_configure_capture() for argument descriptio...
Definition: pwm.h:111
static int pwm_pin_set_nsec(const struct device *dev, uint32_t pwm, uint32_t period, uint32_t pulse, pwm_flags_t flags)
Set the period and pulse width for a single PWM output.
Definition: pwm.h:410
int(* pwm_pin_disable_capture_t)(const struct device *dev, uint32_t pwm)
Callback API upon disabling PWM pin capture See pwm_pin_disable_capture() for argument description.
Definition: pwm.h:129
#define ENOSYS
Definition: errno.h:83
#define EIO
Definition: errno.h:44
#define ENOTSUP
Definition: errno.h:115
#define ERANGE
Definition: errno.h:73
flags
Definition: http_parser.h:131
#define NSEC_PER_SEC
Definition: sys_clock.h:136
#define USEC_PER_SEC
Definition: sys_clock.h:133
Extra arithmetic and bit manipulation functions.
static bool u64_mul_overflow(uint64_t a, uint64_t b, uint64_t *result)
__UINT32_TYPE__ uint32_t
Definition: stdint.h:60
__UINT64_TYPE__ uint64_t
Definition: stdint.h:61
__UINT8_TYPE__ uint8_t
Definition: stdint.h:58
Runtime device structure (in ROM) per driver instance.
Definition: device.h:367
const void * api
Definition: device.h:373
Kernel timeout type.
Definition: sys_clock.h:65
PWM driver API definition.
Definition: pwm.h:142
pwm_pin_disable_capture_t pin_disable_capture
Definition: pwm.h:147
pwm_get_cycles_per_sec_t get_cycles_per_sec
Definition: pwm.h:149
pwm_pin_configure_capture_t pin_configure_capture
Definition: pwm.h:145
pwm_pin_set_t pin_set
Definition: pwm.h:143
pwm_pin_enable_capture_t pin_enable_capture
Definition: pwm.h:146
static const intptr_t user_data[5]
Definition: main.c:590