mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-10-19 22:23:33 +08:00
Resync new repository with old repo r5166
git-svn-id: http://svn.code.sf.net/p/nuttx/code/trunk@5153 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
#
|
||||
# For a description of the syntax of this configuration file,
|
||||
# see misc/tools/kconfig-language.txt.
|
||||
#
|
||||
config INPUT_TSC2007
|
||||
bool "TI TSC2007 touchscreen controller"
|
||||
default n
|
||||
select I2C
|
||||
|
||||
config INPUT_ADS7843E
|
||||
bool "TI ADS7843E touchscreen controller"
|
||||
default n
|
||||
select SPI
|
||||
@@ -0,0 +1,72 @@
|
||||
############################################################################
|
||||
# drivers/input/Make.defs
|
||||
#
|
||||
# Copyright (C) 2011 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.
|
||||
#
|
||||
############################################################################
|
||||
|
||||
# Don't build anything if there is no NX support for input devices
|
||||
|
||||
ifeq ($(CONFIG_INPUT),y)
|
||||
|
||||
# Include the selected touchscreen drivers
|
||||
|
||||
ifeq ($(CONFIG_INPUT_TSC2007),y)
|
||||
CSRCS += tsc2007.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_INPUT_ADS7843E),y)
|
||||
CSRCS += ads7843e.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_INPUT_STMPE811),y)
|
||||
CSRCS += stmpe811_base.c
|
||||
ifneq ($(CONFIG_INPUT_STMPE811_TSC_DISABLE),y)
|
||||
CSRCS += stmpe811_tsc.c
|
||||
endif
|
||||
ifneq ($(CONFIG_INPUT_STMPE811_GPIO_DISABLE),y)
|
||||
CSRCS += stmpe811_gpio.c
|
||||
endif
|
||||
ifneq ($(CONFIG_INPUT_STMPE811_ADC_DISABLE),y)
|
||||
CSRCS += stmpe811_adc.c
|
||||
endif
|
||||
ifneq ($(CONFIG_INPUT_STMPE811_TEMP_DISABLE),y)
|
||||
CSRCS += stmpe811_temp.c
|
||||
endif
|
||||
endif
|
||||
|
||||
# Include input device driver build support
|
||||
|
||||
DEPPATH += --dep-path input
|
||||
VPATH += :input
|
||||
CFLAGS += ${shell $(TOPDIR)/tools/incdir.sh $(INCDIROPT) "$(CC)" $(TOPDIR)/drivers/input}
|
||||
endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,171 @@
|
||||
/********************************************************************************************
|
||||
* drivers/input/ads7843e.h
|
||||
*
|
||||
* Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* References:
|
||||
* "Touch Screen Controller, ADS7843," Burr-Brown Products from Texas
|
||||
* Instruments, SBAS090B, September 2000, Revised May 2002"
|
||||
*
|
||||
* 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_INPUT_ADS7843E_H
|
||||
#define __DRIVERS_INPUT_ADS7843E_H
|
||||
|
||||
/********************************************************************************************
|
||||
* Included Files
|
||||
********************************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <semaphore.h>
|
||||
#include <poll.h>
|
||||
#include <wdog.h>
|
||||
#include <nuttx/wqueue.h>
|
||||
|
||||
#include <nuttx/spi.h>
|
||||
#include <nuttx/clock.h>
|
||||
#include <nuttx/input/ads7843e.h>
|
||||
|
||||
/********************************************************************************************
|
||||
* Pre-Processor Definitions
|
||||
********************************************************************************************/
|
||||
/* Configuration ****************************************************************************/
|
||||
/* Reference counting is partially implemented, but not needed in the current design. */
|
||||
|
||||
#undef CONFIG_ADS7843E_REFCNT
|
||||
|
||||
/* ADS7843E Interfaces *********************************************************************/
|
||||
/* ADS7843E command bit settings */
|
||||
|
||||
#define ADS7843E_CMD_PD0 (1 << 0) /* PD0 */
|
||||
#define ADS7843E_CMD_PD1 (1 << 1) /* PD1 */
|
||||
#define ADS7843E_CMD_DFR (1 << 2) /* SER/DFR */
|
||||
#define ADS7843E_CMD_EIGHT_BITS_MOD (1 << 3) /* Mode */
|
||||
#define ADS7843E_CMD_START (1 << 7) /* Start Bit */
|
||||
#define ADS7843E_CMD_SWITCH_SHIFT 4 /* Address setting */
|
||||
|
||||
/* ADS7843E Commands */
|
||||
|
||||
#define ADS7843_CMD_YPOSITION \
|
||||
((1 << ADS7843E_CMD_SWITCH_SHIFT)|ADS7843E_CMD_START|ADS7843E_CMD_PD0|ADS7843E_CMD_PD1)
|
||||
#define ADS7843_CMD_XPOSITION \
|
||||
((5 << ADS7843E_CMD_SWITCH_SHIFT)|ADS7843E_CMD_START|ADS7843E_CMD_PD0|ADS7843E_CMD_PD1)
|
||||
#define ADS7843_CMD_ENABPINIRQ \
|
||||
((1 << ADS7843E_CMD_SWITCH_SHIFT)|ADS7843E_CMD_START)
|
||||
|
||||
/* Driver support **************************************************************************/
|
||||
/* This format is used to construct the /dev/input[n] device driver path. It
|
||||
* defined here so that it will be used consistently in all places.
|
||||
*/
|
||||
|
||||
#define DEV_FORMAT "/dev/input%d"
|
||||
#define DEV_NAMELEN 16
|
||||
|
||||
/* Poll the pen position while the pen is down at this rate (50MS): */
|
||||
|
||||
#define ADS7843E_WDOG_DELAY ((50 + (MSEC_PER_TICK-1))/ MSEC_PER_TICK)
|
||||
|
||||
/********************************************************************************************
|
||||
* Public Types
|
||||
********************************************************************************************/
|
||||
|
||||
/* This describes the state of one contact */
|
||||
|
||||
enum ads7843e_contact_3
|
||||
{
|
||||
CONTACT_NONE = 0, /* No contact */
|
||||
CONTACT_DOWN, /* First contact */
|
||||
CONTACT_MOVE, /* Same contact, possibly different position */
|
||||
CONTACT_UP, /* Contact lost */
|
||||
};
|
||||
|
||||
/* This structure describes the results of one ADS7843E sample */
|
||||
|
||||
struct ads7843e_sample_s
|
||||
{
|
||||
uint8_t id; /* Sampled touch point ID */
|
||||
uint8_t contact; /* Contact state (see enum ads7843e_contact_e) */
|
||||
bool valid; /* True: x,y contain valid, sampled data */
|
||||
uint16_t x; /* Measured X position */
|
||||
uint16_t y; /* Measured Y position */
|
||||
};
|
||||
|
||||
/* This structure describes the state of one ADS7843E driver instance */
|
||||
|
||||
struct ads7843e_dev_s
|
||||
{
|
||||
#ifdef CONFIG_ADS7843E_MULTIPLE
|
||||
FAR struct ads7843e_dev_s *flink; /* Supports a singly linked list of drivers */
|
||||
#endif
|
||||
#ifdef CONFIG_ADS7843E_REFCNT
|
||||
uint8_t crefs; /* Number of times the device has been opened */
|
||||
#endif
|
||||
uint8_t nwaiters; /* Number of threads waiting for ADS7843E data */
|
||||
uint8_t id; /* Current touch point ID */
|
||||
volatile bool penchange; /* An unreported event is buffered */
|
||||
sem_t devsem; /* Manages exclusive access to this structure */
|
||||
sem_t waitsem; /* Used to wait for the availability of data */
|
||||
|
||||
FAR struct ads7843e_config_s *config; /* Board configuration data */
|
||||
FAR struct spi_dev_s *spi; /* Saved SPI driver instance */
|
||||
struct work_s work; /* Supports the interrupt handling "bottom half" */
|
||||
struct ads7843e_sample_s sample; /* Last sampled touch point data */
|
||||
WDOG_ID wdog; /* Poll the position while the pen is down */
|
||||
|
||||
/* The following is a list if poll structures of threads waiting for
|
||||
* driver events. The 'struct pollfd' reference for each open is also
|
||||
* retained in the f_priv field of the 'struct file'.
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_DISABLE_POLL
|
||||
struct pollfd *fds[CONFIG_ADS7843E_NPOLLWAITERS];
|
||||
#endif
|
||||
};
|
||||
|
||||
/********************************************************************************************
|
||||
* Public Function Prototypes
|
||||
********************************************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define EXTERN extern "C"
|
||||
extern "C" {
|
||||
#else
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
#undef EXTERN
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __DRIVERS_INPUT_ADS7843E_H */
|
||||
@@ -0,0 +1,245 @@
|
||||
/********************************************************************************************
|
||||
* drivers/input/stmpe811.h
|
||||
*
|
||||
* Copyright (C) 2012 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* References:
|
||||
* "STMPE811 S-Touch® advanced resistive touchscreen controller with 8-bit
|
||||
* GPIO expander," Doc ID 14489 Rev 6, CD00186725, STMicroelectronics"
|
||||
*
|
||||
* 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_INPUT_STMPE811_H
|
||||
#define __DRIVERS_INPUT_STMPE811_H
|
||||
|
||||
/********************************************************************************************
|
||||
* Included Files
|
||||
********************************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <wdog.h>
|
||||
#include <semaphore.h>
|
||||
|
||||
#include <nuttx/clock.h>
|
||||
#include <nuttx/wqueue.h>
|
||||
#include <nuttx/input/stmpe811.h>
|
||||
|
||||
#if defined(CONFIG_INPUT) && defined(CONFIG_INPUT_STMPE811)
|
||||
|
||||
/********************************************************************************************
|
||||
* Pre-Processor Definitions
|
||||
********************************************************************************************/
|
||||
/* Configuration ****************************************************************************/
|
||||
/* Reference counting is partially implemented, but not needed in the current design.
|
||||
*/
|
||||
|
||||
#undef CONFIG_STMPE811_REFCNT
|
||||
|
||||
/* No support for the SPI interface yet */
|
||||
|
||||
#ifdef CONFIG_STMPE811_SPI
|
||||
# error "Only the STMPE811 I2C interface is supported by this driver"
|
||||
#endif
|
||||
|
||||
/* Driver support ***************************************************************************/
|
||||
/* This format is used to construct the /dev/input[n] device driver path. It defined here
|
||||
* so that it will be used consistently in all places.
|
||||
*/
|
||||
|
||||
#define DEV_FORMAT "/dev/input%d"
|
||||
#define DEV_NAMELEN 16
|
||||
|
||||
/* STMPE811 Resources ************************************************************************/
|
||||
#ifndef CONFIG_STMPE811_TSC_DISABLE
|
||||
# define STMPE811_ADC_NPINS 4 /* Only pins 0-3 can be used for ADC */
|
||||
# define STMPE811_GPIO_NPINS 4 /* Only pins 0-3 can be used as GPIOs */
|
||||
#else
|
||||
# define STMPE811_ADC_NPINS 8 /* All pins can be used for ADC */
|
||||
# define STMPE811_GPIO_NPINS 8 /* All pins can be used as GPIOs */
|
||||
#endif
|
||||
|
||||
/* Driver flags */
|
||||
|
||||
#define STMPE811_FLAGS_TSC_INITIALIZED (1 << 0) /* 1: The TSC block has been initialized */
|
||||
#define STMPE811_FLAGS_GPIO_INITIALIZED (1 << 1) /* 1: The GIO block has been initialized */
|
||||
#define STMPE811_FLAGS_ADC_INITIALIZED (1 << 2) /* 1: The ADC block has been initialized */
|
||||
#define STMPE811_FLAGS_TS_INITIALIZED (1 << 3) /* 1: The TS block has been initialized */
|
||||
|
||||
/* Timeout to detect missing pen up events */
|
||||
|
||||
#define STMPE811_PENUP_TICKS ((100 + (MSEC_PER_TICK-1)) / MSEC_PER_TICK)
|
||||
|
||||
/********************************************************************************************
|
||||
* Public Types
|
||||
********************************************************************************************/
|
||||
/* This describes the state of one contact */
|
||||
|
||||
enum stmpe811_contact_3
|
||||
{
|
||||
CONTACT_NONE = 0, /* No contact */
|
||||
CONTACT_DOWN, /* First contact */
|
||||
CONTACT_MOVE, /* Same contact, possibly different position */
|
||||
CONTACT_UP, /* Contact lost */
|
||||
};
|
||||
|
||||
/* This structure describes the results of one STMPE811 sample */
|
||||
|
||||
struct stmpe811_sample_s
|
||||
{
|
||||
uint8_t id; /* Sampled touch point ID */
|
||||
uint8_t contact; /* Contact state (see enum stmpe811_contact_e) */
|
||||
bool valid; /* True: x,y,z contain valid, sampled data */
|
||||
uint16_t x; /* Measured X position */
|
||||
uint16_t y; /* Measured Y position */
|
||||
uint8_t z; /* Measured Z index */
|
||||
};
|
||||
|
||||
/* This structure represents the state of the STMPE811 driver */
|
||||
|
||||
struct stmpe811_dev_s
|
||||
{
|
||||
#ifdef CONFIG_STMPE811_MULTIPLE
|
||||
FAR struct stmpe811_dev_s *flink; /* Supports a singly linked list of drivers */
|
||||
#endif
|
||||
|
||||
/* Common fields */
|
||||
|
||||
FAR struct stmpe811_config_s *config; /* Board configuration data */
|
||||
sem_t exclsem; /* Manages exclusive access to this structure */
|
||||
#ifdef CONFIG_STMPE811_SPI
|
||||
FAR struct spi_dev_s *spi; /* Saved SPI driver instance */
|
||||
#else
|
||||
FAR struct i2c_dev_s *i2c; /* Saved I2C driver instance */
|
||||
#endif
|
||||
|
||||
uint8_t inuse; /* STMPE811 pins in use */
|
||||
uint8_t flags; /* See STMPE811_FLAGS_* definitions */
|
||||
struct work_s work; /* Supports the interrupt handling "bottom half" */
|
||||
|
||||
/* Fields that may be disabled to save size if touchscreen support is not used. */
|
||||
|
||||
#ifndef CONFIG_STMPE811_TSC_DISABLE
|
||||
#ifdef CONFIG_STMPE811_REFCNT
|
||||
uint8_t crefs; /* Number of times the device has been opened */
|
||||
#endif
|
||||
uint8_t nwaiters; /* Number of threads waiting for STMPE811 data */
|
||||
uint8_t id; /* Current touch point ID */
|
||||
uint8_t minor; /* Touchscreen minor device number */
|
||||
volatile bool penchange; /* An unreported event is buffered */
|
||||
|
||||
uint16_t threshx; /* Thresholded X value */
|
||||
uint16_t threshy; /* Thresholded Y value */
|
||||
sem_t waitsem; /* Used to wait for the availability of data */
|
||||
|
||||
struct work_s timeout; /* Supports tiemeout work */
|
||||
WDOG_ID wdog; /* Timeout to detect missing pen down events */
|
||||
struct stmpe811_sample_s sample; /* Last sampled touch point data */
|
||||
|
||||
/* The following is a list if poll structures of threads waiting for
|
||||
* driver events. The 'struct pollfd' reference for each open is also
|
||||
* retained in the f_priv field of the 'struct file'.
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_DISABLE_POLL
|
||||
struct pollfd *fds[CONFIG_STMPE811_NPOLLWAITERS];
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Fields that may be disabled to save size of GPIO support is not used */
|
||||
|
||||
#if !defined(CONFIG_STMPE811_GPIO_DISABLE) && !defined(CONFIG_STMPE811_GPIOINT_DISABLE)
|
||||
stmpe811_handler_t handlers[STMPE811_GPIO_NPINS]; /* GPIO "interrupt handlers" */
|
||||
#endif
|
||||
};
|
||||
|
||||
/********************************************************************************************
|
||||
* Public Function Prototypes
|
||||
********************************************************************************************/
|
||||
|
||||
/********************************************************************************************
|
||||
* Name: stmpe811_getreg8
|
||||
*
|
||||
* Description:
|
||||
* Read from an 8-bit STMPE811 register
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
uint8_t stmpe811_getreg8(FAR struct stmpe811_dev_s *priv, uint8_t regaddr);
|
||||
|
||||
/********************************************************************************************
|
||||
* Name: stmpe811_putreg8
|
||||
*
|
||||
* Description:
|
||||
* Write a value to an 8-bit STMPE811 register
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
void stmpe811_putreg8(FAR struct stmpe811_dev_s *priv, uint8_t regaddr, uint8_t regval);
|
||||
|
||||
/********************************************************************************************
|
||||
* Name: stmpe811_getreg16
|
||||
*
|
||||
* Description:
|
||||
* Read 16-bits of data from an STMPE-11 register
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
uint16_t stmpe811_getreg16(FAR struct stmpe811_dev_s *priv, uint8_t regaddr);
|
||||
|
||||
/********************************************************************************************
|
||||
* Name: stmpe811_tscint
|
||||
*
|
||||
* Description:
|
||||
* Handle touchscreen interrupt events (this function actually executes in the context of
|
||||
* the worker thread).
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#ifndef CONFIG_STMPE811_TSC_DISABLE
|
||||
void stmpe811_tscworker(FAR struct stmpe811_dev_s *priv, uint8_t intsta) weak_function;
|
||||
#endif
|
||||
|
||||
/********************************************************************************************
|
||||
* Name: stmpe811_gpioworker
|
||||
*
|
||||
* Description:
|
||||
* Handle GPIO interrupt events (this function actually executes in the context of the
|
||||
* worker thread).
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#if !defined(CONFIG_STMPE811_GPIO_DISABLE) && !defined(CONFIG_STMPE811_GPIOINT_DISABLE)
|
||||
void stmpe811_gpioworker(FAR struct stmpe811_dev_s *priv) weak_function;
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_INPUT && CONFIG_INPUT_STMPE811 */
|
||||
#endif /* __DRIVERS_INPUT_STMPE811_H */
|
||||
@@ -0,0 +1,266 @@
|
||||
/****************************************************************************
|
||||
* drivers/input/stmpe811_adc.c
|
||||
*
|
||||
* Copyright (C) 2012 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* References:
|
||||
* "STMPE811 S-Touch® advanced resistive touchscreen controller with 8-bit
|
||||
* GPIO expander," Doc ID 14489 Rev 6, CD00186725, STMicroelectronics"
|
||||
*
|
||||
* 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 <assert.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/input/stmpe811.h>
|
||||
|
||||
#include "stmpe811.h"
|
||||
|
||||
#if defined(CONFIG_INPUT) && defined(CONFIG_INPUT_STMPE811) && !defined(CONFIG_STMPE811_ADC_DISABLE)
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stmpe811_adcinitialize
|
||||
*
|
||||
* Description:
|
||||
* Configure for ADC mode operation. Set overall ADC ADC timing that
|
||||
* applies to all pins.
|
||||
*
|
||||
* Input Parameters:
|
||||
* handle - The handle previously returned by stmpe811_instantiate
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero is returned on success. Otherwise, a negated errno value is
|
||||
* returned to indicate the nature of the failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int stmpe811_adcinitialize(STMPE811_HANDLE handle)
|
||||
{
|
||||
FAR struct stmpe811_dev_s *priv = (FAR struct stmpe811_dev_s *)handle;
|
||||
uint8_t regval;
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(handle);
|
||||
|
||||
/* Get exclusive access to the device structure */
|
||||
|
||||
ret = sem_wait(&priv->exclsem);
|
||||
if (ret < 0)
|
||||
{
|
||||
int errval = errno;
|
||||
idbg("sem_wait failed: %d\n", errval);
|
||||
return -errval;
|
||||
}
|
||||
|
||||
/* Enable Clocking for ADC */
|
||||
|
||||
regval = stmpe811_getreg8(priv, STMPE811_SYS_CTRL2);
|
||||
regval &= ~SYS_CTRL2_ADC_OFF;
|
||||
stmpe811_putreg8(priv, STMPE811_SYS_CTRL2, regval);
|
||||
|
||||
/* Select Sample Time, bit number and ADC Reference */
|
||||
|
||||
stmpe811_putreg8(priv, STMPE811_ADC_CTRL1, priv->config->ctrl1);
|
||||
|
||||
/* Wait for 20 ms */
|
||||
|
||||
up_mdelay(20);
|
||||
|
||||
/* Select the ADC clock speed */
|
||||
|
||||
stmpe811_putreg8(priv, STMPE811_ADC_CTRL2, priv->config->ctrl2);
|
||||
|
||||
/* Mark ADC initialized */
|
||||
|
||||
priv->flags |= STMPE811_FLAGS_ADC_INITIALIZED;
|
||||
sem_post(&priv->exclsem);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stmpe811_adcconfig
|
||||
*
|
||||
* Description:
|
||||
* Configure a pin for ADC input.
|
||||
*
|
||||
* Input Parameters:
|
||||
* handle - The handle previously returned by stmpe811_instantiate
|
||||
* pin - The ADC pin number
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero is returned on success. Otherwise, a negated errno value is
|
||||
* returned to indicate the nature of the failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int stmpe811_adcconfig(STMPE811_HANDLE handle, int pin)
|
||||
{
|
||||
FAR struct stmpe811_dev_s *priv = (FAR struct stmpe811_dev_s *)handle;
|
||||
uint8_t pinmask = GPIO_PIN(pin);
|
||||
uint8_t regval;
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(handle && (unsigned)pin < STMPE811_ADC_NPINS);
|
||||
|
||||
/* Get exclusive access to the device structure */
|
||||
|
||||
ret = sem_wait(&priv->exclsem);
|
||||
if (ret < 0)
|
||||
{
|
||||
int errval = errno;
|
||||
idbg("sem_wait failed: %d\n", errval);
|
||||
return -errval;
|
||||
}
|
||||
|
||||
/* Make sure that the pin is not already in use */
|
||||
|
||||
if ((priv->inuse & pinmask) != 0)
|
||||
{
|
||||
idbg("PIN%d is already in-use\n", pin);
|
||||
sem_post(&priv->exclsem);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
/* Clear the alternate function bit for the pin, making it an ADC input
|
||||
* (or perhaps an an external reference, depending on the state of the
|
||||
* ADC_CTRL1_REF_SEL bit).
|
||||
*/
|
||||
|
||||
regval = stmpe811_getreg8(priv, STMPE811_GPIO_AF);
|
||||
regval &= ~pinmask;
|
||||
stmpe811_putreg8(priv, STMPE811_GPIO_AF, regval);
|
||||
|
||||
/* Mark the pin as 'in use' */
|
||||
|
||||
priv->inuse |= pinmask;
|
||||
sem_post(&priv->exclsem);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stmpe811_adcread
|
||||
*
|
||||
* Description:
|
||||
* Read the converted analog input value from the select pin.
|
||||
*
|
||||
* Input Parameters:
|
||||
* handle - The handle previously returned by stmpe811_instantiate
|
||||
* pin - The ADC pin number
|
||||
*
|
||||
* Returned Value:
|
||||
* The converted value (there is no error reporting mechanism).
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
uint16_t stmpe811_adcread(STMPE811_HANDLE handle, int pin)
|
||||
{
|
||||
FAR struct stmpe811_dev_s *priv = (FAR struct stmpe811_dev_s *)handle;
|
||||
uint8_t pinmask = GPIO_PIN(pin);
|
||||
uint8_t regval;
|
||||
int i;
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(handle && (unsigned)pin < 8);
|
||||
|
||||
/* Get exclusive access to the device structure */
|
||||
|
||||
ret = sem_wait(&priv->exclsem);
|
||||
if (ret < 0)
|
||||
{
|
||||
int errval = errno;
|
||||
idbg("sem_wait failed: %d\n", errval);
|
||||
return -errval;
|
||||
}
|
||||
|
||||
/* Request AD conversion by setting the bit corresponding the pin in the
|
||||
* ADC CAPT register.
|
||||
*/
|
||||
|
||||
stmpe811_putreg8(priv, STMPE811_ADC_CAPT, pinmask);
|
||||
|
||||
/* Wait for the conversion to complete. The ADC CAPT register reads '1'
|
||||
* if conversion is completed. Reads '0' if conversion is in progress.
|
||||
* Try three times before giving up.
|
||||
*/
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
/* The worst case ADC conversion time is (nominally) 56.4 uS. The
|
||||
* following usleep() looks nice but in reality, the usleep()
|
||||
* does not have that kind of precision (it will probably end up
|
||||
* waiting 10 MS).
|
||||
*/
|
||||
|
||||
usleep(57);
|
||||
|
||||
/* Check if the conversion is complete */
|
||||
|
||||
regval = stmpe811_getreg8(priv, STMPE811_ADC_CAPT);
|
||||
if ((regval & pinmask) != 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* At the completion of the conversion, return whatever we read from
|
||||
* from the channel register associated with the pin.
|
||||
*/
|
||||
|
||||
return stmpe811_getreg16(priv, STMPE811_ADC_DATACH(pin));
|
||||
}
|
||||
|
||||
#endif /* CONFIG_INPUT && CONFIG_INPUT_STMPE811 && !CONFIG_STMPE811_ADC_DISABLE */
|
||||
|
||||
@@ -0,0 +1,546 @@
|
||||
/****************************************************************************
|
||||
* drivers/input/stmpe811_base.c
|
||||
*
|
||||
* Copyright (C) 2012 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* References:
|
||||
* "STMPE811 S-Touch® advanced resistive touchscreen controller with 8-bit
|
||||
* GPIO expander," Doc ID 14489 Rev 6, CD00186725, STMicroelectronics"
|
||||
*
|
||||
* 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/input/stmpe811.h>
|
||||
|
||||
#include "stmpe811.h"
|
||||
|
||||
#if defined(CONFIG_INPUT) && defined(CONFIG_INPUT_STMPE811)
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/* If only a single STMPE811 device is supported, then the driver state
|
||||
* structure may as well be pre-allocated.
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_STMPE811_MULTIPLE
|
||||
static struct stmpe811_dev_s g_stmpe811;
|
||||
|
||||
/* Otherwise, we will need to maintain allocated driver instances in a list */
|
||||
|
||||
#else
|
||||
static struct stmpe811_dev_s *g_stmpe811list;
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stmpe811_worker
|
||||
*
|
||||
* Description:
|
||||
* This is the "bottom half" of the STMPE811 interrupt handler
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void stmpe811_worker(FAR void *arg)
|
||||
{
|
||||
FAR struct stmpe811_dev_s *priv = (FAR struct stmpe811_dev_s *)arg;
|
||||
uint8_t regval;
|
||||
|
||||
DEBUGASSERT(priv && priv->config);
|
||||
|
||||
/* Get the global interrupt status */
|
||||
|
||||
regval = stmpe811_getreg8(priv, STMPE811_INT_STA);
|
||||
|
||||
/* Check for a touchscreen interrupt */
|
||||
|
||||
#ifndef CONFIG_STMPE811_TSC_DISABLE
|
||||
if ((regval & (INT_TOUCH_DET|INT_FIFO_TH|INT_FIFO_OFLOW)) != 0)
|
||||
{
|
||||
/* Dispatch the touchscreen interrupt if it was brought into the link */
|
||||
|
||||
#ifdef CONFIG_HAVE_WEAKFUNCTIONS
|
||||
if (stmpe811_tscworker)
|
||||
#endif
|
||||
{
|
||||
stmpe811_tscworker(priv, regval);
|
||||
}
|
||||
|
||||
stmpe811_putreg8(priv, STMPE811_INT_STA, (INT_TOUCH_DET|INT_FIFO_TH|INT_FIFO_OFLOW));
|
||||
regval &= ~(INT_TOUCH_DET|INT_FIFO_TH|INT_FIFO_OFLOW);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_STMPE811_GPIO_DISABLE) && !defined(CONFIG_STMPE811_GPIOINT_DISABLE)
|
||||
if ((regval & INT_GPIO) != 0)
|
||||
{
|
||||
/* Dispatch the GPIO interrupt if it was brought into the link */
|
||||
|
||||
#ifdef CONFIG_HAVE_WEAKFUNCTIONS
|
||||
if (stmpe811_gpioworker)
|
||||
#endif
|
||||
{
|
||||
stmpe811_gpioworker(priv);
|
||||
}
|
||||
|
||||
stmpe811_putreg8(priv, STMPE811_INT_STA, INT_GPIO);
|
||||
regval &= ~INT_GPIO;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Clear any other residual, unhandled pending interrupt */
|
||||
|
||||
if (regval != 0)
|
||||
{
|
||||
stmpe811_putreg8(priv, STMPE811_INT_STA, regval);
|
||||
}
|
||||
|
||||
/* Re-enable the STMPE811 GPIO interrupt */
|
||||
|
||||
priv->config->enable(priv->config, true);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stmpe811_interrupt
|
||||
*
|
||||
* Description:
|
||||
* The STMPE811 interrupt handler
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int stmpe811_interrupt(int irq, FAR void *context)
|
||||
{
|
||||
FAR struct stmpe811_dev_s *priv;
|
||||
FAR struct stmpe811_config_s *config;
|
||||
int ret;
|
||||
|
||||
/* Which STMPE811 device caused the interrupt? */
|
||||
|
||||
#ifndef CONFIG_STMPE811_MULTIPLE
|
||||
priv = &g_stmpe811;
|
||||
#else
|
||||
for (priv = g_stmpe811list;
|
||||
priv && priv->config->irq != irq;
|
||||
priv = priv->flink);
|
||||
|
||||
ASSERT(priv != NULL);
|
||||
#endif
|
||||
|
||||
/* Get a pointer the callbacks for convenience (and so the code is not so
|
||||
* ugly).
|
||||
*/
|
||||
|
||||
config = priv->config;
|
||||
DEBUGASSERT(config != NULL);
|
||||
|
||||
/* Disable further interrupts */
|
||||
|
||||
config->enable(config, false);
|
||||
|
||||
/* Check if interrupt work is already queue. If it is already busy, then
|
||||
* we already have interrupt processing in the pipeline and we need to do
|
||||
* nothing more.
|
||||
*/
|
||||
|
||||
if (work_available(&priv->work))
|
||||
{
|
||||
/* Yes.. Transfer processing to the worker thread. Since STMPE811
|
||||
* interrupts are disabled while the work is pending, no special
|
||||
* action should be required to protect the work queue.
|
||||
*/
|
||||
|
||||
ret = work_queue(HPWORK, &priv->work, stmpe811_worker, priv, 0);
|
||||
if (ret != 0)
|
||||
{
|
||||
illdbg("Failed to queue work: %d\n", ret);
|
||||
}
|
||||
}
|
||||
|
||||
/* Clear any pending interrupts and return success */
|
||||
|
||||
config->clear(config);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stmpe811_checkid
|
||||
*
|
||||
* Description:
|
||||
* Read and verify the STMPE811 chip ID
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int stmpe811_checkid(FAR struct stmpe811_dev_s *priv)
|
||||
{
|
||||
uint16_t devid = 0;
|
||||
|
||||
/* Read device ID */
|
||||
|
||||
devid = stmpe811_getreg8(priv, STMPE811_CHIP_ID);
|
||||
devid = (uint32_t)(devid << 8);
|
||||
devid |= (uint32_t)stmpe811_getreg8(priv, STMPE811_CHIP_ID+1);
|
||||
ivdbg("devid: %04x\n", devid);
|
||||
|
||||
if (devid != (uint16_t)CHIP_ID)
|
||||
{
|
||||
/* ID is not Correct */
|
||||
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stmpe811_reset
|
||||
*
|
||||
* Description:
|
||||
* Reset the STMPE811
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void stmpe811_reset(FAR struct stmpe811_dev_s *priv)
|
||||
{
|
||||
/* Power Down the STMPE811 */
|
||||
|
||||
stmpe811_putreg8(priv, STMPE811_SYS_CTRL1, SYS_CTRL1_SOFTRESET);
|
||||
|
||||
/* Wait a bit */
|
||||
|
||||
usleep(20*1000);
|
||||
|
||||
/* Then power on again. All registers will be in their reset state. */
|
||||
|
||||
stmpe811_putreg8(priv, STMPE811_SYS_CTRL1, 0);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stmpe811_instantiate
|
||||
*
|
||||
* Description:
|
||||
* Instantiate and configure the STMPE811 device driver to use the provided
|
||||
* I2C or SPIdevice instance.
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - An I2C or SPI driver instance
|
||||
* config - Persistant board configuration data
|
||||
*
|
||||
* Returned Value:
|
||||
* A non-zero handle is returned on success. This handle may then be used
|
||||
* to configure the STMPE811 driver as necessary. A NULL handle value is
|
||||
* returned on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_STMPE811_SPI
|
||||
STMPE811_HANDLE stmpe811_instantiate(FAR struct spi_dev_s *dev,
|
||||
FAR struct stmpe811_config_s *config)
|
||||
#else
|
||||
STMPE811_HANDLE stmpe811_instantiate(FAR struct i2c_dev_s *dev,
|
||||
FAR struct stmpe811_config_s *config)
|
||||
#endif
|
||||
{
|
||||
FAR struct stmpe811_dev_s *priv;
|
||||
uint8_t regval;
|
||||
int ret;
|
||||
|
||||
/* Allocate the device state structure */
|
||||
|
||||
#ifdef CONFIG_STMPE811_MULTIPLE
|
||||
priv = (FAR struct stmpe811_dev_s *)kzalloc(sizeof(struct stmpe811_dev_s));
|
||||
if (!priv)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* And save the device structure in the list of STMPE811 so that we can find it later */
|
||||
|
||||
priv->flink = g_stmpe811list;
|
||||
g_stmpe811list = priv;
|
||||
#else
|
||||
|
||||
/* Use the one-and-only STMPE811 driver instance */
|
||||
|
||||
priv = &g_stmpe811;
|
||||
#endif
|
||||
|
||||
/* Initialize the device state structure */
|
||||
|
||||
sem_init(&priv->exclsem, 0, 1);
|
||||
priv->config = config;
|
||||
|
||||
#ifdef CONFIG_STMPE811_SPI
|
||||
priv->spi = dev;
|
||||
#else
|
||||
priv->i2c = dev;
|
||||
|
||||
/* Set the I2C address and frequency. REVISIT: This logic would be
|
||||
* insufficient if we share the I2C bus with any other devices that also
|
||||
* modify the address and frequency.
|
||||
*/
|
||||
|
||||
I2C_SETADDRESS(dev, config->address, 7);
|
||||
I2C_SETFREQUENCY(dev, config->frequency);
|
||||
#endif
|
||||
|
||||
/* Read and verify the STMPE811 chip ID */
|
||||
|
||||
ret = stmpe811_checkid(priv);
|
||||
if (ret < 0)
|
||||
{
|
||||
#ifdef CONFIG_STMPE811_MULTIPLE
|
||||
kfree(priv);
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Generate STMPE811 Software reset */
|
||||
|
||||
stmpe811_reset(priv);
|
||||
|
||||
/* Configure the interrupt output pin to generate interrupts on high or low level. */
|
||||
|
||||
regval = stmpe811_getreg8(priv, STMPE811_INT_CTRL);
|
||||
#ifdef CONFIG_STMPE811_ACTIVELOW
|
||||
regval &= ~INT_CTRL_INT_POLARITY; /* Pin polarity: Active low / falling edge */
|
||||
#else
|
||||
regval |= INT_CTRL_INT_POLARITY; /* Pin polarity: Active high / rising edge */
|
||||
#endif
|
||||
#ifdef CONFIG_STMPE811_EDGE
|
||||
regval |= INT_CTRL_INT_TYPE; /* Edge interrupt */
|
||||
#else
|
||||
regval &= ~INT_CTRL_INT_TYPE; /* Level interrupt */
|
||||
#endif
|
||||
stmpe811_putreg8(priv, STMPE811_INT_CTRL, regval);
|
||||
|
||||
/* Attach the STMPE811 interrupt handler. */
|
||||
|
||||
config->attach(config, stmpe811_interrupt);
|
||||
|
||||
/* Clear any pending interrupts */
|
||||
|
||||
stmpe811_putreg8(priv, STMPE811_INT_STA, INT_ALL);
|
||||
config->clear(config);
|
||||
config->enable(config, true);
|
||||
|
||||
/* Enable global interrupts */
|
||||
|
||||
regval = stmpe811_getreg8(priv, STMPE811_INT_CTRL);
|
||||
regval |= INT_CTRL_GLOBAL_INT;
|
||||
stmpe811_putreg8(priv, STMPE811_INT_CTRL, regval);
|
||||
|
||||
/* Return our private data structure as an opaque handle */
|
||||
|
||||
return (STMPE811_HANDLE)priv;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stmpe811_getreg8
|
||||
*
|
||||
* Description:
|
||||
* Read from an 8-bit STMPE811 register
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_STMPE811_I2C
|
||||
uint8_t stmpe811_getreg8(FAR struct stmpe811_dev_s *priv, uint8_t regaddr)
|
||||
{
|
||||
/* 8-bit data read sequence:
|
||||
*
|
||||
* Start - I2C_Write_Address - STMPE811_Reg_Address -
|
||||
* Repeated_Start - I2C_Read_Address - STMPE811_Read_Data - STOP
|
||||
*/
|
||||
|
||||
struct i2c_msg_s msg[2];
|
||||
uint8_t regval;
|
||||
int ret;
|
||||
|
||||
/* Setup 8-bit STMPE811 address write message */
|
||||
|
||||
msg[0].addr = priv->config->address; /* 7-bit address */
|
||||
msg[0].flags = 0; /* Write transaction, beginning with START */
|
||||
msg[0].buffer = ®addr; /* Transfer from this address */
|
||||
msg[0].length = 1; /* Send one byte following the address
|
||||
* (no STOP) */
|
||||
|
||||
/* Set up the 8-bit STMPE811 data read message */
|
||||
|
||||
msg[1].addr = priv->config->address; /* 7-bit address */
|
||||
msg[1].flags = I2C_M_READ; /* Read transaction, beginning with Re-START */
|
||||
msg[1].buffer = ®val; /* Transfer to this address */
|
||||
msg[1].length = 1; /* Receive one byte following the address
|
||||
* (then STOP) */
|
||||
|
||||
/* Perform the transfer */
|
||||
|
||||
ret = I2C_TRANSFER(priv->i2c, msg, 2);
|
||||
if (ret < 0)
|
||||
{
|
||||
idbg("I2C_TRANSFER failed: %d\n", ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_STMPE811_REGDEBUG
|
||||
dbg("%02x->%02x\n", regaddr, regval);
|
||||
#endif
|
||||
return regval;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stmpe811_putreg8
|
||||
*
|
||||
* Description:
|
||||
* Write a value to an 8-bit STMPE811 register
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_STMPE811_I2C
|
||||
void stmpe811_putreg8(FAR struct stmpe811_dev_s *priv,
|
||||
uint8_t regaddr, uint8_t regval)
|
||||
{
|
||||
/* 8-bit data read sequence:
|
||||
*
|
||||
* Start - I2C_Write_Address - STMPE811_Reg_Address - STMPE811_Write_Data - STOP
|
||||
*/
|
||||
|
||||
struct i2c_msg_s msg;
|
||||
uint8_t txbuffer[2];
|
||||
int ret;
|
||||
|
||||
#ifdef CONFIG_STMPE811_REGDEBUG
|
||||
dbg("%02x<-%02x\n", regaddr, regval);
|
||||
#endif
|
||||
|
||||
/* Setup to the data to be transferred. Two bytes: The STMPE811 register
|
||||
* address followed by one byte of data.
|
||||
*/
|
||||
|
||||
txbuffer[0] = regaddr;
|
||||
txbuffer[1] = regval;
|
||||
|
||||
/* Setup 8-bit STMPE811 address write message */
|
||||
|
||||
msg.addr = priv->config->address; /* 7-bit address */
|
||||
msg.flags = 0; /* Write transaction, beginning with START */
|
||||
msg.buffer = txbuffer; /* Transfer from this address */
|
||||
msg.length = 2; /* Send two byte following the address
|
||||
* (then STOP) */
|
||||
|
||||
/* Perform the transfer */
|
||||
|
||||
ret = I2C_TRANSFER(priv->i2c, &msg, 1);
|
||||
if (ret < 0)
|
||||
{
|
||||
idbg("I2C_TRANSFER failed: %d\n", ret);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stmpe811_getreg16
|
||||
*
|
||||
* Description:
|
||||
* Read 16-bits of data from an STMPE-11 register
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_STMPE811_I2C
|
||||
uint16_t stmpe811_getreg16(FAR struct stmpe811_dev_s *priv, uint8_t regaddr)
|
||||
{
|
||||
/* 16-bit data read sequence:
|
||||
*
|
||||
* Start - I2C_Write_Address - STMPE811_Reg_Address -
|
||||
* Repeated_Start - I2C_Read_Address - STMPE811_Read_Data_1 -
|
||||
* STMPE811_Read_Data_2 - STOP
|
||||
*/
|
||||
|
||||
|
||||
struct i2c_msg_s msg[2];
|
||||
uint8_t rxbuffer[2];
|
||||
int ret;
|
||||
|
||||
/* Setup 8-bit STMPE811 address write message */
|
||||
|
||||
msg[0].addr = priv->config->address; /* 7-bit address */
|
||||
msg[0].flags = 0; /* Write transaction, beginning with START */
|
||||
msg[0].buffer = ®addr; /* Transfer from this address */
|
||||
msg[0].length = 1; /* Send one byte following the address
|
||||
* (no STOP) */
|
||||
|
||||
/* Set up the 8-bit STMPE811 data read message */
|
||||
|
||||
msg[1].addr = priv->config->address; /* 7-bit address */
|
||||
msg[1].flags = I2C_M_READ; /* Read transaction, beginning with Re-START */
|
||||
msg[1].buffer = rxbuffer; /* Transfer to this address */
|
||||
msg[1].length = 2; /* Receive two bytes following the address
|
||||
* (then STOP) */
|
||||
|
||||
/* Perform the transfer */
|
||||
|
||||
ret = I2C_TRANSFER(priv->i2c, msg, 2);
|
||||
if (ret < 0)
|
||||
{
|
||||
idbg("I2C_TRANSFER failed: %d\n", ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_STMPE811_REGDEBUG
|
||||
dbg("%02x->%02x%02x\n", regaddr, rxbuffer[0], rxbuffer[1]);
|
||||
#endif
|
||||
return (uint16_t)rxbuffer[0] << 8 | (uint16_t)rxbuffer[1];
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_INPUT && CONFIG_INPUT_STMPE811 */
|
||||
|
||||
@@ -0,0 +1,454 @@
|
||||
/****************************************************************************
|
||||
* drivers/input/stmpe811_gpio.c
|
||||
*
|
||||
* Copyright (C) 2012 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* References:
|
||||
* "STMPE811 S-Touch® advanced resistive touchscreen controller with 8-bit
|
||||
* GPIO expander," Doc ID 14489 Rev 6, CD00186725, STMicroelectronics"
|
||||
*
|
||||
* 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 <assert.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/input/stmpe811.h>
|
||||
|
||||
#include "stmpe811.h"
|
||||
|
||||
#if defined(CONFIG_INPUT) && defined(CONFIG_INPUT_STMPE811) && !defined(CONFIG_STMPE811_GPIO_DISABLE)
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stmpe811_gpioinit
|
||||
*
|
||||
* Description:
|
||||
* Initialize the GPIO interrupt subsystem
|
||||
*
|
||||
* Input Parameters:
|
||||
* handle - The handle previously returned by stmpe811_instantiate
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero is returned on success. Otherwise, a negated errno value is
|
||||
* returned to indicate the nature of the failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void stmpe811_gpioinit(FAR struct stmpe811_dev_s *priv)
|
||||
{
|
||||
uint8_t regval;
|
||||
|
||||
if ((priv->flags & STMPE811_FLAGS_GPIO_INITIALIZED) == 0)
|
||||
{
|
||||
/* Enable Clocking for GPIO */
|
||||
|
||||
regval = stmpe811_getreg8(priv, STMPE811_SYS_CTRL2);
|
||||
regval &= ~SYS_CTRL2_GPIO_OFF;
|
||||
stmpe811_putreg8(priv, STMPE811_SYS_CTRL2, regval);
|
||||
|
||||
/* Disable all GPIO interrupts */
|
||||
|
||||
stmpe811_putreg8(priv, STMPE811_GPIO_EN, 0);
|
||||
|
||||
/* Enable global GPIO interrupts */
|
||||
|
||||
#ifndef CONFIG_STMPE811_GPIOINT_DISABLE
|
||||
regval = stmpe811_getreg8(priv, STMPE811_INT_EN);
|
||||
regval |= INT_GPIO;
|
||||
stmpe811_putreg8(priv, STMPE811_INT_EN, regval);
|
||||
#endif
|
||||
|
||||
priv->flags |= STMPE811_FLAGS_GPIO_INITIALIZED;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stmpe811_gpioconfig
|
||||
*
|
||||
* Description:
|
||||
* Configure an STMPE811 GPIO pin
|
||||
*
|
||||
* Input Parameters:
|
||||
* handle - The handle previously returned by stmpe811_instantiate
|
||||
* pinconfig - Bit-encoded pin configuration
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero is returned on success. Otherwise, a negated errno value is
|
||||
* returned to indicate the nature of the failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int stmpe811_gpioconfig(STMPE811_HANDLE handle, uint8_t pinconfig)
|
||||
{
|
||||
FAR struct stmpe811_dev_s *priv = (FAR struct stmpe811_dev_s *)handle;
|
||||
int pin = (pinconfig & STMPE811_GPIO_PIN_MASK) >> STMPE811_GPIO_PIN_SHIFT;
|
||||
uint8_t pinmask = (1 << pin);
|
||||
uint8_t regval;
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(handle && (unsigned)pin < STMPE811_GPIO_NPINS);
|
||||
|
||||
/* Get exclusive access to the device structure */
|
||||
|
||||
ret = sem_wait(&priv->exclsem);
|
||||
if (ret < 0)
|
||||
{
|
||||
int errval = errno;
|
||||
idbg("sem_wait failed: %d\n", errval);
|
||||
return -errval;
|
||||
}
|
||||
|
||||
/* Make sure that the pin is not already in use */
|
||||
|
||||
if ((priv->inuse & pinmask) != 0)
|
||||
{
|
||||
idbg("PIN%d is already in-use\n", pin);
|
||||
sem_post(&priv->exclsem);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
/* Make sure that the GPIO block has been initialized */
|
||||
|
||||
stmpe811_gpioinit(priv);
|
||||
|
||||
/* Set the alternate function bit for the pin, making it a GPIO */
|
||||
|
||||
regval = stmpe811_getreg8(priv, STMPE811_GPIO_AF);
|
||||
regval |= pinmask;
|
||||
stmpe811_putreg8(priv, STMPE811_GPIO_AF, regval);
|
||||
|
||||
/* Is the pin an input or an output? */
|
||||
|
||||
if ((pinconfig & STMPE811_GPIO_DIR) == STMPE811_GPIO_OUTPUT)
|
||||
{
|
||||
/* The pin is an output */
|
||||
|
||||
regval = stmpe811_getreg8(priv, STMPE811_GPIO_DIR);
|
||||
regval &= ~pinmask;
|
||||
stmpe811_putreg8(priv, STMPE811_GPIO_DIR, regval);
|
||||
|
||||
/* Set its initial output value */
|
||||
|
||||
stmpe811_gpiowrite(handle, pinconfig,
|
||||
(pinconfig & STMPE811_GPIO_VALUE) != STMPE811_GPIO_ZERO);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* It is an input */
|
||||
|
||||
regval = stmpe811_getreg8(priv, STMPE811_GPIO_DIR);
|
||||
regval |= pinmask;
|
||||
stmpe811_putreg8(priv, STMPE811_GPIO_DIR, regval);
|
||||
|
||||
/* Set up the falling edge detection */
|
||||
|
||||
regval = stmpe811_getreg8(priv, STMPE811_GPIO_FE);
|
||||
if ((pinconfig & STMPE811_GPIO_FALLING) != 0)
|
||||
{
|
||||
regval |= pinmask;
|
||||
}
|
||||
else
|
||||
{
|
||||
regval &= pinmask;
|
||||
}
|
||||
stmpe811_putreg8(priv, STMPE811_GPIO_FE, regval);
|
||||
|
||||
/* Set up the rising edge detection */
|
||||
|
||||
regval = stmpe811_getreg8(priv, STMPE811_GPIO_RE);
|
||||
if ((pinconfig & STMPE811_GPIO_FALLING) != 0)
|
||||
{
|
||||
regval |= pinmask;
|
||||
}
|
||||
else
|
||||
{
|
||||
regval &= pinmask;
|
||||
}
|
||||
stmpe811_putreg8(priv, STMPE811_GPIO_RE, regval);
|
||||
|
||||
/* Disable interrupts for now */
|
||||
|
||||
regval = stmpe811_getreg8(priv, STMPE811_GPIO_EN);
|
||||
regval &= ~pinmask;
|
||||
stmpe811_putreg8(priv, STMPE811_GPIO_EN, regval);
|
||||
}
|
||||
|
||||
/* Mark the pin as 'in use' */
|
||||
|
||||
priv->inuse |= pinmask;
|
||||
sem_post(&priv->exclsem);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stmpe811_gpiowrite
|
||||
*
|
||||
* Description:
|
||||
* Set or clear the GPIO output
|
||||
*
|
||||
* Input Parameters:
|
||||
* handle - The handle previously returned by stmpe811_instantiate
|
||||
* pinconfig - Bit-encoded pin configuration
|
||||
* value = true: write logic '1'; false: write logic '0;
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void stmpe811_gpiowrite(STMPE811_HANDLE handle, uint8_t pinconfig, bool value)
|
||||
{
|
||||
FAR struct stmpe811_dev_s *priv = (FAR struct stmpe811_dev_s *)handle;
|
||||
int pin = (pinconfig & STMPE811_GPIO_PIN_MASK) >> STMPE811_GPIO_PIN_SHIFT;
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(handle && (unsigned)pin < STMPE811_GPIO_NPINS);
|
||||
|
||||
/* Get exclusive access to the device structure */
|
||||
|
||||
ret = sem_wait(&priv->exclsem);
|
||||
if (ret < 0)
|
||||
{
|
||||
idbg("sem_wait failed: %d\n", errno);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Are we setting or clearing outputs? */
|
||||
|
||||
if (value)
|
||||
{
|
||||
/* Set the output valu(s)e by writing to the SET register */
|
||||
|
||||
stmpe811_putreg8(priv, STMPE811_GPIO_SETPIN, (1 << pin));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Clear the output value(s) by writing to the CLR register */
|
||||
|
||||
stmpe811_putreg8(priv, STMPE811_GPIO_CLRPIN, (1 << pin));
|
||||
}
|
||||
|
||||
sem_post(&priv->exclsem);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stmpe811_gpioread
|
||||
*
|
||||
* Description:
|
||||
* Set or clear the GPIO output
|
||||
*
|
||||
* Input Parameters:
|
||||
* handle - The handle previously returned by stmpe811_instantiate
|
||||
* pinconfig - Bit-encoded pin configuration
|
||||
* value - The location to return the state of the GPIO pin
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero is returned on success. Otherwise, a negated errno value is
|
||||
* returned to indicate the nature of the failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int stmpe811_gpioread(STMPE811_HANDLE handle, uint8_t pinconfig, bool *value)
|
||||
{
|
||||
FAR struct stmpe811_dev_s *priv = (FAR struct stmpe811_dev_s *)handle;
|
||||
int pin = (pinconfig & STMPE811_GPIO_PIN_MASK) >> STMPE811_GPIO_PIN_SHIFT;
|
||||
uint8_t regval;
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(handle && (unsigned)pin < STMPE811_GPIO_NPINS);
|
||||
|
||||
/* Get exclusive access to the device structure */
|
||||
|
||||
ret = sem_wait(&priv->exclsem);
|
||||
if (ret < 0)
|
||||
{
|
||||
int errval = errno;
|
||||
idbg("sem_wait failed: %d\n", errval);
|
||||
return -errval;
|
||||
}
|
||||
|
||||
regval = stmpe811_getreg8(priv, STMPE811_GPIO_MPSTA);
|
||||
*value = ((regval & GPIO_PIN(pin)) != 0);
|
||||
sem_post(&priv->exclsem);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/***********************************************************************************
|
||||
* Name: stmpe811_gpioattach
|
||||
*
|
||||
* Description:
|
||||
* Attach to a GPIO interrupt input pin and enable interrupts on the pin. Using
|
||||
* the value NULL for the handler address will disable interrupts from the pin and
|
||||
* detach the handler.
|
||||
*
|
||||
* NOTE: Callbacks do not occur from an interrupt handler but rather from the
|
||||
* context of the worker thread.
|
||||
*
|
||||
* Input Parameters:
|
||||
* handle - The handle previously returned by stmpe811_instantiate
|
||||
* pinconfig - Bit-encoded pin configuration
|
||||
* handler - The handler that will be called when the interrupt occurs.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero is returned on success. Otherwise, a negated errno value is returned
|
||||
* to indicate the nature of the failure.
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
#ifndef CONFIG_STMPE811_GPIOINT_DISABLE
|
||||
int stmpe811_gpioattach(STMPE811_HANDLE handle, uint8_t pinconfig,
|
||||
stmpe811_handler_t handler)
|
||||
{
|
||||
FAR struct stmpe811_dev_s *priv = (FAR struct stmpe811_dev_s *)handle;
|
||||
int pin = (pinconfig & STMPE811_GPIO_PIN_MASK) >> STMPE811_GPIO_PIN_SHIFT;
|
||||
uint8_t regval;
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(handle && (unsigned)pin < STMPE811_GPIO_NPINS);
|
||||
|
||||
/* Get exclusive access to the device structure */
|
||||
|
||||
ret = sem_wait(&priv->exclsem);
|
||||
if (ret < 0)
|
||||
{
|
||||
int errval = errno;
|
||||
idbg("sem_wait failed: %d\n", errval);
|
||||
return -errval;
|
||||
}
|
||||
|
||||
/* Make sure that the GPIO interrupt system has been gpioinitialized */
|
||||
|
||||
stmpe811_gpioinit(priv);
|
||||
|
||||
/* Set/clear the handler */
|
||||
|
||||
priv->handlers[pin] = handler;
|
||||
|
||||
/* If an handler has provided, then we are enabling interrupts */
|
||||
|
||||
regval = stmpe811_getreg8(priv, STMPE811_GPIO_EN);
|
||||
if (handler)
|
||||
{
|
||||
/* Enable interrupts for this GPIO */
|
||||
|
||||
regval &= ~GPIO_PIN(pin);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Disable interrupts for this GPIO */
|
||||
|
||||
regval &= ~GPIO_PIN(pin);
|
||||
}
|
||||
stmpe811_putreg8(priv, STMPE811_GPIO_EN, regval);
|
||||
|
||||
sem_post(&priv->exclsem);
|
||||
return OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stmpe811_gpioworker
|
||||
*
|
||||
* Description:
|
||||
* Handle GPIO interrupt events (this function actually executes in the
|
||||
* context of the worker thread).
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_STMPE811_GPIOINT_DISABLE
|
||||
void stmpe811_gpioworker(FAR struct stmpe811_dev_s *priv)
|
||||
{
|
||||
uint8_t regval;
|
||||
uint8_t pinmask;
|
||||
int pin;
|
||||
|
||||
/* Get the set of pending GPIO interrupts */
|
||||
|
||||
regval = stmpe811_getreg8(priv, STMPE811_GPIO_INTSTA);
|
||||
|
||||
/* Look at each pin */
|
||||
|
||||
for (pin = 0; pin < STMPE811_GPIO_NPINS; pin++)
|
||||
{
|
||||
pinmask = GPIO_INT(pin);
|
||||
if ((regval & pinmask) != 0)
|
||||
{
|
||||
/* Check if we have a handler for this interrupt (there should
|
||||
* be one)
|
||||
*/
|
||||
|
||||
if (priv->handlers[pin])
|
||||
{
|
||||
/* Interrupt is pending... dispatch the interrupt to the
|
||||
* callback
|
||||
*/
|
||||
|
||||
priv->handlers[pin](pin);
|
||||
}
|
||||
else
|
||||
{
|
||||
illdbg("No handler for PIN%d, GPIO_INTSTA: %02x\n", pin, regval);
|
||||
}
|
||||
|
||||
/* Clear the pending GPIO interrupt by writing a '1' to the
|
||||
* pin position in the status register.
|
||||
*/
|
||||
|
||||
stmpe811_putreg8(priv, STMPE811_GPIO_INTSTA, pinmask);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_INPUT && CONFIG_INPUT_STMPE811 && !CONFIG_STMPE811_GPIO_DISABLE */
|
||||
|
||||
@@ -0,0 +1,174 @@
|
||||
/****************************************************************************
|
||||
* drivers/input/stmpe811_temp.c
|
||||
*
|
||||
* Copyright (C) 2012 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* References:
|
||||
* "STMPE811 S-Touch® advanced resistive touchscreen controller with 8-bit
|
||||
* GPIO expander," Doc ID 14489 Rev 6, CD00186725, STMicroelectronics"
|
||||
*
|
||||
* 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 <assert.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/input/stmpe811.h>
|
||||
|
||||
#include "stmpe811.h"
|
||||
|
||||
#if defined(CONFIG_INPUT) && defined(CONFIG_INPUT_STMPE811) && !defined(CONFIG_STMPE811_TEMP_DISABLE)
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stmpe811_tempinitialize
|
||||
*
|
||||
* Description:
|
||||
* Configure the temperature sensor.
|
||||
*
|
||||
* Input Parameters:
|
||||
* handle - The handle previously returned by stmpe811_instantiate
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero is returned on success. Otherwise, a negated errno value is
|
||||
* returned to indicate the nature of the failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int stmpe811_tempinitialize(STMPE811_HANDLE handle)
|
||||
{
|
||||
FAR struct stmpe811_dev_s *priv = (FAR struct stmpe811_dev_s *)handle;
|
||||
uint8_t regval;
|
||||
|
||||
/* Enable clocking for ADC and the temperature sensor */
|
||||
|
||||
regval = stmpe811_getreg8(priv, STMPE811_SYS_CTRL2);
|
||||
regval &= ~(SYS_CTRL2_TS_OFF | SYS_CTRL2_ADC_OFF);
|
||||
stmpe811_putreg8(priv, STMPE811_SYS_CTRL2, regval);
|
||||
|
||||
/* Enable the temperature sensor */
|
||||
|
||||
stmpe811_putreg8(priv, STMPE811_TEMP_CTRL, TEMP_CTRL_ENABLE);
|
||||
|
||||
/* Aquire data enable */
|
||||
|
||||
stmpe811_putreg8(priv, STMPE811_TEMP_CTRL, (TEMP_CTRL_ACQ|TEMP_CTRL_ENABLE));
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stmpe811_tempread
|
||||
*
|
||||
* Description:
|
||||
* Configure the temperature sensor.
|
||||
*
|
||||
* Input Parameters:
|
||||
* handle - The handle previously returned by stmpe811_instantiate
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero is returned on success. Otherwise, a negated errno value is
|
||||
* returned to indicate the nature of the failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
uint16_t stmpe811_tempread(STMPE811_HANDLE handle)
|
||||
{
|
||||
FAR struct stmpe811_dev_s *priv = (FAR struct stmpe811_dev_s *)handle;
|
||||
uint32_t temp = 0;
|
||||
uint8_t temp1;
|
||||
uint8_t temp2;
|
||||
|
||||
/* Acquire data enable */
|
||||
|
||||
stmpe811_putreg8(priv, STMPE811_TEMP_CTRL, (TEMP_CTRL_ACQ|TEMP_CTRL_ENABLE));
|
||||
|
||||
/* Read the temperature */
|
||||
|
||||
temp1 = stmpe811_getreg8(priv, STMPE811_SYS_CTRL2);
|
||||
temp2 = stmpe811_getreg8(priv, STMPE811_SYS_CTRL2+1);
|
||||
|
||||
/* Scale the temperature (where Vio is assumed to be .33) */
|
||||
|
||||
temp = ((uint32_t)(temp1 & 3) << 8) | temp2;
|
||||
temp = (uint32_t)((33 * temp * 100) / 751);
|
||||
temp = (uint32_t)((temp + 5) / 10);
|
||||
|
||||
return (uint16_t)temp;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stmpe811_tempinterrupt
|
||||
*
|
||||
* Description:
|
||||
* Configure the temperature sensor to sample the temperature periodically.
|
||||
* Set the temperature threshold to generate an interrupt and notify
|
||||
* to the client using the provide callback function pointer.
|
||||
*
|
||||
* Input Parameters:
|
||||
* handle - The handle previously returned by stmpe811_instantiate
|
||||
* threshold - The threshold temperature value
|
||||
* direction - True: Generate an interrupt if the temperate exceeds the
|
||||
* threshold value; False: Generate an interrupt if the
|
||||
* temperature falls below the threshold value.
|
||||
* callback - The client callback function that will be called when
|
||||
* the termperature crosses the threshold.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero is returned on success. Otherwise, a negated errno value is
|
||||
* returned to indicate the nature of the failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
/* Not implemented */
|
||||
|
||||
#endif /* CONFIG_INPUT && CONFIG_INPUT_STMPE811 && !CONFIG_STMPE811_TEMP_DISABLE */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,120 @@
|
||||
/********************************************************************************************
|
||||
* drivers/input/tsc2007.h
|
||||
*
|
||||
* Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* References:
|
||||
* "1.2V to 3.6V, 12-Bit, Nanopower, 4-Wire Micro TOUCH SCREEN CONTROLLER
|
||||
* with I2C Interface," SBAS405A March 2007, Revised, March 2009, Texas
|
||||
* Instruments Incorporated
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
/* The TSC2007 is an analog interface circuit for a human interface touch screen device.
|
||||
* All peripheral functions are controlled through the command byte and onboard state
|
||||
* machines.
|
||||
*/
|
||||
|
||||
#ifndef __DRIVERS_INPUT_TSC2007_H
|
||||
#define __DRIVERS_INPUT_TSC2007_H
|
||||
|
||||
/********************************************************************************************
|
||||
* Included Files
|
||||
********************************************************************************************/
|
||||
|
||||
/********************************************************************************************
|
||||
* Pre-Processor Definitions
|
||||
********************************************************************************************/
|
||||
|
||||
/* TSC2007 Address */
|
||||
|
||||
#define TSC2007_ADDRESS_MASK (0xf8) /* Bits 3-7: Invariant part of TSC2007 address */
|
||||
#define TSC2007_ADDRESS (0x90) /* Bits 3-7: Always set at '10010' */
|
||||
#define TSC2007_A1 (1 << 2) /* Bit 2: A1 */
|
||||
#define TSC2007_A0 (1 << 1) /* Bit 1: A1 */
|
||||
#define TSC2007_READ (1 << 0) /* Bit0=1: Selects read operation */
|
||||
#define TSC2007_WRITE (0) /* Bit0=0: Selects write operation */
|
||||
|
||||
/* TSC2007 Command Byte */
|
||||
|
||||
#define TSC2007_CMD_FUNC_SHIFT (4) /* Bits 4-7: Converter function select bits */
|
||||
#define TSC2007_CMD_FUNC_MASK (15 << TSC2007_CMD_FUNC_SHIFT)
|
||||
# define TSC2007_CMD_FUNC_TEMP0 (0 << TSC2007_CMD_FUNC_SHIFT) /* Measure TEMP0 */
|
||||
# define TSC2007_CMD_FUNC_AUX (2 << TSC2007_CMD_FUNC_SHIFT) /* Measure AUX */
|
||||
# define TSC2007_CMD_FUNC_TEMP1 (4 << TSC2007_CMD_FUNC_SHIFT) /* Measure TEMP1 */
|
||||
# define TSC2007_CMD_FUNC_XON (8 << TSC2007_CMD_FUNC_SHIFT) /* Activate X-drivers */
|
||||
# define TSC2007_CMD_FUNC_YON (9 << TSC2007_CMD_FUNC_SHIFT) /* Activate Y-drivers */
|
||||
# define TSC2007_CMD_FUNC_YXON (10 << TSC2007_CMD_FUNC_SHIFT) /* Activate Y+, X-drivers */
|
||||
# define TSC2007_CMD_FUNC_SETUP (11 << TSC2007_CMD_FUNC_SHIFT) /* Setup command */
|
||||
# define TSC2007_CMD_FUNC_XPOS (12 << TSC2007_CMD_FUNC_SHIFT) /* Measure X position */
|
||||
# define TSC2007_CMD_FUNC_YPOS (13 << TSC2007_CMD_FUNC_SHIFT) /* Measure Y position */
|
||||
# define TSC2007_CMD_FUNC_Z1POS (14 << TSC2007_CMD_FUNC_SHIFT) /* Measure Z1 position */
|
||||
# define TSC2007_CMD_FUNC_Z2POS (15 << TSC2007_CMD_FUNC_SHIFT) /* Measure Z2 positionn */
|
||||
#define TSC2007_CMD_PWRDN_SHIFT (2) /* Bits 2-3: Power-down bits */
|
||||
#define TSC2007_CMD_PWRDN_MASK (3 << TSC2007_CMD_PWRDN_SHIFT)
|
||||
# define TSC2007_CMD_PWRDN_IRQEN (0 << TSC2007_CMD_PWRDN_SHIFT) /* 00: Power down between cycles; PENIRQ enabled */
|
||||
# define TSC2007_CMD_ADCON_IRQDIS (1 << TSC2007_CMD_PWRDN_SHIFT) /* 01: A/D converter on; PENIRQ disabled */
|
||||
# define TSC2007_CMD_ADCOFF_IRQEN (2 << TSC2007_CMD_PWRDN_SHIFT) /* 10: A/D converter off; PENIRQ enabled. */
|
||||
/* 11: A/D converter on; PENIRQ disabled. */
|
||||
#define TSC2007_CMD_12BIT (0) /* Bit 1: 0=12-bit */
|
||||
#define TSC2007_CMD_8BIT (1 << 1) /* Bit 1: 1=8-bit */
|
||||
/* Bit 0: Don't care */
|
||||
|
||||
/* TSC2007 Setup Command */
|
||||
|
||||
#define TSC2007_SETUP_CMD TSC2007_CMD_FUNC_SETUP /* Bits 4-7: Setup command */
|
||||
/* Bits 2-3: Must be zero */
|
||||
#define TSC2007_CMD_USEMAV (0) /* Bit 1: 0: Use the onboard MAV filter (default) */
|
||||
#define TSC2007_CMD_BYPASSMAV (1 << 1) /* Bit 1: 1: Bypass the onboard MAV filter */
|
||||
#define TSC2007_CMD_PU_50KOHM (0) /* Bit 0: 0: RIRQ = 50kOhm (default). */
|
||||
#define TSC2007_CMD_PU_90KOHM (1 << 1) /* Bit 0: 1: 1: RIRQ = 90kOhm */
|
||||
|
||||
/********************************************************************************************
|
||||
* Public Types
|
||||
********************************************************************************************/
|
||||
|
||||
/********************************************************************************************
|
||||
* Public Function Prototypes
|
||||
********************************************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define EXTERN extern "C"
|
||||
extern "C" {
|
||||
#else
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
#undef EXTERN
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __DRIVERS_INPUT_TSC2007_H */
|
||||
Reference in New Issue
Block a user