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