1 /*
2  * Copyright (c) 2006-2023, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2023-05-26     Chushicheng  the first version
9  */
10 
11 #include "drv_gt911.h"
12 
13 #define LOG_TAG             "drv.gt911"
14 #include <drv_log.h>
15 
16 #ifndef BSP_TOUCH_I2C_BUS
17 #define BSP_TOUCH_I2C_BUS       "i2c1"
18 #endif
19 #define CAPT_I2C_ADDR           (0x5D)
20 
21 #define GT911_REG_RT_CMD            0x8040U
22 #define GT911_REG_RT_CMD_SW_RST_Pos 2U
23 #define GT911_REG_RT_CMD_SW_RST_Msk (1U << GT911_REG_RT_CMD_SW_RST_Pos)
24 #define GT911_REG_RT_CMD_READ_Pos   0U
25 #define GT911_REG_RT_CMD_READ_Msk   (1U << GT911_REG_RT_CMD_READ_Pos)
26 
27 #define GT911_REG_CONFIG_VERSION 0x8047U
28 
29 #define GT911_REG_MODULE_SW1         0x804DU
30 #define GT911_REG_MODULE_SW1_INT_Pos 0U
31 #define GT911_REG_MODULE_SW1_INT_Msk (3U << GT911_REG_MODULE_SW1_INT_Pos)
32 
33 #define GT911_REG_PRODUCT_ID 0x8140U
34 
35 #define GT911_REG_COORD            0x814EU
36 #define GT911_REG_COORD_STATUS_Pos 7U
37 #define GT911_REG_COORD_STATUS_Msk (1U << GT911_REG_COORD_STATUS_Pos)
38 
39 #define GT911_REG_POINT0 0x814FU
40 
41 static capt_t capt_obj;
42 
43 static rt_err_t gt911_ctp_read_reg(gt911_t *ctp, rt_uint16_t reg, rt_uint8_t *data, rt_uint16_t len);
44 static rt_err_t gt911_ctp_write_reg(gt911_t *ctp, rt_uint16_t reg, rt_uint8_t data);
45 static rt_err_t gt911_ctp_sw_reset(gt911_t *ctp);
46 static rt_err_t gt911_ctp_read_config(gt911_t *ctp);
47 static rt_err_t gt911_ctp_config_interrupt(gt911_t *ctp);
48 static rt_err_t gt911_ctp_init(gt911_t *ctp);
49 rt_err_t gt911_ctp_read(gt911_t *ctp, gt911_input_t *input);
50 
gt911_ctp_init(gt911_t * ctp)51 static rt_err_t gt911_ctp_init(gt911_t *ctp)
52 {
53     if (ctp->ops.reset)
54     {
55         if (ctp->ops.reset(ctp->user_data) != RT_EOK)
56         {
57             return -RT_ERROR;
58         }
59     }
60     if (gt911_ctp_sw_reset(ctp) != RT_EOK)
61     {
62         return -RT_ERROR;
63     }
64     if (gt911_ctp_read_config(ctp) != RT_EOK)
65     {
66         return -RT_ERROR;
67     }
68     if (gt911_ctp_config_interrupt(ctp) != RT_EOK)
69     {
70         return -RT_ERROR;
71     }
72     return RT_EOK;
73 }
74 
gt911_ctp_read(gt911_t * ctp,gt911_input_t * input)75 rt_err_t gt911_ctp_read(gt911_t *ctp, gt911_input_t *input)
76 {
77     rt_uint8_t rx_data[40] = {0};
78 
79     if (gt911_ctp_read_reg(ctp, GT911_REG_COORD, rx_data, 1) != RT_EOK)
80     {
81         return -RT_ERROR;
82     }
83     if ((rx_data[0] & GT911_REG_COORD_STATUS_Msk) == 0)
84     {
85         input->num_pos = 0U;
86         return RT_EOK;
87     }
88     input->num_pos = rx_data[0] & 0x0F;
89     if (gt911_ctp_read_reg(ctp, GT911_REG_POINT0, rx_data, 40) != RT_EOK)
90     {
91         return -RT_ERROR;
92     }
93     for (rt_uint8_t i = 0; i < input->num_pos; i++)
94     {
95         rt_uint8_t point_offset = 8 * i; /* Each point has 8 bytes */
96 
97         input->pos[i].id    = rx_data[point_offset];                                         /* 0x00: Track ID */
98         input->pos[i].pos_x = rx_data[point_offset + 1] | (rx_data[point_offset + 2] << 8U); /* 0x01-0x02: X coord */
99         input->pos[i].pos_y = rx_data[point_offset + 3] | (rx_data[point_offset + 4] << 8U); /* 0x03-0x04: Y coord */
100         input->pos[i].size  = rx_data[point_offset + 5] | (rx_data[point_offset + 6] << 8U); /* 0x05-0x06: Size*/
101     }
102     /* Clear buffer status latch, ready for new data */
103     gt911_ctp_write_reg(ctp, GT911_REG_COORD, 0x00);
104 
105     return RT_EOK;
106 }
107 
gt911_ctp_read_reg(gt911_t * ctp,rt_uint16_t reg,rt_uint8_t * data,rt_uint16_t len)108 static rt_err_t gt911_ctp_read_reg(gt911_t *ctp, rt_uint16_t reg, rt_uint8_t *data, rt_uint16_t len)
109 {
110     rt_uint8_t tx_data[2] = {(reg >> 8U), (reg & 0xFFU)};
111     gt911_i2c_xfer_t xfer =
112     {
113         .tx_data = tx_data,
114         .rx_data = data,
115         .tx_len  = 2,
116         .rx_len  = len,
117     };
118 
119     return ctp->ops.xfer(ctp->user_data, &xfer);
120 }
121 
gt911_ctp_write_reg(gt911_t * ctp,rt_uint16_t reg,rt_uint8_t data)122 static rt_err_t gt911_ctp_write_reg(gt911_t *ctp, rt_uint16_t reg, rt_uint8_t data)
123 {
124     rt_uint8_t tx_data[3] = {(reg >> 8U), (reg & 0xFFU), data};
125     gt911_i2c_xfer_t xfer =
126     {
127         .tx_data = tx_data,
128         .rx_data = NULL,
129         .tx_len  = 3,
130         .rx_len  = 0,
131     };
132 
133     return ctp->ops.xfer(ctp->user_data, &xfer);
134 }
135 
gt911_ctp_sw_reset(gt911_t * ctp)136 static rt_err_t gt911_ctp_sw_reset(gt911_t *ctp)
137 {
138     return gt911_ctp_write_reg(ctp, GT911_REG_RT_CMD, (GT911_REG_RT_CMD_SW_RST_Msk));
139 }
140 
gt911_ctp_read_config(gt911_t * ctp)141 static rt_err_t gt911_ctp_read_config(gt911_t *ctp)
142 {
143     rt_uint8_t rx_data[7];
144     if (gt911_ctp_read_reg(ctp, GT911_REG_CONFIG_VERSION, rx_data, 7) != RT_EOK)
145     {
146         return -RT_ERROR;
147     }
148     ctp->fw_version = rx_data[0];                      /* 0x8047, Config Version */
149     ctp->pos_x_max  = rx_data[1] | (rx_data[2] << 8U); /* 0x8048-0x8049, Maximum X */
150     ctp->pos_y_max  = rx_data[3] | (rx_data[4] << 8U); /* 0x804A-0x804B, Maximum Y */
151     ctp->pos_max    = rx_data[5] & 0x0FU;              /* 0x804C, Maximum positions */
152 
153     return RT_EOK;
154 }
155 
gt911_ctp_config_interrupt(gt911_t * ctp)156 static rt_err_t gt911_ctp_config_interrupt(gt911_t *ctp)
157 {
158     rt_uint8_t mod_sw1 = 0x00U;
159     if (gt911_ctp_read_reg(ctp, GT911_REG_MODULE_SW1, &mod_sw1, 0x01) != RT_EOK)
160     {
161         return -RT_ERROR;
162     }
163     mod_sw1 &= ~(GT911_REG_MODULE_SW1_INT_Msk);
164     mod_sw1 |= (ctp->int_mode & GT911_REG_MODULE_SW1_INT_Msk);
165 
166     return gt911_ctp_write_reg(ctp, GT911_REG_MODULE_SW1, mod_sw1);
167 }
168 
ctp_impl_xfer(void * handle,gt911_i2c_xfer_t * xfer)169 static rt_err_t ctp_impl_xfer(void *handle, gt911_i2c_xfer_t *xfer)
170 {
171     capt_t *capt = (capt_t*)handle;
172 
173     if(xfer->tx_len) rt_i2c_master_send(capt->bus, CAPT_I2C_ADDR, 0, xfer->tx_data, xfer->tx_len);
174     if(xfer->rx_len) rt_i2c_master_recv(capt->bus, CAPT_I2C_ADDR, 0, xfer->rx_data, xfer->rx_len);
175 
176     return RT_EOK;
177 }
178 
drv_capt_hw_init(void)179 int drv_capt_hw_init(void)
180 {
181     capt_obj.bus = (struct rt_i2c_bus_device*)rt_device_find(BSP_TOUCH_I2C_BUS);
182     if(capt_obj.bus == RT_NULL)
183     {
184         LOG_E("no %s device", BSP_TOUCH_I2C_BUS);
185         return -RT_ERROR;
186     }
187 
188     capt_obj.gt911.user_data = capt_obj.parent.user_data = &capt_obj;
189     capt_obj.gt911.ops.xfer = ctp_impl_xfer;
190     if(gt911_ctp_init(&capt_obj.gt911) != RT_EOK)
191     {
192         return -RT_ERROR;
193     }
194     rt_device_register(&capt_obj.parent, "capt", RT_DEVICE_FLAG_RDWR);
195 
196     return RT_EOK;
197 }
198 INIT_COMPONENT_EXPORT(drv_capt_hw_init);
199