stm32_touchscreen.c 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. /************************************************************************************
  2. * configs/shenzhou/src/stm32_touchscreen.c
  3. *
  4. * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
  5. * Author: Gregory Nutt <gnutt@nuttx.org>
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  10. *
  11. * 1. Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. * 2. Redistributions in binary form must reproduce the above copyright
  14. * notice, this list of conditions and the following disclaimer in
  15. * the documentation and/or other materials provided with the
  16. * distribution.
  17. * 3. Neither the name NuttX nor the names of its contributors may be
  18. * used to endorse or promote products derived from this software
  19. * without specific prior written permission.
  20. *
  21. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  22. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  23. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  24. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  25. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  26. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  27. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  28. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  29. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  30. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  31. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  32. * POSSIBILITY OF SUCH DAMAGE.
  33. *
  34. ************************************************************************************/
  35. /****************************************************************************
  36. * Included Files
  37. ****************************************************************************/
  38. #include <nuttx/config.h>
  39. #include <stdbool.h>
  40. #include <stdio.h>
  41. #include <debug.h>
  42. #include <assert.h>
  43. #include <errno.h>
  44. #include <nuttx/board.h>
  45. #include <nuttx/irq.h>
  46. #include <nuttx/spi/spi.h>
  47. #include <nuttx/input/touchscreen.h>
  48. #include <nuttx/input/ads7843e.h>
  49. #include "stm32.h"
  50. #include "shenzhou.h"
  51. /****************************************************************************
  52. * Pre-processor Definitions
  53. ****************************************************************************/
  54. /* Configuration ************************************************************/
  55. #ifdef CONFIG_INPUT_ADS7843E
  56. #ifndef CONFIG_INPUT
  57. # error "Touchscreen support requires CONFIG_INPUT"
  58. #endif
  59. #ifndef CONFIG_STM32_SPI3
  60. # error "Touchscreen support requires CONFIG_STM32_SPI3"
  61. #endif
  62. #ifndef CONFIG_ADS7843E_FREQUENCY
  63. # define CONFIG_ADS7843E_FREQUENCY 500000
  64. #endif
  65. #ifndef CONFIG_ADS7843E_SPIDEV
  66. # define CONFIG_ADS7843E_SPIDEV 3
  67. #endif
  68. #if CONFIG_ADS7843E_SPIDEV != 3
  69. # error "CONFIG_ADS7843E_SPIDEV must be three"
  70. #endif
  71. #ifndef CONFIG_ADS7843E_DEVMINOR
  72. # define CONFIG_ADS7843E_DEVMINOR 0
  73. #endif
  74. /****************************************************************************
  75. * Private Types
  76. ****************************************************************************/
  77. struct stm32_config_s
  78. {
  79. struct ads7843e_config_s dev;
  80. xcpt_t handler;
  81. };
  82. /****************************************************************************
  83. * Private Function Prototypes
  84. ****************************************************************************/
  85. /* IRQ/GPIO access callbacks. These operations all hidden behind
  86. * callbacks to isolate the ADS7843E driver from differences in GPIO
  87. * interrupt handling by varying boards and MCUs. If possible,
  88. * interrupts should be configured on both rising and falling edges
  89. * so that contact and loss-of-contact events can be detected.
  90. *
  91. * attach - Attach the ADS7843E interrupt handler to the GPIO interrupt
  92. * enable - Enable or disable the GPIO interrupt
  93. * clear - Acknowledge/clear any pending GPIO interrupt
  94. * pendown - Return the state of the pen down GPIO input
  95. */
  96. static int tsc_attach(FAR struct ads7843e_config_s *state, xcpt_t isr);
  97. static void tsc_enable(FAR struct ads7843e_config_s *state, bool enable);
  98. static void tsc_clear(FAR struct ads7843e_config_s *state);
  99. static bool tsc_busy(FAR struct ads7843e_config_s *state);
  100. static bool tsc_pendown(FAR struct ads7843e_config_s *state);
  101. /****************************************************************************
  102. * Private Data
  103. ****************************************************************************/
  104. /* A reference to a structure of this type must be passed to the ADS7843E
  105. * driver. This structure provides information about the configuration
  106. * of the ADS7843E and provides some board-specific hooks.
  107. *
  108. * Memory for this structure is provided by the caller. It is not copied
  109. * by the driver and is presumed to persist while the driver is active. The
  110. * memory must be writable because, under certain circumstances, the driver
  111. * may modify frequency or X plate resistance values.
  112. */
  113. static struct stm32_config_s g_tscinfo =
  114. {
  115. {
  116. .frequency = CONFIG_ADS7843E_FREQUENCY,
  117. .attach = tsc_attach,
  118. .enable = tsc_enable,
  119. .clear = tsc_clear,
  120. .busy = tsc_busy,
  121. .pendown = tsc_pendown,
  122. },
  123. .handler = NULL,
  124. };
  125. /****************************************************************************
  126. * Private Functions
  127. ****************************************************************************/
  128. /* IRQ/GPIO access callbacks. These operations all hidden behind
  129. * callbacks to isolate the ADS7843E driver from differences in GPIO
  130. * interrupt handling by varying boards and MCUs. If possible,
  131. * interrupts should be configured on both rising and falling edges
  132. * so that contact and loss-of-contact events can be detected.
  133. *
  134. * attach - Attach the ADS7843E interrupt handler to the GPIO interrupt
  135. * enable - Enable or disable the GPIO interrupt
  136. * clear - Acknowledge/clear any pending GPIO interrupt
  137. * pendown - Return the state of the pen down GPIO input
  138. */
  139. static int tsc_attach(FAR struct ads7843e_config_s *state, xcpt_t handler)
  140. {
  141. FAR struct stm32_config_s *priv = (FAR struct stm32_config_s *)state;
  142. /* Just save the handler for use when the interrupt is enabled */
  143. priv->handler = handler;
  144. return OK;
  145. }
  146. static void tsc_enable(FAR struct ads7843e_config_s *state, bool enable)
  147. {
  148. FAR struct stm32_config_s *priv = (FAR struct stm32_config_s *)state;
  149. /* The caller should not attempt to enable interrupts if the handler
  150. * has not yet been 'attached'
  151. */
  152. DEBUGASSERT(priv->handler || !enable);
  153. /* Attach and enable, or detach and disable */
  154. iinfo("enable:%d\n", enable);
  155. if (enable)
  156. {
  157. (void)stm32_gpiosetevent(GPIO_TP_INT, true, true, false,
  158. priv->handler, NULL);
  159. }
  160. else
  161. {
  162. (void)stm32_gpiosetevent(GPIO_TP_INT, false, false, false,
  163. NULL, NULL);
  164. }
  165. }
  166. static void tsc_clear(FAR struct ads7843e_config_s *state)
  167. {
  168. /* Does nothing */
  169. }
  170. static bool tsc_busy(FAR struct ads7843e_config_s *state)
  171. {
  172. /* Hmmm... The ADS7843E BUSY pin is not brought out on the Shenzhou board.
  173. * We will most certainly have to revisit this. There is this cryptic
  174. * statement in the XPT2046 spec: "No DCLK delay required with dedicated
  175. * serial port."
  176. *
  177. * The busy state is used by the ADS7843E driver to control the delay
  178. * between sending the command, then reading the returned data.
  179. */
  180. return false;
  181. }
  182. static bool tsc_pendown(FAR struct ads7843e_config_s *state)
  183. {
  184. /* XPT2046 uses an an internal pullup resistor. The PENIRQ output goes low
  185. * due to the current path through the touch screen to ground, which
  186. * initiates an interrupt to the processor via TP_INT.
  187. */
  188. bool pendown = !stm32_gpioread(GPIO_TP_INT);
  189. iinfo("pendown:%d\n", pendown);
  190. return pendown;
  191. }
  192. /****************************************************************************
  193. * Public Functions
  194. ****************************************************************************/
  195. /****************************************************************************
  196. * Name: stm32_tsc_setup
  197. *
  198. * Description:
  199. * This function is called by board-bringup logic to configure the
  200. * touchscreen device. This function will register the driver as
  201. * /dev/inputN where N is the minor device number.
  202. *
  203. * Input Parameters:
  204. * minor - The input device minor number
  205. *
  206. * Returned Value:
  207. * Zero is returned on success. Otherwise, a negated errno value is
  208. * returned to indicate the nature of the failure.
  209. *
  210. ****************************************************************************/
  211. int stm32_tsc_setup(int minor)
  212. {
  213. FAR struct spi_dev_s *dev;
  214. int ret;
  215. iinfo("minor %d\n", minor);
  216. DEBUGASSERT(minor == 0);
  217. /* Configure and enable the ADS7843E interrupt pin as an input. */
  218. (void)stm32_configgpio(GPIO_TP_INT);
  219. /* Get an instance of the SPI interface */
  220. dev = stm32_spibus_initialize(CONFIG_ADS7843E_SPIDEV);
  221. if (!dev)
  222. {
  223. ierr("ERROR: Failed to initialize SPI bus %d\n", CONFIG_ADS7843E_SPIDEV);
  224. return -ENODEV;
  225. }
  226. /* Initialize and register the SPI touschscreen device */
  227. ret = ads7843e_register(dev, &g_tscinfo.dev, CONFIG_ADS7843E_DEVMINOR);
  228. if (ret < 0)
  229. {
  230. ierr("ERROR: Failed to initialize SPI bus %d\n", CONFIG_ADS7843E_SPIDEV);
  231. /* up_spiuninitialize(dev); */
  232. return -ENODEV;
  233. }
  234. return OK;
  235. }
  236. #endif /* CONFIG_INPUT_ADS7843E */