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:
Anthony Merlino
2018-05-02 22:21:49 +00:00
committed by Gregory Nutt
parent 800da58e6c
commit 385d4a9108
2 changed files with 94 additions and 18 deletions
+89 -17
View File
@@ -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);
+5 -1
View File
@@ -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