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