drivers/lcd: Add and IOCTL command to fade the backlight on and off.

This commit is contained in:
Gregory Nutt 2018-02-23 10:44:10 -06:00
parent 52d54b2451
commit a903572ff6
3 changed files with 144 additions and 1 deletions

View File

@ -61,6 +61,7 @@
#include <nuttx/semaphore.h>
#include <nuttx/signal.h>
#include <nuttx/kmalloc.h>
#include <nuttx/clock.h>
#include <nuttx/wqueue.h>
#include <nuttx/fs/fs.h>
#include <nuttx/i2c/i2c_master.h>
@ -90,10 +91,17 @@
# error No FT80x device configured
#endif
#define MIN_FADE_DELAY 10 /* Milliseconds */
#define MAX_FADE_DELAY 16700 /* Milliseconds */
#define FADE_STEP_MSEC 10 /* Milliseconds */
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
static int ft80x_fade(FAR struct ft80x_dev_s *priv,
FAR const struct ft80x_fade_s *fade);
static void ft80x_notify(FAR struct ft80x_dev_s *priv,
enum ft80x_notify_e event, int value);
static void ft80x_interrupt_work(FAR void *arg);
@ -144,6 +152,103 @@ static const struct file_operations g_ft80x_fops =
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: ft80x_fade
*
* Description:
* Change the backlight intensity with a controllable fade.
*
****************************************************************************/
static int ft80x_fade(FAR struct ft80x_dev_s *priv,
FAR const struct ft80x_fade_s *fade)
{
systime_t start;
systime_t elapsed;
int32_t delay;
int32_t duty;
int16_t endduty;
int16_t delta;
/* 0% corresponds to the value 0, but 100% corresponds to the value 128 */
endduty = (uint16_t)((uint16_t)fade->duty << 7) / 100;
/* Get the change in duty from the current to the terminal duty. */
duty = (int32_t)(ft80x_read_byte(priv, FT80X_REG_PWM_DUTY) & 0x7f);
delta = endduty - (int16_t)duty;
/* The "smoothness" of the steps will depend on the resolution of the
* system timer. The minimum delay is <= 2 * system_clock_period.
*
* We will try for a FADE_STEP_MSEC delay, but we will try to adapt to
* whatever we get is we are working close the system time resolution.
* For human factors reasons, any delay less than 100 MS or so should
* appear more or less smooth.
*
* The delay calculation should never overflow:
*
* Max delay: 16,700 msec (MAX_FADE_DELAY)
* Min clock period: 1 usec
* Max delay: 16,700,000 ticks
* INT32_MAX 2,147,483,647
*/
delay = MSEC2TICK((int32_t)fade->delay);
if (delay <= 0)
{
delay = 1;
}
start = clock_systimer();
do
{
/* Wait for FADE_STEP_MSEC msec (or whatever we get) */
(void)nxsig_usleep(FADE_STEP_MSEC * 1000);
/* Get the elapsed time */
elapsed = clock_systimer() - start;
if (elapsed > INT32_MAX || (int32_t)elapsed >= delay)
{
duty = endduty;
}
else
{
/* Interpolate to get the next PWM duty in the fade. This
* calculation should never overflow:
*
* Max delta: 128
* Max elapsed: 16,700,000 ticks
* Max numerator: 2,137,600,000
* Min denominator: 1
* Max duty: 2,137,600,000
* INT32_MAX 2,147,483,647
*/
duty += ((int32_t)delta * (int32_t)elapsed) / delay;
if (duty > 128)
{
duty = 128;
}
else if (duty < 0)
{
duty = 0;
}
}
/* The set the new backlight PWM duty */
ft80x_write_byte(priv, FT80X_REG_PWM_DUTY, (uint8_t)duty);
}
while (duty != endduty);
return OK;
}
/****************************************************************************
* Name: ft80x_notify
*
@ -959,6 +1064,30 @@ static int ft80x_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
}
break;
/* FT80X_IOC_FADE:
* Description: Change the backlight intensity with a controllable
* fade.
* Argument: A reference to an instance of struct ft80x_fade_s.
* Returns: None.
*/
case FT80X_IOC_FADE:
{
FAR const struct ft80x_fade_s *fade =
(FAR const struct ft80x_fade_s *)((uintptr_t)arg);
if (fade == NULL || fade->duty > 100 ||
fade->delay < MIN_FADE_DELAY || fade->delay > MAX_FADE_DELAY)
{
ret = -EINVAL;
}
else
{
ret = ft80x_fade(priv, fade);
}
}
break;
/* Unrecognized IOCTL command */
default:

View File

@ -191,6 +191,11 @@
* indicate only the tag value for TOUCH0.
* Argument: A reference to an instance of struct ft80x_notify_s.
* Returns: None
*
* FT80X_IOC_FADE:
* Description: Change the backlight intensity with a controllable fade.
* Argument: A reference to an instance of struct ft80x_fade_s below.
* Returns: None.
*/
#define FT80X_IOC_CREATEDL _LCDIOC(FT80X_NIOCTL_BASE + 0)
@ -207,6 +212,7 @@
#define FT80X_IOC_PUTREG32 _LCDIOC(FT80X_NIOCTL_BASE + 11)
#define FT80X_IOC_PUTREGS _LCDIOC(FT80X_NIOCTL_BASE + 12)
#define FT80X_IOC_EVENTNOTIFY _LCDIOC(FT80X_NIOCTL_BASE + 13)
#define FT80X_IOC_FADE _LCDIOC(FT80X_NIOCTL_BASE + 14)
/* FT80x Memory Map *************************************************************************/
@ -1447,6 +1453,14 @@ struct ft80x_registers_s
FAR uint32_t *value; /* A pointer to an array of 32-bit register values */
};
/* Used with FT80X_IOC_FADE: */
struct ft80x_fade_s
{
uint8_t duty ; /* Terminal backlight duty as a percentage (0-100) */
uint16_t delay; /* Total number of milliseconds for the fade (10-16700)*/
};
/********************************************************************************************
* Public Function Prototypes
********************************************************************************************/

View File

@ -50,7 +50,7 @@
/* IOCTL commands set aside for FT80x character driver */
#define FT80X_NIOCTL_CMDS 14
#define FT80X_NIOCTL_CMDS 15
#define FT80X_NIOCTL_BASE 0x0001
#endif /* __INCLUDE_NUTTX_INPUT_LCD_IOCTL_H */