mirror of
https://github.com/apache/nuttx.git
synced 2026-06-06 16:50:55 +08:00
Merged in antmerlino/nuttx/rgb_multichan (pull request #635)
drivers/rgbled: Adds support for multichannel PWM (multiple PWM channels on a single timer) Approved-by: Gregory Nutt <gnutt@nuttx.org>
This commit is contained in:
committed by
Gregory Nutt
parent
800da58e6c
commit
385d4a9108
+89
-17
@@ -73,12 +73,14 @@ struct rgbled_upperhalf_s
|
||||
uint8_t crefs; /* The number of times the device has been opened */
|
||||
volatile bool started; /* True: pulsed output is being generated */
|
||||
sem_t exclsem; /* Supports mutual exclusion */
|
||||
struct pwm_info_s ledr; /* Pulsed output for LED R*/
|
||||
struct pwm_info_s ledg; /* Pulsed output for LED G*/
|
||||
struct pwm_info_s ledb; /* Pulsed output for LED B*/
|
||||
struct pwm_lowerhalf_s *devledr;
|
||||
struct pwm_lowerhalf_s *devledg;
|
||||
struct pwm_lowerhalf_s *devledb;
|
||||
#ifdef CONFIG_PWM_MULTICHAN
|
||||
int chanr;
|
||||
int chang;
|
||||
int chanb;
|
||||
#endif
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
@@ -298,11 +300,12 @@ static ssize_t rgbled_write(FAR struct file *filep, FAR const char *buffer,
|
||||
FAR struct pwm_lowerhalf_s *ledr = upper->devledr;
|
||||
FAR struct pwm_lowerhalf_s *ledg = upper->devledg;
|
||||
FAR struct pwm_lowerhalf_s *ledb = upper->devledb;
|
||||
|
||||
struct pwm_info_s pwm;
|
||||
unsigned int red;
|
||||
unsigned int green;
|
||||
unsigned int blue;
|
||||
char color[3];
|
||||
int i;
|
||||
|
||||
/* We need to receive a string #RRGGBB = 7 bytes */
|
||||
|
||||
@@ -383,26 +386,85 @@ static ssize_t rgbled_write(FAR struct file *filep, FAR const char *buffer,
|
||||
blue ^= 0xffff;
|
||||
#endif
|
||||
|
||||
/* Setup LED R */
|
||||
|
||||
upper->ledr.frequency = 100;
|
||||
upper->ledr.duty = red;
|
||||
#ifdef CONFIG_PWM_MULTICHAN
|
||||
pwm.frequency = 100;
|
||||
|
||||
ledr->ops->start(ledr, &upper->ledr);
|
||||
i = 0;
|
||||
pwm.channels[i].duty = red;
|
||||
pwm.channels[i++].channel = upper->chanr;
|
||||
|
||||
/* Setup LED G */
|
||||
/* If the green pwm source is on the same timer as the red,
|
||||
* set that up now too */
|
||||
|
||||
upper->ledg.frequency = 100;
|
||||
upper->ledg.duty = green;
|
||||
if (ledr == ledg)
|
||||
{
|
||||
pwm.channels[i].duty = green;
|
||||
pwm.channels[i++].channel = upper->chang;
|
||||
}
|
||||
|
||||
ledg->ops->start(ledg, &upper->ledg);
|
||||
/* If the blue pwm source is on the same timer as the red,
|
||||
* set that up now too */
|
||||
|
||||
/* Setup LED B */
|
||||
if (ledr == ledb)
|
||||
{
|
||||
pwm.channels[i].duty = blue;
|
||||
pwm.channels[i++].channel = upper->chanb;
|
||||
}
|
||||
|
||||
upper->ledb.frequency = 100;
|
||||
upper->ledb.duty = blue;
|
||||
ledr->ops->start(ledr, &pwm);
|
||||
|
||||
ledb->ops->start(ledb, &upper->ledb);
|
||||
for (i = 0; i < CONFIG_PWM_NCHANNELS; i++)
|
||||
{
|
||||
pwm.channels[i].channel = 0;
|
||||
}
|
||||
|
||||
/* If the green timer is not the same as the red timer, update it seperately */
|
||||
|
||||
if (ledg != ledr)
|
||||
{
|
||||
i = 0;
|
||||
pwm.channels[i].duty = green;
|
||||
pwm.channels[i++].channel = upper->chang;
|
||||
|
||||
/* If the blue pwm source is on the same timer as the green,
|
||||
* set that up now too */
|
||||
|
||||
if (ledg == ledb)
|
||||
{
|
||||
pwm.channels[i].duty = blue;
|
||||
pwm.channels[i++].channel = upper->chanb;
|
||||
}
|
||||
|
||||
ledg->ops->start(ledg, &pwm);
|
||||
|
||||
for (i = 0; i < CONFIG_PWM_NCHANNELS; i++)
|
||||
{
|
||||
pwm.channels[i].channel = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* If the blue timer is not the same as the red or green timer, update it seperately */
|
||||
|
||||
if (ledb != ledr && ledb != ledg)
|
||||
{
|
||||
pwm.channels[0].duty = green;
|
||||
pwm.channels[0].channel = upper->chanb;
|
||||
|
||||
ledb->ops->start(ledb, &pwm);
|
||||
}
|
||||
#else
|
||||
pwminfo.frequency = 100;
|
||||
|
||||
pwminfo.duty = red;
|
||||
ledr->ops->start(ledr, &pwminfo);
|
||||
|
||||
pwminfo.duty = green;
|
||||
ledg->ops->start(ledg, &pwminfo);
|
||||
|
||||
pwminfo.duty = blue;
|
||||
ledb->ops->start(ledb, &pwminfo);
|
||||
#endif
|
||||
|
||||
return buflen;
|
||||
}
|
||||
@@ -437,7 +499,11 @@ static ssize_t rgbled_write(FAR struct file *filep, FAR const char *buffer,
|
||||
|
||||
int rgbled_register(FAR const char *path, FAR struct pwm_lowerhalf_s *ledr,
|
||||
FAR struct pwm_lowerhalf_s *ledg,
|
||||
FAR struct pwm_lowerhalf_s *ledb)
|
||||
FAR struct pwm_lowerhalf_s *ledb
|
||||
#ifdef CONFIG_PWM_MULTICHAN
|
||||
, int chanr, int chang, int chanb
|
||||
#endif
|
||||
)
|
||||
{
|
||||
FAR struct rgbled_upperhalf_s *upper;
|
||||
|
||||
@@ -461,6 +527,12 @@ int rgbled_register(FAR const char *path, FAR struct pwm_lowerhalf_s *ledr,
|
||||
upper->devledg = ledg;
|
||||
upper->devledb = ledb;
|
||||
|
||||
#ifdef CONFIG_PWM_MULTICHAN
|
||||
upper->chanr = chanr;
|
||||
upper->chang = chang;
|
||||
upper->chanb = chanb;
|
||||
#endif
|
||||
|
||||
/* Register the PWM device */
|
||||
|
||||
lcdinfo("Registering %s\n", path);
|
||||
|
||||
@@ -88,7 +88,11 @@ extern "C"
|
||||
|
||||
int rgbled_register(FAR const char *path, FAR struct pwm_lowerhalf_s *ledr,
|
||||
FAR struct pwm_lowerhalf_s *ledg,
|
||||
FAR struct pwm_lowerhalf_s *ledb);
|
||||
FAR struct pwm_lowerhalf_s *ledb
|
||||
#ifdef CONFIG_PWM_MULTICHAN
|
||||
, int chanr, int chang, int chanb
|
||||
#endif
|
||||
);
|
||||
|
||||
#undef EXTERN
|
||||
#ifdef __cplusplus
|
||||
|
||||
Reference in New Issue
Block a user