179 lines
4.7 KiB
C
179 lines
4.7 KiB
C
/*
|
|
* 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*/
|