summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2013-04-02 16:36:19 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2013-04-02 16:36:19 +0000
commit93be53ea683d11cc454d8f3aa6c11f9c842e2ac2 (patch)
tree17b216d87d117659d67daa09747b6a7bb6322bc6
parent87590afa9ca772243c261e6c1b8478565bd2771a (diff)
downloadnuttx-93be53ea683d11cc454d8f3aa6c11f9c842e2ac2.tar.gz
nuttx-93be53ea683d11cc454d8f3aa6c11f9c842e2ac2.tar.bz2
nuttx-93be53ea683d11cc454d8f3aa6c11f9c842e2ac2.zip
SSP driver fixes for the LPC178x; Fixes for Open1788 touchscreen driver
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5812 42af7a65-404d-4744-a932-0658087f49c3
-rw-r--r--apps/examples/README.txt2
-rw-r--r--apps/examples/touchscreen/Kconfig2
-rw-r--r--nuttx/arch/arm/src/armv6-m/Toolchain.defs2
-rw-r--r--nuttx/arch/arm/src/lpc17xx/chip/lpc17_ssp.h11
-rw-r--r--nuttx/arch/arm/src/lpc17xx/lpc17_gpio.c1
-rw-r--r--nuttx/arch/arm/src/lpc17xx/lpc17_ssp.c69
-rw-r--r--nuttx/configs/open1788/README.txt6
-rw-r--r--nuttx/configs/open1788/include/board.h6
-rw-r--r--nuttx/configs/open1788/src/lpc17_ssp.c2
-rw-r--r--nuttx/configs/open1788/src/lpc17_touchscreen.c97
-rw-r--r--nuttx/drivers/input/Kconfig18
11 files changed, 156 insertions, 60 deletions
diff --git a/apps/examples/README.txt b/apps/examples/README.txt
index fe16ada85..3c6fd7029 100644
--- a/apps/examples/README.txt
+++ b/apps/examples/README.txt
@@ -1509,7 +1509,7 @@ examples/touchscreen
CONFIG_EXAMPLES_TOUCHSCREEN_BUILTIN - Build the touchscreen test as
an NSH built-in function. Default: Built as a standalone problem
CONFIG_EXAMPLES_TOUCHSCREEN_MINOR - The minor device number. Minor=N
- corresponds to touchscreen device /dev/input0. Note this value must
+ corresponds to touchscreen device /dev/inputN. Note this value must
with CONFIG_EXAMPLES_TOUCHSCREEN_DEVPATH. Default 0.
CONFIG_EXAMPLES_TOUCHSCREEN_DEVPATH - The path to the touchscreen
device. This must be consistent with CONFIG_EXAMPLES_TOUCHSCREEN_MINOR.
diff --git a/apps/examples/touchscreen/Kconfig b/apps/examples/touchscreen/Kconfig
index 18ece4923..2f40b3d65 100644
--- a/apps/examples/touchscreen/Kconfig
+++ b/apps/examples/touchscreen/Kconfig
@@ -25,7 +25,7 @@ config EXAMPLES_TOUCHSCREEN_MINOR
default 0
---help---
The minor device number. Minor=N corresponds to touchscreen device
- /dev/input0. Note this value must with EXAMPLES_TOUCHSCREEN_DEVPATH.
+ /dev/inputN. Note this value must with EXAMPLES_TOUCHSCREEN_DEVPATH.
Default 0.
config EXAMPLES_TOUCHSCREEN_DEVPATH
diff --git a/nuttx/arch/arm/src/armv6-m/Toolchain.defs b/nuttx/arch/arm/src/armv6-m/Toolchain.defs
index 7fc4bf9cd..22427d188 100644
--- a/nuttx/arch/arm/src/armv6-m/Toolchain.defs
+++ b/nuttx/arch/arm/src/armv6-m/Toolchain.defs
@@ -160,6 +160,6 @@ endif
ifeq ($(CONFIG_ARMV6M_TOOLCHAIN),GNU_EABI)
CROSSDEV ?= arm-none-eabi-
ARCROSSDEV ?= arm-none-eabi-
- MAXOPTIMIZATION = -O3
+ MAXOPTIMIZATION = -Os
ARCHCPUFLAGS = -mcpu=cortex-m0 -mthumb -march=armv6-m -mfloat-abi=soft
endif
diff --git a/nuttx/arch/arm/src/lpc17xx/chip/lpc17_ssp.h b/nuttx/arch/arm/src/lpc17xx/chip/lpc17_ssp.h
index e97a670a8..dd791327f 100644
--- a/nuttx/arch/arm/src/lpc17xx/chip/lpc17_ssp.h
+++ b/nuttx/arch/arm/src/lpc17xx/chip/lpc17_ssp.h
@@ -89,6 +89,17 @@
#define LPC17_SSP1_ICR (LPC17_SSP1_BASE+LPC17_SSP_ICR_OFFSET)
#define LPC17_SSP1_DMACR (LPC17_SSP1_BASE+LPC17_SSP_DMACR_OFFSET)
+#define LPC17_SSP2_CR0 (LPC17_SSP2_BASE+LPC17_SSP_CR0_OFFSET)
+#define LPC17_SSP2_CR1 (LPC17_SSP2_BASE+LPC17_SSP_CR1_OFFSET)
+#define LPC17_SSP2_DR (LPC17_SSP2_BASE+LPC17_SSP_DR_OFFSET)
+#define LPC17_SSP2_SR (LPC17_SSP2_BASE+LPC17_SSP_SR_OFFSET)
+#define LPC17_SSP2_CPSR (LPC17_SSP2_BASE+LPC17_SSP_CPSR_OFFSET)
+#define LPC17_SSP2_IMSC (LPC17_SSP2_BASE+LPC17_SSP_IMSC_OFFSET)
+#define LPC17_SSP2_RIS (LPC17_SSP2_BASE+LPC17_SSP_RIS_OFFSET)
+#define LPC17_SSP2_MIS (LPC17_SSP2_BASE+LPC17_SSP_MIS_OFFSET)
+#define LPC17_SSP2_ICR (LPC17_SSP2_BASE+LPC17_SSP_ICR_OFFSET)
+#define LPC17_SSP2_DMACR (LPC17_SSP2_BASE+LPC17_SSP_DMACR_OFFSET)
+
/* Register bit definitions *********************************************************/
/* Control Register 0 */
diff --git a/nuttx/arch/arm/src/lpc17xx/lpc17_gpio.c b/nuttx/arch/arm/src/lpc17xx/lpc17_gpio.c
index 05c3caa20..43b2fc891 100644
--- a/nuttx/arch/arm/src/lpc17xx/lpc17_gpio.c
+++ b/nuttx/arch/arm/src/lpc17xx/lpc17_gpio.c
@@ -52,7 +52,6 @@
#include "chip.h"
#include "lpc17_gpio.h"
-
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
diff --git a/nuttx/arch/arm/src/lpc17xx/lpc17_ssp.c b/nuttx/arch/arm/src/lpc17xx/lpc17_ssp.c
index 3c9a51904..11f8da38b 100644
--- a/nuttx/arch/arm/src/lpc17xx/lpc17_ssp.c
+++ b/nuttx/arch/arm/src/lpc17xx/lpc17_ssp.c
@@ -92,6 +92,7 @@
#endif
/* SSP Clocking *************************************************************/
+
#if defined(LPC176x)
/* The CPU clock by 1, 2, 4, or 8 to get the SSP peripheral clock (SSP_CLOCK).
* SSP_CLOCK may be further divided by 2-254 to get the SSP clock. If we
@@ -106,17 +107,16 @@
# if LPC17_CCLK > 100000000
# error "CCLK <= 100,000,000 assumed"
-# endif
+# endif
# define SSP_PCLKSET_DIV SYSCON_PCLKSEL_CCLK
# define SSP_CLOCK LPC17_CCLK
+#elif defined(LPC178x)
/* All peripherals are clocked by the same peripheral clock in the LPC178x
* family.
*/
-#elif defined(LPC178x)
-
# define SSP_CLOCK BOARD_PCLK_FREQUENCY
#endif
@@ -397,10 +397,12 @@ static int ssp_lock(FAR struct spi_dev_s *dev, bool lock)
static uint32_t ssp_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency)
{
FAR struct lpc17_sspdev_s *priv = (FAR struct lpc17_sspdev_s *)dev;
- uint32_t divisor;
+ uint32_t cpsdvsr;
+ uint32_t scr;
+ uint32_t regval;
uint32_t actual;
- /* Check if the requested frequence is the same as the frequency selection */
+ /* Check if the requested frequency is the same as the frequency selection */
DEBUGASSERT(priv && frequency <= SSP_CLOCK / 2);
#ifndef CONFIG_SPI_OWNBUS
@@ -412,30 +414,65 @@ static uint32_t ssp_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency)
}
#endif
- /* frequency = SSP_CLOCK / divisor, or divisor = SSP_CLOCK / frequency */
+ /* The SSP bit frequency is given by:
+ *
+ * frequency = SSP_CLOCK / (CPSDVSR * (SCR+1)).
+ *
+ * Let's try for a solution with the smallest value of SCR. NOTES:
+ * (1) In the calculations below, the value of the variable 'scr' is
+ * (SCR+1) in the above equation. (2) On slower LPC17xx parts, SCR
+ * will probably always be zero.
+ */
- divisor = SSP_CLOCK / frequency;
+ for (scr = 1; scr <= 256; scr++)
+ {
+ /* CPSDVSR = SSP_CLOCK / (SCR + 1) / frequency */
+
+ cpsdvsr = SSP_CLOCK / (scr * frequency);
- /* "In master mode, CPSDVSRmin = 2 or larger (even numbers only)" */
+ /* Break out on the first solution we find with the smallest value
+ * of SCR and with CPSDVSR within the maximum range or 254.
+ */
- if (divisor < 2)
+ if (cpsdvsr < 255)
+ {
+ break;
+ }
+ }
+
+ DEBUGASSERT(scr <= 256 && cpsdvsr <= 255);
+
+ /* "In master mode, CPSDVSRmin = 2 or larger (even numbers only)" */
+
+ if (cpsdvsr < 2)
{
- divisor = 2;
+ /* Clip to the minimum value. */
+
+ cpsdvsr = 2;
}
- else if (divisor > 254)
+ else if (cpsdvsr > 254)
{
- divisor = 254;
+ /* This should never happen */
+
+ cpsdvsr = 254;
}
- divisor = (divisor + 1) & ~1;
+ /* Force even */
- /* Save the new divisor value */
+ cpsdvsr = (cpsdvsr + 1) & ~1;
+
+ /* Save the new CPSDVSR and SCR values */
- ssp_putreg(priv, LPC17_SSP_CPSR_OFFSET, divisor);
+ ssp_putreg(priv, LPC17_SSP_CPSR_OFFSET, cpsdvsr);
+
+ regval = ssp_getreg(priv, LPC17_SSP_CR0_OFFSET);
+ regval &= ~SSP_CR0_SCR_MASK;
+ regval |= ((scr - 1) << SSP_CR0_SCR_SHIFT);
+ ssp_putreg(priv, LPC17_SSP_CR0_OFFSET, regval);
/* Calculate the new actual */
- actual = SSP_CLOCK / divisor;
+ actual = SSP_CLOCK / (cpsdvsr * scr);
/* Save the frequency setting */
diff --git a/nuttx/configs/open1788/README.txt b/nuttx/configs/open1788/README.txt
index 61a01c3a7..1c3a5191e 100644
--- a/nuttx/configs/open1788/README.txt
+++ b/nuttx/configs/open1788/README.txt
@@ -453,10 +453,11 @@ CONFIGURATION
following ways:
CONFIG_INPUT=y : Enable support for input devices
- CONFIG_GPIO_IRQ=y : GPIO interrupt support
CONFIG_INPUT_ADS7843E=y : Enable support for the XPT2048
+ CONFIG_ADS7843E_SPIDEV=1 : Use SSP1 for communication
CONFIG_SPI=y : Enable SPI support
CONFIG_SPI_EXCHANGE=n : exchange() method is not supported
+ CONFIG_GPIO_IRQ=y : GPIO interrupt support
CONFIG_LPC17_SSP1=y : Enable support for SSP1
CONFIG_EXAMPLES_TOUCHSCREEN=y : Enable the touchscreen built-int test
CONFIG_EXAMPLES_TOUCHSCREEN_BUILTIN=y
@@ -466,7 +467,8 @@ CONFIGURATION
You will also have to disable SD card support to use this test. The
SD card detect (CD) signal is on P0[13]. This signal is shared. It
is also used for MOSI1 and USB_UP_LED. The CD pin may be disconnected.
- There is a jumper on board that enables the CD pin.
+ There is a jumper on board that enables the CD pin. OR, you can simply
+ remove the SD module so that it does not drive the CD pin.
CONFIG_LPC17_GPDMA=n : No DMA
CONFIG_ARCH_DMA=n
diff --git a/nuttx/configs/open1788/include/board.h b/nuttx/configs/open1788/include/board.h
index 421476cab..ffcdf7211 100644
--- a/nuttx/configs/open1788/include/board.h
+++ b/nuttx/configs/open1788/include/board.h
@@ -407,12 +407,6 @@
#define GPIO_SSP1_MOSI GPIO_SSP1_MOSI_2
#define GPIO_SSP1_SCK GPIO_SSP1_SCK_2
-#define GPIO_SSP1_SSEL_1 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN6)
-#define GPIO_SSP1_SSEL_2 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN14)
-#define GPIO_SSP1_SSEL_3 (GPIO_ALT5 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN26)
-#define GPIO_SSP1_SSEL_4 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT4 | GPIO_PIN21)
-
-
/************************************************************************************
* Public Types
************************************************************************************/
diff --git a/nuttx/configs/open1788/src/lpc17_ssp.c b/nuttx/configs/open1788/src/lpc17_ssp.c
index e27894e72..4f3995243 100644
--- a/nuttx/configs/open1788/src/lpc17_ssp.c
+++ b/nuttx/configs/open1788/src/lpc17_ssp.c
@@ -174,7 +174,7 @@ void lpc17_ssp1select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool sel
sspdbg("devid: %d CS: %s\n", (int)devid, selected ? "assert" : "de-assert");
if (devid == SPIDEV_TOUCHSCREEN)
{
- /* Assert/de-assert the CS pin to the card */
+ /* Assert/de-assert the CS pin to the touchscreen */
ssp_dumpgpio(GPIO_TC_CS, "lpc17_ssp1select() Entry");
lpc17_gpiowrite(GPIO_TC_CS, !selected);
diff --git a/nuttx/configs/open1788/src/lpc17_touchscreen.c b/nuttx/configs/open1788/src/lpc17_touchscreen.c
index 1ee8d6237..19b8b5805 100644
--- a/nuttx/configs/open1788/src/lpc17_touchscreen.c
+++ b/nuttx/configs/open1788/src/lpc17_touchscreen.c
@@ -80,17 +80,27 @@
#endif
#ifndef CONFIG_ADS7843E_SPIDEV
-# define CONFIG_ADS7843E_SPIDEV 3
+# define CONFIG_ADS7843E_SPIDEV 1
#endif
-#if CONFIG_ADS7843E_SPIDEV != 3
-# error "CONFIG_ADS7843E_SPIDEV must be three"
+#if CONFIG_ADS7843E_SPIDEV != 1
+# error "CONFIG_ADS7843E_SPIDEV must be one"
#endif
#ifndef CONFIG_ADS7843E_DEVMINOR
# define CONFIG_ADS7843E_DEVMINOR 0
#endif
+/* REVISIT: Currently, XPT2046 reports BUSY all of the time. This is
+ * probably GPIO setting issues. But there is this cryptic statement in
+ * the XPT2046 spec: "No DCLK delay required with dedicated serial port."
+ *
+ * The busy state is used by the XPT2046 driver to control the delay
+ * between sending the command, then reading the returned data.
+ */
+
+#define XPT2046_NO_BUSY 1
+
/****************************************************************************
* Private Types
****************************************************************************/
@@ -100,12 +110,12 @@
****************************************************************************/
/* IRQ/GPIO access callbacks. These operations all hidden behind
- * callbacks to isolate the ADS7843E driver from differences in GPIO
+ * callbacks to isolate the XPT2046 driver from differences in GPIO
* interrupt handling by varying boards and MCUs. If possible,
* interrupts should be configured on both rising and falling edges
* so that contact and loss-of-contact events can be detected.
*
- * attach - Attach the ADS7843E interrupt handler to the GPIO interrupt
+ * attach - Attach the XPT2046 interrupt handler to the GPIO interrupt
* enable - Enable or disable the GPIO interrupt
* clear - Acknowledge/clear any pending GPIO interrupt
* pendown - Return the state of the pen down GPIO input
@@ -121,9 +131,9 @@ static bool tsc_pendown(FAR struct ads7843e_config_s *state);
* Private Data
****************************************************************************/
-/* A reference to a structure of this type must be passed to the ADS7843E
+/* A reference to a structure of this type must be passed to the XPT2046
* driver. This structure provides information about the configuration
- * of the ADS7843E and provides some board-specific hooks.
+ * of the XPT2046 and provides some board-specific hooks.
*
* Memory for this structure is provided by the caller. It is not copied
* by the driver and is presumed to persist while the driver is active.
@@ -144,12 +154,12 @@ static struct ads7843e_config_s g_tscinfo =
****************************************************************************/
/* IRQ/GPIO access callbacks. These operations all hidden behind
- * callbacks to isolate the ADS7843E driver from differences in GPIO
+ * callbacks to isolate the XPT2046 driver from differences in GPIO
* interrupt handling by varying boards and MCUs. If possible,
* interrupts should be configured on both rising and falling edges
* so that contact and loss-of-contact events can be detected.
*
- * attach - Attach the ADS7843E interrupt handler to the GPIO interrupt
+ * attach - Attach the XPT2046 interrupt handler to the GPIO interrupt
* enable - Enable or disable the GPIO interrupt
* clear - Acknowledge/clear any pending GPIO interrupt
* pendown - Return the state of the pen down GPIO input
@@ -183,6 +193,20 @@ static void tsc_clear(FAR struct ads7843e_config_s *state)
static bool tsc_busy(FAR struct ads7843e_config_s *state)
{
+/* The busy state is used by the XPT2046 driver to control the delay
+ * between sending the command, then reading the returned data.
+ */
+
+#ifdef XPT2046_NO_BUSY
+/* REVISIT: Currently, XPT2046 reports BUSY all of the time. This is
+ * probably GPIO setting issues. But there is this cryptic statement in
+ * the XPT2046 spec: "No DCLK delay required with dedicated serial port."
+ */
+
+ return false;
+
+#else /* XPT2046_NO_BUSY */
+
#if defined(CONFIG_DEBUG_INPUT) && defined(CONFIG_DEBUG_VERBOSE)
static bool last = (bool)-1;
#endif
@@ -199,6 +223,8 @@ static bool tsc_busy(FAR struct ads7843e_config_s *state)
#endif
return busy;
+
+#endif /* XPT2046_NO_BUSY */
}
static bool tsc_pendown(FAR struct ads7843e_config_s *state)
@@ -237,37 +263,50 @@ static bool tsc_pendown(FAR struct ads7843e_config_s *state)
int arch_tcinitialize(int minor)
{
+ static bool initialized = false;
FAR struct spi_dev_s *dev;
int ret;
- idbg("minor %d\n", minor);
+ idbg("initialized:%d minor:%d\n", initialized, minor);
DEBUGASSERT(minor == 0);
- /* Configure and enable the ADS7843E PENIRQ pin as an interrupting input. */
+ /* Since there is no uninitialized logic, this initialization can be
+ * performed only one time.
+ */
- (void)lpc17_configgpio(GPIO_TC_PENIRQ);
+ if (!initialized)
+ {
+ /* Configure and enable the XPT2046 PENIRQ pin as an interrupting input. */
- /* Configure the ADS7843E BUSY pin as a normal input. */
+ (void)lpc17_configgpio(GPIO_TC_PENIRQ);
- (void)lpc17_configgpio(GPIO_TC_BUSY);
+ /* Configure the XPT2046 BUSY pin as a normal input. */
- /* Get an instance of the SPI interface */
+#ifndef XPT2046_NO_BUSY
+ (void)lpc17_configgpio(GPIO_TC_BUSY);
+#endif
- dev = lpc17_sspinitialize(CONFIG_ADS7843E_SPIDEV);
- if (!dev)
- {
- idbg("Failed to initialize SPI bus %d\n", CONFIG_ADS7843E_SPIDEV);
- return -ENODEV;
- }
+ /* Get an instance of the SPI interface */
- /* Initialize and register the SPI touschscreen device */
+ dev = lpc17_sspinitialize(CONFIG_ADS7843E_SPIDEV);
+ if (!dev)
+ {
+ idbg("Failed to initialize SPI bus %d\n", CONFIG_ADS7843E_SPIDEV);
+ return -ENODEV;
+ }
- ret = ads7843e_register(dev, &g_tscinfo, CONFIG_ADS7843E_DEVMINOR);
- if (ret < 0)
- {
- idbg("Failed to initialize SPI bus %d\n", CONFIG_ADS7843E_SPIDEV);
- /* up_spiuninitialize(dev); */
- return -ENODEV;
+ /* Initialize and register the SPI touchscreen device */
+
+ ret = ads7843e_register(dev, &g_tscinfo, CONFIG_ADS7843E_DEVMINOR);
+ if (ret < 0)
+ {
+ idbg("Failed to register touchscreen device minor=%d\n",
+ CONFIG_ADS7843E_DEVMINOR);
+ /* up_spiuninitialize(dev); */
+ return -ENODEV;
+ }
+
+ initialized = true;
}
return OK;
@@ -291,7 +330,7 @@ int arch_tcinitialize(int minor)
void arch_tcuninitialize(void)
{
- /* No support for un-initializing the touchscreen ADS7843E device yet */
+ /* No support for un-initializing the touchscreen XPT2046 device yet */
}
#endif /* CONFIG_INPUT_ADS7843E */
diff --git a/nuttx/drivers/input/Kconfig b/nuttx/drivers/input/Kconfig
index 6da3a9f39..aafb5007b 100644
--- a/nuttx/drivers/input/Kconfig
+++ b/nuttx/drivers/input/Kconfig
@@ -57,13 +57,27 @@ config ADS7843E_NPOLLWAITERS
---help---
Maximum number of threads that can be waiting on poll()
+config ADS7843E_SPIDEV
+ int "SPI bus number"
+ default 0
+ ---help---
+ Selects the SPI bus number identying that SPI interface that
+ connects the ADS843E to the MCU.
+
+config ADS7843E_DEVMINOR
+ int "Input device minor number"
+ default 0
+ ---help---
+ The ADS7843E device will be registered as /dev/inputN where N is the
+ value provided by this setting.
+
config ADS7843E_SPIMODE
int "SPI mode"
default 0
range 0,3
---help---
- Controls the SPI mode. The device should work in mode 0, but sometimes
- you need to experiment.
+ Controls the SPI mode. The device should work in mode 0, but
+ sometimes you need to experiment.
config ADS7843E_FREQUENCY
int "SPI frequency"