/* * Copyright (c) 2006-2022, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2018-12-04 Sundm75 the first version */ #include <stdint.h> #include <string.h> #include <stdlib.h> #include <rtthread.h> #include <rtdevice.h> #include "ls1c.h" #include "../libraries/ls1c_public.h" #include "../libraries/ls1c_regs.h" #include "../libraries/ls1c_clock.h" #include "../libraries/ls1c_pwm.h" #include "../libraries/ls1c_pin.h" #define PWM_CHANNEL_MAX (4) /* 0-3*/ #ifdef RT_USING_PWM struct rt_ls1c_pwm { struct rt_device_pwm parent; rt_uint32_t period[PWM_CHANNEL_MAX]; rt_uint32_t pulse[PWM_CHANNEL_MAX]; }; static struct rt_ls1c_pwm _ls1c_pwm_device; static rt_err_t set(struct rt_device_pwm *device, struct rt_pwm_configuration *configuration) { rt_err_t result = RT_EOK; struct rt_ls1c_pwm *ls1c_pwm_device = (struct rt_ls1c_pwm *)device; if (configuration->channel > (PWM_CHANNEL_MAX - 1)) { result = -RT_EIO; goto _exit; } rt_kprintf("drv_pwm.c set channel %d: period: %d, pulse: %d\n", configuration->channel, configuration->period, configuration->pulse); ls1c_pwm_device->period[configuration->channel] = configuration->period; ls1c_pwm_device->pulse[configuration->channel] = configuration->pulse; _exit: return result; } static rt_err_t get(struct rt_device_pwm *device, struct rt_pwm_configuration *configuration) { rt_err_t result = RT_EOK; struct rt_ls1c_pwm *ls1c_pwm_device = (struct rt_ls1c_pwm *)device; if (configuration->channel > (PWM_CHANNEL_MAX - 1)) { result = -RT_EIO; goto _exit; } configuration->period = ls1c_pwm_device->period[configuration->channel]; configuration->pulse = ls1c_pwm_device->pulse[configuration->channel]; rt_kprintf("drv_pwm.c get channel %d: period: %d, pulse: %d\n", configuration->channel, configuration->period, configuration->pulse); _exit: return result; } static rt_err_t control(struct rt_device_pwm *device, int cmd, void *arg) { rt_err_t result = RT_EOK; struct rt_pwm_configuration * configuration = (struct rt_pwm_configuration *)arg; rt_kprintf("drv_pwm.c control cmd: %d. \n", cmd); if (cmd == PWM_CMD_ENABLE) { rt_kprintf("PWM_CMD_ENABLE\n"); pwm_info_t pwm_info; switch ( configuration->channel) { case 0: pwm_info.gpio = LS1C_PWM0_GPIO06; //pwm_info.gpio = LS1C_PWM0_GPIO04; break; case 1: pwm_info.gpio = LS1C_PWM1_GPIO92; //pwm_info.gpio = LS1C_PWM1_GPIO05; break; case 2: pwm_info.gpio = LS1C_PWM2_GPIO52; //pwm_info.gpio = LS1C_PWM2_GPIO46; break; case 3: pwm_info.gpio = LS1C_PWM3_GPIO47; //pwm_info.gpio = LS1C_PWM3_GPIO53; break; default: break; } pwm_info.mode = PWM_MODE_NORMAL; pwm_info.duty = ( (float)configuration->pulse ) / ((float)configuration->period ); pwm_info.period_ns = configuration->period; pwm_init(&pwm_info); pwm_enable(&pwm_info); } else if (cmd == PWM_CMD_DISABLE) { rt_kprintf("PWM_CMD_DISABLE\n"); pwm_info_t pwm_info; switch ( configuration->channel) { case 0: pwm_info.gpio = LS1C_PWM0_GPIO06; //pwm_info.gpio = LS1C_PWM0_GPIO04; break; case 1: pwm_info.gpio = LS1C_PWM1_GPIO92; //pwm_info.gpio = LS1C_PWM1_GPIO05; break; case 2: pwm_info.gpio = LS1C_PWM2_GPIO52; //pwm_info.gpio = LS1C_PWM2_GPIO46; break; case 3: pwm_info.gpio = LS1C_PWM3_GPIO47; //pwm_info.gpio = LS1C_PWM3_GPIO53; break; default: break; } pwm_info.mode = PWM_MODE_NORMAL; pwm_info.duty = ( (float)configuration->pulse ) / ((float)configuration->period ); pwm_info.period_ns = configuration->period; pwm_init(&pwm_info); pwm_disable(&pwm_info); } else if (cmd == PWM_CMD_SET) { rt_kprintf("PWM_CMD_SET\n"); result = set(device, (struct rt_pwm_configuration *)arg); } else if (cmd == PWM_CMD_GET) { rt_kprintf("PWM_CMD_GET\n"); result = get(device, (struct rt_pwm_configuration *)arg); } return result; } static const struct rt_pwm_ops pwm_ops = { control, }; int rt_hw_pwm_init(void) { int ret = RT_EOK; /* add pwm initial. */ ret = rt_device_pwm_register(&_ls1c_pwm_device.parent, "pwm", &pwm_ops, RT_NULL); return ret; } INIT_DEVICE_EXPORT(rt_hw_pwm_init); #endif /*RT_USING_PWM*/