1 /*
2 * Copyright (c) 2021 Bestechnic (Shanghai) Co., Ltd. All rights reserved.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include "touch.h"
16 #include "platform_if.h"
17 #include "hdf_log.h"
18
19 struct TouchManager {
20 struct touch_device *device[TOUCH_DEV_MAX];
21 uint32_t deviceNum;
22 };
23 static struct TouchManager g_touchManager;
24
RegisterTouchDevice(struct touch_device * device)25 int32_t RegisterTouchDevice(struct touch_device *device)
26 {
27 uint32_t deviceNum;
28
29 if (device == NULL) {
30 HDF_LOGE("%s: device is null", __func__);
31 return HDF_ERR_INVALID_PARAM;
32 }
33 deviceNum = g_touchManager.deviceNum;
34 if (deviceNum >= TOUCH_DEV_MAX) {
35 HDF_LOGE("%s: deviceNum > TOUCH_DEV_MAX", __func__);
36 return HDF_FAILURE;
37 }
38 if (device->init == NULL || device->read == NULL || device->irq_enable == NULL) {
39 HDF_LOGE("%s: device invalid", __func__);
40 return HDF_FAILURE;
41 }
42 g_touchManager.device[deviceNum] = device;
43 g_touchManager.deviceNum++;
44 HDF_LOGD("%s: new touch device %s", __func__, device->name);
45 return HDF_SUCCESS;
46 }
47
touch_task(void * arg)48 static void touch_task(void *arg)
49 {
50 struct touch_device *dev = (struct touch_device *)arg;
51 struct touch_msg last_msg = {0};
52 dev->irq_enable(true); // enable irq first
53 while (1) {
54 if (osSemaphoreAcquire(dev->sem, osWaitForever) != 0) {
55 continue;
56 }
57 dev->irq_enable(false); // avoid too much irq
58 struct touch_msg msg;
59 if (dev->read(dev, &msg) == 0) {
60 if (msg.event != TOUCH_EVENT_NONE && memcmp(&msg, &last_msg, sizeof(struct touch_msg)) != 0) {
61 if (osMessageQueuePut(dev->mq, &msg, 0, osWaitForever) != 0) {
62 HDF_LOGW("failed to enqueue touch_msg");
63 } else {
64 last_msg = msg; // filter repeated msg
65 }
66 }
67 }
68 dev->irq_enable(true); // enable irq after data process
69 }
70 }
71
TouchRead(DevHandle handle,struct touch_msg * msg,uint32_t timeout)72 int TouchRead(DevHandle handle, struct touch_msg *msg, uint32_t timeout)
73 {
74 struct touch_device *dev = (struct touch_device *)handle;
75 if (!dev || !dev->mq || !msg) {
76 return -1;
77 }
78 return osMessageQueueGet(dev->mq, msg, NULL, timeout);
79 }
80
TouchOpen(int id)81 DevHandle TouchOpen(int id)
82 {
83 if (id < 0 || id >= g_touchManager.deviceNum) {
84 return NULL;
85 }
86 struct touch_device *dev = g_touchManager.device[id];
87 if (dev->init(dev) != 0) {
88 HDF_LOGE("%s: touch device init failed", __func__);
89 return NULL;
90 }
91
92 dev->sem = osSemaphoreNew(1, 0, NULL);
93 if (dev->sem == NULL) {
94 TouchClose(dev);
95 HDF_LOGE("%s: osSemaphoreNew failed", __func__);
96 return NULL;
97 }
98 dev->mq = osMessageQueueNew(TOUCH_MSG_MAX, sizeof(struct touch_msg), NULL);
99 if (dev->mq == NULL) {
100 TouchClose(dev);
101 HDF_LOGE("%s: osSemaphoreNew failed", __func__);
102 return NULL;
103 }
104
105 osThreadAttr_t attr = {0};
106 attr.stack_size = 2048;
107 attr.priority = osPriorityNormal;
108 attr.name = dev->name;
109 dev->tid = osThreadNew((osThreadFunc_t)touch_task, dev, &attr);
110 if (dev->tid == NULL) {
111 TouchClose(dev);
112 HDF_LOGE("%s: osThreadNew failed", __func__);
113 return NULL;
114 }
115 return dev;
116 }
117
TouchClose(DevHandle handle)118 void TouchClose(DevHandle handle)
119 {
120 struct touch_device *dev = (struct touch_device *)handle;
121 if (!dev) {
122 return;
123 }
124 if (dev->deinit) {
125 dev->deinit();
126 }
127 if (dev->mq) {
128 osMessageQueueDelete(dev->mq);
129 dev->mq = NULL;
130 }
131 if (dev->sem) {
132 osSemaphoreDelete(dev->sem);
133 dev->sem = NULL;
134 }
135 if (dev->tid) {
136 osThreadTerminate(dev->tid);
137 dev->tid = NULL;
138 }
139 }