Added firmware and tools for SILead Touchscreen.
This commit is contained in:
parent
d5c6d8adb0
commit
0c1cc2f379
20
firmware/README.md
Normal file
20
firmware/README.md
Normal file
@ -0,0 +1,20 @@
|
||||
cube/i10
|
||||
--------
|
||||
|
||||
| Item | Description |
|
||||
|---------------------------|-------------|
|
||||
| Manufacturer | Cube |
|
||||
| Device | i10 |
|
||||
| Website | http://www.cube-tablet.com/cube-i10-10-6-inch-dual-boot-tablet.html |
|
||||
| Vendor driver (Windows) | http://techtablets.com/download/cube/i10/Windows%208.1%20Drivers/i10%20Windows%208.1%20drivers%20and%20touchscreen%20config%20files.zip or https://drive.google.com/open?id=0B3eEskvA0DSXZ0RZRVJnR2t1RE0 (drivers for Windows 8.1) http://pan.baidu.com/s/1pKabwdP (system image for i10-R) http://pan.baidu.com/s/1kT8gooJ (system image for i10-BW) http://pan.baidu.com/s/1eQz3bN0 (system image for i10-W) http://pan.baidu.com/s/1kT5yzbT (system image for i10-W) |
|
||||
| Extracted firmware | [Touch screen calibration files Touch/SileadTouch.fw](Touch screen calibration files Touch/SileadTouch.fw) |
|
||||
| Firmware for gslx680-acpi | [silead_ts.fw](silead_ts.fw) |
|
||||
| Display resolution | 1366x768 |
|
||||
| Touch panel resolution | 1366x768 (unverified) |
|
||||
| Touch controller | ? |
|
||||
| Multitouch support | Yes (10) (unverified) |
|
||||
| Finger tracking | Yes |
|
||||
| Mirrored horizontally | No |
|
||||
| Mirrored vertically | No |
|
||||
| Axes swapped | No |
|
||||
| Comments | ./fwtool -c SileadTouch.fw -3 -m 1680 -w 1366 -h 768 -t 10 silead_ts.fw |
|
3
firmware/Touch screen calibration files Touch/ReadMe.txt
Normal file
3
firmware/Touch screen calibration files Touch/ReadMe.txt
Normal file
@ -0,0 +1,3 @@
|
||||
Move these files to C;/windows/system32/drivers and reboot.
|
||||
This will restore the touch screen.
|
||||
Techtablets.com
|
File diff suppressed because one or more lines are too long
BIN
firmware/Touch screen calibration files Touch/SileadTouch.sys
Normal file
BIN
firmware/Touch screen calibration files Touch/SileadTouch.sys
Normal file
Binary file not shown.
BIN
firmware/silead_ts.fw
Normal file
BIN
firmware/silead_ts.fw
Normal file
Binary file not shown.
3
tools/AUTHORS.md
Normal file
3
tools/AUTHORS.md
Normal file
@ -0,0 +1,3 @@
|
||||
fw_extractor is (c) 2013-2014 by Joe Burmeister <joe.a.burmeister@gmail.com>
|
||||
fwtool, unscramble, untscfg and autoconvert are (c) 2015-2016 by Gregor Riepl <onitake@gmail.com>
|
||||
scanwindrv is (c) 2018 by Gregor Riepl <onitake@gmail.com>, based on an example script by Bernhard Übelacker <bernhardu@mailbox.org>
|
530
tools/Firmware/Silead.pm
Normal file
530
tools/Firmware/Silead.pm
Normal file
@ -0,0 +1,530 @@
|
||||
package Firmware::Silead;
|
||||
|
||||
use strict;
|
||||
use IO::File;
|
||||
|
||||
our $MAGIC = 'GSLX';
|
||||
our $FORMAT = 1;
|
||||
our $HEADER_SIZE = 24;
|
||||
our $PAGE_SIZE = 132;
|
||||
|
||||
sub _unpack_header {
|
||||
my ($header) = @_;
|
||||
return (unpack '(a4a4S4C4L)<', $header);
|
||||
}
|
||||
|
||||
sub _unpack_page {
|
||||
my ($buffer) = @_;
|
||||
return (unpack '(S2a128)<', $buffer);
|
||||
}
|
||||
|
||||
sub _pack_header {
|
||||
my ($model, @params) = @_;
|
||||
return pack '(a4a4S4C4L)<', $MAGIC, $model, $FORMAT, @params
|
||||
}
|
||||
|
||||
sub _pack_page {
|
||||
my ($page, $data) = @_;
|
||||
return pack '(S2a128)<', $page, length $data, $data;
|
||||
}
|
||||
|
||||
sub new {
|
||||
my ($class) = @_;
|
||||
return bless {
|
||||
pages => { },
|
||||
model => '',
|
||||
touches => 0,
|
||||
width => 0,
|
||||
height => 0,
|
||||
swapped => 0,
|
||||
xmirrored => 0,
|
||||
ymirrored => 0,
|
||||
tracking => 0,
|
||||
}, ref $class ? ref $class : $class;
|
||||
}
|
||||
|
||||
sub load {
|
||||
my ($class, $handle) = @_;
|
||||
if (!ref $handle) {
|
||||
$handle = IO::File->new($handle, 'r');
|
||||
}
|
||||
if (!defined $handle) {
|
||||
$@ = "Invalid file handle";
|
||||
return undef;
|
||||
}
|
||||
binmode $handle;
|
||||
read $handle, my $header, $HEADER_SIZE;
|
||||
my ($magic, $model, $format, $touches, $width, $height, $swapped, $xmirrored, $ymirrored, $tracking, $pages) = _unpack_header $header;
|
||||
if ($magic ne $MAGIC) {
|
||||
$@ = "Invalid magic $magic";
|
||||
return undef;
|
||||
}
|
||||
if ($format ne $FORMAT) {
|
||||
$@ = "Invalid file format $format";
|
||||
return undef;
|
||||
}
|
||||
my $self = bless {
|
||||
pages => { },
|
||||
model => $model,
|
||||
touches => $touches,
|
||||
width => $width,
|
||||
height => $height,
|
||||
swapped => $swapped,
|
||||
xmirrored => $xmirrored,
|
||||
ymirrored => $ymirrored,
|
||||
tracking => $tracking,
|
||||
}, ref $class ? ref $class : $class;
|
||||
for (my $i = 0; $i < $pages; $i++) {
|
||||
read $handle, my $buffer, $PAGE_SIZE;
|
||||
my ($address, $size, $data) = _unpack_page $buffer;
|
||||
if (!$self->set_page($address, substr $data, 0, $size)) {
|
||||
return undef;
|
||||
}
|
||||
}
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub save {
|
||||
my ($self, $handle) = @_;
|
||||
if (!ref $handle) {
|
||||
$handle = IO::File->new($handle, 'w');
|
||||
}
|
||||
if (!defined $handle) {
|
||||
$@ = "Invalid file handle";
|
||||
return 0;
|
||||
}
|
||||
binmode $handle;
|
||||
my @pages = $self->get_pages;
|
||||
my $header = _pack_header $self->model, $self->touches, $self->width, $self->height, $self->swapped, $self->xmirrored, $self->ymirrored, $self->tracking, scalar(@pages);
|
||||
print $handle $header;
|
||||
for my $page (@pages) {
|
||||
my $pagedata = $self->get_page($page);
|
||||
my $buffer = _pack_page $page, $pagedata;
|
||||
print $handle $buffer;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub unpack {
|
||||
my ($class, $data) = @_;
|
||||
my $header = substr $data, 0, $HEADER_SIZE;
|
||||
my ($magic, $model, $format, $touches, $width, $height, $swapped, $xmirrored, $ymirrored, $tracking, $pages) = _unpack_header $header;
|
||||
if ($magic ne $MAGIC) {
|
||||
$@ = "Invalid magic $magic";
|
||||
return undef;
|
||||
}
|
||||
if ($format ne $FORMAT) {
|
||||
$@ = "Invalid file format $format";
|
||||
return undef;
|
||||
}
|
||||
my $self = bless {
|
||||
pages => { },
|
||||
model => $model,
|
||||
touches => $touches,
|
||||
width => $width,
|
||||
height => $height,
|
||||
swapped => $swapped,
|
||||
xmirrored => $xmirrored,
|
||||
ymirrored => $ymirrored,
|
||||
tracking => $tracking,
|
||||
}, ref $class ? ref $class : $class;
|
||||
for (my $i = 0; $i < $pages; $i++) {
|
||||
my $buffer = substr $HEADER_SIZE + $i * $PAGE_SIZE, $PAGE_SIZE;
|
||||
my ($address, $size, $data) = _unpack_page $buffer ;
|
||||
if (!$self->set_page($address, substr $data, 0, $size)) {
|
||||
return undef;
|
||||
}
|
||||
}
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub pack {
|
||||
my ($self) = @_;
|
||||
my $data = '';
|
||||
my @pages = $self->get_pages;
|
||||
my $header = _pack_header $self->model, $self->touches, $self->width, $self->height, $self->swapped, $self->xmirrored, $self->ymirrored, $self->tracking, scalar(@pages);
|
||||
$data .= $header;
|
||||
for my $page (@pages) {
|
||||
my $pagedata = $self->get_page($page);
|
||||
my $buffer = _pack_page $page, $pagedata;
|
||||
$data .= $buffer;
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
sub import_scrambled {
|
||||
my ($self, $input) = @_;
|
||||
my $tscfg = '';
|
||||
for my $byte (split //, $input) {
|
||||
my $descrambled = chr(ord($byte) ^ 0x88);
|
||||
$tscfg .= $descrambled;
|
||||
}
|
||||
return $self->import_tscfg($tscfg);
|
||||
}
|
||||
|
||||
sub import_tscfg {
|
||||
my ($self, $input) = @_;
|
||||
my ($cfg, $fw) = (0, '');
|
||||
for my $line (split /\n/, $input) {
|
||||
if ($cfg and $line =~ /};/) {
|
||||
$cfg = 0;
|
||||
}
|
||||
if ($line =~ /TS_CFG_DATA|GSLX68X_FW/) {
|
||||
$cfg = 1;
|
||||
}
|
||||
if ($cfg) {
|
||||
$line =~ s/\s//g;
|
||||
$line = lc($line);
|
||||
if ($line =~ /{0x([0-9a-f]+),0x([0-9a-f]+)},/) {
|
||||
my $address = hex($1);
|
||||
my $data = hex($2);
|
||||
$fw .= pack '(LL)<', $address, $data;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $self->import_fw($fw);
|
||||
}
|
||||
|
||||
sub import_fw {
|
||||
my ($self, $input) = @_;
|
||||
|
||||
my $length = length $input;
|
||||
|
||||
my ($page, $lastaddr, $data);
|
||||
for (my $offset = 0; $offset + 7 < $length; $offset += 8) {
|
||||
my $buffer = substr $input, $offset, 8;
|
||||
my ($addr, $value) = unpack '(L2)<', $buffer;
|
||||
if ($addr == 0xf0) {
|
||||
if (defined $data) {
|
||||
$self->set_page($page, $data) or return 0;
|
||||
}
|
||||
$page = $value;
|
||||
$lastaddr = undef;
|
||||
$data = '';
|
||||
printf "Got page 0x%02x\n", $page;
|
||||
} else {
|
||||
if (!defined $page) {
|
||||
$@ = "Invalid firmware: page command missing at start";
|
||||
return 0;
|
||||
}
|
||||
if ($addr > 128) {
|
||||
$@ = sprintf "Invalid firmware: invalid address %d at page 0x%02x, max 128", $addr, $page;
|
||||
return 0;
|
||||
}
|
||||
if (defined $lastaddr and $addr != $lastaddr + 4) {
|
||||
$@ = sprintf "Invalid firmware: non-consecutive at page 0x%02x, address 0x%02x, expected 0x%02x", $page, $addr, $lastaddr + 4;
|
||||
return 0;
|
||||
}
|
||||
$data .= substr $buffer, 4, 4;
|
||||
$lastaddr = $addr;
|
||||
}
|
||||
}
|
||||
if (defined $page and defined $data) {
|
||||
# the last page has not been stored yet
|
||||
return $self->set_page($page, $data);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub export_fw {
|
||||
my ($self) = @_;
|
||||
my $data = '';
|
||||
my @pages = $self->get_pages;
|
||||
for my $page (@pages) {
|
||||
my $pagedata = $self->get_page($page);
|
||||
$data .= pack '(L2)<', 0xf0, $page;
|
||||
my $length = length $pagedata;
|
||||
for (my $offset = 0; $offset + 3 < $length; $offset += 4) {
|
||||
my $word = substr $pagedata, $offset, 4;
|
||||
$data .= pack '(La4)<', $offset, $word;
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
sub set_page {
|
||||
my ($self, $page, $data) = @_;
|
||||
if ($page > 0xff) {
|
||||
$@ = "Invalid page number $page";
|
||||
return 0;
|
||||
}
|
||||
if (length $data > 128) {
|
||||
$@ = "Page too large";
|
||||
return 0;
|
||||
}
|
||||
$self->{pages}->{$page} = $data;
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub delete_page {
|
||||
my ($self, $page) = @_;
|
||||
if (!exists $self->{pages}->{$page}) {
|
||||
$@ = "Page number $page does not exist";
|
||||
return 0;
|
||||
}
|
||||
delete $self->{pages}->{$page};
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub get_pages {
|
||||
my ($self) = @_;
|
||||
return sort { $a <=> $b } keys %{$self->{pages}};
|
||||
}
|
||||
|
||||
sub get_page {
|
||||
my ($self, $page) = @_;
|
||||
return $self->{pages}->{$page};
|
||||
}
|
||||
|
||||
sub touches {
|
||||
return shift->{touches};
|
||||
}
|
||||
|
||||
sub set_touches {
|
||||
my ($self, $value) = @_;
|
||||
$self->{touches} = $value;
|
||||
}
|
||||
|
||||
sub model {
|
||||
return shift->{model};
|
||||
}
|
||||
|
||||
sub set_model {
|
||||
my ($self, $value) = @_;
|
||||
$self->{model} = $value;
|
||||
}
|
||||
|
||||
sub width {
|
||||
return shift->{width};
|
||||
}
|
||||
|
||||
sub set_width {
|
||||
my ($self, $value) = @_;
|
||||
$self->{width} = $value;
|
||||
}
|
||||
|
||||
sub height {
|
||||
return shift->{height};
|
||||
}
|
||||
|
||||
sub set_height {
|
||||
my ($self, $value) = @_;
|
||||
$self->{height} = $value;
|
||||
}
|
||||
|
||||
sub swapped {
|
||||
return shift->{swapped};
|
||||
}
|
||||
|
||||
sub set_swapped {
|
||||
my ($self, $value) = @_;
|
||||
$self->{swapped} = $value;
|
||||
}
|
||||
|
||||
sub xmirrored {
|
||||
return shift->{xmirrored};
|
||||
}
|
||||
|
||||
sub set_xmirrored {
|
||||
my ($self, $value) = @_;
|
||||
$self->{xmirrored} = $value;
|
||||
}
|
||||
|
||||
sub ymirrored {
|
||||
return shift->{ymirrored};
|
||||
}
|
||||
|
||||
sub set_ymirrored {
|
||||
my ($self, $value) = @_;
|
||||
$self->{ymirrored} = $value;
|
||||
}
|
||||
|
||||
sub tracking {
|
||||
return shift->{tracking};
|
||||
}
|
||||
|
||||
sub set_tracking {
|
||||
my ($self, $value) = @_;
|
||||
$self->{tracking} = $value;
|
||||
}
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Firmware::Silead - Silead touchscren firmware packager
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use Firmware::Silead;
|
||||
my $rep = Firmware::Silead->new();
|
||||
printf "width=%d height=%d num_touches=%d\n", $req->width, $rep->height, $rep->touches;
|
||||
$rep->add_page(0x00, "\0" x 128);
|
||||
$rep->save('firmware.fw');
|
||||
|
||||
$rep = Firmware::Silead->load('firmware.fw');
|
||||
print unpack('H*', $req->get_page(0x00));
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
=head2 Constructors
|
||||
|
||||
On error, all constructors set C<$@> to a description
|
||||
of the error and return C<undef>.
|
||||
|
||||
=head3 C<new>
|
||||
|
||||
Creates a new firmware image without data.
|
||||
|
||||
=head3 C<load($io)>
|
||||
|
||||
Loads a firmware image from a file.
|
||||
C<$io> may be a file handle or a file name.
|
||||
|
||||
=head3 C<unpack($string)>
|
||||
|
||||
Unpacks a firmware image from a byte string.
|
||||
|
||||
=head2 Import/Export
|
||||
|
||||
These methods allow importing firmware data from various formats.
|
||||
Limited export is also available.
|
||||
|
||||
Note: Page order is not preserved when importing firmware.
|
||||
Pages are always sorted sequentially.
|
||||
|
||||
=head3 C<import_scrambled($string)>
|
||||
|
||||
Import a firmware image from a scrambled TS_CFG.h byte string, as used in the form
|
||||
of SileadTouch.fw by newer Windows drivers.
|
||||
|
||||
=head3 C<import_tscfg($string)>
|
||||
|
||||
Import a firmware image from a plain TS_CFG.h byte string, as used by older
|
||||
Windows drivers.
|
||||
|
||||
=head3 C<import_fw($string)>
|
||||
|
||||
Import a firmware image in legacy format, as used by most other Linux and
|
||||
Android drivers.
|
||||
|
||||
=head3 C<export_fw>
|
||||
|
||||
Export a firmware image into legacy format, as usable by most other Linux and
|
||||
Android drivers. A binary string is returned.
|
||||
|
||||
=head2 Storage
|
||||
|
||||
=head3 C<save($io)>
|
||||
|
||||
Saves the firmware data to a file.
|
||||
C<$io> may be a file handle or a file name.
|
||||
|
||||
=head3 C<pack>
|
||||
|
||||
Packs a firmware image into a byte string and returns it.
|
||||
|
||||
=head2 Accessors
|
||||
|
||||
=head3 C<model>
|
||||
C<set_model($model)>
|
||||
|
||||
Gets/sets the controller model ID.
|
||||
The ID is a 4-character ASCII string identifying the
|
||||
particular controller supported by this firmware.
|
||||
|
||||
Examples: 1680, 3682
|
||||
|
||||
=head3 C<width>
|
||||
C<set_width($width)>
|
||||
|
||||
Gets/sets the panel width.
|
||||
|
||||
=head3 C<height>
|
||||
C<set_height($height)>
|
||||
|
||||
Gets/sets the panel height.
|
||||
|
||||
=head3 C<touches>
|
||||
C<set_touches($num_touches)>
|
||||
|
||||
Gets/sets the number of supported touch points.
|
||||
|
||||
=head3 C<swapped>
|
||||
C<set_swapped($is_swapped)>
|
||||
|
||||
Gets/sets the axis swapping flag.
|
||||
If true, the X and Y axes are swapped.
|
||||
|
||||
=head3 C<xmirrored>
|
||||
C<set_xmirrored($is_mirrored)>
|
||||
|
||||
Gets/sets the X axis mirroring flag.
|
||||
If true, the X axis is inverted.
|
||||
|
||||
=head3 C<ymirrored>
|
||||
C<set_ymirrored($is_mirrored)>
|
||||
|
||||
Gets/sets the y axis mirroring flag.
|
||||
If true, the Y axis is inverted.
|
||||
|
||||
=head3 C<tracking>
|
||||
C<set_tracking($need_tracking)>
|
||||
|
||||
Gets/sets the software tracking flag.
|
||||
If true, hardware finger tracking is not available and
|
||||
driver finger tracking will be used instead.
|
||||
|
||||
=head2 Page access
|
||||
|
||||
On error, all page accessors set C<$@> to a description
|
||||
of the error. They return 1 on success, 0 on error.
|
||||
|
||||
=head3 C<get_pages>
|
||||
|
||||
Returns the list of defined pages (their page addresses, actually).
|
||||
|
||||
=head3 C<get_page($page_no)>
|
||||
|
||||
Returns the binary data for page number C<$page_no>.
|
||||
|
||||
=head3 C<set_page($page_no, $data)>
|
||||
|
||||
Stores the data of page number C<$page_no>. Automatically defines
|
||||
the page if it did not exist previously.
|
||||
|
||||
=head3 C<delete_page($page_no)>
|
||||
|
||||
Removes page C<$page_no>.
|
||||
|
||||
=head1 FIRMWARE FORMAT
|
||||
|
||||
=head2 New-style firmware file format, version 1
|
||||
|
||||
Offset | Type | Description
|
||||
-------------------------------------------------------------------
|
||||
0 | u8[4] | ASCII 'GSLX' (magic)
|
||||
4 | u8[4] | Touchscreen model (ASCII string)
|
||||
8 | u16le | File format version (1)
|
||||
10 | u16le | Number of supported touch events
|
||||
12 | u16le | Panel width (0..4095)
|
||||
14 | u16le | Panel height (0..4095)
|
||||
16 | u8 | 1 if X and Y axis are swapped, 0 otherwise
|
||||
17 | u8 | 1 if X axis is mirrored, 0 otherwise
|
||||
18 | u8 | 1 if Y axis is mirrored, 0 otherwise
|
||||
19 | u8 | 0 if finger tracking is supported by hardware,
|
||||
| | 1 if the driver needs to provide it
|
||||
20 | u32le | Number of memory pages that follow (N)
|
||||
24 | u16le | Memory page 1: Page address
|
||||
26 | u16le | Memory page 1: Effective size in bytes
|
||||
28 | u8[128] | Memory page 1: Data (must be 0 padded)
|
||||
...
|
||||
24+N*132 | u16le | Memory page N: Page address
|
||||
26+N*132 | u16le | Memory page N: Effective size in bytes
|
||||
28+N*132 | u8[128] | Memory page N: Data (must be 0 padded)
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Gregor Riepl <onitake@gmail.com>
|
||||
|
||||
=cut
|
||||
|
||||
1;
|
339
tools/LICENSE
Normal file
339
tools/LICENSE
Normal file
@ -0,0 +1,339 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
1
tools/SileadTouch.fw
Normal file
1
tools/SileadTouch.fw
Normal file
File diff suppressed because one or more lines are too long
82
tools/autoconvert
Executable file
82
tools/autoconvert
Executable file
@ -0,0 +1,82 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use IO::File;
|
||||
use IO::Dir;
|
||||
use File::Basename;
|
||||
use File::Spec::Functions qw(rel2abs catdir catfile);
|
||||
|
||||
our $mydir = dirname(rel2abs(__FILE__));
|
||||
our $basedir = catdir($mydir, '..', 'firmware');
|
||||
our $fwtool = catfile($mydir, 'fwtool');
|
||||
|
||||
my $root = IO::Dir->new($basedir) or die("Can't access $basedir: $!");
|
||||
for (my $vendor = $root->read(); defined($vendor); $vendor = $root->read()) {
|
||||
if ($vendor !~ /^(.|..)$/) {
|
||||
my $vendordir = catdir($basedir, $vendor);
|
||||
my $devices = IO::Dir->new($vendordir);
|
||||
if (defined($devices)) {
|
||||
for (my $device = $devices->read(); defined($device); $device = $devices->read()) {
|
||||
if ($device !~ /^(.|..)$/) {
|
||||
my $devicedir = catdir($vendordir, $device);
|
||||
if (-d $devicedir) {
|
||||
print("Processing $vendor/$device...\n");
|
||||
my $readme = catfile($devicedir, 'README.md');
|
||||
my $sileadts = catfile($devicedir, 'silead_ts.fw');
|
||||
if (-e $readme) {
|
||||
my $overwrite;
|
||||
if (-e $sileadts) {
|
||||
print("silead_ts.fw found, overwrite? (y/N)");
|
||||
my $answer = readline();
|
||||
$overwrite = ($answer =~ /^[yY]/);
|
||||
} else {
|
||||
$overwrite = 1;
|
||||
}
|
||||
if ($overwrite) {
|
||||
my $firmware = catfile($devicedir, 'firmware.fw');
|
||||
my $model = '1680';
|
||||
my $width = 4095;
|
||||
my $height = 4095;
|
||||
my $points = 10;
|
||||
my %flags = ( xflip => 0, yflip => 0, swap => 0, track => 0 );
|
||||
|
||||
my $table = IO::File->new($readme, 'r') or warn("Error opening README.md");
|
||||
while (my $line = <$table>) {
|
||||
if ($line =~ /Touch controller\s*\|[ \ta-zA-Z]*([0-9]{4})/) {
|
||||
$model = $1;
|
||||
} elsif ($line =~ /Extracted firmware\s*\|[^(]*\(([a-zA-Z0-9_.]+)\)/) {
|
||||
$firmware = catfile($devicedir, $1);
|
||||
} elsif ($line =~ /Touch panel resolution\s*\|[^0-9]*([0-9]+)[ \t\/xX,]+([0-9]+)/) {
|
||||
$width = $1;
|
||||
$height = $2;
|
||||
} elsif ($line =~ /Multitouch support\s*\|[^0-9]*([0-9]+)/) {
|
||||
$points = $1;
|
||||
} elsif ($line =~ /Finger tracking\s*\|\W*[Nn]/) {
|
||||
$flags{track} = 1;
|
||||
} elsif ($line =~ /Mirrored horizontally\s*\|\W*[Yy]/) {
|
||||
$flags{xflip} = 1;
|
||||
} elsif ($line =~ /Mirrored vertically\s*\|\W*[Yy]/) {
|
||||
$flags{yflip} = 1;
|
||||
} elsif ($line =~ /Axes swapped\s*\|\W*[Yy]/) {
|
||||
$flags{swap} = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (-e $firmware) {
|
||||
my $flagstring = join(',', map({ $flags{$_} ? "$_" : "no$_" } keys(%flags)));
|
||||
print("Running: fwtool -c $firmware -1 -m $model -w $width -h $height -t $points -f $flagstring $sileadts\n");
|
||||
system($fwtool, '-c', $firmware, '-1', '-m', $model, '-w', $width, '-h', $height, '-t', $points, '-f', $flagstring, $sileadts);
|
||||
} else {
|
||||
print("Firmware $firmware found.\n");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
print("No README.md found.\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
36
tools/fw_extractor
Executable file
36
tools/fw_extractor
Executable file
@ -0,0 +1,36 @@
|
||||
#! /usr/bin/python
|
||||
from subprocess import *
|
||||
import sys
|
||||
import os
|
||||
|
||||
if len(sys.argv) != 2:
|
||||
print "Firware extractor.\n"
|
||||
print "Requires elf file (driver) argument"
|
||||
sys.exit(1)
|
||||
|
||||
filename = sys.argv[1]
|
||||
|
||||
p = Popen(['/bin/sh', '-c', 'readelf -S '+ filename + ' | grep \ \.rodata\ | sed \'s/\\[ *//g\''], stdout=PIPE)
|
||||
|
||||
args = p.stdout.readlines()
|
||||
|
||||
if len(args) != 1:
|
||||
print "No simple .rodata section found"
|
||||
sys.exit(1)
|
||||
|
||||
rodata = args[0]
|
||||
|
||||
args = rodata.split(']')
|
||||
args = args[1].split()
|
||||
|
||||
offset = int(args[3], 16)
|
||||
|
||||
print ".rodata offset is ", offset, "\n"
|
||||
|
||||
p = Popen(['/bin/sh', '-c', 'readelf -s '+ filename +' | grep -i fw'], stdout=PIPE)
|
||||
|
||||
for line in p.stdout:
|
||||
args = line.split()
|
||||
|
||||
print "Found", args[7], "offset", offset + int(args[1],16), "count", args[2]
|
||||
call(['dd','if='+filename,'bs=1','count='+args[2], 'skip='+str(offset + int(args[1],16)),'of='+args[7] + ".fw"])
|
143
tools/fwtool
Executable file
143
tools/fwtool
Executable file
@ -0,0 +1,143 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use IO::File;
|
||||
use Getopt::Long;
|
||||
use File::Basename;
|
||||
use lib dirname (__FILE__);
|
||||
use Firmware::Silead;
|
||||
|
||||
sub usage() {
|
||||
print STDERR "Usage: fwtool {-i | -c <original.fw> | -s | -x <legacy.fw>} [ -1 | -2 | -3 ] [-w <width>] [-h <height>] [-t <num_touches>] [-f <flags>] <firmware.fw>\n";
|
||||
print STDERR "-i Prints statistics and information about new-style firmware.fw\n";
|
||||
print STDERR "-c Converts any older firmware format into new-style firmware.fw\n";
|
||||
print STDERR "-s Sets parameters and flags\n";
|
||||
print STDERR "-x Exports a firmware into plain format, to use with other Linux/Android drivers\n";
|
||||
print STDERR " The source firmware format can be specified with these parameters:\n";
|
||||
print STDERR "-1 Plain firmware, as used with the Android driver (default)\n";
|
||||
print STDERR "-2 Windows GSL_TS_CFG.h firmware\n";
|
||||
print STDERR "-3 Scrambled Windows SileadTouch.fw firmware\n";
|
||||
print STDERR " For the -c and -s modes, the following parameters may be set:\n";
|
||||
print STDERR "-m Sets the controller model (4-byte ASCII string, ex.: 1680)\n";
|
||||
print STDERR "-w Sets the width parameter\n";
|
||||
print STDERR "-h Sets the height parameter\n";
|
||||
print STDERR "-t Sets the number of supported touch points parameter\n";
|
||||
print STDERR "-f Sets flags, separated by commas (optional, supported flags: xflip, yflip, swap, track)\n";
|
||||
print STDERR " xflip enables horizontal flipping\n";
|
||||
print STDERR " yflip enables vertical flipping\n";
|
||||
print STDERR " swap enables axis swapping\n";
|
||||
print STDERR " track enables in-driver finger tracking (use for controllers that don't support it)\n";
|
||||
print STDERR " Each flag may be prefixed with 'no' to disable it.\n";
|
||||
-1;
|
||||
}
|
||||
|
||||
my ($mode, $format, $tscfg, $model, $width, $height, $touches, $flags, $plain) = ('info', 'plain');
|
||||
GetOptions(
|
||||
'info' => sub { $mode = 'info'; },
|
||||
'convert=s' => sub { $mode = 'convert'; $tscfg = $_[1]; },
|
||||
'set' => sub { $mode = 'set'; },
|
||||
'xport=s' => sub { $mode = 'export'; $plain = $_[1]; },
|
||||
'model=s' => \$model,
|
||||
'width=i' => \$width,
|
||||
'height=i' => \$height,
|
||||
'touches=i' => \$touches,
|
||||
'flags=s' => \$flags,
|
||||
'1' => sub { $format = 'plain' },
|
||||
'2' => sub { $format = 'tscfg' },
|
||||
'3' => sub { $format = 'scrambled' },
|
||||
) or exit usage;
|
||||
|
||||
my $fwfile = $ARGV[0] or exit usage;
|
||||
|
||||
sub set_params {
|
||||
my ($rep) = @_;
|
||||
if (defined $model) {
|
||||
$rep->set_model($model);
|
||||
}
|
||||
if (defined $width) {
|
||||
$rep->set_width($width);
|
||||
}
|
||||
if (defined $height) {
|
||||
$rep->set_height($height);
|
||||
}
|
||||
if (defined $touches) {
|
||||
$rep->set_touches($touches);
|
||||
}
|
||||
if (defined $flags) {
|
||||
for my $flag (split /,\s*/, $flags) {
|
||||
if ($flag =~ /^(no)?xflip$/) {
|
||||
$rep->set_xmirrored($flag !~ /^no/);
|
||||
} elsif ($flag =~ /^(no)?yflip$/) {
|
||||
$rep->set_ymirrored($flag !~ /^no/);
|
||||
} elsif ($flag =~ /^(no)?swap$/) {
|
||||
$rep->set_swapped($flag !~ /^no/);
|
||||
} elsif ($flag =~ /^(no)?track$/) {
|
||||
$rep->set_tracking($flag !~ /^no/);
|
||||
} else {
|
||||
warn "Invalid flag: $flag";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($mode eq 'info') {
|
||||
print "Loading $fwfile...\n";
|
||||
my $rep = Firmware::Silead->load($fwfile) or die "Can't load firmware $fwfile: $@";
|
||||
print "Controller model: " . $rep->model . "\n";
|
||||
print "Panel width: " . $rep->width . "\n";
|
||||
print "Panel height: " . $rep->height . "\n";
|
||||
print "Number of touch points: " . $rep->touches . "\n";
|
||||
print "X axis flipped: " . ($rep->xmirrored ? "yes" : "no") . "\n";
|
||||
print "Y axis flipped: " . ($rep->ymirrored ? "yes" : "no") . "\n";
|
||||
print "X and Y axes swapped: " . ($rep->swapped ? "yes" : "no") . "\n";
|
||||
print "Software tracking enabled: " . ($rep->tracking ? "yes" : "no") . "\n";
|
||||
my @pages = $rep->get_pages;
|
||||
print "Number of pages: ". scalar(@pages) . "\n";
|
||||
print "Page list:";
|
||||
for my $page (@pages) {
|
||||
printf " %02x", $page;
|
||||
}
|
||||
print "\n";
|
||||
} elsif ($mode eq 'set') {
|
||||
print "Loading $fwfile...\n";
|
||||
my $rep = Firmware::Silead->load($fwfile) or die "Can't load firmware $fwfile: $@";
|
||||
print "Setting parameters...\n";
|
||||
set_params($rep);
|
||||
print "Saving $fwfile...\n";
|
||||
$rep->save($fwfile);
|
||||
} elsif ($mode eq 'convert') {
|
||||
print "Loading $tscfg...\n";
|
||||
my $data;
|
||||
do {
|
||||
my $in = IO::File->new($tscfg, 'r') or die "Can't open $tscfg: $!";
|
||||
$in->binmode;
|
||||
local $/ = undef;
|
||||
$data = <$in>;
|
||||
defined($data) or die "Can't load firmware: $!";
|
||||
$in->close();
|
||||
};
|
||||
|
||||
my $rep = Firmware::Silead->new();
|
||||
if ($format eq 'plain') {
|
||||
$rep->import_fw($data) or die "Can't parse firmware: $@";
|
||||
} elsif ($format eq 'tscfg') {
|
||||
$rep->import_tscfg($data) or die "Can't parse firmware: $@";
|
||||
} elsif ($format eq 'scrambled') {
|
||||
$rep->import_scrambled($data) or die "Can't parse firmware: $@";
|
||||
}
|
||||
|
||||
print "Setting parameters...\n";
|
||||
set_params($rep);
|
||||
|
||||
print "Saving $fwfile...\n";
|
||||
$rep->save($fwfile) or die "Can't write firmware: $@";
|
||||
} elsif ($mode eq 'export') {
|
||||
print "Loading $fwfile...\n";
|
||||
my $rep = Firmware::Silead->load($fwfile) or die "Can't load firmware $fwfile: $@";
|
||||
print "Exporting to $plain...\n";
|
||||
my $out = IO::File->new($plain, 'w') or die "Can't open $plain: $!";
|
||||
my $data = $rep->export_fw();
|
||||
$out->print($data) or die "Can't write firmware: $!";
|
||||
$out->close();
|
||||
}
|
129
tools/scanwindrv
Executable file
129
tools/scanwindrv
Executable file
@ -0,0 +1,129 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
require 5.018;
|
||||
use IO::File;
|
||||
|
||||
sub usage() {
|
||||
print(STDERR "Usage: scanwindrv SileadTouch.sys\n");
|
||||
print(STDERR "Scans a Windows driver for sections that look like a firmware image and\n");
|
||||
print(STDERR "writes each into sequentially numbered files: firmware_01.fw firmware_02.fw ...\n");
|
||||
-1;
|
||||
}
|
||||
|
||||
my $drvfile = $ARGV[0] or exit usage;
|
||||
|
||||
my $driver = '';
|
||||
do {
|
||||
my $in = IO::File->new($drvfile, 'r') or die "Can't open $drvfile: $!";
|
||||
$in->binmode();
|
||||
local $/;
|
||||
$driver = <$in>;
|
||||
defined $driver or die "Can't read firmware: $!";
|
||||
$in->close();
|
||||
};
|
||||
|
||||
my $candidate = 0;
|
||||
|
||||
# find candidates
|
||||
for (my $offset = 0; $offset + 8 <= length($driver); $offset++) {
|
||||
|
||||
my ($cmd, $page) = unpack('(LL)<', substr($driver, $offset, 8));
|
||||
if ($cmd == 0x000000f0 && ($page & 0xffffff00) == 0x00000000) {
|
||||
printf(STDERR "Found possible candidate at offset 0x%08x\n", $offset);
|
||||
# possible candidate, start copying pages
|
||||
|
||||
my $firmware = '';
|
||||
my $size;
|
||||
FIRMWARE: for ($size = 0; $offset + $size + 129 * 8 <= length($driver);) {
|
||||
|
||||
#printf(STDERR "offset=0x%08x size=%u[0x%08x]\n", $offset, $size, $size);
|
||||
my ($cmd, $page) = unpack('(LL)<', substr($driver, $offset + $size, 8));
|
||||
#printf(STDERR "Page header at 0x%08x: [0x%02x, 0x%08x]\n", $offset + $size, $cmd, $page);
|
||||
|
||||
# if this doesn't look like a page register - page pair, we're done
|
||||
if ($cmd != 0x000000f0 || ($page & 0xffffff00) != 0x00000000) {
|
||||
last FIRMWARE;
|
||||
}
|
||||
|
||||
for (my $index = 0; $index + 4 <= 128; $index += 4) {
|
||||
my ($idx, $dat) = unpack('(LL)<', substr($driver, $offset + $size + 8 + $index * 2, 8));
|
||||
#printf(STDERR "Data at 0x%08x: [0x%02x, 0x%02x]\n", $offset + $size + 8 + $index * 2, $idx, $dat);
|
||||
|
||||
# if the index is not sequential, this is probably not part of the fw and we're done
|
||||
if ($idx != $index) {
|
||||
#printf(STDERR "Expected index 0x%02x, got 0x%02x\n", $index, $idx);
|
||||
last FIRMWARE;
|
||||
}
|
||||
}
|
||||
|
||||
# one page complete, copy
|
||||
substr($firmware, $size, 33 * 8) = substr($driver, $offset + $size, 33 * 8);
|
||||
$size += 33 * 8;
|
||||
}
|
||||
|
||||
# check if we have enough data
|
||||
if (length($firmware) > 8) {
|
||||
my $fwname = sprintf("firmware_%02u.fw", $candidate);
|
||||
printf(STDERR "Writing firmware to %s, size = %u bytes\n", $fwname, length($firmware));
|
||||
my $out = IO::File->new($fwname, 'w', 0666) or die "Can't open $fwname: $!";
|
||||
$out->binmode();
|
||||
print($out $firmware);
|
||||
$out->close();
|
||||
$candidate++;
|
||||
} else {
|
||||
printf(STDERR "Not a firmware, ignoring\n");
|
||||
}
|
||||
|
||||
# skip ahead
|
||||
$offset += $size;
|
||||
}
|
||||
}
|
||||
|
||||
=cut
|
||||
export F=SileadTouch.sys
|
||||
cat $F \
|
||||
| hexdump -e '1/1 "0x%8.8_ax "' -e '1/1 "%8._ad "' -e '8/1 "%02X ""\n"""' \
|
||||
| grep -i -E "F0 00 00 00 02 00 00 00|7C 00 00 00 .. .. .. .." \
|
||||
| grep "F0 00 00 00 02 00 00 00" -B1 \
|
||||
; \
|
||||
echo -- \
|
||||
; \
|
||||
cat $F \
|
||||
| hexdump -e '1/1 "0x%8.8_ax "' -e '1/1 "%8._ad "' -e '8/1 "%02X ""\n"""' \
|
||||
| grep -i -E "F0 00 00 00 02 00 00 00|7C 00 00 00 .. .. .. .." \
|
||||
| tail -n2
|
||||
|
||||
cat <<EOF
|
||||
Search for the hex sequence F0 00 00 00, followed by a 32 bit
|
||||
number of the form xx 00 00 00 (i.e. an 8 bit value in a little
|
||||
endian 32 bit word) and lots of yy 00 00 00 zz zz zz zz word pairs
|
||||
(where yy is counting from 00 to 7C and zz is any hex code).
|
||||
There are normally several blocks of data with the same pattern that
|
||||
follow. Copy all of them into a new file and call it firmware.fw.
|
||||
This should be the firmware image for your device.
|
||||
EOF
|
||||
|
||||
cat <<EOF
|
||||
0x00009540 38208 7C 00 00 00 00 00 00 01
|
||||
0x00009548 38216 F0 00 00 00 02 00 00 00 (start fw_1)
|
||||
--
|
||||
0x0000b010 45072 7C 00 00 00 00 00 00 00 (end fw_1)
|
||||
0x0000b818 47128 F0 00 00 00 02 00 00 00 (start fw_2)
|
||||
--
|
||||
0x000152c0 86720 7C 00 00 00 30 32 3A 32 (end fw_2)
|
||||
0x00015ac8 88776 F0 00 00 00 02 00 00 00 (start fw_3)
|
||||
--
|
||||
0x0001f570 128368 7C 00 00 00 30 32 3A 32 (end fw_3)
|
||||
0x0001fd78 130424 F0 00 00 00 02 00 00 00 (start fw_4)
|
||||
--
|
||||
0x00029b38 170808 7C 00 00 00 30 32 3A 32 (end fw_4)
|
||||
0x0002b468 177256 7C 00 00 00 01 30 07 30
|
||||
EOF
|
||||
|
||||
dd bs=1 if=$F of=firmware.fw_1 skip=38216 count=$(( 45072 - 38216 + 8))
|
||||
dd bs=1 if=$F of=firmware.fw_2 skip=47128 count=$(( 86720 - 47128 + 8))
|
||||
dd bs=1 if=$F of=firmware.fw_3 skip=88776 count=$((128368 - 88776 + 8))
|
||||
dd bs=1 if=$F of=firmware.fw_4 skip=130424 count=$((170808 - 130424 + 8))
|
||||
|
BIN
tools/silead_ts.fw
Normal file
BIN
tools/silead_ts.fw
Normal file
Binary file not shown.
52
tools/unscramble
Executable file
52
tools/unscramble
Executable file
@ -0,0 +1,52 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use IO::File;
|
||||
|
||||
sub usage() {
|
||||
print STDERR "Usage: unscramble SileadTouch.fw gsl_ts.fw\n";
|
||||
print STDERR "Converts a scrambled Silead Windows driver firmware image into legacy binary format.\n";
|
||||
-1;
|
||||
}
|
||||
|
||||
my $scrfile = $ARGV[0] or exit usage;
|
||||
my $fwfile = $ARGV[1] or exit usage;
|
||||
|
||||
my $scrambled = '';
|
||||
do {
|
||||
my $in = IO::File->new($scrfile, 'r') or die "Can't open $scrfile: $!";
|
||||
$in->binmode();
|
||||
local $/;
|
||||
$scrambled = <$in>;
|
||||
defined $scrambled or die "Can't read firmware: $!";
|
||||
$in->close();
|
||||
};
|
||||
|
||||
my $unscrambled = '';
|
||||
for my $char (split //, $scrambled) {
|
||||
$unscrambled .= chr(ord($char) ^ 0x88);
|
||||
}
|
||||
|
||||
my $out = IO::File->new($fwfile, 'w') or die "Can't open $fwfile: $!";
|
||||
|
||||
my $cfg = 0;
|
||||
for my $line (split /\n/, $unscrambled) {
|
||||
if ($cfg and $line =~ /};/) {
|
||||
$cfg = 0;
|
||||
}
|
||||
if ($line =~ /TS_CFG_DATA/) {
|
||||
$cfg = 1;
|
||||
}
|
||||
if ($cfg) {
|
||||
$line =~ s/\s//g;
|
||||
$line = lc($line);
|
||||
if ($line =~ /{0x([0-9a-f]+),0x([0-9a-f]+)},/) {
|
||||
my $address = hex($1);
|
||||
my $data = hex($2);
|
||||
print $out pack('(LL)<', $address, $data) or die "Can't write to output: $!";;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$out->close();
|
47
tools/untscfg
Executable file
47
tools/untscfg
Executable file
@ -0,0 +1,47 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use IO::File;
|
||||
|
||||
sub usage() {
|
||||
print STDERR "Usage: untscfg GSL_TS_CFG.h gsl_ts.fw\n";
|
||||
print STDERR "Converts the GSL_TS_CFG.h from a Silead Windows driver package into legacy binary format.\n";
|
||||
-1;
|
||||
}
|
||||
|
||||
my $tscffile = $ARGV[0] or exit usage;
|
||||
my $fwfile = $ARGV[1] or exit usage;
|
||||
|
||||
my $unscrambled = '';
|
||||
do {
|
||||
my $in = IO::File->new($tscffile, 'r') or die "Can't open $tscffile: $!";
|
||||
$in->binmode();
|
||||
local $/;
|
||||
$unscrambled = <$in>;
|
||||
defined $unscrambled or die "Can't read firmware: $!";
|
||||
$in->close();
|
||||
};
|
||||
|
||||
my $out = IO::File->new($fwfile, 'w') or die "Can't open $fwfile: $!";
|
||||
|
||||
my $cfg = 0;
|
||||
for my $line (split /\n/, $unscrambled) {
|
||||
if ($cfg and $line =~ /};/) {
|
||||
$cfg = 0;
|
||||
}
|
||||
if ($line =~ /TS_CFG_DATA/) {
|
||||
$cfg = 1;
|
||||
}
|
||||
if ($cfg) {
|
||||
$line =~ s/\s//g;
|
||||
$line = lc($line);
|
||||
if ($line =~ /{0x([0-9a-f]+),0x([0-9a-f]+)},/) {
|
||||
my $address = hex($1);
|
||||
my $data = hex($2);
|
||||
print $out pack('(LL)<', $address, $data) or die "Can't write to output: $!";;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$out->close();
|
Loading…
Reference in New Issue
Block a user