• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }