1 /*
2  * Copyright (c) 2006-2024 RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2018-05-07     aozima       the first version
9  * 2022-09-24     yuqi         add phase and dead time configuration
10  */
11 
12 #ifndef __DEV_PWM_H__
13 #define __DEV_PWM_H__
14 
15 #include <rtthread.h>
16 /**
17  * @defgroup    group_drivers_pwm PWM
18  * @brief       PWM driver api
19  * @ingroup     group_device_driver
20  *
21  * <b>Example</b>
22  * @code {.c}
23  * #include <rtthread.h>
24  * #include <rtdevice.h>
25  *
26  * #define PWM_DEV_NAME        "pwm3"  // PWM设备名称
27  * #define PWM_DEV_CHANNEL     4       // PWM通道
28  *
29  * struct rt_device_pwm *pwm_dev;      // PWM设备句柄
30  *
31  * static int pwm_led_sample(int argc, char *argv[])
32  * {
33  *     rt_uint32_t period, pulse, dir;
34  *
35  *     period = 500000;    // 周期为0.5ms,单位为纳秒ns
36  *     dir = 1;            // PWM脉冲宽度值的增减方向
37  *     pulse = 0;          // PWM脉冲宽度值,单位为纳秒ns
38  *
39  *     // 查找设备
40  *     pwm_dev = (struct rt_device_pwm *)rt_device_find(PWM_DEV_NAME);
41  *     if (pwm_dev == RT_NULL)
42  *     {
43  *         rt_kprintf("pwm sample run failed! can't find %s device!\n", PWM_DEV_NAME);
44  *         return -RT_ERROR;
45  *     }
46  *
47  *     // 设置PWM周期和脉冲宽度默认值
48  *     rt_pwm_set(pwm_dev, PWM_DEV_CHANNEL, period, pulse);
49  *     // 使能设备
50  *     rt_pwm_enable(pwm_dev, PWM_DEV_CHANNEL);
51  *
52  *     while (1)
53  *     {
54  *         rt_thread_mdelay(50);
55  *         if (dir)
56  *         {
57  *             pulse += 5000;      // 从0值开始每次增加5000ns
58  *         }
59  *         else
60  *         {
61  *             pulse -= 5000;      // 从最大值开始每次减少5000ns
62  *         }
63  *         if (pulse >= period)
64  *         {
65  *             dir = 0;
66  *         }
67  *         if (0 == pulse)
68  *         {
69  *             dir = 1;
70  *         }
71  *
72  *         // 设置PWM周期和脉冲宽度
73  *         rt_pwm_set(pwm_dev, PWM_DEV_CHANNEL, period, pulse);
74  *     }
75  * }
76  *
77  * MSH_CMD_EXPORT(pwm_led_sample, pwm sample);
78  * @endcode
79  */
80 
81 /*!
82  * @addtogroup group_drivers_pwm
83  * @{
84  */
85 #define PWM_CMD_ENABLE      (RT_DEVICE_CTRL_BASE(PWM) + 0)
86 #define PWM_CMD_DISABLE     (RT_DEVICE_CTRL_BASE(PWM) + 1)
87 #define PWM_CMD_SET         (RT_DEVICE_CTRL_BASE(PWM) + 2)
88 #define PWM_CMD_GET         (RT_DEVICE_CTRL_BASE(PWM) + 3)
89 #define PWMN_CMD_ENABLE     (RT_DEVICE_CTRL_BASE(PWM) + 4)
90 #define PWMN_CMD_DISABLE    (RT_DEVICE_CTRL_BASE(PWM) + 5)
91 #define PWM_CMD_SET_PERIOD  (RT_DEVICE_CTRL_BASE(PWM) + 6)
92 #define PWM_CMD_SET_PULSE   (RT_DEVICE_CTRL_BASE(PWM) + 7)
93 #define PWM_CMD_SET_DEAD_TIME  (RT_DEVICE_CTRL_BASE(PWM) + 8)
94 #define PWM_CMD_SET_PHASE   (RT_DEVICE_CTRL_BASE(PWM) + 9)
95 #define PWM_CMD_ENABLE_IRQ  (RT_DEVICE_CTRL_BASE(PWM) + 10)
96 #define PWM_CMD_DISABLE_IRQ  (RT_DEVICE_CTRL_BASE(PWM) + 11)
97 
98 /**
99  * @brief PWM configuration
100  */
101 struct rt_pwm_configuration
102 {
103     rt_uint32_t channel; /* 0 ~ n or 0 ~ -n, which depends on specific MCU requirements */
104     rt_uint32_t period;  /* unit:ns 1ns~4.29s:1Ghz~0.23hz */
105     rt_uint32_t pulse;   /* unit:ns (pulse<=period) */
106     rt_uint32_t dead_time;  /* unit:ns */
107     rt_uint32_t phase;  /*unit: degree, 0~360, which is the phase of pwm output, */
108     /*
109      * RT_TRUE  : The channel of pwm is complememtary.
110      * RT_FALSE : The channel of pwm is nomal.
111     */
112     rt_bool_t  complementary;
113 };
114 
115 struct rt_device_pwm;
116 /**
117  * @brief PWM operations
118  */
119 struct rt_pwm_ops
120 {
121     rt_err_t (*control)(struct rt_device_pwm *device, int cmd, void *arg);
122 };
123 
124 /**
125  * @brief PWM device
126  */
127 struct rt_device_pwm
128 {
129     struct rt_device parent;
130     const struct rt_pwm_ops *ops;
131 };
132 /**
133  * @brief register a PWM device
134  * @param device the PWM device
135  * @param name the name of PWM device
136  * @param ops the operations of PWM device
137  * @param user_data the user data of PWM device
138  * @return rt_err_t error code
139  */
140 rt_err_t rt_device_pwm_register(struct rt_device_pwm *device, const char *name, const struct rt_pwm_ops *ops, const void *user_data);
141 
142 /**
143  * @brief enable the PWM channel
144  * @param device the PWM device
145  * @param channel the channel of PWM
146  * @return rt_err_t error code
147  */
148 rt_err_t rt_pwm_enable(struct rt_device_pwm *device, int channel);
149 
150 /**
151  * @brief disable the PWM channel
152  * @param device the PWM device
153  * @param channel the channel of PWM
154  * @return rt_err_t error code
155  */
156 rt_err_t rt_pwm_disable(struct rt_device_pwm *device, int channel);
157 
158 /**
159  * @brief set the PWM channel
160  * @param device the PWM device
161  * @param channel the channel of PWM
162  * @param period the period of PWM
163  * @param pulse the pulse of PWM
164  * @return rt_err_t error code
165  */
166 rt_err_t rt_pwm_set(struct rt_device_pwm *device, int channel, rt_uint32_t period, rt_uint32_t pulse);
167 
168 /**
169  * @brief set the PWM channel period
170  * @param device the PWM device
171  * @param channel the channel of PWM
172  * @param period the period of PWM
173  * @return rt_err_t error code
174 */
175 rt_err_t rt_pwm_set_period(struct rt_device_pwm *device, int channel, rt_uint32_t period);
176 
177 /**
178  * @brief set the PWM channel pulse
179  * @param device the PWM device
180  * @param channel the channel of PWM
181  * @param pulse the period of PWM
182  * @return rt_err_t error code
183 */
184 rt_err_t rt_pwm_set_pulse(struct rt_device_pwm *device, int channel, rt_uint32_t pulse);
185 
186 /**
187  * @brief set the dead zone time of PWM
188  * @param device the PWM device
189  * @param channel the channel of PWM
190  * @param dead_time dead zone time
191  * @return rt_err_t error code
192 */
193 rt_err_t rt_pwm_set_dead_time(struct rt_device_pwm *device, int channel, rt_uint32_t dead_time);
194 
195 /**
196  * @brief set the phase of PWM
197  * @param device the PWM device
198  * @param channel the channel of PWM
199  * @param phase phase
200  * @return rt_err_t error code
201 */
202 rt_err_t rt_pwm_set_phase(struct rt_device_pwm *device, int channel, rt_uint32_t phase);
203 
204 /*! @}*/
205 
206 #endif /* __DEV_PWM_H__ */
207