diff --git a/drivers/leds/rgbled.c b/drivers/leds/rgbled.c index f5a9910f705..57e150188bc 100644 --- a/drivers/leds/rgbled.c +++ b/drivers/leds/rgbled.c @@ -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); diff --git a/include/nuttx/leds/rgbled.h b/include/nuttx/leds/rgbled.h index 4fb192dc330..a5a495641ba 100644 --- a/include/nuttx/leds/rgbled.h +++ b/include/nuttx/leds/rgbled.h @@ -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