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