123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235 |
- /*
- * Copyright (c) 2006-2018, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2017-08-08 Yang the first version
- * 2018-10-29 XY
- */
- #include <rthw.h>
- #include <rtthread.h>
- #include <rtdevice.h>
- #include "drv_touch.h"
- #include "fsl_iomuxc.h"
- #include "fsl_gpio.h"
- #define TP_INT_PIN 54 /* GPIO_AD_B0_11 */
- #define TP_RST_PIN 45 /* GPIO_AD_B0_02 */
- #define FT5x06_TS_ADDR (0x38)
- #if 0
- #define TPDEBUG rt_kprintf
- #else
- #define TPDEBUG(...)
- #endif
- static struct touch_driver ft5x06_driver;
- typedef enum _touch_event
- {
- kTouch_Down = 0, /*!< The state changed to touched. */
- kTouch_Up = 1, /*!< The state changed to not touched. */
- kTouch_Contact = 2, /*!< There is a continuous touch being detected. */
- kTouch_Reserved = 3 /*!< No touch information available. */
- } touch_event_t;
- typedef struct _touch_point
- {
- touch_event_t TOUCH_EVENT; /*!< Indicates the state or event of the touch point. */
- uint8_t TOUCH_ID; /*!< Id of the touch point. This numeric value stays constant between down and up event. */
- uint16_t TOUCH_X; /*!< X coordinate of the touch point */
- uint16_t TOUCH_Y; /*!< Y coordinate of the touch point */
- } touch_point_t;
- typedef struct _ft5406_touch_point
- {
- uint8_t XH;
- uint8_t XL;
- uint8_t YH;
- uint8_t YL;
- uint8_t RESERVED[2];
- } ft5406_touch_point_t;
- typedef struct _ft5406_touch_data
- {
- uint8_t DEVIDE_MODE;
- uint8_t GEST_ID;
- uint8_t TD_STATUS;
- ft5406_touch_point_t TOUCH;
- } ft5406_touch_data_t;
- #define TOUCH_POINT_GET_EVENT(T) ((touch_event_t)((T).XH >> 6))
- #define TOUCH_POINT_GET_ID(T) ((T).YH >> 4)
- #define TOUCH_POINT_GET_X(T) ((((T).XH & 0x0f) << 8) | (T).XL)
- #define TOUCH_POINT_GET_Y(T) ((((T).YH & 0x0f) << 8) | (T).YL)
- static int ft5406_read_touch(touch_point_t *dp)
- {
- rt_uint8_t cmd = 0;
- ft5406_touch_data_t touch_data;
- if (rt_touch_read(FT5x06_TS_ADDR, &cmd, 1, &touch_data, sizeof(ft5406_touch_data_t)) != 0)
- return -1;
- dp->TOUCH_X = TOUCH_POINT_GET_Y(touch_data.TOUCH);
- dp->TOUCH_Y = TOUCH_POINT_GET_X(touch_data.TOUCH);
- dp->TOUCH_EVENT = TOUCH_POINT_GET_EVENT(touch_data.TOUCH);
- dp->TOUCH_ID = TOUCH_POINT_GET_ID(touch_data.TOUCH);
- if (dp->TOUCH_EVENT == 3) return -1;
- if (touch_data.TD_STATUS != 0)
- return 0;
- else
- return -1;
- }
- static void ft5x06_isr_enable(rt_bool_t enable)
- {
- if(enable == RT_TRUE)
- {
- rt_pin_irq_enable(TP_INT_PIN, PIN_IRQ_ENABLE);
- }
- else
- {
- rt_pin_irq_enable(TP_INT_PIN, PIN_IRQ_DISABLE);
- }
- }
- static void ft5x06_touch_isr(void *parameter)
- {
- TPDEBUG("[TP] ft5x06_touch_isr\n");
- ft5x06_isr_enable(RT_FALSE);
- rt_sem_release(ft5x06_driver.isr_sem);
- }
- static rt_err_t ft5x06_read_point(touch_message_t msg)
- {
- touch_point_t dp;
- if (ft5406_read_touch(&dp) != 0)
- {
- msg->event = TOUCH_EVENT_UP;
- }
- else
- {
- if (dp.TOUCH_EVENT == kTouch_Up)
- {
- msg->event = TOUCH_EVENT_UP;
- }
- else if (dp.TOUCH_EVENT == kTouch_Down)
- {
- msg->event = TOUCH_EVENT_DOWN;
- }
- else if (dp.TOUCH_EVENT == kTouch_Contact)
- {
- msg->event = TOUCH_EVENT_MOVE;
- }
- else
- {
- msg->event = TOUCH_EVENT_UP;
- }
- }
- msg->x = dp.TOUCH_X;
- msg->y = dp.TOUCH_Y;
- TPDEBUG("[TP] [%d, %d] %s\n", msg->x, msg->y,
- msg->event == TOUCH_EVENT_DOWN ? "DOWN" : (msg->event == TOUCH_EVENT_MOVE ? "MOVE" : (msg->event == TOUCH_EVENT_UP ? "UP" : "NONE")));
- if (msg->event != TOUCH_EVENT_UP)
- {
- rt_sem_release(ft5x06_driver.isr_sem);
- }
- else
- {
- ft5x06_isr_enable(RT_TRUE);
- }
- return RT_EOK;
- }
- static void ft5x06_init(struct rt_i2c_bus_device *i2c_bus)
- {
- ft5x06_driver.isr_sem = rt_sem_create("ft5x06", 0, RT_IPC_FLAG_FIFO);
- RT_ASSERT(ft5x06_driver.isr_sem);
- rt_pin_attach_irq(TP_INT_PIN, PIN_IRQ_MODE_LOW_LEVEL, ft5x06_touch_isr, &ft5x06_driver);
- rt_pin_irq_enable(TP_INT_PIN, PIN_IRQ_ENABLE);
- rt_thread_delay(RT_TICK_PER_SECOND / 5);
- }
- static void ft5x06_deinit(void)
- {
- if (ft5x06_driver.isr_sem)
- {
- rt_sem_delete(ft5x06_driver.isr_sem);
- ft5x06_driver.isr_sem = RT_NULL;
- }
- }
- struct touch_ops ft5x06_ops =
- {
- ft5x06_init,
- ft5x06_deinit,
- ft5x06_read_point,
- };
- static void ft5406_hw_reset(void)
- {
- gpio_pin_config_t pin_config =
- {
- kGPIO_DigitalOutput, 0,
- };
- CLOCK_EnableClock(kCLOCK_Gpio1);
- IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_02_GPIO1_IO02, 0U);
- IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_02_GPIO1_IO02, 0x10B0u);
- /* Enable touch panel controller */
- GPIO_PinInit(GPIO1, 2, &pin_config);
- GPIO_WritePinOutput(GPIO1, 2, 1);
- rt_thread_delay(RT_TICK_PER_SECOND / 20);
- GPIO_WritePinOutput(GPIO1, 2, 0);
- rt_thread_delay(RT_TICK_PER_SECOND / 20);
- GPIO_WritePinOutput(GPIO1, 2, 1);
- }
- static rt_bool_t ft5x06_probe(struct rt_i2c_bus_device *i2c_bus)
- {
- rt_uint16_t cmd = 0x000c;
- rt_uint16_t tmp[2];
- rt_uint16_t CurVersion;
- ft5406_hw_reset();
- if (rt_touch_read(FT5x06_TS_ADDR, &cmd, 2, tmp, 2) != 0)
- {
- TPDEBUG("[TP] %s failed!\n", __func__);
- return RT_FALSE;
- }
- CurVersion = (tmp[0]<<8) | tmp[1];
- rt_kprintf("[TP] FT5X06 Touch Version : %d\n", CurVersion);
- return RT_TRUE;
- }
- int ft5x06_driver_register(void)
- {
- ft5x06_driver.probe = ft5x06_probe;
- ft5x06_driver.ops = &ft5x06_ops;
- ft5x06_driver.user_data = RT_NULL;
- rt_touch_drivers_register(&ft5x06_driver);
- return 0;
- }
- INIT_ENV_EXPORT(ft5x06_driver_register);
|