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
|
bool
|
||||||
default n
|
default n
|
||||||
|
|
||||||
|
config ARCH_HAVE_PWM_MULTICHAN
|
||||||
|
bool
|
||||||
|
default n
|
||||||
|
|
||||||
menuconfig PWM
|
menuconfig PWM
|
||||||
bool "PWM Driver Support"
|
bool "PWM Driver Support"
|
||||||
default n
|
default n
|
||||||
@ -147,6 +151,7 @@ menuconfig PWM
|
|||||||
See include/nuttx/pwm.h for further PWM driver information.
|
See include/nuttx/pwm.h for further PWM driver information.
|
||||||
|
|
||||||
if PWM
|
if PWM
|
||||||
|
|
||||||
config PWM_PULSECOUNT
|
config PWM_PULSECOUNT
|
||||||
bool "PWM Pulse Count Support"
|
bool "PWM Pulse Count Support"
|
||||||
default n
|
default n
|
||||||
@ -157,6 +162,26 @@ config PWM_PULSECOUNT
|
|||||||
hardware will support a fixed pulse count, then this configuration
|
hardware will support a fixed pulse count, then this configuration
|
||||||
should be set to enable the capability.
|
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
|
endif # PWM
|
||||||
|
|
||||||
config ARCH_HAVE_I2CRESET
|
config ARCH_HAVE_I2CRESET
|
||||||
|
@ -107,11 +107,17 @@ struct pwm_upperhalf_s
|
|||||||
* Private Function Prototypes
|
* 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_open(FAR struct file *filep);
|
||||||
static int pwm_close(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_read(FAR struct file *filep, FAR char *buffer,
|
||||||
static ssize_t pwm_write(FAR struct file *filep, FAR const char *buffer, size_t buflen);
|
size_t buflen);
|
||||||
static int pwm_start(FAR struct pwm_upperhalf_s *upper, unsigned int oflags);
|
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);
|
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
|
* 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
|
* Name: pwm_open
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* This function is called whenever the PWM device is opened.
|
* This function is called whenever the PWM device is opened.
|
||||||
*
|
*
|
||||||
************************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static int pwm_open(FAR struct file *filep)
|
static int pwm_open(FAR struct file *filep)
|
||||||
{
|
{
|
||||||
@ -205,13 +241,13 @@ errout:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************************
|
/****************************************************************************
|
||||||
* Name: pwm_close
|
* Name: pwm_close
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* This function is called when the PWM device is closed.
|
* This function is called when the PWM device is closed.
|
||||||
*
|
*
|
||||||
************************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static int pwm_close(FAR struct file *filep)
|
static int pwm_close(FAR struct file *filep)
|
||||||
{
|
{
|
||||||
@ -262,41 +298,43 @@ errout:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************************
|
/****************************************************************************
|
||||||
* Name: pwm_read
|
* Name: pwm_read
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* A dummy read method. This is provided only to satisfy the VFS layer.
|
* 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 zero -- usually meaning end-of-file */
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************************
|
/****************************************************************************
|
||||||
* Name: pwm_write
|
* Name: pwm_write
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* A dummy write method. This is provided only to satisfy the VFS layer.
|
* 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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************************
|
/****************************************************************************
|
||||||
* Name: pwm_start
|
* Name: pwm_start
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Handle the PWMIOC_START ioctl command
|
* Handle the PWMIOC_START ioctl command
|
||||||
*
|
*
|
||||||
************************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#ifdef CONFIG_PWM_PULSECOUNT
|
#ifdef CONFIG_PWM_PULSECOUNT
|
||||||
static int pwm_start(FAR struct pwm_upperhalf_s *upper, unsigned int oflags)
|
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
|
#endif
|
||||||
|
|
||||||
/************************************************************************************
|
/****************************************************************************
|
||||||
* Name: pwm_ioctl
|
* Name: pwm_ioctl
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* The standard ioctl method. This is where ALL of the PWM work is done.
|
* 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)
|
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);
|
FAR const struct pwm_info_s *info = (FAR const struct pwm_info_s *)((uintptr_t)arg);
|
||||||
DEBUGASSERT(info != NULL && lower->ops->start != NULL);
|
DEBUGASSERT(info != NULL && lower->ops->start != NULL);
|
||||||
|
|
||||||
#ifdef CONFIG_PWM_PULSECOUNT
|
pwm_dump("PWMIOC_SETCHARACTERISTICS", info, upper->started);
|
||||||
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
|
|
||||||
|
|
||||||
/* Save the pulse train characteristics */
|
/* 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));
|
memcpy(info, &upper->info, sizeof(struct pwm_info_s));
|
||||||
|
|
||||||
#ifdef CONFIG_PWM_PULSECOUNT
|
pwm_dump("PWMIOC_GETCHARACTERISTICS", info, upper->started);
|
||||||
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
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -498,14 +524,7 @@ static int pwm_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
|
|||||||
|
|
||||||
case PWMIOC_START:
|
case PWMIOC_START:
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_PWM_PULSECOUNT
|
pwm_dump("PWMIOC_START", &upper->info, upper->started);
|
||||||
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
|
|
||||||
DEBUGASSERT(lower->ops->start != NULL);
|
DEBUGASSERT(lower->ops->start != NULL);
|
||||||
|
|
||||||
/* Start the pulse train */
|
/* 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
|
#ifdef CONFIG_PWM_PULSECOUNT
|
||||||
if (upper->waiting)
|
if (upper->waiting)
|
||||||
{
|
{
|
||||||
upper->waiting = FALSE;
|
upper->waiting = false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -122,17 +122,30 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Types
|
* 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 */
|
/* This structure describes the characteristics of the pulsed output */
|
||||||
|
|
||||||
struct pwm_info_s
|
struct pwm_info_s
|
||||||
{
|
{
|
||||||
uint32_t frequency; /* Frequency of the pulse train */
|
uint32_t frequency; /* Frequency of the pulse train */
|
||||||
ub16_t duty; /* Duty of the pulse train, "1"-to-"0" duration.
|
#ifdef CONFIG_PWM_MULTICHAN
|
||||||
* Maximum: 65535/65536 (0x0000ffff)
|
struct pwm_chan_s channels[CONFIG_PWM_NCHANNELS];
|
||||||
* Minimum: 1/65536 (0x00000001) */
|
#else
|
||||||
#ifdef CONFIG_PWM_PULSECOUNT
|
ub16_t duty; /* Duty of the pulse train, "1"-to-"0" duration.
|
||||||
uint32_t count; /* The number of pulse to generate. 0 means to
|
* Maximum: 65535/65536 (0x0000ffff)
|
||||||
* generate an indefinite number of pulses */
|
* Minimum: 1/65536 (0x00000001) */
|
||||||
|
# ifdef CONFIG_PWM_PULSECOUNT
|
||||||
|
uint32_t count; /* The number of pulse to generate. 0 means to
|
||||||
|
* generate an indefinite number of pulses */
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user