PWM: Add support for multiple output channels per timer
This commit is contained in:
parent
00af71dd78
commit
e8c2466c1c
@ -139,6 +139,10 @@ config ARCH_HAVE_PWM_PULSECOUNT
|
||||
bool
|
||||
default n
|
||||
|
||||
config ARCH_HAVE_PWM_MULTICHAN
|
||||
bool
|
||||
default n
|
||||
|
||||
menuconfig PWM
|
||||
bool "PWM Driver Support"
|
||||
default n
|
||||
@ -147,6 +151,7 @@ menuconfig PWM
|
||||
See include/nuttx/pwm.h for further PWM driver information.
|
||||
|
||||
if PWM
|
||||
|
||||
config PWM_PULSECOUNT
|
||||
bool "PWM Pulse Count Support"
|
||||
default n
|
||||
@ -157,6 +162,26 @@ config PWM_PULSECOUNT
|
||||
hardware will support a fixed pulse count, then this configuration
|
||||
should be set to enable the capability.
|
||||
|
||||
config PWM_MULTICHAN
|
||||
bool "PWM Multiple Output Channel Support"
|
||||
default n
|
||||
depends on ARCH_HAVE_PWM_MULTICHAN
|
||||
depends on !PWM_PULSECOUNT
|
||||
---help---
|
||||
Enables support for multiple output channels per timer.
|
||||
|
||||
if PWM_MULTICHAN
|
||||
|
||||
config PWM_NCHANNELS
|
||||
int "Number of Output Channels Per Timer"
|
||||
default 1
|
||||
range 1 4
|
||||
---help---
|
||||
Specifies the number of output channels per timer. Each timer
|
||||
may support fewer output channels than this value.
|
||||
|
||||
endif # PWM_MULTICHAN
|
||||
|
||||
endif # PWM
|
||||
|
||||
config ARCH_HAVE_I2CRESET
|
||||
|
@ -107,11 +107,17 @@ struct pwm_upperhalf_s
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
static void pwm_dump(FAR const char *msg,
|
||||
FAR const struct pwm_info_s *info,
|
||||
bool started);
|
||||
static int pwm_open(FAR struct file *filep);
|
||||
static int pwm_close(FAR struct file *filep);
|
||||
static ssize_t pwm_read(FAR struct file *filep, FAR char *buffer, size_t buflen);
|
||||
static ssize_t pwm_write(FAR struct file *filep, FAR const char *buffer, size_t buflen);
|
||||
static int pwm_start(FAR struct pwm_upperhalf_s *upper, unsigned int oflags);
|
||||
static ssize_t pwm_read(FAR struct file *filep, FAR char *buffer,
|
||||
size_t buflen);
|
||||
static ssize_t pwm_write(FAR struct file *filep, FAR const char *buffer,
|
||||
size_t buflen);
|
||||
static int pwm_start(FAR struct pwm_upperhalf_s *upper,
|
||||
unsigned int oflags);
|
||||
static int pwm_ioctl(FAR struct file *filep, int cmd, unsigned long arg);
|
||||
|
||||
/****************************************************************************
|
||||
@ -135,13 +141,43 @@ static const struct file_operations g_pwmops =
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: pwm_dump
|
||||
****************************************************************************/
|
||||
|
||||
static void pwm_dump(FAR const char *msg, FAR const struct pwm_info_s *info,
|
||||
bool started)
|
||||
{
|
||||
#ifdef CONFIG_PWM_MULTICHAN
|
||||
int i;
|
||||
#endif
|
||||
|
||||
pwmvdbg("%s: frequency: %d", msg, info->frequency);
|
||||
|
||||
#ifdef CONFIG_PWM_MULTICHAN
|
||||
for (i = 0; i < CONFIG_PWM_NCHANNELS; i++)
|
||||
{
|
||||
pwmvdbg(" channel: %d duty: %08x",
|
||||
info->channels[i].channel, info->channels[i].duty);
|
||||
}
|
||||
#else
|
||||
pwmvdbg(" duty: %08x", info->duty);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PWM_PULSECOUNT
|
||||
pwmvdbg(" count: %d\n", info->count);
|
||||
#endif
|
||||
|
||||
pwmvdbg(" started: %d\n", started);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pwm_open
|
||||
*
|
||||
* Description:
|
||||
* This function is called whenever the PWM device is opened.
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static int pwm_open(FAR struct file *filep)
|
||||
{
|
||||
@ -205,13 +241,13 @@ errout:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: pwm_close
|
||||
*
|
||||
* Description:
|
||||
* This function is called when the PWM device is closed.
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static int pwm_close(FAR struct file *filep)
|
||||
{
|
||||
@ -262,41 +298,43 @@ errout:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: pwm_read
|
||||
*
|
||||
* Description:
|
||||
* A dummy read method. This is provided only to satisfy the VFS layer.
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static ssize_t pwm_read(FAR struct file *filep, FAR char *buffer, size_t buflen)
|
||||
static ssize_t pwm_read(FAR struct file *filep, FAR char *buffer,
|
||||
size_t buflen)
|
||||
{
|
||||
/* Return zero -- usually meaning end-of-file */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: pwm_write
|
||||
*
|
||||
* Description:
|
||||
* A dummy write method. This is provided only to satisfy the VFS layer.
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static ssize_t pwm_write(FAR struct file *filep, FAR const char *buffer, size_t buflen)
|
||||
static ssize_t pwm_write(FAR struct file *filep, FAR const char *buffer,
|
||||
size_t buflen)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: pwm_start
|
||||
*
|
||||
* Description:
|
||||
* Handle the PWMIOC_START ioctl command
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_PWM_PULSECOUNT
|
||||
static int pwm_start(FAR struct pwm_upperhalf_s *upper, unsigned int oflags)
|
||||
@ -397,13 +435,13 @@ static int pwm_start(FAR struct pwm_upperhalf_s *upper, unsigned int oflags)
|
||||
}
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: pwm_ioctl
|
||||
*
|
||||
* Description:
|
||||
* The standard ioctl method. This is where ALL of the PWM work is done.
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static int pwm_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
|
||||
{
|
||||
@ -441,13 +479,7 @@ static int pwm_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
|
||||
FAR const struct pwm_info_s *info = (FAR const struct pwm_info_s *)((uintptr_t)arg);
|
||||
DEBUGASSERT(info != NULL && lower->ops->start != NULL);
|
||||
|
||||
#ifdef CONFIG_PWM_PULSECOUNT
|
||||
pwmvdbg("PWMIOC_SETCHARACTERISTICS frequency: %d duty: %08x count: %d started: %d\n",
|
||||
info->frequency, info->duty, info->count, upper->started);
|
||||
#else
|
||||
pwmvdbg("PWMIOC_SETCHARACTERISTICS frequency: %d duty: %08x started: %d\n",
|
||||
info->frequency, info->duty, upper->started);
|
||||
#endif
|
||||
pwm_dump("PWMIOC_SETCHARACTERISTICS", info, upper->started);
|
||||
|
||||
/* Save the pulse train characteristics */
|
||||
|
||||
@ -480,13 +512,7 @@ static int pwm_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
|
||||
|
||||
memcpy(info, &upper->info, sizeof(struct pwm_info_s));
|
||||
|
||||
#ifdef CONFIG_PWM_PULSECOUNT
|
||||
pwmvdbg("PWMIOC_GETCHARACTERISTICS frequency: %d duty: %08x count: %d\n",
|
||||
info->frequency, info->duty, info->count);
|
||||
#else
|
||||
pwmvdbg("PWMIOC_GETCHARACTERISTICS frequency: %d duty: %08x\n",
|
||||
info->frequency, info->duty);
|
||||
#endif
|
||||
pwm_dump("PWMIOC_GETCHARACTERISTICS", info, upper->started);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -498,14 +524,7 @@ static int pwm_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
|
||||
|
||||
case PWMIOC_START:
|
||||
{
|
||||
#ifdef CONFIG_PWM_PULSECOUNT
|
||||
pwmvdbg("PWMIOC_START frequency: %d duty: %08x count: %d started: %d\n",
|
||||
upper->info.frequency, upper->info.duty, upper->info.count,
|
||||
upper->started);
|
||||
#else
|
||||
pwmvdbg("PWMIOC_START frequency: %d duty: %08x started: %d\n",
|
||||
upper->info.frequency, upper->info.duty, upper->started);
|
||||
#endif
|
||||
pwm_dump("PWMIOC_START", &upper->info, upper->started);
|
||||
DEBUGASSERT(lower->ops->start != NULL);
|
||||
|
||||
/* Start the pulse train */
|
||||
@ -531,7 +550,7 @@ static int pwm_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
|
||||
#ifdef CONFIG_PWM_PULSECOUNT
|
||||
if (upper->waiting)
|
||||
{
|
||||
upper->waiting = FALSE;
|
||||
upper->waiting = false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -122,11 +122,23 @@
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_PWM_MULTICHAN
|
||||
struct pwm_chan_s
|
||||
{
|
||||
ub16_t duty;
|
||||
uint8_t channel;
|
||||
};
|
||||
#endif
|
||||
|
||||
/* This structure describes the characteristics of the pulsed output */
|
||||
|
||||
struct pwm_info_s
|
||||
{
|
||||
uint32_t frequency; /* Frequency of the pulse train */
|
||||
#ifdef CONFIG_PWM_MULTICHAN
|
||||
struct pwm_chan_s channels[CONFIG_PWM_NCHANNELS];
|
||||
#else
|
||||
ub16_t duty; /* Duty of the pulse train, "1"-to-"0" duration.
|
||||
* Maximum: 65535/65536 (0x0000ffff)
|
||||
* Minimum: 1/65536 (0x00000001) */
|
||||
@ -134,6 +146,7 @@ struct pwm_info_s
|
||||
uint32_t count; /* The number of pulse to generate. 0 means to
|
||||
* generate an indefinite number of pulses */
|
||||
# endif
|
||||
#endif
|
||||
};
|
||||
|
||||
/* This structure is a set a callback functions used to call from the upper-
|
||||
|
Loading…
Reference in New Issue
Block a user