-
Notifications
You must be signed in to change notification settings - Fork 583
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
os/: IST415 touch driver with multitouch support and respective test case #6404
Conversation
baf07a4
to
e8bf4bc
Compare
e8bf4bc
to
7fbd0cd
Compare
os/include/tinyara/input/ist415.h
Outdated
@@ -0,0 +1,315 @@ | |||
/**************************************************************************** |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think, this file can be in os/drives/input.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
os/include/tinyara/input/ist415.h
Outdated
|
||
u32 CalResult; | ||
u32 SCalResult; | ||
}stIST415xInfo_t; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's add space.
And this struct is necessary?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we have taken this from tizen applied code. yes, It's not necessary, so I have removed it.
31be834
to
70b3695
Compare
FAR struct i2c_dev_s *i2c; | ||
|
||
rtl8730e_ist415_gpio_init(); | ||
rtl8730e_ist415_gpio_reset(false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To properly perform a reset TSP here, you need to set the GPIO pin low and then set it high.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
os/drivers/input/touch.c
Outdated
DEBUGASSERT(buffer); | ||
DEBUGASSERT(buflen > 0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the wrong argument used, So we don't need to reboot the whole system.
How about change this to return minus errno number?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
os/drivers/input/ist415.c
Outdated
* Private Functions | ||
****************************************************************************/ | ||
|
||
static int ist415_get_touch_data (struct ist415_dev_s *dev, FAR void *buf) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove space
static int ist415_get_touch_data(struct ist415_dev_s *dev, FAR void *buf)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
os/drivers/input/touch.c
Outdated
} | ||
sem_init(&g_dev->sem, 0, 1); | ||
sem_init(&g_dev->pollsem, 0, 1); | ||
g_dev->dev = dev; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about following the to the upper and lower parts like timer?
FAR struct timer_upperhalf_s *upper;
upper->lower = lower;
lower->upper = upper; or lower->parent = upper;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
upper is defined in drivers/.c and lower is defined in tinyara/.h, so how can lower use upper
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ewoodev Is this enough? If yes, please mark it as resolved conversation.
os/drivers/input/touch.c
Outdated
{ | ||
int itr; | ||
for (itr = 0; itr < CONFIG_TOUCH_NPOLLWAITERS; itr++) { | ||
struct pollfd *fds = g_dev->fds[itr]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you can access priv upper layer as below, let's remove global variable
int touch_register(struct touch_dev_s *dev) {
dev->upper= upper;
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@namanjain7 @ewoodev How is this?
os/drivers/input/ist415.c
Outdated
return OK; | ||
} | ||
|
||
static void touch_interrupt(int d) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we need argument here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have removed the argument.
int ret = 0; | ||
uint8_t reg[1]; | ||
reg[0] = 0x23; | ||
ret = i2c_write(i2c, &(g_ist415info.touch_config.i2c_config), (uint8_t *)reg, 1); | ||
if (ret < OK) { | ||
touchdbg("ERROR: i2c_write failed\n"); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This does not seem to be a board-specific code.
Please move to ist415.c
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
one write is necessary for working. without this, touch won't work.
I have moved other write and read to driver.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's split a commit for app.
- add ist415 touch support
- modify lcd test app for touch
70b3695
to
c0247cd
Compare
c0247cd
to
e4469bf
Compare
c5131fe
to
81dba20
Compare
os/drivers/input/touch.c
Outdated
|
||
/* Read the touch data, only if screen has been touched or if we're waiting for touch up */ | ||
outlen = sizeof(struct touch_sample_s); | ||
ret = priv->dev->touch_read(priv->dev, buffer); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should use ioctl instead of read & write.
If another device should use some specific structure to bring data, then write & read will not bring data.
That's why all character device use ioctl instead of read / write
os/drivers/input/touch.c
Outdated
* Name: touch_pollnotify | ||
****************************************************************************/ | ||
|
||
void touch_pollnotify(FAR struct touch_dev_s *priv, pollevent_t eventset) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
'priv' means private data of iNode. You register dev structure to private area of iNode. so dev is proper, instead of priv.
os/drivers/input/touch.c
Outdated
{ | ||
int itr; | ||
for (itr = 0; itr < CONFIG_TOUCH_NPOLLWAITERS; itr++) { | ||
struct pollfd *fds = g_dev->fds[itr]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
g_dev allocated when driver registered. then I think you can add this to dev structure. INode will hold this structure too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
os/drivers/input/touch.c
Outdated
* Name: touch_poll | ||
****************************************************************************/ | ||
|
||
static int touch_poll(FAR struct file *filep, FAR struct pollfd *fds, bool setup) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ist415 doesn't support interrupt mode??
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
when there is interrupt in touch, it calls touch_notify.
Then apps calls poll in fd to get touch data.
74dd5ae
to
939bd90
Compare
os/drivers/input/touchscreen.c
Outdated
if (sem_wait(sem) < 0) { | ||
/* EINTR is the only error that we expect */ | ||
int errcode = get_errno(); | ||
DEBUGASSERT(errcode == EINTR); | ||
if (errout) { | ||
return errcode; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (sem_wait(sem) < 0) { | |
/* EINTR is the only error that we expect */ | |
int errcode = get_errno(); | |
DEBUGASSERT(errcode == EINTR); | |
if (errout) { | |
return errcode; | |
} | |
} | |
while (sem_wait(sem) != OK) { | |
ASSERT(get_errno() == EINTR); | |
if (errout) { | |
return -EINTR; | |
} | |
} |
sem_wait can be woken up by other signal. this case should be call sem_wait again
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
* Name: touch_read | ||
****************************************************************************/ | ||
|
||
static ssize_t touch_read(FAR struct file *filep, FAR char *buffer, size_t buflen) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as per my previous reveiew, it should be moved to ioctl.
Not all device just return touched data, some other process before collect touch data can be required.
Please do not use read/write to collect or send data, if possible. It's not a good way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think touch_read and touch_write are fine because all devices require those.
We can add a separate ioctl which can be used to set configuration/setting before calling touch_read/touch_write in future devices.
@ewoodev should we add a separate ioctl or should we remove the touch_read/touch_write and only use ioctl?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, some arguments or pre process can be added. That's why most of character device provide ioctl to send or receive data from application.
Also Tizen Lite follow posix, in POSIX, character device return private data on iNode when read requested.
Hello Mr. Nam @ewoodev pls suggest. |
939bd90
to
c496d65
Compare
|
||
#define PIN_LOW 0 | ||
#define PIN_HIGH 1 | ||
#define TOUCH_DEV_PATH "/dev/touch0" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's use the same definition.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
@@ -69,7 +69,8 @@ | |||
#include <tinyara/config.h> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's keep 644 for file permission.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
@@ -121,7 +124,7 @@ | |||
#define TOUCH_POS_VALID (1 << 4) /* Hardware provided a valid X/Y position */ | |||
#define TOUCH_PRESSURE_VALID (1 << 5) /* Hardware provided a valid pressure */ | |||
#define TOUCH_SIZE_VALID (1 << 6) /* Hardware provided a valid H/W contact size */ | |||
|
|||
#define TOUCH_MAX_POINTS 15 /* Maximum number of simultaneous touch point supported */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this ok to configure in SW? In other words, isn't it a hw dependency configuration?
As you made, here is no hw dependency code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's main purpose is for buffer allocation where touch data will be written.
if there is a hardware which has support for less fingers say 10. so, it will detect at max 10 fingers and data will be written for at max 10 indexes. rest 5 index will be empty.
I have added the ifdef config CONFIG_TOUCH_IST415 similar to what we have done in mipi.
so, different touch hardware can define their own TOUCH_MAX_POINTS
#include <tinyara/fs/ioctl.h> | ||
|
||
#ifdef CONFIG_INPUT | ||
#ifdef CONFIG_TOUCH | ||
#include <tinyara/i2c.h> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks strange.
- Why do you put i2c.h under CONFIG_TOUCH even you locate ioctl.h at outside of the conditional? I think both should be in the conditional.
- Even this header is touchscreen.h, do we need to cover the code with the conditional?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have added the ioctl inside the condition.
touchdbg("ERROR: I2C write failed\n"); | ||
return ret; | ||
} | ||
ret = i2c_read(i2c, &config, touch_event + EVENT_PACKET_SIZE, touch_point * EVENT_PACKET_SIZE); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it always give data when host request touch data to ist415? there is no some kind of state reg value?
As per my experience, there's some bits to check state of measure position.
dev = &g_ist415_dev0; | ||
} | ||
struct rtl8730e_ist415_s *priv = dev->priv; | ||
gpio_irq_disable((gpio_irq_t *)&priv->data_ready); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure but as I know, it should not disable entire of interrupt.
if (touh_down_mode()) {
diable_interrupt;
do_something;
enable_interrupt;
}
Because 'up' event happened only once, so it is required to prevent lose up event during process touch.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done.
|
||
static int touch_ioctl(FAR struct file *filep, int cmd, unsigned long arg) | ||
{ | ||
return OK; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think there should be suspend mode or something to handle sleep mode.
It is depend on requirement of product, but I think ioctl should provide some interface to handle suspend & wakeup to prevent touch interrupt during sleep mode.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi Mr. kwon,
I have added a ioctl support for sleep mode and wake up mode.
the interrupts will be disabled in case of sleep mode and interrupts will be enabled in case of wake up mode.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, i think so, it could be needed, but this PR is opening long ago. Let's seperate PR about this.
c496d65
to
078a286
Compare
Hi, |
078a286
to
a485350
Compare
Add Touch device driver in rtl8730e board and HAL touch common layer for application The structure of touch buffer is: struct touch_sample_s { int npoints; /* The number of touch points in point[] / struct touch_point_s point[1]; / Actual dimension is npoints / struct touch_point_s point[TOUCH_MAX_POINTS]; / Actual dimension is npoints */ }; struct touch_point_s { uint8_t id; /* Unique identifies contact; Same in all reports for the contact / uint8_t flags; / See TOUCH_* definitions above / int16_t x; / X coordinate of the touch point (uncalibrated) / int16_t y; / Y coordinate of the touch point (uncalibrated) / int16_t h; / Height of touch point (uncalibrated) / int16_t w; / Width of touch point (uncalibrated) / uint16_t pressure; / Touch pressure */ }; We have added the array for number of consecutive fingers touching the screen. you can also refer the example app for usage apps/examples/lcd_test/example_lcd.c function: static void touch_test(void) TASH>>lcd_test TASH>>=== LCD demo === xres : 480, yres:800 Total touch points 3 coordinates id: 0, x : 190 y : 135 touch type: 2 Touch hold/move event coordinates id: 1, x : 309 y : 532 touch type: 1 Touch press event coordinates id: 2, x : 161 y : 304 touch type: 1 Touch press event Total touch points 4 coordinates id: 0, x : 187 y : 135 touch type: 2 Touch hold/move event coordinates id: 1, x : 309 y : 532 touch type: 2 Touch hold/move event coordinates id: 2, x : 161 y : 304 touch type: 2 Touch hold/move event coordinates id: 3, x : 210 y : 431 touch type: 2 Touch hold/move event
Add Touch Device test for both single touch and multitouch. It shows the coordinates along with Touch id (Number of simultaneous touch)
a485350
to
a8c6b87
Compare
Hi, |
{ | ||
FAR struct touchscreen_s *upper = priv->upper; | ||
priv->ops->irq_enable(); | ||
work_queue(HPWORK, &ist415_work, get_touch_data, priv, 0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is kernel side work queue.
if app is dead, work_queue operation might corrupted.
Could you please find other way to notify to application?
Let's seperate below to another new PR
|
@namanjain7 @anjana348 Could you check all changes in this PR were merged with other PRs? Can we close this? |
@namanjain7 @anjana348 What about touch callback functionality? |
Touch callback PR: #6539 |
Please review and merge.