xref: /nrf52832-nimble/rt-thread/components/drivers/misc/rt_drv_pwm.c (revision 104654410c56c573564690304ae786df310c91fc)
1 /*
2  * Copyright (c) 2006-2018, 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  */
10 
11 #include <string.h>
12 
13 #include <drivers/rt_drv_pwm.h>
14 
_pwm_control(rt_device_t dev,int cmd,void * args)15 static rt_err_t _pwm_control(rt_device_t dev, int cmd, void *args)
16 {
17     rt_err_t result = RT_EOK;
18     struct rt_device_pwm *pwm = (struct rt_device_pwm *)dev;
19 
20     if (pwm->ops->control)
21     {
22         result = pwm->ops->control(pwm, cmd, args);
23     }
24 
25     return result;
26 }
27 
28 
29 /*
30 pos: channel
31 void *buffer: rt_uint32_t pulse[size]
32 size : number of pulse, only set to sizeof(rt_uint32_t).
33 */
_pwm_read(rt_device_t dev,rt_off_t pos,void * buffer,rt_size_t size)34 static rt_size_t _pwm_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
35 {
36     rt_err_t result = RT_EOK;
37     struct rt_device_pwm *pwm = (struct rt_device_pwm *)dev;
38     rt_uint32_t *pulse = (rt_uint32_t *)buffer;
39     struct rt_pwm_configuration configuration = {0};
40 
41     configuration.channel = pos;
42 
43     if (pwm->ops->control)
44     {
45         result = pwm->ops->control(pwm, PWM_CMD_GET,  &configuration);
46         if (result != RT_EOK)
47         {
48             return 0;
49         }
50 
51         *pulse = configuration.pulse;
52     }
53 
54     return size;
55 }
56 
57 /*
58 pos: channel
59 void *buffer: rt_uint32_t pulse[size]
60 size : number of pulse, only set to sizeof(rt_uint32_t).
61 */
_pwm_write(rt_device_t dev,rt_off_t pos,const void * buffer,rt_size_t size)62 static rt_size_t _pwm_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
63 {
64     rt_err_t result = RT_EOK;
65     struct rt_device_pwm *pwm = (struct rt_device_pwm *)dev;
66     rt_uint32_t *pulse = (rt_uint32_t *)buffer;
67     struct rt_pwm_configuration configuration = {0};
68 
69     configuration.channel = pos;
70 
71     if (pwm->ops->control)
72     {
73         result = pwm->ops->control(pwm, PWM_CMD_GET, &configuration);
74         if (result != RT_EOK)
75         {
76             return 0;
77         }
78 
79         configuration.pulse = *pulse;
80 
81         result = pwm->ops->control(pwm, PWM_CMD_SET, &configuration);
82         if (result != RT_EOK)
83         {
84             return 0;
85         }
86     }
87 
88     return size;
89 }
90 
91 #ifdef RT_USING_DEVICE_OPS
92 static const struct rt_device_ops pwm_device_ops =
93 {
94     RT_NULL,
95     RT_NULL,
96     RT_NULL,
97     _pwm_read,
98     _pwm_write,
99     _pwm_control
100 };
101 #endif /* RT_USING_DEVICE_OPS */
102 
rt_device_pwm_register(struct rt_device_pwm * device,const char * name,const struct rt_pwm_ops * ops,const void * user_data)103 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)
104 {
105     rt_err_t result = RT_EOK;
106 
107     memset(device, 0, sizeof(struct rt_device_pwm));
108 
109 #ifdef RT_USING_DEVICE_OPS
110     device->parent.ops = &pwm_device_ops;
111 #else
112     device->parent.init = RT_NULL;
113     device->parent.open = RT_NULL;
114     device->parent.close = RT_NULL;
115     device->parent.read  = _pwm_read;
116     device->parent.write = _pwm_write;
117     device->parent.control = _pwm_control;
118 #endif /* RT_USING_DEVICE_OPS */
119 
120     device->parent.type         = RT_Device_Class_Miscellaneous;
121     device->ops                 = ops;
122     device->parent.user_data    = (void *)user_data;
123 
124     result = rt_device_register(&device->parent, name, RT_DEVICE_FLAG_RDWR);
125 
126     return result;
127 }
128 
rt_pwm_enable(struct rt_device_pwm * device,int channel)129 rt_err_t rt_pwm_enable(struct rt_device_pwm *device, int channel)
130 {
131     rt_err_t result = RT_EOK;
132     struct rt_pwm_configuration configuration = {0};
133 
134     if (!device)
135     {
136         return -RT_EIO;
137     }
138 
139     configuration.channel = channel;
140     result = rt_device_control(&device->parent, PWM_CMD_ENABLE, &configuration);
141 
142     return result;
143 }
144 
rt_pwm_disable(struct rt_device_pwm * device,int channel)145 rt_err_t rt_pwm_disable(struct rt_device_pwm *device, int channel)
146 {
147     rt_err_t result = RT_EOK;
148     struct rt_pwm_configuration configuration = {0};
149 
150     if (!device)
151     {
152         return -RT_EIO;
153     }
154 
155     configuration.channel = channel;
156     result = rt_device_control(&device->parent, PWM_CMD_DISABLE, &configuration);
157 
158     return result;
159 }
160 
rt_pwm_set(struct rt_device_pwm * device,int channel,rt_uint32_t period,rt_uint32_t pulse)161 rt_err_t rt_pwm_set(struct rt_device_pwm *device, int channel, rt_uint32_t period, rt_uint32_t pulse)
162 {
163     rt_err_t result = RT_EOK;
164     struct rt_pwm_configuration configuration = {0};
165 
166     if (!device)
167     {
168         return -RT_EIO;
169     }
170 
171     configuration.channel = channel;
172     configuration.period = period;
173     configuration.pulse = pulse;
174     result = rt_device_control(&device->parent, PWM_CMD_SET, &configuration);
175 
176     return result;
177 }
178 
179 #ifdef RT_USING_FINSH
180 #include <finsh.h>
181 
182 FINSH_FUNCTION_EXPORT_ALIAS(rt_pwm_enable, pwm_enable, enable pwm by channel.);
183 FINSH_FUNCTION_EXPORT_ALIAS(rt_pwm_set, pwm_set, set pwm.);
184 
185 #ifdef FINSH_USING_MSH
pwm_enable(int argc,char ** argv)186 static int pwm_enable(int argc, char **argv)
187 {
188     int result = 0;
189     struct rt_device_pwm *device = RT_NULL;
190 
191     if (argc != 3)
192     {
193         rt_kprintf("Usage: pwm_enable pwm1 1\n");
194         result = -RT_ERROR;
195         goto _exit;
196     }
197 
198     device = (struct rt_device_pwm *)rt_device_find(argv[1]);
199     if (!device)
200     {
201         result = -RT_EIO;
202         goto _exit;
203     }
204 
205     result = rt_pwm_enable(device, atoi(argv[2]));
206 
207 _exit:
208     return result;
209 }
210 MSH_CMD_EXPORT(pwm_enable, pwm_enable pwm1 1);
211 
pwm_disable(int argc,char ** argv)212 static int pwm_disable(int argc, char **argv)
213 {
214     int result = 0;
215     struct rt_device_pwm *device = RT_NULL;
216 
217     if (argc != 3)
218     {
219         rt_kprintf("Usage: pwm_enable pwm1 1\n");
220         result = -RT_ERROR;
221         goto _exit;
222     }
223 
224     device = (struct rt_device_pwm *)rt_device_find(argv[1]);
225     if (!device)
226     {
227         result = -RT_EIO;
228         goto _exit;
229     }
230 
231     result = rt_pwm_disable(device, atoi(argv[2]));
232 
233 _exit:
234     return result;
235 }
236 MSH_CMD_EXPORT(pwm_disable, pwm_disable pwm1 1);
237 
pwm_set(int argc,char ** argv)238 static int pwm_set(int argc, char **argv)
239 {
240     int result = 0;
241     struct rt_device_pwm *device = RT_NULL;
242 
243     if (argc != 5)
244     {
245         rt_kprintf("Usage: pwm_set pwm1 1 100 50\n");
246         result = -RT_ERROR;
247         goto _exit;
248     }
249 
250     device = (struct rt_device_pwm *)rt_device_find(argv[1]);
251     if (!device)
252     {
253         result = -RT_EIO;
254         goto _exit;
255     }
256 
257     result = rt_pwm_set(device, atoi(argv[2]), atoi(argv[3]), atoi(argv[4]));
258 
259 _exit:
260     return result;
261 }
262 MSH_CMD_EXPORT(pwm_set, pwm_set 1 100 50);
263 
264 #endif /* FINSH_USING_MSH */
265 #endif /* RT_USING_FINSH */
266