View Single Post
Old 05-15-2012, 11:57 AM   #10
geekmaster
Carpe diem, c'est la vie.
geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.
 
geekmaster's Avatar
 
Posts: 6,433
Karma: 10773668
Join Date: Nov 2011
Location: Multiverse 6627A
Device: K1 to PW3
I decided to show you how zforcediag works. I want to use its low-level direct access to the touchscreen LEDs and photodiodes in my own code (I love getting closer to the "bare metal").

I rebooted to diags, and I started SSH from menu items N) U) Z) X), then I ran /usr/local/bin/zforcediag. Here is the output of zforcediag when I touch one finger, then two fingers, then release the first and then the second finger:
Spoiler:
Code:
# ./zforcediag
05/15/12 03:52:28 PM
*** X Leds ***
[0] 4 4   83 77
[1] 4 5   81 87
[2] 4 5   89 87
[3] 4 5   78 80
[4] 4 5   76 80
[5] 4 5   94 80
[6] 4 5   110 80
[7] 4 6   101 73
[8] 5 8   82 84
[9] 5 5   84 80
[10] 4 4   107 78
*** Y Leds ***
[0] 2 1   88 91
[1] 2 1   96 94
[2] 2 4   86 120
[3] 4 2   114 70
[4] 4 4   100 77
[5] 4 5   83 81
[6] 6 4   80 107
[7] 4 2   77 97
[8] 1 4   92 94
[9] 4 4   92 112
[10] 3 1   82 90
[11] 1 1   105 87
[12] 1 1   108 117
[13] 1 1   107 100
[14] 3 4   82 105
*** ***
05/15/12 03:52:31 PM
*** X Leds ***
[0] 4 5   81 77
[1] 15 15   37 4
[2] 15 8   7 75
[3] 5 5   91 81
[4] 5 5   78 76
[5] 4 5   95 78
[6] 4 5   114 75
[7] 4 6   81 75
[8] 5 8   78 88
[9] 5 5   80 82
[10] 4 4   104 81
*** Y Leds ***
[0] 2 1   77 89
[1] 2 1   90 92
[2] 2 4   86 117
[3] 4 2   110 74
[4] 4 4   96 82
[5] 4 5   80 85
[6] 6 4   78 107
[7] 4 1   76 81
[8] 1 4   91 96
[9] 4 4   98 115
[10] 2 1   83 98
[11] 1 2   110 88
[12] 15 15   0 1
[13] 4 1   60 95
[14] 3 4   75 104
*** ***
05/15/12 03:52:34 PM
*** X Leds ***
[0] 4 5   82 77
[1] 15 15   57 3
[2] 15 15   2 28
[3] 7 5   74 80
[4] 4 5   75 76
[5] 4 5   94 95
[6] 4 6   108 73
[7] 4 12   94 85
[8] 15 15   1 3
[9] 8 5   68 72
[10] 4 4   103 80
*** Y Leds ***
[0] 2 1   92 93
[1] 2 1   83 95
[2] 2 15   78 103
[3] 15 15   3 63
[4] 4 4   90 79
[5] 4 5   83 84
[6] 5 4   76 110
[7] 4 1   77 82
[8] 1 4   91 97
[9] 4 3   98 70
[10] 2 1   80 102
[11] 1 4   87 99
[12] 15 15   0 0
[13] 4 1   79 97
[14] 3 4   82 106
*** ***
05/15/12 03:52:37 PM
*** X Leds ***
[0] 4 4   82 77
[1] 4 5   81 88
[2] 4 5   85 79
[3] 4 5   80 81
[4] 4 5   76 82
[5] 4 5   88 88
[6] 4 6   107 74
[7] 4 9   94 85
[8] 15 15   1 2
[9] 9 5   73 72
[10] 4 4   102 78
*** Y Leds ***
[0] 2 1   86 91
[1] 2 1   83 93
[2] 3 15   70 89
[3] 15 6   10 80
[4] 4 4   90 79
[5] 4 5   85 82
[6] 5 4   74 115
[7] 4 2   76 85
[8] 1 4   85 95
[9] 4 4   99 111
[10] 3 1   89 97
[11] 1 1   103 92
[12] 1 1   98 71
[13] 1 1   110 97
[14] 3 4   72 108
*** ***
05/15/12 03:52:40 PM
*** X Leds ***
[0] 4 4   84 78
[1] 4 5   81 75
[2] 4 5   93 84
[3] 4 5   81 82
[4] 4 5   77 82
[5] 4 5   94 86
[6] 4 5   111 82
[7] 4 6   103 80
[8] 5 8   81 83
[9] 5 5   78 81
[10] 4 4   105 77
*** Y Leds ***
[0] 2 1   82 90
[1] 2 1   85 94
[2] 2 4   86 72
[3] 4 2   111 78
[4] 4 4   104 79
[5] 4 5   80 81
[6] 6 4   74 105
[7] 4 1   76 79
[8] 1 4   87 95
[9] 4 4   97 112
[10] 2 1   76 91
[11] 1 1   100 80
[12] 1 1   95 108
[13] 1 1   99 101
[14] 3 4   76 108
*** ***
^C

Here is the output of "strace zforcediags", while I touch the screen two times:
Spoiler:
Code:
# /mnt/us/strace zforcediag
execve("/usr/local/bin/zforcediag", ["zforcediag"], [/* 18 vars */]) = 0
restart_syscall(<... resuming interrupted call ...>pid 1451 stray syscall entry
 <unfinished ...>
brk(0)                                  = 0x12000
uname({sys="Linux", node="[192_168_15_244]", ...}) = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x40017000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY)      = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=37047, ...}) = 0
mmap2(NULL, 37047, PROT_READ, MAP_PRIVATE, 3, 0) = 0x40021000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/libc.so.6", O_RDONLY)        = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0(\0\1\0\0\0\301V\1\000"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0644, st_size=988620, ...}) = 0
mmap2(NULL, 1025308, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x4002b000
mprotect(0x40118000, 32768, PROT_NONE)  = 0
mmap2(0x40120000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0xed) = 0x40120000
mmap2(0x40123000, 9500, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x40123000
close(3)                                = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x40019000
syscall_983045(0x40019570, 0x4002091c, 0x40019c48, 0x40019570, 0x40020000, 0x40018eb0, 0x40020050, 0xf0005, 0x11, 0x50, 0x1, 0x87c, 0, 0xbefa4968, 0x40001c45, 0x40010d56, 0x30, 0x40019570, 0, 0, 0xc764, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) = 0
mprotect(0x40120000, 8192, PROT_READ)   = 0
mprotect(0x4001f000, 4096, PROT_READ)   = 0
munmap(0x40021000, 37047)               = 0
open("/dev/zforce", O_RDWR)             = 3
setitimer(ITIMER_REAL, {it_interval={3, 0}, it_value={3, 0}}, NULL) = 0
rt_sigaction(SIGALRM, NULL, {SIG_DFL}, 8) = 0
rt_sigaction(SIGALRM, {0x8868, [], 0x4000000 /* SA_??? */}, NULL, 8) = 0
pause()                                 = ? ERESTARTNOHAND (To be restarted)
--- SIGALRM (Alarm clock) @ 0 (0) ---
sigreturn()                             = ? (mask now [QUIT TRAP BUS KILL ALRM TERM STKFLT CONT SYS])
ioctl(3, 0x5a07, 0)                     = 0
ioctl(3, ITE_GPIO_OUT, 0xbefa4b14)      = 0
gettimeofday({1337096929, 402478}, NULL) = 0
brk(0)                                  = 0x12000
brk(0x33000)                            = 0x33000
open("/etc/localtime", O_RDONLY)        = -1 ENOENT (No such file or directory)
fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x4001a000
write(1, "05/15/12 03:48:49 PM\n", 2105/15/12 03:48:49 PM
)  = 21
write(1, "*** X Leds ***\n", 15*** X Leds ***
)        = 15
write(1, "[0] 4 4   82 78\n", 16[0] 4 4   82 78
)       = 16
write(1, "[1] 4 5   82 80\n", 16[1] 4 5   82 80
)       = 16
write(1, "[2] 4 5   90 80\n", 16[2] 4 5   90 80
)       = 16
write(1, "[3] 4 5   82 82\n", 16[3] 4 5   82 82
)       = 16
write(1, "[4] 4 5   79 82\n", 16[4] 4 5   79 82
)       = 16
write(1, "[5] 4 8   98 72\n", 16[5] 4 8   98 72
)       = 16
write(1, "[6] 15 15   5 4\n", 16[6] 15 15   5 4
)       = 16
write(1, "[7] 15 8   32 76\n", 17[7] 15 8   32 76
)      = 17
write(1, "[8] 5 8   80 86\n", 16[8] 5 8   80 86
)       = 16
write(1, "[9] 5 5   79 85\n", 16[9] 5 5   79 85
)       = 16
write(1, "[10] 4 4   107 84\n", 18[10] 4 4   107 84
)     = 18
write(1, "*** Y Leds ***\n", 15*** Y Leds ***
)        = 15
write(1, "[0] 2 1   77 94\n", 16[0] 2 1   77 94
)       = 16
write(1, "[1] 2 1   82 89\n", 16[1] 2 1   82 89
)       = 16
write(1, "[2] 2 4   78 120\n", 17[2] 2 4   78 120
)      = 17
write(1, "[3] 4 2   108 83\n", 17[3] 4 2   108 83
)      = 17
write(1, "[4] 4 4   109 82\n", 17[4] 4 4   109 82
)      = 17
write(1, "[5] 4 5   85 85\n", 16[5] 4 5   85 85
)       = 16
write(1, "[6] 5 4   80 102\n", 17[6] 5 4   80 102
)      = 17
write(1, "[7] 9 15   82 7\n", 16[7] 9 15   82 7
)       = 16
write(1, "[8] 15 15   0 1\n", 16[8] 15 15   0 1
)       = 16
write(1, "[9] 15 4   39 97\n", 17[9] 15 4   39 97
)      = 17
write(1, "[10] 3 1   73 90\n", 17[10] 3 1   73 90
)      = 17
write(1, "[11] 1 1   100 91\n", 18[11] 1 1   100 91
)     = 18
write(1, "[12] 1 1   90 74\n", 17[12] 1 1   90 74
)      = 17
write(1, "[13] 1 1   68 70\n", 17[13] 1 1   68 70
)      = 17
write(1, "[14] 3 4   71 106\n", 18[14] 3 4   71 106
)     = 18
write(1, "*** ***\n", 8*** ***
)                = 8
pause()                                 = ? ERESTARTNOHAND (To be restarted)
--- SIGALRM (Alarm clock) @ 0 (0) ---
sigreturn()                             = ? (mask now [QUIT TRAP BUS KILL ALRM TERM STKFLT CONT SYS])
ioctl(3, 0x5a07, 0)                     = 0
ioctl(3, ITE_GPIO_OUT, 0xbefa4b14)      = 0
gettimeofday({1337096932, 396310}, NULL) = 0
open("/etc/localtime", O_RDONLY)        = -1 ENOENT (No such file or directory)
write(1, "05/15/12 03:48:52 PM\n", 2105/15/12 03:48:52 PM
)  = 21
write(1, "*** X Leds ***\n", 15*** X Leds ***
)        = 15
write(1, "[0] 4 4   85 78\n", 16[0] 4 4   85 78
)       = 16
write(1, "[1] 4 5   80 73\n", 16[1] 4 5   80 73
)       = 16
write(1, "[2] 8 15   79 11\n", 17[2] 8 15   79 11
)      = 17
write(1, "[3] 15 9   5 82\n", 16[3] 15 9   5 82
)       = 16
write(1, "[4] 5 5   80 73\n", 16[4] 5 5   80 73
)       = 16
write(1, "[5] 4 5   95 90\n", 16[5] 4 5   95 90
)       = 16
write(1, "[6] 4 5   108 76\n", 17[6] 4 5   108 76
)      = 17
write(1, "[7] 4 6   100 75\n", 17[7] 4 6   100 75
)      = 17
write(1, "[8] 5 8   72 83\n", 16[8] 5 8   72 83
)       = 16
write(1, "[9] 5 5   80 81\n", 16[9] 5 5   80 81
)       = 16
write(1, "[10] 4 4   106 78\n", 18[10] 4 4   106 78
)     = 18
write(1, "*** Y Leds ***\n", 15*** Y Leds ***
)        = 15
write(1, "[0] 2 1   86 93\n", 16[0] 2 1   86 93
)       = 16
write(1, "[1] 2 1   78 85\n", 16[1] 2 1   78 85
)       = 16
write(1, "[2] 2 3   83 70\n", 16[2] 2 3   83 70
)       = 16
write(1, "[3] 4 2   110 75\n", 17[3] 4 2   110 75
)      = 17
write(1, "[4] 4 4   100 83\n", 17[4] 4 4   100 83
)      = 17
write(1, "[5] 4 5   83 85\n", 16[5] 4 5   83 85
)       = 16
write(1, "[6] 6 4   77 107\n", 17[6] 6 4   77 107
)      = 17
write(1, "[7] 4 2   75 96\n", 16[7] 4 2   75 96
)       = 16
write(1, "[8] 1 4   92 95\n", 16[8] 1 4   92 95
)       = 16
write(1, "[9] 4 3   102 68\n", 17[9] 4 3   102 68
)      = 17
write(1, "[10] 2 1   77 92\n", 17[10] 2 1   77 92
)      = 17
write(1, "[11] 1 4   96 91\n", 17[11] 1 4   96 91
)      = 17
write(1, "[12] 15 15   1 0\n", 17[12] 15 15   1 0
)      = 17
write(1, "[13] 15 15   2 72\n", 18[13] 15 15   2 72
)     = 18
write(1, "[14] 4 4   99 109\n", 18[14] 4 4   99 109
)     = 18
write(1, "*** ***\n", 8*** ***
)                = 8
pause(^[^C <unfinished ...>

Being able to determine what coin is (gently) placed on the screen by measuring its diameter would be a cool hack.

EDIT: By comparing the output of zforcediags to the 0-4095 outputs from the zforce event input device, you can see that they interpolate the touch centroid from the proportional "blocked light" values of the outermost blocked sensors. From my testing, it appears that they really DO get 4K pixel accuracy this way (which is why they patented it). You can roll your fingertip on the screen to see subpixel movements. I am curious why amazon is switching to capacitive touchscreens on future kindles -- perhaps to use a thinner bezel so the K5 can be as thin as the K4 (but more likely for cost savings).

EDIT 2: You can see in the first output listing how two finger touches cast shadows forming a rectangle, making it difficult to determine where the two fingers really are without tracking movement history. In fact, the finger positions returned by the event device driver DO get confused and swap half the coordinate pair between fingers when you rotate two fingers on the screen across a common X or Y coordinate. This makes the finger positions reported suddenly jump to the "other" corners of the rectangle. I know how to compensate for this by using velocity tracking instead of position tracking (and in fact it does appear to be fixed in a recent update to the main code trunk for the linux touchscreen driver, but not in the version used in the kindle). Even though the coordinates reported may be for the wrong corners of the rectangle, they are still useful for pinch and stretch gestures, because both diagonals of a rectangle are the same length. I can resize an animated vector object (such as my signature vector) easily enough, but rotating it past a horizontal or vertical axis is difficult unless I add two-finger velocity tracking and "corner swap" correction (and that hack could break if they ever DO fix this problem, and preventing unwanted future behavior adds to the code complexity).


Last edited by geekmaster; 05-15-2012 at 02:42 PM.
geekmaster is offline   Reply With Quote