This commit adds a barbones FTDI FT80x driver. It is untested (I don't even have hardware yet and, hence, it is marked as EXPERIMENTAL
Squashed commit of the following: drivers/lcd: Finishes off basic FT80X. Still missing some niceties. drivers/lcd: Rethink FT80X display list interface. drivers/lcd: More FT800x display list logic. Still not complete. drivers/lcd: Add some basic FT80x initialization logic. drivers/lcd: Add ft80x display list IOCTL framework. Still missing low level display list operations. drivers/lcd: FT80x driver cannot be a standard LCD driver but must, instead, be a custom character driver. drivers/lcd: Add FT800 co-processor commands and display list helpers. drivers/lcd: Add SPI interface and framework for the initialization and the basic LCD driver. drivers/lcd: Add beginnings of some FT80x implementation. drivers/lcd: Add definitions for the FTDI FT801 part include/nuttx/lcd/ft800.h: Add initial FT800 interface definition. drivers/lcd: Add ft800 header file.
This commit is contained in:
parent
d040316143
commit
6a405ead67
|
@ -1173,6 +1173,61 @@ config LCD_RA8875_EXTENDED
|
|||
driver anyway.
|
||||
|
||||
endif # LCD_RA8875
|
||||
|
||||
config LCD_FT80X
|
||||
bool "FTDI FT80x GUI Controller"
|
||||
default n
|
||||
depends on EXPERIMENTAL
|
||||
---help---
|
||||
Integrated LCD, Audio, Touchscreen controller driver for the FTDI
|
||||
FT80x "EVE" series.
|
||||
|
||||
if LCD_FT80X
|
||||
|
||||
choice
|
||||
prompt "FTDI FT80x part"
|
||||
default LCD_FT800
|
||||
|
||||
config LCD_FT800
|
||||
bool "FT800"
|
||||
|
||||
config LCD_FT801
|
||||
bool "FT801"
|
||||
|
||||
endchoice # FTDI FT80x part
|
||||
|
||||
choice
|
||||
prompt "FTDI FT80x Interface"
|
||||
default LCD_FT80X_SPI
|
||||
|
||||
config LCD_FT80X_SPI
|
||||
bool "SPI"
|
||||
select SPI
|
||||
|
||||
config LCD_FT80X_I2C
|
||||
bool "I2C"
|
||||
select I2C
|
||||
|
||||
endchoice # FTDI FT80x Interface
|
||||
|
||||
config LCD_FT801_MULTITOUCH
|
||||
bool "FT801 Multi-touch"
|
||||
default n
|
||||
depends on LCD_FT801
|
||||
|
||||
choice
|
||||
prompt "Display size"
|
||||
default LCD_FT80X_WQVGA
|
||||
|
||||
config LCD_FT80X_WQVGA
|
||||
bool "WQVGA 480x272"
|
||||
|
||||
config LCD_FT80X_QVGA
|
||||
bool "QVGA 320x240"
|
||||
|
||||
endchoice # Display size
|
||||
endif # LCD_FT80X
|
||||
|
||||
endmenu # LCD Driver selection
|
||||
endif # LCD
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
############################################################################
|
||||
# drivers/lcd/Make.defs
|
||||
#
|
||||
# Copyright (C) 2010-2012, 2017 Gregory Nutt. All rights reserved.
|
||||
# Copyright (C) 2010-2012, 2017-2018 Gregory Nutt. All rights reserved.
|
||||
# Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
|
@ -43,6 +43,15 @@ endif
|
|||
|
||||
# Include support for Graphics LCD drivers
|
||||
|
||||
ifeq ($(CONFIG_LCD_FT80X),y)
|
||||
CSRCS += ft80x_base.c
|
||||
ifeq ($(CONFIG_LCD_FT80X_SPI),y)
|
||||
CSRCS += ft80x_spi.c
|
||||
else ifeq ($(CONFIG_LCD_FT80X_I2C),y)
|
||||
CSRCS += ft80x_i2c.c
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_LCD_P14201),y)
|
||||
CSRCS += p14201.c
|
||||
endif
|
||||
|
|
|
@ -0,0 +1,448 @@
|
|||
/*******************************************************************************************
|
||||
* drivers/lcd/ft80x.h
|
||||
* Definitions for the FTDI FT80x GUI
|
||||
*
|
||||
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* References:
|
||||
* - Document No.: FT_000792, "FT800 Embedded Video Engine", Datasheet Version 1.1,
|
||||
* Clearance No.: FTDI# 334, Future Technology Devices International Ltd.
|
||||
* - Document No.: FT_000986, "FT801 Embedded Video Engine Datasheet", Version 1.0,
|
||||
* Clearance No.: FTDI#376, Future Technology Devices International Ltd.
|
||||
* - Some definitions derive from FTDI sample code.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*******************************************************************************************/
|
||||
|
||||
#ifndef __DRIVERS_LCD_FT80X_H
|
||||
#define __DRIVERS_LCD_FT80X_H
|
||||
|
||||
/*******************************************************************************************
|
||||
* Included Files
|
||||
*******************************************************************************************/
|
||||
|
||||
/*******************************************************************************************
|
||||
* Pre-processor Definitions
|
||||
*******************************************************************************************/
|
||||
|
||||
/* FT80x Memory Map ************************************************************************/
|
||||
|
||||
/* Address region */
|
||||
|
||||
#define FT80X_RAM_G 0x000000 /* Main graphics RAM (256Kb) */
|
||||
#define FT80X_ROM_CHIPID 0x0c0000 /* FT80x chip identification and revision
|
||||
* information (4b):
|
||||
* Byte [0:1] Chip ID: 0800 or 0801
|
||||
* Byte [2:3] Version ID: 0100 */
|
||||
#define FT80X_ROM_FONT 0x0bb23c /* Font table and bitmap (275Kb) */
|
||||
#define FT80X_ROM_FONT_ADDR 0x0ffffc /* Font table pointer address (4b) */
|
||||
#define FT80X_RAM_DL 0x100000 /* Display List RAM (8Kb) */
|
||||
#define FT80X_RAM_PAL 0x102000 /* Palette RAM (1Kb) */
|
||||
#define FT80X_REG 0x102400 /* Registers (380b) */
|
||||
#define FT80X_RAM_CMD 0x108000 /* Command Buffer (4Kb) */
|
||||
|
||||
#ifdef CONFIG_LCD_FT801
|
||||
# define FT80X_RAM_SCREENSHOT 0x1c2000 /* Screenshot readout buffer (2Kb) */
|
||||
#endif
|
||||
|
||||
/* Memory buffer sizes */
|
||||
|
||||
#define FT80X_RAM_G_SIZE (256 * 1024)
|
||||
#define FT80X_CMDFIFO_SIZE (4 * 1024)
|
||||
#define FT80X_RAM_DL_SIZE (8 * 1024)
|
||||
#define FT80X_RAM_PAL_SIZE (1 * 1024)
|
||||
|
||||
/* FT80x Register Addresses ****************************************************************/
|
||||
|
||||
#define FT80X_REG_ID 0x102400 /* Identification register, always reads as 7c */
|
||||
#define FT80X_REG_FRAMES 0x102404 /* Frame counter, since reset */
|
||||
#define FT80X_REG_CLOCK 0x102408 /* Clock cycles, since reset */
|
||||
#define FT80X_REG_FREQUENCY 0x10240c /* Main clock frequency */
|
||||
|
||||
#if defined(CONFIG_LCD_FT800)
|
||||
# define FT80X_REG_RENDERMODE 0x102410 /* Rendering mode: 0 = normal, 1 = single-line */
|
||||
# define FT80X_REG_SNAPY 0x102414 /* Scan line select for RENDERMODE 1 */
|
||||
# define FT80X_REG_SNAPSHOT 0x102418 /* Trigger for RENDERMODE 1 */
|
||||
#elif defined(CONFIG_LCD_FT801)
|
||||
# define FT80X_REG_SCREENSHOT_EN 0x102410 /* Set to enable screenshot mode */
|
||||
# define FT80X_REG_SCREENSHOT_Y 0x102414 /* Y line number for screenshot */
|
||||
# define FT80X_REG_SCREENSHOT_START 0x102418 /* Screenshot start trigger */
|
||||
#endif
|
||||
|
||||
#define FT80X_REG_CPURESET 0x10241c /* Graphics, audio and touch engines reset
|
||||
* control */
|
||||
#define FT80X_REG_TAP_CRC 0x102420 /* Live video tap crc. Frame CRC is computed
|
||||
* every DL SWAP. */
|
||||
#define FT80X_REG_TAP_MASK 0x102424 /* Live video tap mask */
|
||||
#define FT80X_REG_HCYCLE 0x102428 /* Horizontal total cycle count */
|
||||
#define FT80X_REG_HOFFSET 0x10242c /* Horizontal display start offset */
|
||||
#define FT80X_REG_HSIZE 0x102430 /* Horizontal display pixel count */
|
||||
#define FT80X_REG_HSYNC0 0x102434 /* Horizontal sync fall offset */
|
||||
#define FT80X_REG_HSYNC1 0x102438 /* Horizontal sync rise offset */
|
||||
#define FT80X_REG_VCYCLE 0x10243c /* Vertical total cycle count */
|
||||
#define FT80X_REG_VOFFSET 0x102440 /* Vertical display start offset */
|
||||
#define FT80X_REG_VSIZE 0x102444 /* Vertical display line count */
|
||||
#define FT80X_REG_VSYNC0 0x102448 /* Vertical sync fall offset */
|
||||
#define FT80X_REG_VSYNC1 0x10244c /* Vertical sync rise offset */
|
||||
#define FT80X_REG_DLSWAP 0x102450 /* Display list swap control */
|
||||
#define FT80X_REG_ROTATE 0x102454 /* Screen 180 degree rotate */
|
||||
#define FT80X_REG_OUTBITS 0x102458 /* Output bit resolution, 3x3x3 bits */
|
||||
#define FT80X_REG_DITHER 0x10245c /* Output dither enable */
|
||||
#define FT80X_REG_SWIZZLE 0x102460 /* Output RGB signal swizzle */
|
||||
#define FT80X_REG_CSPREAD 0x102464 /* Output clock spreading enable */
|
||||
#define FT80X_REG_PCLK_POL 0x102468 /* PCLK polarity: 0=rising edge, 1= falling edge */
|
||||
#define FT80X_REG_PCLK 0x10246c /* PCLK frequency divider, 0 = disable */
|
||||
#define FT80X_REG_TAG_X 0x102470 /* Tag query X coordinate */
|
||||
#define FT80X_REG_TAG_Y 0x102474 /* Tag query Y coordinate */
|
||||
#define FT80X_REG_TAG 0x102478 /* Tag query result */
|
||||
#define FT80X_REG_VOL_PB 0x10247c /* Volume for playback */
|
||||
#define FT80X_REG_VOL_SOUND 0x102480 /* Volume for synthesizer sound */
|
||||
#define FT80X_REG_SOUND 0x102484 /* Sound effect select */
|
||||
#define FT80X_REG_PLAY 0x102488 /* Start effect playback */
|
||||
#define FT80X_REG_GPIO_DIR 0x10248c /* GPIO pin direction, 0=input, 1=output */
|
||||
#define FT80X_REG_GPIO 0x102490 /* Pin value (bits 0,1,7); Drive strength
|
||||
* (bits 2-6) */
|
||||
/* 0x102494 Reserved */
|
||||
#define FT80X_REG_INT_FLAGS 0x102498 /* Interrupt flags, clear by read */
|
||||
#define FT80X_REG_INT_EN 0x10249c /* Global interrupt enable */
|
||||
#define FT80X_REG_INT_MASK 0x1024a0 /* Interrupt enable mask */
|
||||
#define FT80X_REG_PLAYBACK_START 0x1024a4 /* Audio playback RAM start address */
|
||||
#define FT80X_REG_PLAYBACK_LENGTH 0x1024a8 /* Audio playback sample length (bytes) */
|
||||
#define FT80X_REG_PLAYBACK_READPTR 0x1024ac /* Audio playback current read pointer */
|
||||
#define FT80X_REG_PLAYBACK_FREQ 0x1024b0 /* Audio playback sampling frequency (Hz) */
|
||||
#define FT80X_REG_PLAYBACK_FORMAT 0x1024b4 /* Audio playback format */
|
||||
#define FT80X_REG_PLAYBACK_LOOP 0x1024b8 /* Audio playback loop enable */
|
||||
#define FT80X_REG_PLAYBACK_PLAY 0x1024bc /* Start audio playback */
|
||||
#define FT80X_REG_PWM_HZ 0x1024c0 /* BACKLIGHT PWM output frequency (Hz) */
|
||||
#define FT80X_REG_PWM_DUTY 0x1024c4 /* BACKLIGHT PWM output duty cycle 0=0%,
|
||||
* 128=100% */
|
||||
#define FT80X_REG_MACRO_0 0x1024c8 /* Display list macro command 0 */
|
||||
#define FT80X_REG_MACRO_1 0x1024cc /* Display list macro command 1 */
|
||||
|
||||
#if defined(CONFIG_LCD_FT800)
|
||||
/* 0x1024d0 – 0x1024e0 Reserved */
|
||||
#elif defined(CONFIG_LCD_FT801)
|
||||
/* 0x1024d0 – 0x1024d4 Reserved */
|
||||
# define FT80X_REG_SCREENSHOT_BUSY 0x1024d8 /* Screenshot ready flags */
|
||||
/* 0x1024e0 Reserved */
|
||||
#endif
|
||||
|
||||
#define FT80X_REG_CMD_READ 0x1024e4 /* Command buffer read pointer */
|
||||
#define FT80X_REG_CMD_WRITE 0x1024e8 /* Command buffer write pointer */
|
||||
#define FT80X_REG_CMD_DL 0x1024ec /* Command display list offset */
|
||||
#define FT80X_REG_TOUCH_MODE 0x1024f0 /* Touch-screen sampling mode */
|
||||
|
||||
#if defined(CONFIG_LCD_FT800)
|
||||
# define FT80X_REG_TOUCH_ADC_MODE 0x1024f4 /* Select single ended (low power) or
|
||||
* differential (accurate) sampling */
|
||||
# define FT80X_REG_TOUCH_CHARGE 0x1024f8 /* Touch-screen charge time, units of 6 clocks */
|
||||
# define FT80X_REG_TOUCH_SETTLE 0x1024fc /* Touch-screen settle time, units of 6 clocks */
|
||||
# define FT80X_REG_TOUCH_OVERSAMPLE 0x102500 /* Touch-screen oversample factor */
|
||||
# define FT80X_REG_TOUCH_RZTHRESH 0x102504 /* Touch-screen resistance threshold */
|
||||
# define FT80X_REG_TOUCH_RAW_XY 0x102508 /* Touch-screen raw (x-MSB16; y-LSB16) */
|
||||
# define FT80X_REG_TOUCH_RZ 0x10250c /* Touch-screen resistance */
|
||||
# define FT80X_REG_TOUCH_SCREEN_XY 0x102510 /* Touch-screen screen (x-MSB16; y-LSB16) */
|
||||
# define FT80X_REG_TOUCH_TAG_XY 0x102514 /* Touch-screen screen (x-MSB16; y-LSB16)
|
||||
* used for tag lookup */
|
||||
# define FT80X_REG_TOUCH_TAG 0x102518 /* Touch-screen tag result */
|
||||
# define FT80X_REG_TOUCH_TRANSFORM_A 0x10251c /* Touch-screen transform coefficient (s15.16) */
|
||||
# define FT80X_REG_TOUCH_TRANSFORM_B 0x102520 /* Touch-screen transform coefficient (s15.16) */
|
||||
# define FT80X_REG_TOUCH_TRANSFORM_C 0x102524 /* Touch-screen transform coefficient (s15.16) */
|
||||
# define FT80X_REG_TOUCH_TRANSFORM_D 0x102528 /* Touch-screen transform coefficient (s15.16) */
|
||||
# define FT80X_REG_TOUCH_TRANSFORM_E 0x10252c /* Touch-screen transform coefficient (s15.16) */
|
||||
# define FT80X_REG_TOUCH_TRANSFORM_F 0x102530 /* Touch-screen transform coefficient (s15.16) */
|
||||
/* 0x102534 – 0x102470 Reserved */
|
||||
# define FT80X_REG_TOUCH_DIRECT_XY 0x102574 /* Touch screen direct (x-MSB16; y-LSB16)
|
||||
* conversions */
|
||||
# define FT80X_REG_TOUCH_DIRECT_Z1Z2 0x102578 /* Touch screen direct (z1-MSB16; z2-LSB16)
|
||||
* conversions */
|
||||
#elif defined(CONFIG_LCD_FT801)
|
||||
/* 0x1024d0 – 0x1024d4 Reserved */
|
||||
# define FT80X_REG_CTOUCH_EXTENDED 0x1024f4 /* Set capacitive touch operation mode:
|
||||
* 0: extended mode (multi-touch)
|
||||
* 0: 1: FT800 compatibility mode (single touch) */
|
||||
# define FT80X_REG_CTOUCH_REG 0x1024f8 /* CTPM configure register write
|
||||
* Bits [7:0]: configure register address
|
||||
* Bits [15:8]: configure register value */
|
||||
/* 0x1024fc - 0x102504 Reserved */
|
||||
# define FT80X_REG_CTOUCH_RAW_XY 0x102508 /* Compatibility mode: touch-screen raw
|
||||
* (x-MSB16; y-LSB16) */
|
||||
# define FT80X_REG_CTOUCH_TOUCH1_XY 0x102508 /* Extended mode: touch-screen screen data for touch 1
|
||||
* (x-MSB16; y-LSB16) */
|
||||
# define FT80X_REG_CTOUCH_TOUCH4_XY 0x10250c /* Extended mode: touch-screen screen Y data for touch 4 */
|
||||
# define FT80X_REG_CTOUCH_SCREEN_XY 0x102510 /* Compatibility mode: touch-screen screen
|
||||
* (x-MSB16; y-LSB16) */
|
||||
# define FT80X_REG_CTOUCH_TOUCH0_XY 0x102510 /* Extended mode: touch-screen screen data for touch 0
|
||||
* (x-MSB16; y-LSB16) */
|
||||
# define FT80X_REG_CTOUCH_TAG_XY 0x102514 /* Touch-screen screen (x-MSB16; y-LSB16)
|
||||
* used for tag lookup */
|
||||
# define FT80X_REG_CTOUCH_TAG 0x102518 /* Touch-screen tag result */
|
||||
# define FT80X_REG_CTOUCH_TRANSFORM_A 0x10251c /* Touch-screen transform coefficient (s15.16) */
|
||||
# define FT80X_REG_CTOUCH_TRANSFORM_B 0x102520 /* Touch-screen transform coefficient (s15.16) */
|
||||
# define FT80X_REG_CTOUCH_TRANSFORM_C 0x102524 /* Touch-screen transform coefficient (s15.16) */
|
||||
# define FT80X_REG_CTOUCH_TRANSFORM_D 0x102528 /* Touch-screen transform coefficient (s15.16) */
|
||||
# define FT80X_REG_CTOUCH_TRANSFORM_E 0x10252c /* Touch-screen transform coefficient (s15.16) */
|
||||
# define FT80X_REG_CTOUCH_TRANSFORM_F 0x102530 /* Touch-screen transform coefficient (s15.16) */
|
||||
/* 0x102534 Reserved */
|
||||
# define FT80X_REG_CTOUCH_TOUCH4_X 0x102538 /* Extended mode: touch-screen screen X data for
|
||||
* touch 4 */
|
||||
/* 0x10253c – 0x102450 Reserved */
|
||||
# define FT80X_REG_SCREENSHOT_READ 0x102554 /* Set to enable readout of the screenshot of the
|
||||
* selected Y line */
|
||||
/* 0x10253c – 0x102468 Reserved */
|
||||
# define FT80X_REG_TRIM 0x10256c /* Internal relaxation clock trimming */
|
||||
/* 0x102570 Reserved */
|
||||
# define FT80X_REG_CTOUCH_DIRECT_XY 0x102574 /* Compatibility mode: Touch screen direct
|
||||
* (x-MSB16; y-LSB16) conversions */
|
||||
# define FT80X_REG_CTOUCH_TOUCH2_XY 0x102574 /* Extended mode: touch-screen screen data for
|
||||
* touch 2 (x-MSB16; y-LSB16) */
|
||||
# define FT80X_REG_CTOUCH_DIRECT_Z1Z2 0x102578 /* Compatibility mode: Touch screen direct
|
||||
* (z1-MSB16; z2-LSB16) conversions */
|
||||
# define FT80X_REG_CTOUCH_TOUCH3_XY 0x102578 /* Extended mode: touch-screen screen data for
|
||||
* touch 3 (x-MSB16; y-LSB16) */
|
||||
#endif
|
||||
|
||||
#define FT80X_REG_TRACKER 0x109000 /* Track register (Track value – MSB16;
|
||||
* Tag value - LSB8) */
|
||||
|
||||
/* FT80x Register Bit Definitions **********************************************************/
|
||||
|
||||
#define ID_MASK 0xff /* Bits 0-7: Register ID */
|
||||
#define DLSWAP_LINE 1 /* Bits 0-1: 1=Graphics engine will render
|
||||
* the screen immediately after current line.
|
||||
* May cause a tearing effect.
|
||||
*/
|
||||
#define DLSWAP_FRAME 2 /* Bits 0-1: 2=Graphics engine will render
|
||||
* the screen immediately after the current
|
||||
* frame is scanned out (recommended).
|
||||
*/
|
||||
|
||||
/*******************************************************************************************
|
||||
* Public Types
|
||||
*******************************************************************************************/
|
||||
|
||||
/* Host write command
|
||||
*
|
||||
* For a SPI write command write transaction, the host writes a zero bit followed by a one
|
||||
* bit, followed by the 5-bit command, followed by two bytes of zero. All data is streamed
|
||||
* with a single chip select.
|
||||
*
|
||||
* I2C data format is equivalent (with obvious differences in bus protocol)
|
||||
*/
|
||||
|
||||
struct ft80x_hostwrite_s
|
||||
{
|
||||
uint8_t cmd; /* Bits 6-7: 01, Bits 0-5: command */
|
||||
uint8_t pad1; /* Zero */
|
||||
uint8_t pad2; /* Zero */
|
||||
};
|
||||
|
||||
/* For SPI memory read transaction, the host sends two zero bits, followed by the 22-bit
|
||||
* address. This is followed by a dummy byte. After the dummy byte, the FT80x responds to
|
||||
* each host byte with read data bytes.
|
||||
*
|
||||
* For I2C memory read transaction, bytes are packed in the I2C protocol as follow:
|
||||
*
|
||||
* [start] <DEVICE ADDRESS + write bit>
|
||||
* <00b+Address[21:16]>
|
||||
* <Address[15:8]>
|
||||
* <Address[7:0]>
|
||||
* [restart] <DEVICE ADDRESS + read bit>
|
||||
* <Read data byte 0>
|
||||
* ....
|
||||
* <Read data byte n> [stop]
|
||||
*/
|
||||
|
||||
struct ft80x_spiread_s
|
||||
{
|
||||
uint8_t addrh; /* Bits 6-7: 00, Bits 0-5: Address[21:16] */
|
||||
uint8_t addrm; /* Address[15:8] */
|
||||
uint8_t addrl; /* Address[7:0] */
|
||||
uint8_t dummy; /* Dummy byte */
|
||||
};
|
||||
|
||||
struct ft80x_i2cread_s
|
||||
{
|
||||
uint8_t addrh; /* Bits 6-7: 00, Bits 0-5: Address[21:16] */
|
||||
uint8_t addrm; /* Address[15:8] */
|
||||
uint8_t addrl; /* Address[7:0] */
|
||||
};
|
||||
|
||||
/* For SPI memory write transaction, the host sends a '1' bit and '0' bit, followed by the
|
||||
* 22-bit address. This is followed by the write data.
|
||||
*
|
||||
* For I2C memory write transaction, bytes are packed in the I2C protocol as follow:
|
||||
*
|
||||
* [start] <DEVICE ADDRESS + write bit>
|
||||
* <10b,Address[21:16]>
|
||||
* <Address[15:8]>
|
||||
* <Address[7:0]>
|
||||
* <Write data byte 0>
|
||||
* ....
|
||||
* <Write data byte n> [stop]
|
||||
*/
|
||||
|
||||
struct ft80x_spiwrite_s
|
||||
{
|
||||
uint8_t addrh; /* Bits 6-7: 10, Bits 0-5: Address[21:16] */
|
||||
uint8_t addrm; /* Address[15:8] */
|
||||
uint8_t addrl; /* Address[7:0] */
|
||||
/* Write data follows */
|
||||
};
|
||||
|
||||
struct ft80x_spiwrite8_s
|
||||
{
|
||||
uint8_t addrh; /* Bits 6-7: 10, Bits 0-5: Address[21:16] */
|
||||
uint8_t addrm; /* Address[15:8] */
|
||||
uint8_t addrl; /* Address[7:0] */
|
||||
uint8_t data; /* 8-bit data follows */
|
||||
};
|
||||
struct ft80x_spiwrite16_s
|
||||
{
|
||||
uint8_t addrh; /* Bits 6-7: 10, Bits 0-5: Address[21:16] */
|
||||
uint8_t addrm; /* Address[15:8] */
|
||||
uint8_t addrl; /* Address[7:0] */
|
||||
uint8_t data[2]; /* 16-bit data follows */
|
||||
};
|
||||
struct ft80x_spiwrite32_s
|
||||
{
|
||||
uint8_t addrh; /* Bits 6-7: 10, Bits 0-5: Address[21:16] */
|
||||
uint8_t addrm; /* Address[15:8] */
|
||||
uint8_t addrl; /* Address[7:0] */
|
||||
uint8_t data[4]; /* 32-bit data follows */
|
||||
};
|
||||
struct ft80x_i2cwrite_s
|
||||
{
|
||||
uint8_t addrh; /* Bits 6-7: 10, Bits 0-5: Address[21:16] */
|
||||
uint8_t addrm; /* Address[15:8] */
|
||||
uint8_t addrl; /* Address[7:0] */
|
||||
/* Write data follows */
|
||||
};
|
||||
|
||||
/* This structure describes the overall state of the FT80x driver */
|
||||
|
||||
struct spi_dev_s; /* Forward reference */
|
||||
struct i2c_master_s; /* Forward reference */
|
||||
|
||||
struct ft80x_dev_s
|
||||
{
|
||||
#ifdef CONFIG_LCD_FT80X_SPI
|
||||
FAR struct spi_dev_s *spi; /* Cached SPI device reference */
|
||||
#else
|
||||
FAR struct i2c_master_s *i2c; /* Cached SPI device reference */
|
||||
#endif
|
||||
FAR const struct ft80x_config_s *lower; /* Cached lower half instance */
|
||||
uint32_t frequency; /* Effective frequency */
|
||||
sem_t exclsem; /* Mutual exclusion semaphore */
|
||||
uint8_t crefs; /* Open count */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ft80x_host_command
|
||||
*
|
||||
* Description:
|
||||
* Send a host command to the FT80x
|
||||
*
|
||||
* FFor a SPI write command write transaction, the host writes a zero bit
|
||||
* followed by a one bit, followed by the 5-bit command, followed by two
|
||||
* bytes of zero. All data is streamed with a single chip select.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void ft80x_host_command(FAR struct ft80x_dev_s *priv, uint8_t cmd);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ft80x_read_memory
|
||||
*
|
||||
* Description:
|
||||
* Read from FT80X memory
|
||||
*
|
||||
* For SPI memory read transaction, the host sends two zero bits, followed
|
||||
* by the 22-bit address. This is followed by a dummy byte. After the dummy
|
||||
* byte, the FT80x responds to each host byte with read data bytes.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void ft80x_read_memory(FAR struct ft80x_dev_s *priv, uint32_t addr,
|
||||
FAR void *buffer, size_t buflen);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ft80x_read_byte, ft80x_read_hword, ft80x_read_word
|
||||
*
|
||||
* Description:
|
||||
* Read an 8-, 16-, or 32-bt bit value from FT80X memory
|
||||
*
|
||||
* For SPI memory read transaction, the host sends two zero bits, followed
|
||||
* by the 22-bit address. This is followed by a dummy byte. After the dummy
|
||||
* byte, the FT80x responds to each host byte with read data bytes.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
uint8_t ft80x_read_byte(FAR struct ft80x_dev_s *priv, uint32_t addr);
|
||||
uint16_t ft80x_read_hword(FAR struct ft80x_dev_s *priv, uint32_t addr);
|
||||
uint32_t ft80x_read_word(FAR struct ft80x_dev_s *priv, uint32_t addr);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ft80x_write_memory
|
||||
*
|
||||
* Description:
|
||||
* Write to FT80X memory
|
||||
*
|
||||
* For SPI memory write transaction, the host sends a '1' bit and '0' bit,
|
||||
* followed by the 22-bit address. This is followed by the write data.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void ft80x_write_memory(FAR struct ft80x_dev_s *priv, uint32_t addr,
|
||||
FAR const void *buffer, size_t buflen);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ft80x_write_byte, ft80x_write_hword, ft80x_write_word
|
||||
*
|
||||
* Description:
|
||||
* Write an 8-, 16-, or 32-bt bit value to FT80X memory
|
||||
*
|
||||
* For SPI memory write transaction, the host sends a '1' bit and '0' bit,
|
||||
* followed by the 22-bit address. This is followed by the write data.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void ft80x_write_byte(FAR struct ft80x_dev_s *priv, uint32_t addr,
|
||||
uint8_t data);
|
||||
void ft80x_write_hword(FAR struct ft80x_dev_s *priv, uint32_t addr,
|
||||
uint16_t data);
|
||||
void ft80x_write_word(FAR struct ft80x_dev_s *priv, uint32_t addr,
|
||||
uint32_t data);
|
||||
|
||||
#endif /* __DRIVERS_LCD_FT80X_H */
|
|
@ -0,0 +1,734 @@
|
|||
/**************************************************************************************
|
||||
* drivers/lcd/ft80x_base.c
|
||||
*
|
||||
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* References:
|
||||
* - Document No.: FT_000792, "FT800 Embedded Video Engine", Datasheet Version 1.1,
|
||||
* Clearance No.: FTDI# 334, Future Technology Devices International Ltd.
|
||||
* - Document No.: FT_000986, "FT801 Embedded Video Engine Datasheet", Version 1.0,
|
||||
* Clearance No.: FTDI#376, Future Technology Devices International Ltd.
|
||||
* - Application Note AN_240AN_240, "FT800 From the Ground Up", Version 1.1,
|
||||
* Issue Date: 2014-06-09, Future Technology Devices International Ltd.
|
||||
* - "FT800 Series Programmer Guide Guide", Version 2.1, Issue Date: 2016-09-19,
|
||||
* Future Technology Devices International Ltd.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
**************************************************************************************/
|
||||
|
||||
/**************************************************************************************
|
||||
* Included Files
|
||||
**************************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <poll.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/semaphore.h>
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/i2c/i2c_master.h>
|
||||
#include <nuttx/spi/spi.h>
|
||||
#include <nuttx/lcd/lcd.h>
|
||||
#include <nuttx/lcd/ft80x.h>
|
||||
|
||||
#include <arch/irq.h>
|
||||
|
||||
#include "ft80x.h"
|
||||
|
||||
#ifdef CONFIG_LCD_FT80X
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(CONFIG_LCD_FT800)
|
||||
# define DEVNAME "/dev/ft800"
|
||||
# define ROMID 0x01000800
|
||||
#elif defined(CONFIG_LCD_FT801)
|
||||
# define DEVNAME "/dev/ft801"
|
||||
# define ROMID 0x01000801
|
||||
#else
|
||||
# error No FT80x device configured
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/* Character driver methods */
|
||||
|
||||
static int ft80x_open(FAR struct file *filep);
|
||||
static int ft80x_close(FAR struct file *filep);
|
||||
|
||||
static ssize_t ft80x_read(FAR struct file *filep, FAR char *buffer,
|
||||
size_t buflen);
|
||||
static ssize_t ft80x_write(FAR struct file *filep, FAR const char *buffer,
|
||||
size_t buflen);
|
||||
static int ft80x_ioctl(FAR struct file *filep, int cmd, unsigned long arg);
|
||||
#ifndef CONFIG_DISABLE_POLL
|
||||
static int ft80x_poll(FAR struct file *filep, FAR struct pollfd *fds,
|
||||
bool setup);
|
||||
#endif
|
||||
|
||||
/* Initialization */
|
||||
|
||||
static int ft80x_initialize(FAR struct ft80x_dev_s *priv);
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static const struct file_operations g_ft80x_fops =
|
||||
{
|
||||
ft80x_open, /* open */
|
||||
ft80x_close, /* close */
|
||||
ft80x_read, /* read */
|
||||
ft80x_write, /* write */
|
||||
NULL, /* seek */
|
||||
ft80x_ioctl /* ioctl */
|
||||
#ifndef CONFIG_DISABLE_POLL
|
||||
, ft80x_poll /* poll */
|
||||
#endif
|
||||
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
|
||||
, NULL /* unlink */
|
||||
#endif
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ft80x_open
|
||||
*
|
||||
* Description:
|
||||
* This function is called whenever the PWM device is opened.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int ft80x_open(FAR struct file *filep)
|
||||
{
|
||||
FAR struct inode *inode;
|
||||
FAR struct ft80x_dev_s *priv;
|
||||
uint8_t tmp;
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(filep != NULL);
|
||||
inode = filep->f_inode;
|
||||
DEBUGASSERT(inode != NULL && inode->i_private != NULL);
|
||||
priv = inode->i_private;
|
||||
|
||||
lcdinfo("crefs: %d\n", priv->crefs);
|
||||
|
||||
/* Get exclusive access to the device structures */
|
||||
|
||||
ret = nxsem_wait(&priv->exclsem);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Increment the count of references to the device */
|
||||
|
||||
tmp = priv->crefs + 1;
|
||||
if (tmp == 0)
|
||||
{
|
||||
/* More than 255 opens; uint8_t overflows to zero */
|
||||
|
||||
ret = -EMFILE;
|
||||
goto errout_with_sem;
|
||||
}
|
||||
|
||||
/* Save the new open count */
|
||||
|
||||
priv->crefs = tmp;
|
||||
ret = OK;
|
||||
|
||||
errout_with_sem:
|
||||
nxsem_post(&priv->exclsem);
|
||||
|
||||
errout:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ft80x_close
|
||||
*
|
||||
* Description:
|
||||
* This function is called when the PWM device is closed.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int ft80x_close(FAR struct file *filep)
|
||||
{
|
||||
FAR struct inode *inode;
|
||||
FAR struct ft80x_dev_s *priv;
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(filep != NULL);
|
||||
inode = filep->f_inode;
|
||||
DEBUGASSERT(inode != NULL && inode->i_private != NULL);
|
||||
priv = inode->i_private;
|
||||
|
||||
lcdinfo("crefs: %d\n", priv->crefs);
|
||||
|
||||
/* Get exclusive access to the device structures */
|
||||
|
||||
ret = nxsem_wait(&priv->exclsem);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Decrement the references to the driver. */
|
||||
|
||||
if (priv->crefs > 1)
|
||||
{
|
||||
priv->crefs--;
|
||||
}
|
||||
|
||||
ret = OK;
|
||||
nxsem_post(&priv->exclsem);
|
||||
|
||||
errout:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ft80x_read
|
||||
****************************************************************************/
|
||||
|
||||
static ssize_t ft80x_read(FAR struct file *filep, FAR char *buffer,
|
||||
size_t len)
|
||||
{
|
||||
/* Reading from the FT80X is an undefined operation and not support */
|
||||
|
||||
lcdinfo("buffer: %p len %lu\n", buffer, (unsigned long)len);
|
||||
return 0; /* Return EOF */
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ft80x_write
|
||||
****************************************************************************/
|
||||
|
||||
static ssize_t ft80x_write(FAR struct file *filep, FAR const char *buffer,
|
||||
size_t len)
|
||||
{
|
||||
FAR struct inode *inode;
|
||||
FAR struct ft80x_dev_s *priv;
|
||||
int ret;
|
||||
|
||||
lcdinfo("buffer: %p len %lu\n", buffer, (unsigned long)len);
|
||||
DEBUGASSERT(buffer != NULL && ((uintptr_t)buffer & 3) == 0 &&
|
||||
len > 0 && (len & 3) == 0 && len <= FT80X_RAM_DL_SIZE);
|
||||
|
||||
DEBUGASSERT(filep != NULL);
|
||||
inode = filep->f_inode;
|
||||
DEBUGASSERT(inode != NULL && inode->i_private != NULL);
|
||||
priv = inode->i_private;
|
||||
|
||||
if (buffer == NULL || ((uintptr_t)buffer & 3) != 0 ||
|
||||
len == 0 || (len & 3) != 0 || len > FT80X_RAM_DL_SIZE)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Get exclusive access to the device structures */
|
||||
|
||||
ret = nxsem_wait(&priv->exclsem);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* The write method is functionally equivalent to the FT80XIOC_PUTDISPLAYLIST
|
||||
* IOCTL command: It simply copies the display list in the user buffer to
|
||||
* the FT80x display list memory.
|
||||
*/
|
||||
|
||||
ft80x_write_memory(priv, FT80X_RAM_DL, buffer, len);
|
||||
|
||||
nxsem_post(&priv->exclsem);
|
||||
return len;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ft80x_ioctl
|
||||
*
|
||||
* Description:
|
||||
* The standard ioctl method. This is where ALL of the PWM work is done.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int ft80x_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
|
||||
{
|
||||
FAR struct inode *inode;
|
||||
FAR struct ft80x_dev_s *priv;
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(filep != NULL);
|
||||
inode = filep->f_inode;
|
||||
DEBUGASSERT(inode != NULL && inode->i_private != NULL);
|
||||
priv = inode->i_private;
|
||||
|
||||
lcdinfo("cmd: %d arg: %lu\n", cmd, arg);
|
||||
|
||||
/* Get exclusive access to the device structures */
|
||||
|
||||
ret = nxsem_wait(&priv->exclsem);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Handle built-in ioctl commands */
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
/* FT80XIOC_PUTDISPLAYLIST:
|
||||
* Description: Write a display list to the FT80x display list memory
|
||||
* Argument: A reference to a display list structure instance.
|
||||
* See struct ft80x_displaylist_s.
|
||||
* Returns: None
|
||||
*/
|
||||
|
||||
case FT80XIOC_PUTDISPLAYLIST:
|
||||
{
|
||||
FAR struct ft80x_displaylist_s *dl =
|
||||
(FAR struct ft80x_displaylist_s *)((uintptr_t)arg);
|
||||
|
||||
if (dl == NULL || ((uintptr_t)&dl->cmd & 3) != 0 ||
|
||||
dl->dlsize == 0 || (dl->dlsize & 3) != 0 ||
|
||||
dl->dlsize > FT80X_RAM_DL_SIZE)
|
||||
{
|
||||
ret = -EINVAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This IOCTL command simply copies the display list
|
||||
* provided into the FT80x display list memory.
|
||||
*/
|
||||
|
||||
ft80x_write_memory(priv, FT80X_RAM_DL, &dl->cmd, dl->dlsize);
|
||||
ret = OK;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
/* FT80XIOC_GETRESULT32:
|
||||
* Description: Read a 32-bit value from the display list.
|
||||
* Argument: A reference to an instance of struct ft80x_result32_s.
|
||||
* Returns: The 32-bit value read from the display list.
|
||||
*/
|
||||
|
||||
case FT80XIOC_GETRESULT32:
|
||||
{
|
||||
FAR struct ft80x_result32_s *result =
|
||||
(FAR struct ft80x_result32_s *)((uintptr_t)arg);
|
||||
|
||||
if (result == NULL || ((uintptr_t)&result->offset & 3) != 0 ||
|
||||
result->offset >= FT80X_RAM_DL_SIZE)
|
||||
{
|
||||
ret = -EINVAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
result->value = ft80x_read_word(priv,
|
||||
FT80X_RAM_DL + result->offset);
|
||||
ret = OK;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
/* FT80XIOC_GETTRACKER:
|
||||
* Description: After CMD_TRACK has been issued, the coprocessor
|
||||
* will update the TRACKER register with new position
|
||||
* data.
|
||||
* Argument: A pointer to a writable uint32_t memory location.
|
||||
* Returns: The new content of the tracker register.
|
||||
*/
|
||||
|
||||
case FT80XIOC_GETTRACKER:
|
||||
{
|
||||
FAR uint32_t *tracker = (FAR uint32_t *)((uintptr_t)arg);
|
||||
|
||||
if (tracker == NULL)
|
||||
{
|
||||
ret = -EINVAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
*tracker = ft80x_read_word(priv, FT80X_REG_TRACKER);
|
||||
ret = OK;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
/* Unrecognized IOCTL command */
|
||||
|
||||
default:
|
||||
lcderr("ERROR: Unrecognized cmd: %d arg: %ld\n", cmd, arg);
|
||||
ret = -ENOTTY;
|
||||
break;
|
||||
}
|
||||
|
||||
nxsem_post(&priv->exclsem);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ft80x_poll
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_DISABLE_POLL
|
||||
static int ft80x_poll(FAR struct file *filep, FAR struct pollfd *fds,
|
||||
bool setup)
|
||||
{
|
||||
#warning Missing logic
|
||||
return -ENOSYS;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ft80x_initialize
|
||||
*
|
||||
* Description:
|
||||
* Initialize the FT80x
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int ft80x_initialize(FAR struct ft80x_dev_s *priv)
|
||||
{
|
||||
uint8_t regval32;
|
||||
uint8_t regval8;
|
||||
|
||||
/* To configure the display, load the timing control registers with values
|
||||
* for the particular display. These registers control horizontal timing:
|
||||
*
|
||||
* - FT80X_REG_PCLK
|
||||
* - FT80X_REG_PCLK_POL
|
||||
* - FT80X_REG_HCYCLE
|
||||
* - FT80X_REG_HOFFSET
|
||||
* - FT80X_REG_HSIZE
|
||||
* - FT80X_REG_HSYNC0
|
||||
* - FT80X_REG_HSYNC1
|
||||
*
|
||||
* These registers control vertical timing:
|
||||
*
|
||||
* - FT80X_REG_VCYCLE
|
||||
* - FT80X_REG_VOFFSET
|
||||
* - FT80X_REG_VSIZE
|
||||
* - FT80X_REG_VSYNC0
|
||||
* - FT80X_REG_VSYNC1
|
||||
*
|
||||
* And the FT80X_REG_CSPREAD register changes color clock timing to reduce system
|
||||
* noise.
|
||||
*
|
||||
* GPIO bit 7 is used for the display enable pin of the LCD module. By
|
||||
* setting the direction of the GPIO bit to out direction, the display can
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* Initialization Sequence from Power Down using PD_N pin:
|
||||
*
|
||||
* 1. Drive the PD_N pin high
|
||||
* 2. Wait for at least 20ms
|
||||
* 3. Execute "Initialization Sequence during the Boot up" from steps 1 to 9
|
||||
*
|
||||
* Initialization Sequence from Sleep Mode:
|
||||
*
|
||||
* 1. Send Host command "ACTIVE" to enable clock to FT800
|
||||
* 2. Wait for at least 20ms
|
||||
* 3. Execute "Initialization Sequence during Boot Up" from steps 5 to 8
|
||||
*
|
||||
* Initialization sequence from standby mode:
|
||||
*
|
||||
* Execute all the steps mentioned in "Initialization Sequence from Sleep
|
||||
* Mode" except waiting for at least 20ms in step 2.
|
||||
*/
|
||||
|
||||
DEBUGASSERT(priv->lower != NULL && priv->lower->pwrdown != NULL);
|
||||
priv->lower->pwrdown(priv->lower, false);
|
||||
up_mdelay(20);
|
||||
|
||||
/* Initialization Sequence during the boot up:
|
||||
*
|
||||
* 1. Use MCU SPI clock not more than 11MHz
|
||||
* 2. Send Host command CLKEXT to FT800
|
||||
* 3. Send Host command ACTIVE to enable clock to FT800.
|
||||
* 4. Configure video timing registers, except FT80X_REG_PCLK
|
||||
* 5. Write first display list
|
||||
* 6. Write FT80X_REG_DLSWAP, FT800 swaps display list immediately
|
||||
* 7. Enable back light control for display
|
||||
* 8. Write FT80X_REG_PCLK, video output begins with the first display list
|
||||
* 9. Use MCU SPI clock not more than 30MHz
|
||||
*/
|
||||
|
||||
/* 1. Select the initial SPI frequency */
|
||||
|
||||
DEBUGASSERT(priv->lower->init_frequency <= 11000000);
|
||||
priv->frequency = priv->lower->init_frequency;
|
||||
|
||||
/* 2. Send Host command CLKEXT to FT800
|
||||
* 3. Send Host command ACTIVE to enable clock to FT800.
|
||||
*/
|
||||
|
||||
ft80x_host_command(priv, FT80X_CMD_CLKEXT);
|
||||
ft80x_host_command(priv, FT80X_CMD_ACTIVE);
|
||||
|
||||
/* Verify the chip ID */
|
||||
|
||||
regval32 = ft80x_read_word(priv, FT80X_REG_ID);
|
||||
if ((regval32 & ID_MASK) != 0x7c)
|
||||
{
|
||||
lcderr("ERROR: Bad chip ID: %02x\n",
|
||||
(unsigned int)(regval32 & ID_MASK));
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
regval32 = ft80x_read_word(priv, FT80X_ROM_CHIPID);
|
||||
if (regval32 != ROMID)
|
||||
{
|
||||
lcderr("ERROR: Bad ROM chip ID: %08lx\n", (unsigned long)regval32);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* 4. Configure video timing registers, except FT80X_REG_PCLK
|
||||
*
|
||||
* Once the FT800 is awake and the internal clock set and Device ID
|
||||
* checked, the next task is to configure the LCD display parameters for
|
||||
* the chosen display with the values determined in Section 2.3.3 above.
|
||||
*
|
||||
* a. Set FT80X_REG_PCLK to zero - This disables the pixel clock output while
|
||||
* the LCD and other system parameters are configured
|
||||
* b. Set the following registers with values for the chosen display.
|
||||
* Typical WQVGA and QVGA values are shown:
|
||||
*
|
||||
* Register Description WQVGA QVGA 320 x 240
|
||||
* 480x272 320x240
|
||||
* FT80X_REG_PCLK_POL Pixel Clock Polarity 1 0
|
||||
* FT80X_REG_HSIZE Image width in pixels 480 320
|
||||
* FT80X_REG_HCYCLE Total number of clocks per line 548 408
|
||||
* FT80X_REG_HOFFSET Horizontal image start 43 70
|
||||
* (pixels from left)
|
||||
* FT80X_REG_HSYNC0 Start of HSYNC pulse 0 0
|
||||
* (falling edge)
|
||||
* FT80X_REG_HSYNC1 End of HSYNC pulse 41 10
|
||||
* (rising edge)
|
||||
* FT80X_REG_VSIZE Image height in pixels 272 240
|
||||
* FT80X_REG_VCYCLE Total number of lines per screen 292 263
|
||||
* FT80X_REG_VOFFSET Vertical image start 12 13
|
||||
* (lines from top)
|
||||
* FT80X_REG_VSYNC0 Start of VSYNC pulse 0 0
|
||||
* (falling edge)
|
||||
* FT80X_REG_VSYNC1 End of VSYNC pulse 10 2
|
||||
* (rising edge)
|
||||
*
|
||||
* c. Enable or disable FT80X_REG_CSPREAD with a value of 01h or 00h,
|
||||
* respectively. Enabling FT80X_REG_CSPREAD will offset the R, G and B
|
||||
* output bits so all they do not all change at the same time.
|
||||
*/
|
||||
|
||||
ft80x_write_byte(priv, FT80X_REG_PCLK, 0);
|
||||
|
||||
#if defined(CONFIG_LCD_FT80X_WQVGA)
|
||||
ft80x_write_hword(priv, FT80X_REG_HCYCLE, 548);
|
||||
ft80x_write_hword(priv, FT80X_REG_HOFFSET, 43);
|
||||
ft80x_write_hword(priv, FT80X_REG_HSYNC0, 0);
|
||||
ft80x_write_hword(priv, FT80X_REG_HSYNC1, 41);
|
||||
ft80x_write_hword(priv, FT80X_REG_VCYCLE, 292);
|
||||
ft80x_write_hword(priv, FT80X_REG_VOFFSET, 12);
|
||||
ft80x_write_hword(priv, FT80X_REG_VSYNC0, 0);
|
||||
ft80x_write_hword(priv, FT80X_REG_VSYNC1, 10);
|
||||
ft80x_write_byte(priv, FT80X_REG_SWIZZLE, 0);
|
||||
ft80x_write_byte(priv, FT80X_REG_PCLK_POL, 1);
|
||||
ft80x_write_byte(priv, FT80X_REG_CSPREAD, 1);
|
||||
ft80x_write_hword(priv, FT80X_REG_HSIZE, 480);
|
||||
ft80x_write_hword(priv, FT80X_REG_VSIZE, 272);
|
||||
|
||||
#elif defined(CONFIG_LCD_FT80X_QVGA)
|
||||
ft80x_write_hword(priv, FT80X_REG_HCYCLE, 408);
|
||||
ft80x_write_hword(priv, FT80X_REG_HOFFSET, 70);
|
||||
ft80x_write_hword(priv, FT80X_REG_HSYNC0, 0);
|
||||
ft80x_write_hword(priv, FT80X_REG_HSYNC1, 10);
|
||||
ft80x_write_hword(priv, FT80X_REG_VCYCLE, 263);
|
||||
ft80x_write_hword(priv, FT80X_REG_VOFFSET, 13);
|
||||
ft80x_write_hword(priv, FT80X_REG_VSYNC0, 0);
|
||||
ft80x_write_hword(priv, FT80X_REG_VSYNC1, 2);
|
||||
ft80x_write_byte(priv, FT80X_REG_SWIZZLE, 0); /* REVISIT */
|
||||
ft80x_write_byte(priv, FT80X_REG_PCLK_POL, 0);
|
||||
ft80x_write_byte(priv, FT80X_REG_CSPREAD, 1);
|
||||
ft80x_write_hword(priv, FT80X_REG_HSIZE, 320);
|
||||
ft80x_write_hword(priv, FT80X_REG_VSIZE, 240);
|
||||
|
||||
#else
|
||||
# error Unknown display size
|
||||
#endif
|
||||
|
||||
/* 5. Write first display list */
|
||||
|
||||
ft80x_write_word(priv, FT80X_RAM_DL + 0, FT80X_CLEAR_COLOR_RGB(0,0,0));
|
||||
ft80x_write_word(priv, FT80X_RAM_DL + 4, FT80X_CLEAR(1,1,1));
|
||||
ft80x_write_word(priv, FT80X_RAM_DL + 8, FT80X_DISPLAY());
|
||||
|
||||
/* 6. Write FT80X_REG_DLSWAP, FT800 swaps display list immediately */
|
||||
|
||||
ft80x_write_byte(priv, FT80X_REG_DLSWAP, DLSWAP_FRAME);
|
||||
|
||||
/* GPIO bit 7 is used for the display enable pin of the LCD module. By
|
||||
* setting the direction of the GPIO bit to out direction, the display can
|
||||
* 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.
|
||||
*/
|
||||
|
||||
regval8 = ft80x_read_byte(priv, FT80X_REG_GPIO_DIR);
|
||||
regval8 |= (1 << 7);
|
||||
ft80x_write_byte(priv, FT80X_REG_GPIO_DIR, regval8);
|
||||
|
||||
regval8 = ft80x_read_byte(priv, FT80X_REG_GPIO);
|
||||
regval8 |= (1 << 7);
|
||||
ft80x_write_byte(priv, FT80X_REG_GPIO, regval8);
|
||||
|
||||
/* 7. Enable back light control for display */
|
||||
#warning Missing logic
|
||||
|
||||
/* 8. Write FT80X_REG_PCLK, video output begins with the first display list */
|
||||
|
||||
ft80x_write_byte(priv, FT80X_REG_PCLK, 5);
|
||||
|
||||
/* 9. Use MCU SPI clock not more than 30MHz */
|
||||
|
||||
DEBUGASSERT(priv->lower->op_frequency <= 30000000);
|
||||
priv->frequency = priv->lower->op_frequency;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/**************************************************************************************
|
||||
* Public Functions
|
||||
**************************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ft80x_register
|
||||
*
|
||||
* Description:
|
||||
* Configure the ADS7843E to use the provided SPI device instance. This
|
||||
* will register the driver as /dev/ft80x.
|
||||
*
|
||||
* Input Parameters:
|
||||
* spi - An SPI driver instance
|
||||
* i2c - An I2C master driver instance
|
||||
* lower - Persistent board configuration data / lower half interface
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero is returned on success. Otherwise, a negated errno value is
|
||||
* returned to indicate the nature of the failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(CONFIG_LCD_FT80X_SPI)
|
||||
int ft80x_register(FAR struct spi_dev_s *spi,
|
||||
FAR const struct ft80x_config_s *lower)
|
||||
#elif defined(CONFIG_LCD_FT80X_I2C)
|
||||
int ft80x_register(FAR struct i2c_master_s *i2c,
|
||||
FAR const struct ft80x_config_s *lower)
|
||||
#endif
|
||||
{
|
||||
FAR struct ft80x_dev_s *priv;
|
||||
int ret;
|
||||
|
||||
#if defined(CONFIG_LCD_FT80X_SPI)
|
||||
DEBUGASSERT(spi != NULL && lower != NULL);
|
||||
#elif defined(CONFIG_LCD_FT80X_I2C)
|
||||
DEBUGASSERT(i2c != NULL && lower != NULL);
|
||||
#endif
|
||||
|
||||
/* Allocate the driver state structure */
|
||||
|
||||
priv = (FAR struct ft80x_dev_s *)kmm_zalloc(sizeof(struct ft80x_dev_s));
|
||||
if (priv == NULL)
|
||||
{
|
||||
lcderr("ERROR: Failed to allocate state structure\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Save the lower level interface and configuration information */
|
||||
|
||||
priv->lower = lower;
|
||||
|
||||
#ifdef CONFIG_LCD_FT80X_SPI
|
||||
/* Remember the SPI configuration */
|
||||
|
||||
priv->spi = spi;
|
||||
#else
|
||||
/* Remember the I2C configuration */
|
||||
|
||||
priv->i2c = i2c;
|
||||
#endif
|
||||
|
||||
/* Initialize the mutual exclusion semaphore */
|
||||
|
||||
sem_init(&priv->exclsem, 0, 1);
|
||||
|
||||
/* Initialize the FT80x */
|
||||
|
||||
ret = ft80x_initialize(priv);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto errout_with_sem;
|
||||
}
|
||||
|
||||
/* Register the FT80x character driver */
|
||||
|
||||
ret = register_driver(DEVNAME, &g_ft80x_fops, 0666, priv);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto errout_with_sem;
|
||||
}
|
||||
|
||||
return OK;
|
||||
|
||||
errout_with_sem:
|
||||
sem_destroy(&priv->exclsem);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_LCD_FT80X */
|
|
@ -0,0 +1,363 @@
|
|||
/****************************************************************************
|
||||
* drivers/lcd/ft80x_spi.c
|
||||
*
|
||||
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/lcd/ft80x.h>
|
||||
#include <nuttx/spi/spi.h>
|
||||
#include "ft80x.h"
|
||||
|
||||
#if defined(CONFIG_LCD_FT80X) && defined(CONFIG_LCD_FT80X_SPI)
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ft80x_select
|
||||
*
|
||||
* Description:
|
||||
* Select the FT80X part
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void ft80x_select(FAR struct ft80x_dev_s *priv)
|
||||
{
|
||||
lcdinfo("Mode: %d Bits: 8 Frequency: %d\n",
|
||||
CONFIG_FT80X_SPIMODE, CONFIG_FT80X_FREQUENCY);
|
||||
|
||||
DEBUGASSERT(priv != NULL);
|
||||
|
||||
/* Lock the SPI bus */
|
||||
|
||||
(void)SPI_LOCK(priv->spi, true);
|
||||
|
||||
/* Configure SPI for the FT80X */
|
||||
|
||||
SPI_SETMODE(priv->spi, SPIDEV_MODE0);
|
||||
SPI_SETBITS(priv->spi, 8);
|
||||
(void)SPI_HWFEATURES(priv->spi, 0);
|
||||
(void)SPI_SETFREQUENCY(priv->spi, priv->frequency);
|
||||
|
||||
/* Select SPI device */
|
||||
|
||||
SPI_SELECT(priv->spi, SPIDEV_DISPLAY(0), true);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ft80x_deselect
|
||||
*
|
||||
* Description:
|
||||
* De-select the FT80X part
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void ft80x_deselect(FAR struct ft80x_dev_s *priv)
|
||||
{
|
||||
/* Des-select the FT80x device */
|
||||
|
||||
SPI_SELECT(priv->spi, SPIDEV_DISPLAY(0), false);
|
||||
|
||||
/* Unlock bus */
|
||||
|
||||
(void)SPI_LOCK(priv->spi, false);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ft80x_host_command
|
||||
*
|
||||
* Description:
|
||||
* Send a host command to the FT80x
|
||||
*
|
||||
* FFor a SPI write command write transaction, the host writes a zero bit
|
||||
* followed by a one bit, followed by the 5-bit command, followed by two
|
||||
* bytes of zero. All data is streamed with a single chip select.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void ft80x_host_command(FAR struct ft80x_dev_s *priv, uint8_t cmd)
|
||||
{
|
||||
struct ft80x_hostwrite_s hostwrite;
|
||||
|
||||
DEBUGASSERT(priv != NULL && (cnd & 0xc0) == 0);
|
||||
|
||||
/* Format the host write command */
|
||||
|
||||
hostwrite.cmd = 0x40 | cmd;
|
||||
hostwrite.pad1 = 0;
|
||||
hostwrite.pad2 = 0;
|
||||
|
||||
/* Select the FT80x */
|
||||
|
||||
ft80x_select(priv);
|
||||
|
||||
/* Send the host write command */
|
||||
|
||||
SPI_SNDBLOCK(priv->spi, &hostwrite, sizeof(struct ft80x_hostwrite_s));
|
||||
|
||||
/* De-select the FT80x */
|
||||
|
||||
ft80x_deselect(priv);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ft80x_read_memory
|
||||
*
|
||||
* Description:
|
||||
* Read from FT80X memory
|
||||
*
|
||||
* For SPI memory read transaction, the host sends two zero bits, followed
|
||||
* by the 22-bit address. This is followed by a dummy byte. After the dummy
|
||||
* byte, the FT80x responds to each host byte with read data bytes.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void ft80x_read_memory(FAR struct ft80x_dev_s *priv, uint32_t addr,
|
||||
FAR void *buffer, size_t buflen)
|
||||
{
|
||||
struct ft80x_spiread_s spiread;
|
||||
|
||||
DEBUGASSERT(priv != NULL && (addr & 0xffc00000) == 0 &&
|
||||
buffer != NULL && bulen > 0);
|
||||
|
||||
/* Format the read header */
|
||||
|
||||
spiread.addrh = (addr >> 16) & 0x3f;
|
||||
spiread.addrm = (addr >> 8) & 0xff;
|
||||
spiread.addrl = addr & 0xff;
|
||||
spiread.dummy = 0xff;
|
||||
|
||||
/* Select the FT80x */
|
||||
|
||||
ft80x_select(priv);
|
||||
|
||||
/* Send the read header */
|
||||
|
||||
SPI_SNDBLOCK(priv->spi, &spiread, sizeof(struct ft80x_spiread_s));
|
||||
|
||||
/* Then read the FT80x memory into the user provided buffer */
|
||||
|
||||
SPI_RECVBLOCK(priv->spi, buffer, buflen);
|
||||
|
||||
/* De-select the FT80x */
|
||||
|
||||
ft80x_deselect(priv);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ft80x_read_byte, ft80x_read_hword, ft80x_read_word
|
||||
*
|
||||
* Description:
|
||||
* Read an 8-, 16-, or 32-bt bit value from FT80X memory
|
||||
*
|
||||
* For SPI memory read transaction, the host sends two zero bits, followed
|
||||
* by the 22-bit address. This is followed by a dummy byte. After the dummy
|
||||
* byte, the FT80x responds to each host byte with read data bytes.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
uint8_t ft80x_read_byte(FAR struct ft80x_dev_s *priv, uint32_t addr)
|
||||
{
|
||||
uint8_t data;
|
||||
ft80x_read_memory(priv, addr, (FAR void *)&data, 1);
|
||||
return data;
|
||||
}
|
||||
|
||||
uint16_t ft80x_read_hword(FAR struct ft80x_dev_s *priv, uint32_t addr)
|
||||
{
|
||||
uint16_t data;
|
||||
ft80x_read_memory(priv, addr, (FAR void *)&data, 2);
|
||||
return data;
|
||||
}
|
||||
|
||||
uint32_t ft80x_read_word(FAR struct ft80x_dev_s *priv, uint32_t addr)
|
||||
{
|
||||
uint32_t data;
|
||||
ft80x_read_memory(priv, addr, (FAR void *)&data, 4);
|
||||
return data;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ft80x_write_memory
|
||||
*
|
||||
* Description:
|
||||
* Write to FT80X memory
|
||||
*
|
||||
* For SPI memory write transaction, the host sends a '1' bit and '0' bit,
|
||||
* followed by the 22-bit address. This is followed by the write data.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void ft80x_write_memory(FAR struct ft80x_dev_s *priv, uint32_t addr,
|
||||
FAR const void *buffer, size_t buflen)
|
||||
{
|
||||
struct ft80x_spiwrite_s spiwrite;
|
||||
|
||||
DEBUGASSERT(priv != NULL && (addr & 0xffc00000) == 0 &&
|
||||
buffer != NULL && bulen > 0);
|
||||
|
||||
/* Format the write header */
|
||||
|
||||
spiwrite.addrh = 0x80 | ((addr >> 16) & 0x3f);
|
||||
spiwrite.addrm = (addr >> 8) & 0xff;
|
||||
spiwrite.addrl = addr & 0xff;
|
||||
|
||||
/* Select the FT80x */
|
||||
|
||||
ft80x_select(priv);
|
||||
|
||||
/* Send the write header */
|
||||
|
||||
SPI_SNDBLOCK(priv->spi, &spiwrite, sizeof(struct ft80x_spiwrite_s));
|
||||
|
||||
/* Then write to the FT80x memory from the user provided buffer */
|
||||
|
||||
SPI_SNDBLOCK(priv->spi, buffer, buflen);
|
||||
|
||||
/* De-select the FT80x */
|
||||
|
||||
ft80x_deselect(priv);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ft80x_write_byte, ft80x_write_hword, ft80x_write_word
|
||||
*
|
||||
* Description:
|
||||
* Write an 8-, 16-, or 32-bt bit value to FT80X memory
|
||||
*
|
||||
* For SPI memory write transaction, the host sends a '1' bit and '0' bit,
|
||||
* followed by the 22-bit address. This is followed by the write data.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void ft80x_write_byte(FAR struct ft80x_dev_s *priv, uint32_t addr,
|
||||
uint8_t data)
|
||||
{
|
||||
struct ft80x_spiwrite8_s spiwrite;
|
||||
|
||||
DEBUGASSERT(priv != NULL && (addr & 0xffc00000) == 0);
|
||||
|
||||
/* Format the write header */
|
||||
|
||||
spiwrite.addrh = 0x80 | ((addr >> 16) & 0x3f);
|
||||
spiwrite.addrm = (addr >> 8) & 0xff;
|
||||
spiwrite.addrl = addr & 0xff;
|
||||
spiwrite.data = data;
|
||||
|
||||
/* Select the FT80x */
|
||||
|
||||
ft80x_select(priv);
|
||||
|
||||
/* Send the write header and 8-bit data */
|
||||
|
||||
SPI_SNDBLOCK(priv->spi, &spiwrite, sizeof(struct ft80x_spiwrite8_s));
|
||||
|
||||
/* De-select the FT80x */
|
||||
|
||||
ft80x_deselect(priv);
|
||||
}
|
||||
|
||||
void ft80x_write_hword(FAR struct ft80x_dev_s *priv, uint32_t addr,
|
||||
uint16_t data)
|
||||
{
|
||||
struct ft80x_spiwrite16_s spiwrite;
|
||||
|
||||
DEBUGASSERT(priv != NULL && (addr & 0xffc00000) == 0);
|
||||
|
||||
/* Format the write header */
|
||||
|
||||
spiwrite.addrh = 0x80 | ((addr >> 16) & 0x3f);
|
||||
spiwrite.addrm = (addr >> 8) & 0xff;
|
||||
spiwrite.addrl = addr & 0xff;
|
||||
spiwrite.data[0] = data & 0xff; /* Little endian */
|
||||
spiwrite.data[1] = (data >> 8) & 0xff;
|
||||
|
||||
/* Select the FT80x */
|
||||
|
||||
ft80x_select(priv);
|
||||
|
||||
/* Send the write header and 16-bit data */
|
||||
|
||||
SPI_SNDBLOCK(priv->spi, &spiwrite, sizeof(struct ft80x_spiwrite16_s));
|
||||
|
||||
/* De-select the FT80x */
|
||||
|
||||
ft80x_deselect(priv);
|
||||
}
|
||||
|
||||
void ft80x_write_word(FAR struct ft80x_dev_s *priv, uint32_t addr,
|
||||
uint32_t data)
|
||||
{
|
||||
struct ft80x_spiwrite32_s spiwrite;
|
||||
|
||||
DEBUGASSERT(priv != NULL && (addr & 0xffc00000) == 0);
|
||||
|
||||
/* Format the write header */
|
||||
|
||||
spiwrite.addrh = 0x80 | ((addr >> 16) & 0x3f);
|
||||
spiwrite.addrm = (addr >> 8) & 0xff;
|
||||
spiwrite.addrl = addr & 0xff;
|
||||
spiwrite.data[0] = data & 0xff; /* Little endian */
|
||||
spiwrite.data[1] = (data >> 8) & 0xff;
|
||||
spiwrite.data[2] = (data >> 16) & 0xff;
|
||||
spiwrite.data[3] = (data >> 24) & 0xff;
|
||||
|
||||
/* Select the FT80x */
|
||||
|
||||
ft80x_select(priv);
|
||||
|
||||
/* Send the write header and 32-bit data */
|
||||
|
||||
SPI_SNDBLOCK(priv->spi, &spiwrite, sizeof(struct ft80x_spiwrite32_s));
|
||||
|
||||
/* De-select the FT80x */
|
||||
|
||||
ft80x_deselect(priv);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_LCD_FT80X && CONFIG_LCD_FT80X_SPI */
|
|
@ -266,9 +266,8 @@ static int pwm_close(FAR struct file *filep)
|
|||
|
||||
lower->ops->shutdown(lower);
|
||||
}
|
||||
ret = OK;
|
||||
|
||||
//errout_with_sem:
|
||||
ret = OK;
|
||||
nxsem_post(&upper->exclsem);
|
||||
|
||||
errout:
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
/****************************************************************************
|
||||
* include/nuttx/fs/ioctl.h
|
||||
*
|
||||
* Copyright (C) 2008, 2009, 2011-2014, 2017 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2008, 2009, 2011-2014, 2017-2018 Gregory Nutt. All rights
|
||||
* reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -67,29 +68,30 @@
|
|||
#define _BATIOCBASE (0x0e00) /* Battery driver ioctl commands */
|
||||
#define _QEIOCBASE (0x0f00) /* Quadrature encoder ioctl commands */
|
||||
#define _AUDIOIOCBASE (0x1000) /* Audio ioctl commands */
|
||||
#define _SLCDIOCBASE (0x1100) /* Segment LCD ioctl commands */
|
||||
#define _WLIOCBASE (0x1200) /* Wireless modules ioctl network commands */
|
||||
#define _WLCIOCBASE (0x1300) /* Wireless modules ioctl character driver commands */
|
||||
#define _CFGDIOCBASE (0x1400) /* Config Data device (app config) ioctl commands */
|
||||
#define _TCIOCBASE (0x1500) /* Timer ioctl commands */
|
||||
#define _JOYBASE (0x1600) /* Joystick ioctl commands */
|
||||
#define _PIPEBASE (0x1700) /* FIFO/pipe ioctl commands */
|
||||
#define _RTCBASE (0x1800) /* RTC ioctl commands */
|
||||
#define _RELAYBASE (0x1900) /* Relay devices ioctl commands */
|
||||
#define _CANBASE (0x1a00) /* CAN ioctl commands */
|
||||
#define _BTNBASE (0x1b00) /* Button ioctl commands */
|
||||
#define _ULEDBASE (0x1c00) /* User LED ioctl commands */
|
||||
#define _ZCBASE (0x1d00) /* Zero Cross ioctl commands */
|
||||
#define _LOOPBASE (0x1e00) /* Loop device commands */
|
||||
#define _MODEMBASE (0x1f00) /* Modem ioctl commands */
|
||||
#define _I2CBASE (0x2000) /* I2C driver commands */
|
||||
#define _SPIBASE (0x2100) /* SPI driver commands */
|
||||
#define _GPIOBASE (0x2200) /* GPIO driver commands */
|
||||
#define _CLIOCBASE (0x2300) /* Contactless modules ioctl commands */
|
||||
#define _USBCBASE (0x2400) /* USB-C controller ioctl commands */
|
||||
#define _MAC802154BASE (0x2500) /* 802.15.4 MAC ioctl commands */
|
||||
#define _PWRBASE (0x2600) /* Power-related ioctl commands */
|
||||
#define _FBIOCBASE (0x2700) /* Frame buffer character driver ioctl commands */
|
||||
#define _LCDIOCBASE (0x1100) /* LCD character driver ioctl commands */
|
||||
#define _SLCDIOCBASE (0x1200) /* Segment LCD ioctl commands */
|
||||
#define _WLIOCBASE (0x1300) /* Wireless modules ioctl network commands */
|
||||
#define _WLCIOCBASE (0x1400) /* Wireless modules ioctl character driver commands */
|
||||
#define _CFGDIOCBASE (0x1500) /* Config Data device (app config) ioctl commands */
|
||||
#define _TCIOCBASE (0x1600) /* Timer ioctl commands */
|
||||
#define _JOYBASE (0x1700) /* Joystick ioctl commands */
|
||||
#define _PIPEBASE (0x1800) /* FIFO/pipe ioctl commands */
|
||||
#define _RTCBASE (0x1900) /* RTC ioctl commands */
|
||||
#define _RELAYBASE (0x1a00) /* Relay devices ioctl commands */
|
||||
#define _CANBASE (0x1b00) /* CAN ioctl commands */
|
||||
#define _BTNBASE (0x1c00) /* Button ioctl commands */
|
||||
#define _ULEDBASE (0x1d00) /* User LED ioctl commands */
|
||||
#define _ZCBASE (0x1e00) /* Zero Cross ioctl commands */
|
||||
#define _LOOPBASE (0x1f00) /* Loop device commands */
|
||||
#define _MODEMBASE (0x2000) /* Modem ioctl commands */
|
||||
#define _I2CBASE (0x2100) /* I2C driver commands */
|
||||
#define _SPIBASE (0x2200) /* SPI driver commands */
|
||||
#define _GPIOBASE (0x2300) /* GPIO driver commands */
|
||||
#define _CLIOCBASE (0x2400) /* Contactless modules ioctl commands */
|
||||
#define _USBCBASE (0x2500) /* USB-C controller ioctl commands */
|
||||
#define _MAC802154BASE (0x2600) /* 802.15.4 MAC ioctl commands */
|
||||
#define _PWRBASE (0x2700) /* Power-related ioctl commands */
|
||||
#define _FBIOCBASE (0x2800) /* Frame buffer character driver ioctl commands */
|
||||
|
||||
/* boardctl() commands share the same number space */
|
||||
|
||||
|
@ -307,6 +309,12 @@
|
|||
#define _AUDIOIOCVALID(c) (_IOC_TYPE(c)==_AUDIOIOCBASE)
|
||||
#define _AUDIOIOC(nr) _IOC(_AUDIOIOCBASE,nr)
|
||||
|
||||
/* LCD character driver ioctl definitions ***********************************/
|
||||
/* (see nuttx/include/lcd/slcd_codec.h */
|
||||
|
||||
#define _LCDIOCVALID(c) (_IOC_TYPE(c)==_LCDIOCBASE)
|
||||
#define _LCDIOC(nr) _IOC(_LCDIOCBASE,nr)
|
||||
|
||||
/* Segment LCD driver ioctl definitions *************************************/
|
||||
/* (see nuttx/include/lcd/slcd_codec.h */
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,56 @@
|
|||
/************************************************************************************
|
||||
* include/nuttx/input/slcd_ioctl.h
|
||||
* IOCTL commands for segment LCDs
|
||||
*
|
||||
* Copyright (C) 2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
#ifndef __INCLUDE_NUTTX_INPUT_LCD_IOCTL_H
|
||||
#define __INCLUDE_NUTTX_INPUT_LCD_IOCTL_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <nuttx/fs/ioctl.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* IOCTL commands set aside for FT80x character driver */
|
||||
|
||||
#define FT80X_NIOCTL_CMDS 3
|
||||
#define FT80X_NIOCTL_BASE 0x0001
|
||||
|
||||
#endif /* __INCLUDE_NUTTX_INPUT_LCD_IOCTL_H */
|
Loading…
Reference in New Issue