ChibiOS 21.11.4
hal_pwm.h
Go to the documentation of this file.
1/*
2 ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15*/
16
17/**
18 * @file hal_pwm.h
19 * @brief PWM Driver macros and structures.
20 *
21 * @addtogroup PWM
22 * @{
23 */
24
25#ifndef HAL_PWM_H
26#define HAL_PWM_H
27
28#if (HAL_USE_PWM == TRUE) || defined(__DOXYGEN__)
29
30/*===========================================================================*/
31/* Driver constants. */
32/*===========================================================================*/
33
34/**
35 * @name PWM output mode macros
36 * @{
37 */
38/**
39 * @brief Standard output modes mask.
40 */
41#define PWM_OUTPUT_MASK 0x0FU
42
43/**
44 * @brief Output not driven, callback only.
45 */
46#define PWM_OUTPUT_DISABLED 0x00U
47
48/**
49 * @brief Positive PWM logic, active is logic level one.
50 */
51#define PWM_OUTPUT_ACTIVE_HIGH 0x01U
52
53/**
54 * @brief Inverse PWM logic, active is logic level zero.
55 */
56#define PWM_OUTPUT_ACTIVE_LOW 0x02U
57/** @} */
58
59/*===========================================================================*/
60/* Driver pre-compile time settings. */
61/*===========================================================================*/
62
63/*===========================================================================*/
64/* Derived constants and error checks. */
65/*===========================================================================*/
66
67/*===========================================================================*/
68/* Driver data structures and types. */
69/*===========================================================================*/
70
71/**
72 * @brief Driver state machine possible states.
73 */
74typedef enum {
75 PWM_UNINIT = 0, /**< Not initialized. */
76 PWM_STOP = 1, /**< Stopped. */
77 PWM_READY = 2 /**< Ready. */
79
80/**
81 * @brief Type of a structure representing a PWM driver.
82 */
83typedef struct PWMDriver PWMDriver;
84
85/**
86 * @brief Type of a PWM notification callback.
87 *
88 * @param[in] pwmp pointer to a @p PWMDriver object
89 */
90typedef void (*pwmcallback_t)(PWMDriver *pwmp);
91
92#include "hal_pwm_lld.h"
93
94/*===========================================================================*/
95/* Driver macros. */
96/*===========================================================================*/
97
98/**
99 * @name PWM duty cycle conversion
100 * @{
101 */
102/**
103 * @brief Converts from fraction to pulse width.
104 * @note Be careful with rounding errors, this is integer math not magic.
105 * You can specify tenths of thousandth but make sure you have the
106 * proper hardware resolution by carefully choosing the clock source
107 * and prescaler settings, see @p PWM_COMPUTE_PSC.
108 *
109 * @param[in] pwmp pointer to a @p PWMDriver object
110 * @param[in] denominator denominator of the fraction
111 * @param[in] numerator numerator of the fraction
112 * @return The pulse width to be passed to @p pwmEnableChannel().
113 *
114 * @api
115 */
116#define PWM_FRACTION_TO_WIDTH(pwmp, denominator, numerator) \
117 ((pwmcnt_t)((((pwmcnt_t)(pwmp)->period) * \
118 (pwmcnt_t)(numerator)) / (pwmcnt_t)(denominator)))
119
120/**
121 * @brief Converts from degrees to pulse width.
122 * @note Be careful with rounding errors, this is integer math not magic.
123 * You can specify hundredths of degrees but make sure you have the
124 * proper hardware resolution by carefully choosing the clock source
125 * and prescaler settings, see @p PWM_COMPUTE_PSC.
126 *
127 * @param[in] pwmp pointer to a @p PWMDriver object
128 * @param[in] degrees degrees as an integer between 0 and 36000
129 * @return The pulse width to be passed to @p pwmEnableChannel().
130 *
131 * @api
132 */
133#define PWM_DEGREES_TO_WIDTH(pwmp, degrees) \
134 PWM_FRACTION_TO_WIDTH(pwmp, 36000, degrees)
135
136/**
137 * @brief Converts from percentage to pulse width.
138 * @note Be careful with rounding errors, this is integer math not magic.
139 * You can specify tenths of thousandth but make sure you have the
140 * proper hardware resolution by carefully choosing the clock source
141 * and prescaler settings, see @p PWM_COMPUTE_PSC.
142 *
143 * @param[in] pwmp pointer to a @p PWMDriver object
144 * @param[in] percentage percentage as an integer between 0 and 10000
145 * @return The pulse width to be passed to @p pwmEnableChannel().
146 *
147 * @api
148 */
149#define PWM_PERCENTAGE_TO_WIDTH(pwmp, percentage) \
150 PWM_FRACTION_TO_WIDTH(pwmp, 10000, percentage)
151/** @} */
152
153/**
154 * @name Macro Functions
155 * @{
156 */
157/**
158 * @brief Changes the period the PWM peripheral.
159 * @details This function changes the period of a PWM unit that has already
160 * been activated using @p pwmStart().
161 * @pre The PWM unit must have been activated using @p pwmStart().
162 * @post The PWM unit period is changed to the new value.
163 * @note If a period is specified that is shorter than the pulse width
164 * programmed in one of the channels then the behavior is not
165 * guaranteed.
166 *
167 * @param[in] pwmp pointer to a @p PWMDriver object
168 * @param[in] value new cycle time in ticks
169 *
170 * @iclass
171 */
172#define pwmChangePeriodI(pwmp, value) { \
173 (pwmp)->period = (value); \
174 pwm_lld_change_period(pwmp, value); \
175}
176
177/**
178 * @brief Enables a PWM channel.
179 * @pre The PWM unit must have been activated using @p pwmStart().
180 * @post The channel is active using the specified configuration.
181 * @note Depending on the hardware implementation this function has
182 * effect starting on the next cycle (recommended implementation)
183 * or immediately (fallback implementation).
184 *
185 * @param[in] pwmp pointer to a @p PWMDriver object
186 * @param[in] channel PWM channel identifier (0...channels-1)
187 * @param[in] width PWM pulse width as clock pulses number
188 *
189 * @iclass
190 */
191#define pwmEnableChannelI(pwmp, channel, width) do { \
192 (pwmp)->enabled |= ((pwmchnmsk_t)1U << (pwmchnmsk_t)(channel)); \
193 pwm_lld_enable_channel(pwmp, channel, width); \
194} while (false)
195
196/**
197 * @brief Disables a PWM channel.
198 * @pre The PWM unit must have been activated using @p pwmStart().
199 * @post The channel is disabled and its output line returned to the
200 * idle state.
201 * @note Depending on the hardware implementation this function has
202 * effect starting on the next cycle (recommended implementation)
203 * or immediately (fallback implementation).
204 *
205 * @param[in] pwmp pointer to a @p PWMDriver object
206 * @param[in] channel PWM channel identifier (0...channels-1)
207 *
208 * @iclass
209 */
210#define pwmDisableChannelI(pwmp, channel) do { \
211 (pwmp)->enabled &= ~((pwmchnmsk_t)1U << (pwmchnmsk_t)(channel)); \
212 pwm_lld_disable_channel(pwmp, channel); \
213} while (false)
214
215/**
216 * @brief Returns a PWM channel status.
217 * @pre The PWM unit must have been activated using @p pwmStart().
218 *
219 * @param[in] pwmp pointer to a @p PWMDriver object
220 * @param[in] channel PWM channel identifier (0...channels-1)
221 *
222 * @iclass
223 */
224#define pwmIsChannelEnabledI(pwmp, channel) \
225 (((pwmp)->enabled & ((pwmchnmsk_t)1U << (pwmchnmsk_t)(channel))) != 0U)
226
227/**
228 * @brief Enables the periodic activation edge notification.
229 * @pre The PWM unit must have been activated using @p pwmStart().
230 * @note If the notification is already enabled then the call has no effect.
231 *
232 * @param[in] pwmp pointer to a @p PWMDriver object
233 *
234 * @iclass
235 */
236#define pwmEnablePeriodicNotificationI(pwmp) \
237 pwm_lld_enable_periodic_notification(pwmp)
238
239/**
240 * @brief Disables the periodic activation edge notification.
241 * @pre The PWM unit must have been activated using @p pwmStart().
242 * @note If the notification is already disabled then the call has no effect.
243 *
244 * @param[in] pwmp pointer to a @p PWMDriver object
245 *
246 * @iclass
247 */
248#define pwmDisablePeriodicNotificationI(pwmp) \
249 pwm_lld_disable_periodic_notification(pwmp)
250
251/**
252 * @brief Enables a channel de-activation edge notification.
253 * @pre The PWM unit must have been activated using @p pwmStart().
254 * @pre The channel must have been activated using @p pwmEnableChannel().
255 * @note If the notification is already enabled then the call has no effect.
256 *
257 * @param[in] pwmp pointer to a @p PWMDriver object
258 * @param[in] channel PWM channel identifier (0...channels-1)
259 *
260 * @iclass
261 */
262#define pwmEnableChannelNotificationI(pwmp, channel) \
263 pwm_lld_enable_channel_notification(pwmp, channel)
264
265/**
266 * @brief Disables a channel de-activation edge notification.
267 * @pre The PWM unit must have been activated using @p pwmStart().
268 * @pre The channel must have been activated using @p pwmEnableChannel().
269 * @note If the notification is already disabled then the call has no effect.
270 *
271 * @param[in] pwmp pointer to a @p PWMDriver object
272 * @param[in] channel PWM channel identifier (0...channels-1)
273 *
274 * @iclass
275 */
276#define pwmDisableChannelNotificationI(pwmp, channel) \
277 pwm_lld_disable_channel_notification(pwmp, channel)
278/** @} */
279
280/*===========================================================================*/
281/* External declarations. */
282/*===========================================================================*/
283
284#ifdef __cplusplus
285extern "C" {
286#endif
287 void pwmInit(void);
288 void pwmObjectInit(PWMDriver *pwmp);
289 msg_t pwmStart(PWMDriver *pwmp, const PWMConfig *config);
290 void pwmStop(PWMDriver *pwmp);
292 void pwmEnableChannel(PWMDriver *pwmp,
293 pwmchannel_t channel,
294 pwmcnt_t width);
295 void pwmDisableChannel(PWMDriver *pwmp, pwmchannel_t channel);
300#ifdef __cplusplus
301}
302#endif
303
304#endif /* HAL_USE_PWM == TRUE */
305
306#endif /* HAL_PWM_H */
307
308/** @} */
void pwmDisablePeriodicNotification(PWMDriver *pwmp)
Disables the periodic activation edge notification.
Definition hal_pwm.c:259
void pwmInit(void)
PWM Driver initialization.
Definition hal_pwm.c:56
void pwmEnablePeriodicNotification(PWMDriver *pwmp)
Enables the periodic activation edge notification.
Definition hal_pwm.c:236
uint32_t pwmcnt_t
Type of a PWM counter.
Definition hal_pwm_lld.h:83
void pwmObjectInit(PWMDriver *pwmp)
Initializes the standard part of a PWMDriver structure.
Definition hal_pwm.c:68
uint8_t pwmchannel_t
Type of a PWM channel.
Definition hal_pwm_lld.h:73
void pwmStop(PWMDriver *pwmp)
Deactivates the PWM peripheral.
Definition hal_pwm.c:129
void(* pwmcallback_t)(PWMDriver *pwmp)
Type of a PWM notification callback.
Definition hal_pwm.h:90
msg_t pwmStart(PWMDriver *pwmp, const PWMConfig *config)
Configures and activates the PWM peripheral.
Definition hal_pwm.c:90
pwmstate_t
Driver state machine possible states.
Definition hal_pwm.h:74
void pwmEnableChannelNotification(PWMDriver *pwmp, pwmchannel_t channel)
Enables a channel de-activation edge notification.
Definition hal_pwm.c:284
void pwmDisableChannel(PWMDriver *pwmp, pwmchannel_t channel)
Disables a PWM channel and its notification.
Definition hal_pwm.c:214
void pwmDisableChannelNotification(PWMDriver *pwmp, pwmchannel_t channel)
Disables a channel de-activation edge notification.
Definition hal_pwm.c:312
void pwmChangePeriod(PWMDriver *pwmp, pwmcnt_t period)
Changes the period the PWM peripheral.
Definition hal_pwm.c:161
void pwmEnableChannel(PWMDriver *pwmp, pwmchannel_t channel, pwmcnt_t width)
Enables a PWM channel.
Definition hal_pwm.c:185
@ PWM_READY
Definition hal_pwm.h:77
@ PWM_STOP
Definition hal_pwm.h:76
@ PWM_UNINIT
Definition hal_pwm.h:75
int32_t msg_t
Definition chearly.h:88
PLATFORM PWM subsystem low level driver header.
Type of a PWM driver configuration structure.
Structure representing a PWM driver.
pwmcnt_t period
Current PWM period in ticks.
const PWMConfig * config
Current driver configuration data.