Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 | /* * Copyright (c) 2016 Intel Corporation. * * SPDX-License-Identifier: Apache-2.0 */ /** * @file * @brief Public PWM Driver APIs */ #ifndef ZEPHYR_INCLUDE_DRIVERS_PWM_H_ #define ZEPHYR_INCLUDE_DRIVERS_PWM_H_ /** * @brief PWM Interface * @defgroup pwm_interface PWM Interface * @ingroup io_interfaces * @{ */ #include <errno.h> #include <zephyr/types.h> #include <stddef.h> #include <device.h> #ifdef __cplusplus extern "C" { #endif /** * @typedef pwm_pin_set_t * @brief Callback API upon setting the pin * See @a pwm_pin_set_cycles() for argument description */ typedef int (*pwm_pin_set_t)(struct device *dev, u32_t pwm, u32_t period_cycles, u32_t pulse_cycles); /** * @typedef pwm_get_cycles_per_sec_t * @brief Callback API upon getting cycles per second * See @a pwm_get_cycles_per_sec() for argument description */ typedef int (*pwm_get_cycles_per_sec_t)(struct device *dev, u32_t pwm, u64_t *cycles); /** @brief PWM driver API definition. */ struct pwm_driver_api { pwm_pin_set_t pin_set; pwm_get_cycles_per_sec_t get_cycles_per_sec; }; /** * @brief Set the period and pulse width for a single PWM output. * * @param dev Pointer to the device structure for the driver instance. * @param pwm PWM pin. * @param period Period (in clock cycle) set to the PWM. HW specific. * @param pulse Pulse width (in clock cycle) set to the PWM. HW specific. * * @retval 0 If successful. * @retval Negative errno code if failure. */ __syscall int pwm_pin_set_cycles(struct device *dev, u32_t pwm, u32_t period, u32_t pulse); static inline int z_impl_pwm_pin_set_cycles(struct device *dev, u32_t pwm, u32_t period, u32_t pulse) { struct pwm_driver_api *api; api = (struct pwm_driver_api *)dev->driver_api; return api->pin_set(dev, pwm, period, pulse); } /** * @brief Get the clock rate (cycles per second) for a single PWM output. * * @param dev Pointer to the device structure for the driver instance. * @param pwm PWM pin. * @param cycles Pointer to the memory to store clock rate (cycles per sec). * HW specific. * * @retval 0 If successful. * @retval Negative errno code if failure. */ __syscall int pwm_get_cycles_per_sec(struct device *dev, u32_t pwm, u64_t *cycles); static inline int z_impl_pwm_get_cycles_per_sec(struct device *dev, u32_t pwm, u64_t *cycles) { struct pwm_driver_api *api; api = (struct pwm_driver_api *)dev->driver_api; return api->get_cycles_per_sec(dev, pwm, cycles); } /** * @brief Set the period and pulse width for a single PWM output. * * @param dev Pointer to the device structure for the driver instance. * @param pwm PWM pin. * @param period Period (in microseconds) set to the PWM. * @param pulse Pulse width (in microseconds) set to the PWM. * * @retval 0 If successful. * @retval Negative errno code if failure. */ static inline int pwm_pin_set_usec(struct device *dev, u32_t pwm, u32_t period, u32_t pulse) { u64_t period_cycles, pulse_cycles, cycles_per_sec; if (pwm_get_cycles_per_sec(dev, pwm, &cycles_per_sec) != 0) { return -EIO; } period_cycles = (period * cycles_per_sec) / USEC_PER_SEC; if (period_cycles >= ((u64_t)1 << 32)) { return -ENOTSUP; } pulse_cycles = (pulse * cycles_per_sec) / USEC_PER_SEC; if (pulse_cycles >= ((u64_t)1 << 32)) { return -ENOTSUP; } return pwm_pin_set_cycles(dev, pwm, (u32_t)period_cycles, (u32_t)pulse_cycles); } /** * @brief Set the period and pulse width for a single PWM output. * * @param dev Pointer to the device structure for the driver instance. * @param pwm PWM pin. * @param period Period (in nanoseconds) set to the PWM. * @param pulse Pulse width (in nanoseconds) set to the PWM. * * @retval 0 If successful. * @retval Negative errno code if failure. */ static inline int pwm_pin_set_nsec(struct device *dev, u32_t pwm, u32_t period, u32_t pulse) { u64_t period_cycles, pulse_cycles, cycles_per_sec; if (pwm_get_cycles_per_sec(dev, pwm, &cycles_per_sec) != 0) { return -EIO; } period_cycles = (period * cycles_per_sec) / NSEC_PER_SEC; if (period_cycles >= ((u64_t)1 << 32)) { return -ENOTSUP; } pulse_cycles = (pulse * cycles_per_sec) / NSEC_PER_SEC; if (pulse_cycles >= ((u64_t)1 << 32)) { return -ENOTSUP; } return pwm_pin_set_cycles(dev, pwm, (u32_t)period_cycles, (u32_t)pulse_cycles); } #ifdef __cplusplus } #endif /** * @} */ #include <syscalls/pwm.h> #endif /* ZEPHYR_INCLUDE_DRIVERS_PWM_H_ */ |