143 lines
3.7 KiB
C
143 lines
3.7 KiB
C
![]() |
#include <rthw.h>
|
||
|
#include <rtthread.h>
|
||
|
#include <rtdevice.h>
|
||
|
|
||
|
#include "drivers/rt_drv_pwm.h"
|
||
|
|
||
|
#include "typedef.h"
|
||
|
#include "drv_pwm.h"
|
||
|
#include "pwm.h"
|
||
|
#include "generic.h"
|
||
|
|
||
|
#include "drv_model_pub.h"
|
||
|
|
||
|
#define MAX_PERIOD (65535 / 26)
|
||
|
#define MIN_PERIOD (2)
|
||
|
|
||
|
#define PWM_MIN_CHANNEL (0)
|
||
|
#define PWM_MAX_CHANNEL (5)
|
||
|
|
||
|
#ifdef RT_USING_PWM
|
||
|
static rt_err_t rt_pwm_set_channel(pwm_param_t *param, struct rt_pwm_configuration *configuration);
|
||
|
static rt_err_t drv_pwm_control(struct rt_device_pwm *device, int cmd, void *arg);
|
||
|
static struct rt_pwm_ops drv_ops =
|
||
|
{
|
||
|
drv_pwm_control
|
||
|
};
|
||
|
|
||
|
static rt_err_t drv_pwm_enable(pwm_param_t *param, struct rt_pwm_configuration *configuration, rt_bool_t enable)
|
||
|
{
|
||
|
rt_err_t result = RT_EOK;
|
||
|
UINT32 ret = DRV_SUCCESS;
|
||
|
|
||
|
result = rt_pwm_set_channel(param, configuration);
|
||
|
if (result != RT_EOK)
|
||
|
{
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
if (!enable)
|
||
|
{
|
||
|
param->cfg.bits.en = PWM_DISABLE;
|
||
|
ret = sddev_control(PWM_DEV_NAME, CMD_PWM_INIT_PARAM, param);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
param->cfg.bits.en = PWM_ENABLE;
|
||
|
ret = sddev_control(PWM_DEV_NAME, CMD_PWM_INIT_PARAM, param);
|
||
|
}
|
||
|
|
||
|
if (ret != DRV_SUCCESS)
|
||
|
{
|
||
|
result = -RT_EIO;
|
||
|
}
|
||
|
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
static rt_err_t rt_pwm_set_channel(pwm_param_t *param, struct rt_pwm_configuration *configuration)
|
||
|
{
|
||
|
if (configuration->channel < PWM_MIN_CHANNEL || configuration->channel > PWM_MAX_CHANNEL)
|
||
|
{
|
||
|
rt_kprintf("pwm channel invalid\n");
|
||
|
return -RT_EINVAL;
|
||
|
}
|
||
|
param->channel = configuration->channel;
|
||
|
|
||
|
return RT_EOK;
|
||
|
}
|
||
|
|
||
|
static rt_err_t drv_pwm_set(pwm_param_t *param, struct rt_pwm_configuration *configuration)
|
||
|
{
|
||
|
UINT32 ret = RT_EOK;
|
||
|
if (configuration->period < 0 || configuration->pulse < 0 || (configuration->period <= configuration->pulse))
|
||
|
{
|
||
|
rt_kprintf("invalid param\n");
|
||
|
return -RT_ERROR;
|
||
|
}
|
||
|
|
||
|
configuration->period = configuration->period / 1000;
|
||
|
configuration->pulse = configuration->pulse / 1000;
|
||
|
if(configuration->period <= MIN_PERIOD || configuration->period > MAX_PERIOD)
|
||
|
{
|
||
|
rt_kprintf("invalid param, period should be 2000 ~ 2520000\n");
|
||
|
return -RT_ERROR;
|
||
|
}
|
||
|
ret = rt_pwm_set_channel(param, configuration);
|
||
|
if (ret == -RT_EINVAL)
|
||
|
{
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
param->duty_cycle = configuration->pulse * 26;
|
||
|
param->end_value = configuration->period * 26;
|
||
|
ret = sddev_control(PWM_DEV_NAME, CMD_PWM_INIT_PARAM, param);
|
||
|
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
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;
|
||
|
pwm_param_t *param = (pwm_param_t *)device->parent.user_data;
|
||
|
|
||
|
switch (cmd)
|
||
|
{
|
||
|
case PWM_CMD_ENABLE:
|
||
|
return drv_pwm_enable(param, configuration, RT_TRUE);
|
||
|
case PWM_CMD_DISABLE:
|
||
|
return drv_pwm_enable(param, configuration, RT_FALSE);
|
||
|
case PWM_CMD_SET:
|
||
|
return drv_pwm_set(param, configuration);
|
||
|
// case PWM_CMD_GET:
|
||
|
// return drv_pwm_get(param, configuration);
|
||
|
default:
|
||
|
return -RT_EINVAL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pwm_param_t pwm_param;
|
||
|
|
||
|
static void rt_pwm_init(void)
|
||
|
{
|
||
|
pwm_param.channel = PWM0;
|
||
|
pwm_param.cfg.bits.en = PWM_DISABLE;
|
||
|
pwm_param.cfg.bits.int_en = PWM_INT_DIS;
|
||
|
pwm_param.cfg.bits.mode = PMODE_PWM;
|
||
|
pwm_param.cfg.bits.clk = PWM_CLK_26M;
|
||
|
pwm_param.p_Int_Handler = 0;
|
||
|
pwm_param.duty_cycle = 0;
|
||
|
pwm_param.end_value = 0x00;
|
||
|
}
|
||
|
#endif /* RT_USING_PWM */
|
||
|
|
||
|
int drv_pwm_init(void)
|
||
|
{
|
||
|
#ifdef RT_USING_PWM
|
||
|
rt_pwm_init();
|
||
|
rt_device_pwm_register(rt_calloc(1, sizeof(struct rt_device_pwm)), "pwm", &drv_ops, &pwm_param);
|
||
|
#endif /* RT_USING_PWM */
|
||
|
return RT_EOK;
|
||
|
}
|
||
|
INIT_DEVICE_EXPORT(drv_pwm_init);
|