123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281 |
- /*
- * Copyright (c) 2006-2022, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2022-07-13 Rbb666 first version
- */
- #include "drv_pwm.h"
- #ifdef RT_USING_PWM
- #include <drivers/rt_drv_pwm.h>
- #include "drv_gpio.h"
- //#define DRV_DEBUG
- #define LOG_TAG "drv.pwm"
- #include <drv_log.h>
- struct rt_device_pwm pwm_device;
- struct ifx_pwm
- {
- struct rt_device_pwm pwm_device;
- cyhal_pwm_t *pwm_obj;
- rt_uint8_t channel;
- char *name;
- rt_uint8_t gpio;
- };
- static struct ifx_pwm ifx_pwm_obj[] =
- {
- #ifdef BSP_USING_PWM0_PORT13
- PWM0_CH3_PORT13_CONFIG,
- #endif
- #ifdef BSP_USING_PWM0_PORT2
- PWM0_CH7_PORT2_CONFIG,
- #endif
- #ifdef BSP_USING_PWM0_PORT5
- PWM0_CH7_PORT5_CONFIG,
- #endif
- #ifdef BSP_USING_PWM0_PORT7
- PWM0_CH7_PORT7_CONFIG,
- #endif
- #ifdef BSP_USING_PWM0_PORT9
- PWM0_CH7_PORT9_CONFIG,
- #endif
- #ifdef BSP_USING_PWM0_PORT10
- PWM0_CH7_PORT10_CONFIG,
- #endif
- #ifdef BSP_USING_PWM0_PORT12
- PWM0_CH7_PORT12_CONFIG,
- #endif
- };
- static rt_err_t drv_pwm_enable(cyhal_pwm_t *htim, struct rt_pwm_configuration *configuration, rt_bool_t enable)
- {
- /* get the value of channel */
- rt_uint32_t channel = configuration->channel;
- if (!configuration->complementary || configuration->complementary)
- {
- if (!enable)
- {
- if (channel == 3)
- {
- htim->tcpwm.resource.channel_num = channel;
- }
- else if (channel == 7)
- {
- htim->tcpwm.resource.channel_num = channel;
- }
- cyhal_pwm_stop(htim);
- }
- else
- {
- if (channel == 3)
- {
- htim->tcpwm.resource.channel_num = channel;
- }
- else if (channel == 7)
- {
- htim->tcpwm.resource.channel_num = channel;
- }
- cyhal_pwm_start(htim);
- }
- }
- return RT_EOK;
- }
- static rt_err_t drv_pwm_set(cyhal_pwm_t *htim, struct rt_pwm_configuration *configuration)
- {
- rt_uint64_t tim_clock;
- rt_uint32_t period, pulse;
- tim_clock = (rt_uint32_t)(htim->tcpwm.clock_hz);
- htim->tcpwm.resource.channel_num = configuration->channel;
- period = (unsigned long long)configuration->period / 1000ULL;
- pulse = (unsigned long long)configuration->pulse / 1000ULL;
- cyhal_pwm_set_period(htim, period, pulse);
- return RT_EOK;
- }
- static rt_err_t drv_pwm_get(cyhal_pwm_t *htim, struct rt_pwm_configuration *configuration)
- {
- uint32_t Period = Cy_TCPWM_PWM_GetPeriod0(htim->tcpwm.base, _CYHAL_TCPWM_CNT_NUMBER(htim->tcpwm.resource));
- uint32_t Compare = Cy_TCPWM_PWM_GetCounter(htim->tcpwm.base, _CYHAL_TCPWM_CNT_NUMBER(htim->tcpwm.resource));
- configuration->period = Period;
- configuration->pulse = Compare;
- return RT_EOK;
- }
- static rt_err_t drv_pwm_control(struct rt_device_pwm *device, int cmd, void *arg)
- {
- struct rt_pwm_configuration *configuration = (struct rt_pwm_configuration *)arg;
- cyhal_pwm_t *htim = (cyhal_pwm_t *)device->parent.user_data;
- switch (cmd)
- {
- case PWMN_CMD_ENABLE:
- configuration->complementary = RT_TRUE;
- case PWM_CMD_ENABLE:
- return drv_pwm_enable(htim, configuration, RT_TRUE);
- case PWMN_CMD_DISABLE:
- configuration->complementary = RT_FALSE;
- case PWM_CMD_DISABLE:
- return drv_pwm_enable(htim, configuration, RT_FALSE);
- case PWM_CMD_SET:
- return drv_pwm_set(htim, configuration);
- case PWM_CMD_GET:
- return drv_pwm_get(htim, configuration);
- default:
- return RT_EINVAL;
- }
- }
- static struct rt_pwm_ops drv_ops = {drv_pwm_control};
- static rt_err_t ifx_hw_pwm_init(struct ifx_pwm *device)
- {
- rt_err_t result = RT_EOK;
- RT_ASSERT(device != RT_NULL);
- /* config pwm channel */
- if (device->channel == 0x03)
- {
- if (cyhal_pwm_init_adv(device->pwm_obj, device->gpio, NC, CYHAL_PWM_LEFT_ALIGN, true, 0u, false, RT_NULL) != RT_EOK)
- {
- LOG_E("%s channel3 config failed", device->name);
- result = -RT_ERROR;
- goto __exit;
- }
- }
- /* config pwm channel */
- if (device->channel == 0x07)
- {
- if (cyhal_pwm_init_adv(device->pwm_obj, device->gpio, NC, CYHAL_PWM_LEFT_ALIGN, true, 0u, false, RT_NULL) != RT_EOK)
- {
- LOG_E("%s channel7 config failed", device->name);
- result = -RT_ERROR;
- goto __exit;
- }
- }
- __exit:
- return result;
- }
- static int rt_hw_pwm_init(void)
- {
- int i;
- int result = RT_EOK;
- for (i = 0; i < sizeof(ifx_pwm_obj) / sizeof(ifx_pwm_obj[0]); i++)
- {
- ifx_pwm_obj[i].pwm_obj = rt_malloc(sizeof(cyhal_pwm_t));
- RT_ASSERT(ifx_pwm_obj[i].pwm_obj != RT_NULL);
- /* pwm init */
- if (ifx_hw_pwm_init(&ifx_pwm_obj[i]) != RT_EOK)
- {
- LOG_E("%s init failed", ifx_pwm_obj[i].name);
- result = -RT_ERROR;
- goto __exit;
- }
- else
- {
- if (rt_device_pwm_register(&ifx_pwm_obj[i].pwm_device, ifx_pwm_obj[i].name, &drv_ops, ifx_pwm_obj[i].pwm_obj) == RT_EOK)
- {
- LOG_D("%s register success", ifx_pwm_obj[i].name);
- }
- else
- {
- LOG_D("%s register failed", ifx_pwm_obj[i].name);
- result = -RT_ERROR;
- }
- }
- }
- __exit:
- return result;
- }
- INIT_BOARD_EXPORT(rt_hw_pwm_init);
- #define PWM_DEV_NAME "pwm0"
- #define PWM_DEV_CHANNEL 7
- struct rt_device_pwm *pwm_dev;
- static int pwm_sample(int argc, char *argv[])
- {
- rt_uint32_t period, pulse, dir;
- period = 1 * 1000 * 1000;
- dir = 1;
- pulse = 0;
- pwm_dev = (struct rt_device_pwm *)rt_device_find(PWM_DEV_NAME);
- if (pwm_dev == RT_NULL)
- {
- rt_kprintf("pwm sample run failed! can't find %s device!\n", PWM_DEV_NAME);
- return RT_ERROR;
- }
- rt_pwm_set(pwm_dev, PWM_DEV_CHANNEL, period, pulse);
- rt_pwm_enable(pwm_dev, PWM_DEV_CHANNEL);
- rt_kprintf("Now PWM[%s] Channel[%d] Period[%d] Pulse[%d]\n", PWM_DEV_NAME, PWM_DEV_CHANNEL, period, pulse);
- while (1)
- {
- rt_thread_mdelay(50);
- if (dir)
- {
- pulse += 100000;
- }
- else
- {
- pulse -= 100000;
- }
- if (pulse >= period)
- {
- dir = 0;
- }
- if (0 == pulse)
- {
- dir = 1;
- }
- rt_pwm_set(pwm_dev, PWM_DEV_CHANNEL, period, pulse);
- }
- }
- MSH_CMD_EXPORT(pwm_sample, <pwm0> channel7 sample);
- #endif
|