From cdfef4839594423a53c683b6234587ff5bab12eb Mon Sep 17 00:00:00 2001 From: aozima Date: Thu, 7 Jun 2018 21:23:22 +0800 Subject: [PATCH 1/3] [DeviceDrivers] add pwm driver framework. --- components/drivers/Kconfig | 4 + .../drivers/include/drivers/rt_drv_pwm.h | 54 ++++++ components/drivers/include/rtdevice.h | 4 + components/drivers/misc/SConscript | 3 + components/drivers/misc/_pwm.c | 163 ++++++++++++++++++ 5 files changed, 228 insertions(+) create mode 100644 components/drivers/include/drivers/rt_drv_pwm.h create mode 100644 components/drivers/misc/_pwm.c diff --git a/components/drivers/Kconfig b/components/drivers/Kconfig index 7c3debb77..1eb23df2f 100755 --- a/components/drivers/Kconfig +++ b/components/drivers/Kconfig @@ -66,6 +66,10 @@ config RT_USING_PIN bool "Using generic GPIO device drivers" default y +config RT_USING_PWM + bool "Using PWM device drivers" + default n + config RT_USING_MTD_NOR bool "Using MTD Nor Flash device drivers" default n diff --git a/components/drivers/include/drivers/rt_drv_pwm.h b/components/drivers/include/drivers/rt_drv_pwm.h new file mode 100644 index 000000000..ffd08edab --- /dev/null +++ b/components/drivers/include/drivers/rt_drv_pwm.h @@ -0,0 +1,54 @@ +/* + * File : rt_drv_pwm.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2018, RT-Thread Development Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2018-05-07 aozima the first version + */ + +#ifndef __DRV_PWM_H_INCLUDE__ +#define __DRV_PWM_H_INCLUDE__ + +#define PWM_CMD_ENABLE (128 + 0) +#define PWM_CMD_DISABLE (128 + 1) +#define PWM_CMD_SET (128 + 2) +#define PWM_CMD_GET (128 + 3) + +struct rt_pwm_configuration +{ + rt_uint32_t channel; /* 0-n */ + rt_uint32_t period; /* unit:ns 1ns~4.29s:1Ghz~0.23hz */ + rt_uint32_t pulse; /* unit:ns (pulse<=period) */ +}; + +struct rt_device_pwm; +struct rt_pwm_ops +{ + rt_err_t (*control)(struct rt_device_pwm *device, int cmd, void *arg); +}; + +struct rt_device_pwm +{ + struct rt_device parent; + const struct rt_pwm_ops *ops; +}; + +extern 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); + +#endif /* __DRV_PWM_H_INCLUDE__ */ diff --git a/components/drivers/include/rtdevice.h b/components/drivers/include/rtdevice.h index f7aadd830..e3c826fe5 100644 --- a/components/drivers/include/rtdevice.h +++ b/components/drivers/include/rtdevice.h @@ -112,6 +112,10 @@ extern "C" { #include "drivers/cputime.h" #endif +#ifdef RT_USING_PWM +#include "drivers/rt_drv_pwm.h" +#endif + #ifdef __cplusplus } #endif diff --git a/components/drivers/misc/SConscript b/components/drivers/misc/SConscript index 7f269d4ee..a8e042554 100644 --- a/components/drivers/misc/SConscript +++ b/components/drivers/misc/SConscript @@ -8,6 +8,9 @@ group = [] if GetDepend(['RT_USING_PIN']): src = src + ['pin.c'] +if GetDepend(['RT_USING_PWM']): + src = src + ['_pwm.c'] + if len(src): group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH) diff --git a/components/drivers/misc/_pwm.c b/components/drivers/misc/_pwm.c new file mode 100644 index 000000000..82d0ca523 --- /dev/null +++ b/components/drivers/misc/_pwm.c @@ -0,0 +1,163 @@ +/* + * File : _pwm.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2018, RT-Thread Development Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2018-05-07 aozima the first version + */ + +#include + +#include +#include + + +static rt_err_t _pwm_control(rt_device_t dev, int cmd, void *args) +{ + rt_err_t result = RT_EOK; + struct rt_device_pwm *pwm = (struct rt_device_pwm *)dev; + + if (pwm->ops->control) + { + result = pwm->ops->control(pwm, cmd, args); + } + + return result; +} + + +/* +pos: channel +void *buffer: rt_uint32_t pulse[size] +size : number of pulse, only set to sizeof(rt_uint32_t). +*/ +static rt_size_t _pwm_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size) +{ + rt_err_t result = RT_EOK; + struct rt_device_pwm *pwm = (struct rt_device_pwm *)dev; + rt_uint32_t *pulse = (rt_uint32_t *)buffer; + struct rt_pwm_configuration configuration={0}; + + configuration.channel = pos; + + if (pwm->ops->control) + { + result = pwm->ops->control(pwm, PWM_CMD_GET, &configuration); + if (result != RT_EOK) + { + return 0; + } + + *pulse = configuration.pulse; + } + + return size; +} + +/* +pos: channel +void *buffer: rt_uint32_t pulse[size] +size : number of pulse, only set to sizeof(rt_uint32_t). +*/ +static rt_size_t _pwm_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size) +{ + rt_err_t result = RT_EOK; + struct rt_device_pwm *pwm = (struct rt_device_pwm *)dev; + rt_uint32_t *pulse = (rt_uint32_t *)buffer; + struct rt_pwm_configuration configuration={0}; + + configuration.channel = pos; + + if (pwm->ops->control) + { + result = pwm->ops->control(pwm, PWM_CMD_GET, &configuration); + if (result != RT_EOK) + { + return 0; + } + + configuration.pulse = *pulse; + + result = pwm->ops->control(pwm, PWM_CMD_SET, &configuration); + if (result != RT_EOK) + { + return 0; + } + + } + + return size; +} + +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) +{ + rt_err_t result = RT_EOK; + + memset(device, 0, sizeof(struct rt_device_pwm)); + + device->parent.type = RT_Device_Class_Miscellaneous; + + device->parent.init = RT_NULL; + device->parent.open = RT_NULL; + device->parent.close = RT_NULL; + device->parent.read = _pwm_read; + device->parent.write = _pwm_write; + device->parent.control = _pwm_control; + + device->ops = ops; + device->parent.user_data = (void *)user_data; + + result = rt_device_register(&device->parent, name, RT_DEVICE_FLAG_RDWR); + + return result; +} + +rt_err_t rt_pwm_enable(int channel) +{ + rt_err_t result = RT_EOK; + struct rt_device *device = rt_device_find("pwm"); + struct rt_pwm_configuration configuration={0}; + + if(!device) + { + return -RT_EIO; + } + + configuration.channel = channel; + result = rt_device_control(device, PWM_CMD_ENABLE, &configuration); + + return result; +} + +rt_err_t rt_pwm_set(int channel, rt_uint32_t period, rt_uint32_t pulse) +{ + rt_err_t result = RT_EOK; + struct rt_device *pwm = rt_device_find("pwm"); + + if(!pwm) + { + return -RT_EIO; + } + + return result; +} + + +#ifdef finsh +#endif /**/ From 0e5b4a0ff220cfb83086e28c5a4b93ca6e63bbac Mon Sep 17 00:00:00 2001 From: aozima Date: Fri, 8 Jun 2018 16:04:29 +0800 Subject: [PATCH 2/3] [DeviceDrivers] export pwm_enable/set to shell. --- components/drivers/misc/_pwm.c | 101 +++++++++++++++++++++++++-------- 1 file changed, 76 insertions(+), 25 deletions(-) diff --git a/components/drivers/misc/_pwm.c b/components/drivers/misc/_pwm.c index 82d0ca523..fc5b9b597 100644 --- a/components/drivers/misc/_pwm.c +++ b/components/drivers/misc/_pwm.c @@ -36,9 +36,9 @@ static rt_err_t _pwm_control(rt_device_t dev, int cmd, void *args) if (pwm->ops->control) { result = pwm->ops->control(pwm, cmd, args); - } + } - return result; + return result; } @@ -52,9 +52,9 @@ static rt_size_t _pwm_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_ rt_err_t result = RT_EOK; struct rt_device_pwm *pwm = (struct rt_device_pwm *)dev; rt_uint32_t *pulse = (rt_uint32_t *)buffer; - struct rt_pwm_configuration configuration={0}; - - configuration.channel = pos; + struct rt_pwm_configuration configuration = {0}; + + configuration.channel = pos; if (pwm->ops->control) { @@ -80,9 +80,9 @@ static rt_size_t _pwm_write(rt_device_t dev, rt_off_t pos, const void *buffer, r rt_err_t result = RT_EOK; struct rt_device_pwm *pwm = (struct rt_device_pwm *)dev; rt_uint32_t *pulse = (rt_uint32_t *)buffer; - struct rt_pwm_configuration configuration={0}; + struct rt_pwm_configuration configuration = {0}; - configuration.channel = pos; + configuration.channel = pos; if (pwm->ops->control) { @@ -131,33 +131,84 @@ rt_err_t rt_device_pwm_register(struct rt_device_pwm *device, const char *name, rt_err_t rt_pwm_enable(int channel) { rt_err_t result = RT_EOK; - struct rt_device *device = rt_device_find("pwm"); - struct rt_pwm_configuration configuration={0}; + struct rt_device *device = rt_device_find("pwm"); + struct rt_pwm_configuration configuration = {0}; - if(!device) - { - return -RT_EIO; - } - - configuration.channel = channel; + if (!device) + { + return -RT_EIO; + } + + configuration.channel = channel; result = rt_device_control(device, PWM_CMD_ENABLE, &configuration); - return result; + return result; } rt_err_t rt_pwm_set(int channel, rt_uint32_t period, rt_uint32_t pulse) { rt_err_t result = RT_EOK; - struct rt_device *pwm = rt_device_find("pwm"); - - if(!pwm) - { - return -RT_EIO; - } + struct rt_device *device = rt_device_find("pwm"); + struct rt_pwm_configuration configuration = {0}; - return result; + if (!device) + { + return -RT_EIO; + } + + configuration.channel = channel; + configuration.period = period; + configuration.pulse = pulse; + result = rt_device_control(device, PWM_CMD_SET, &configuration); + + return result; } -#ifdef finsh -#endif /**/ +#ifdef RT_USING_FINSH +#include + +FINSH_FUNCTION_EXPORT_ALIAS(rt_pwm_enable, pwm_enable, enable pwm by channel.); +FINSH_FUNCTION_EXPORT_ALIAS(rt_pwm_set, pwm_set, set pwm.); + +#ifdef FINSH_USING_MSH +static int pwm_enable(int argc, char **argv) +{ + int result = 0; + + if (argc != 2) + { + rt_kprintf("Usage: pwm_enable 1\n"); + result = -RT_ERROR; + goto _exit; + } + + result = rt_pwm_enable(atoi(argv[1])); + +_exit: + return result; +} +MSH_CMD_EXPORT(pwm_enable, pwm_enable 1); + +static int pwm_set(int argc, char **argv) +{ + int result = 0; + + if (argc != 4) + { + rt_kprintf("Usage: pwm_set 1 100 50\n"); + result = -RT_ERROR; + goto _exit; + } + + result = rt_pwm_set(atoi(argv[1]), atoi(argv[2]), atoi(argv[3])); + +_exit: + return result; +} +MSH_CMD_EXPORT(pwm_set, pwm_set 1 100 50); + +#endif /* FINSH_USING_MSH */ + + +#endif /* RT_USING_FINSH */ From 5569d17b957edcccefeac83818c90030ee9d955d Mon Sep 17 00:00:00 2001 From: aozima Date: Fri, 8 Jun 2018 16:07:12 +0800 Subject: [PATCH 3/3] [DeviceDrivers] rename _pwm.c to rt_drv_pwm.c --- components/drivers/misc/SConscript | 2 +- components/drivers/misc/{_pwm.c => rt_drv_pwm.c} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename components/drivers/misc/{_pwm.c => rt_drv_pwm.c} (99%) diff --git a/components/drivers/misc/SConscript b/components/drivers/misc/SConscript index a8e042554..4cc5f8008 100644 --- a/components/drivers/misc/SConscript +++ b/components/drivers/misc/SConscript @@ -9,7 +9,7 @@ if GetDepend(['RT_USING_PIN']): src = src + ['pin.c'] if GetDepend(['RT_USING_PWM']): - src = src + ['_pwm.c'] + src = src + ['rt_drv_pwm.c'] if len(src): group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH) diff --git a/components/drivers/misc/_pwm.c b/components/drivers/misc/rt_drv_pwm.c similarity index 99% rename from components/drivers/misc/_pwm.c rename to components/drivers/misc/rt_drv_pwm.c index fc5b9b597..6884f8cfe 100644 --- a/components/drivers/misc/_pwm.c +++ b/components/drivers/misc/rt_drv_pwm.c @@ -1,5 +1,5 @@ /* - * File : _pwm.c + * File : rt_drv_pwm.c * This file is part of RT-Thread RTOS * COPYRIGHT (C) 2018, RT-Thread Development Team *