From 8fe9e811837ce789f413cc327c5c9acbbdcfcfaf Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Tue, 27 Feb 2018 08:45:34 -0600 Subject: [PATCH] drivers/lcd: Add FT80x controls for the case where the audio amplifier is controlled by FT80x GPIOs vs MCU gpios. --- configs/viewtool-stm32f107/README.txt | 13 +++++ configs/viewtool-stm32f107/ft80x/defconfig | 1 + configs/viewtool-stm32f107/src/stm32_ft80x.c | 6 ++ drivers/lcd/Kconfig | 32 +++++++++++ drivers/lcd/ft80x.c | 59 ++++++++++++++++++++ include/nuttx/lcd/ft80x.h | 24 ++++++++ include/nuttx/lcd/lcd_ioctl.h | 2 +- 7 files changed, 136 insertions(+), 1 deletion(-) diff --git a/configs/viewtool-stm32f107/README.txt b/configs/viewtool-stm32f107/README.txt index db17063653..859fdb3412 100644 --- a/configs/viewtool-stm32f107/README.txt +++ b/configs/viewtool-stm32f107/README.txt @@ -526,6 +526,12 @@ FT80x Integration 7 INT J18 Pin 8 PA1 8 PD J18 Pin 6 PC5 9 AUDIO-L 10 GND J18 Pin 4 + The Haoyu display has no audio amplifier on board; Output is raw PWM + audio. MikroElektronkia ConnectEVE FT800. + + GPIO0 and MODE are pulled low meaning that SPI is the default interface + with slave address bit 0 = 0. GPIO1 is not connected. + MikroElektronkia ConnectEVE FT800 --------------------------------- @@ -618,6 +624,13 @@ FT80x Integration PB4/MISO1 also used by JTAG PB5/MOSI1 also used by USART1, Ethernet, and J28 pin 10 + There is a LM4864 audio amplifier on board so audio outputs are ready for + use with a small 1W 8Ohm speaker. GPIO0 should be configured as an + output because it is used to control the shutdown pin of the LM4864 audio + output. + + GPIO0 is not connected. + Toolchains ========== diff --git a/configs/viewtool-stm32f107/ft80x/defconfig b/configs/viewtool-stm32f107/ft80x/defconfig index 3b14136e5e..36c14a5f14 100644 --- a/configs/viewtool-stm32f107/ft80x/defconfig +++ b/configs/viewtool-stm32f107/ft80x/defconfig @@ -14,6 +14,7 @@ CONFIG_EXPERIMENTAL=y CONFIG_FS_PROCFS=y CONFIG_HOST_WINDOWS=y CONFIG_INTELHEX_BINARY=y +CONFIG_LCD_FT80X_AUDIO_GPIOSHUTDOWN=y CONFIG_LCD_FT80X=y CONFIG_LCD=y CONFIG_MAX_TASKS=16 diff --git a/configs/viewtool-stm32f107/src/stm32_ft80x.c b/configs/viewtool-stm32f107/src/stm32_ft80x.c index 61691e5b2b..3d0ee13480 100644 --- a/configs/viewtool-stm32f107/src/stm32_ft80x.c +++ b/configs/viewtool-stm32f107/src/stm32_ft80x.c @@ -101,7 +101,9 @@ static void ft80x_clear(FAR const struct ft80x_config_s *lower); static void ft80x_pwrdown(FAR const struct ft80x_config_s *lower, bool pwrdown); +#ifdef CONFIG_LCD_FT80X_AUDIO_MCUSHUTDOWN static void ft80x_audio(FAR const struct ft80x_config_s *lower, bool enable); +#endif #ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS static void ft80x_destroy(FAR const struct ft80x_config_s *lower); #endif @@ -131,7 +133,9 @@ static struct viewtool_ft80xlower_s g_ft80xlower = .enable = ft80x_enable, .clear = ft80x_clear, .pwrdown = ft80x_pwrdown, +#ifdef CONFIG_LCD_FT80X_AUDIO_MCUSHUTDOWN .audio = ft80x_audio, +#endif #ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS .destroy = ft80x_destroy, #endif @@ -235,10 +239,12 @@ static void ft80x_pwrdown(FAR const struct ft80x_config_s *lower, stm32_gpiowrite(GPIO_FT80_PD, !pwrdown); } +#ifdef CONFIG_LCD_FT80X_AUDIO_MCUSHUTDOWN static void ft80x_audio(FAR const struct ft80x_config_s *lower, bool enable) { /* Does nothing */ } +#endif #ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS static void ft80x_destroy(FAR const struct ft80x_config_s *lower) diff --git a/drivers/lcd/Kconfig b/drivers/lcd/Kconfig index c4eca0d530..08f99f6c54 100644 --- a/drivers/lcd/Kconfig +++ b/drivers/lcd/Kconfig @@ -1227,6 +1227,38 @@ config LCD_FT80X_QVGA bool "QVGA 320x240" endchoice # Display size + +choice + prompt "Audio Shutdown Options" + default LCD_FT80X_AUDIO_NOSHUTDOWN + +config LCD_FT80X_AUDIO_NOSHUTDOWN + bool "No amplifier shutdown control" + ---help--- + There is no audio amplifier or the audio amplifier is not under + software control. + +config LCD_FT80X_AUDIO_MCUSHUTDOWN + bool "MCU controls audio shutdown" + ---help--- + The audio amplifier is controlled via an MCU GPIO output pin. + +config LCD_FT80X_AUDIO_GPIOSHUTDOWN + bool "FT80X controls audio shutdown" + ---help--- + The audio amplifier is controlled via an FT80x GPIO output pin. + +endchoice # Audio Shutdown Option + +config LCD_FT80X_AUDIO_GPIO + int "FT80x audio shutdown GPIO" + default 0 + range 0 1 + depends on LCD_FT80X_AUDIO_GPIOSHUTDOWN + ---help--- + Identifies the GPIO pin used to control the amplifier shutdown + output. + endif # LCD_FT80X endmenu # LCD Driver selection diff --git a/drivers/lcd/ft80x.c b/drivers/lcd/ft80x.c index 46ff000a3a..0a06564d28 100644 --- a/drivers/lcd/ft80x.c +++ b/drivers/lcd/ft80x.c @@ -1088,6 +1088,55 @@ static int ft80x_ioctl(FAR struct file *filep, int cmd, unsigned long arg) } break; + /* FT80X_IOC_AUDIO: + * Description: Enable/disable an external audio amplifer. + * Argument: 0=disable; 1=enable. + * Returns: None. + */ + + case FT80X_IOC_AUDIO: + { +#if defined(CONFIG_LCD_FT80X_AUDIO_MCUSHUTDOWN) + /* Amplifier is controlled by an MCU GPIO pin */ + + DEBUGASSERT(priv->lower->attach != NULL && priv->lower->audio != NULL); + DEBUGASSERT(arg == 0 || arg == 1); + + priv->lower->audio(priv->lower, (arg != 0)); + ret = OK; + +#elif defined(CONFIG_LCD_FT80X_AUDIO_GPIOSHUTDOWN) + /* Amplifier is controlled by an FT80x GPIO pin */ + + uint8_t regval8; + + DEBUGASSERT(arg == 0 || arg == 1); + + regval8 = ft80x_read_byte(priv, FT80X_REG_GPIO); + + /* Active low logic assumed */ + + if (arg == 0) + { + regval8 |= (1 << CONFIG_LCD_FT80X_AUDIO_GPIO); + } + else + { + regval8 &= ~(1 << CONFIG_LCD_FT80X_AUDIO_GPIO); + } + + ft80x_write_byte(priv, FT80X_REG_GPIO, regval8); + ret = OK; + +#else + /* Amplifier is not controllable. */ + + DEBUGASSERT(arg == 0 || arg == 1); + return OK; +#endif + } + break; + /* Unrecognized IOCTL command */ default: @@ -1360,14 +1409,24 @@ static int ft80x_initialize(FAR struct ft80x_dev_s *priv) * be enabled by writing value of 1 into GPIO bit 7 or the display can be * disabled by writing a value of 0 into GPIO bit 7. By default GPIO bit 7 * direction is output and the value is 0. + * + * If an external audio amplified is controlled by an FT80x GPIO, then + * configure that GPIO as well. Active low logic is assumed so that the + * amplifier is initially in the shutdown state. */ regval8 = ft80x_read_byte(priv, FT80X_REG_GPIO_DIR); regval8 |= (1 << 7); +#ifdef CONFIG_LCD_FT80X_AUDIO_GPIOSHUTDOWN + regval8 |= (1 << CONFIG_LCD_FT80X_AUDIO_GPIO); +#endif ft80x_write_byte(priv, FT80X_REG_GPIO_DIR, regval8); regval8 = ft80x_read_byte(priv, FT80X_REG_GPIO); regval8 |= (1 << 7); +#ifdef CONFIG_LCD_FT80X_AUDIO_GPIOSHUTDOWN + regval8 |= (1 << CONFIG_LCD_FT80X_AUDIO_GPIO); +#endif ft80x_write_byte(priv, FT80X_REG_GPIO, regval8); /* 7. Enable back light control for display */ diff --git a/include/nuttx/lcd/ft80x.h b/include/nuttx/lcd/ft80x.h index 26b41ebbdb..fc09ea6093 100644 --- a/include/nuttx/lcd/ft80x.h +++ b/include/nuttx/lcd/ft80x.h @@ -196,6 +196,11 @@ * Description: Change the backlight intensity with a controllable fade. * Argument: A reference to an instance of struct ft80x_fade_s below. * Returns: None. + * + * FT80X_IOC_AUDIO: + * Description: Enable/disable an external audio amplifer. + * Argument: 0=disable; 1=enable. + * Returns: None. */ #define FT80X_IOC_CREATEDL _LCDIOC(FT80X_NIOCTL_BASE + 0) @@ -213,6 +218,7 @@ #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) +#define FT80X_IOC_AUDIO _LCDIOC(FT80X_NIOCTL_BASE + 15) /* FT80x Memory Map *************************************************************************/ @@ -564,6 +570,19 @@ #define FT08X_NOTE_B7 ((uint16_t)107 << 8) /* B7, 3951.1 Hz */ #define FT08X_NOTE_C8 ((uint16_t)108 << 8) /* C8, 4186.0 Hz */ +/* FT80X_REG_GPIO */ + + /* Bits 0-1: GPIO 0-1 value */ + /* Bits 2-3: MISO and nINT drive strength */ + /* Bits 4: Display signal drive strength */ +#define FT80X_GPIO_DRIVE_SHIFT 5 /* Bits 5-6: GPIO output drive strength */ +#define FT80X_GPIO_DRIVE_MASK (3 << FT80X_GPIO_DRIVE_SHIFT) +# define FT80X_GPIO_DRIVE_4MA (0 << FT80X_GPIO_DRIVE_SHIFT) +# define FT80X_GPIO_DRIVE_8MA (1 << FT80X_GPIO_DRIVE_SHIFT) +# define FT80X_GPIO_DRIVE_12MA (2 << FT80X_GPIO_DRIVE_SHIFT) +# define FT80X_GPIO_DRIVE_16MA (3 << FT80X_GPIO_DRIVE_SHIFT) + /* Bit 7: GPIO 7 value */ + /* FT80X_REG_PLAYBACK_FORMAT */ #define AUDIO_FORMAT_LINEAR 0 /* Linear Sample format */ @@ -1021,6 +1040,9 @@ * * N/A O nSHDN Audio shutdown (active low) * + * REVISIT: In all of the architectures that I am aware of, the audio amplifier is + * controlled by GPIOs driven by the FT80x and, hence, not controllable by board logic. + * * SCL/SDA, SCLK/MISO/MOSI/nCS are handled by generic I2C or SPI logic. nInt and nPD are * directly managed by this interface. */ @@ -1061,7 +1083,9 @@ struct ft80x_config_s CODE void (*enable)(FAR const struct ft80x_config_s *lower, bool enable); CODE void (*clear)(FAR const struct ft80x_config_s *lower); CODE void (*pwrdown)(FAR const struct ft80x_config_s *lower, bool pwrdown); +#ifdef CONFIG_LCD_FT80X_AUDIO_MCUSHUTDOWN CODE void (*audio)(FAR const struct ft80x_config_s *lower, bool enable); +#endif #ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS CODE void (*destroy)(FAR const struct ft80x_config_s *lower); #endif diff --git a/include/nuttx/lcd/lcd_ioctl.h b/include/nuttx/lcd/lcd_ioctl.h index 5d43e58227..054edbea90 100644 --- a/include/nuttx/lcd/lcd_ioctl.h +++ b/include/nuttx/lcd/lcd_ioctl.h @@ -50,7 +50,7 @@ /* IOCTL commands set aside for FT80x character driver */ -#define FT80X_NIOCTL_CMDS 15 +#define FT80X_NIOCTL_CMDS 16 #define FT80X_NIOCTL_BASE 0x0001 #endif /* __INCLUDE_NUTTX_INPUT_LCD_IOCTL_H */