├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── build.cmd ├── ci ├── .gitignore ├── input │ ├── dflash │ │ ├── 10b2682a88a78962933abeab0543b2ab9bac09cd.bin │ │ ├── 14a0823be62fb1c822015c7c41aee861abd68967.bin │ │ ├── 161bfe72dfd5ada0cf9d1d766f476fce91afaa77.bin │ │ ├── 1860cc88563a8692b921e2936b785f11a5920a07.bin │ │ ├── 1adc95bebe9eea8c112d40cd04ab7a8d75c4f961.bin │ │ ├── 20bd1106278cfa9b9e481a650ed885d082dfb33d.bin │ │ ├── 33cc32d2610fa9f52778ffaf16f91bbfe367a7af.bin │ │ ├── 4208ada9b94692937991b4d801b67b54c03ba4da.bin │ │ ├── 47ddffedfc002b8304e8bb75f426eca4e3dc3ef0.bin │ │ ├── 5040d7b8ca78260e3ce71212abae7c73d8328b2a.bin │ │ ├── 5188431849b4613152fd7bdba6a3ff0a4fd6424b.bin │ │ ├── 5c3eb80066420002bc3dcc7ca4ab6efad7ed4ae5.bin │ │ ├── 5e15893e86bf1457b252ebdb5e12ebc28727acac.bin │ │ ├── 6219f7ff949c12e56e6db2539dc797ec93c5f3cf.bin │ │ ├── 68271aa8c938f5e9f20221d92b827f3705729d17.bin │ │ ├── 83062f511f231a09eca2fd2ede48c16b188849bd.bin │ │ ├── 8bd0739686f58c8c87721906622572aeb1f84db8.bin │ │ ├── a0a100df53e4ab8b805a0311a8807cbedee2af1c.bin │ │ ├── a9b164cc4d214e6622cf9c9ae4f5a8d38b34d267.bin │ │ ├── b6e0efd7f7f7e0b6ccd28913c1a06e4ca412a93c.bin │ │ ├── c68ad9c32a9fb8780260a22d4a678f3771a4ea9d.bin │ │ ├── d124c43f4ea4d5e0be433b2ab82de56148d3a4ab.bin │ │ ├── da39a3ee5e6b4b0d3255bfef95601890afd80709.bin │ │ ├── e8a3198ff010b0dfb5b038b51eb5f9aa15597122.bin │ │ ├── ed29ac2f668761431867bab869ae92a76326eea7.bin │ │ ├── f1f3a6a6e23fa01d7d2ddd2614913b0d3adfba6d.bin │ │ ├── fdf2b40462e32ca2ee6b68111f35d50f2fa9c18e.bin │ │ └── fef6aaf7d48908c9521c884b7844271e4739821b.bin │ ├── eee │ │ ├── 10b2682a88a78962933abeab0543b2ab9bac09cd.bin │ │ ├── 161bfe72dfd5ada0cf9d1d766f476fce91afaa77.bin │ │ ├── 1860cc88563a8692b921e2936b785f11a5920a07.bin │ │ ├── 1adc95bebe9eea8c112d40cd04ab7a8d75c4f961.bin │ │ ├── 20bd1106278cfa9b9e481a650ed885d082dfb33d.bin │ │ ├── 33cc32d2610fa9f52778ffaf16f91bbfe367a7af.bin │ │ ├── 4208ada9b94692937991b4d801b67b54c03ba4da.bin │ │ ├── 47ddffedfc002b8304e8bb75f426eca4e3dc3ef0.bin │ │ ├── 5040d7b8ca78260e3ce71212abae7c73d8328b2a.bin │ │ ├── 5188431849b4613152fd7bdba6a3ff0a4fd6424b.bin │ │ ├── 5e15893e86bf1457b252ebdb5e12ebc28727acac.bin │ │ ├── 6219f7ff949c12e56e6db2539dc797ec93c5f3cf.bin │ │ ├── 68271aa8c938f5e9f20221d92b827f3705729d17.bin │ │ ├── 83062f511f231a09eca2fd2ede48c16b188849bd.bin │ │ ├── 8bd0739686f58c8c87721906622572aeb1f84db8.bin │ │ ├── a0a100df53e4ab8b805a0311a8807cbedee2af1c.bin │ │ ├── b6e0efd7f7f7e0b6ccd28913c1a06e4ca412a93c.bin │ │ ├── c68ad9c32a9fb8780260a22d4a678f3771a4ea9d.bin │ │ ├── d124c43f4ea4d5e0be433b2ab82de56148d3a4ab.bin │ │ ├── e8a3198ff010b0dfb5b038b51eb5f9aa15597122.bin │ │ ├── ed29ac2f668761431867bab869ae92a76326eea7.bin │ │ ├── f1f3a6a6e23fa01d7d2ddd2614913b0d3adfba6d.bin │ │ ├── fdf2b40462e32ca2ee6b68111f35d50f2fa9c18e.bin │ │ └── fef6aaf7d48908c9521c884b7844271e4739821b.bin │ └── logs │ │ ├── 10b2682a88a78962933abeab0543b2ab9bac09cd.bin │ │ ├── 14a0823be62fb1c822015c7c41aee861abd68967.bin │ │ ├── 161bfe72dfd5ada0cf9d1d766f476fce91afaa77.bin │ │ ├── 1860cc88563a8692b921e2936b785f11a5920a07.bin │ │ ├── 1adc95bebe9eea8c112d40cd04ab7a8d75c4f961.bin │ │ ├── 20bd1106278cfa9b9e481a650ed885d082dfb33d.bin │ │ ├── 33cc32d2610fa9f52778ffaf16f91bbfe367a7af.bin │ │ ├── 4208ada9b94692937991b4d801b67b54c03ba4da.bin │ │ ├── 47ddffedfc002b8304e8bb75f426eca4e3dc3ef0.bin │ │ ├── 5040d7b8ca78260e3ce71212abae7c73d8328b2a.bin │ │ ├── 5188431849b4613152fd7bdba6a3ff0a4fd6424b.bin │ │ ├── 5c3eb80066420002bc3dcc7ca4ab6efad7ed4ae5.bin │ │ ├── 5e15893e86bf1457b252ebdb5e12ebc28727acac.bin │ │ ├── 6219f7ff949c12e56e6db2539dc797ec93c5f3cf.bin │ │ ├── 68271aa8c938f5e9f20221d92b827f3705729d17.bin │ │ ├── 83062f511f231a09eca2fd2ede48c16b188849bd.bin │ │ ├── 8bd0739686f58c8c87721906622572aeb1f84db8.bin │ │ ├── a0a100df53e4ab8b805a0311a8807cbedee2af1c.bin │ │ ├── a9b164cc4d214e6622cf9c9ae4f5a8d38b34d267.bin │ │ ├── b6e0efd7f7f7e0b6ccd28913c1a06e4ca412a93c.bin │ │ ├── c68ad9c32a9fb8780260a22d4a678f3771a4ea9d.bin │ │ ├── d124c43f4ea4d5e0be433b2ab82de56148d3a4ab.bin │ │ ├── da39a3ee5e6b4b0d3255bfef95601890afd80709.bin │ │ ├── e8a3198ff010b0dfb5b038b51eb5f9aa15597122.bin │ │ ├── ed29ac2f668761431867bab869ae92a76326eea7.bin │ │ ├── f1f3a6a6e23fa01d7d2ddd2614913b0d3adfba6d.bin │ │ ├── fdf2b40462e32ca2ee6b68111f35d50f2fa9c18e.bin │ │ └── fef6aaf7d48908c9521c884b7844271e4739821b.bin └── run_ci.sh ├── dflash_to_eee.py ├── gui.py └── webserver ├── convert.php ├── download.php ├── index.html └── settings.php /.gitignore: -------------------------------------------------------------------------------- 1 | **.pyc 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | install: true 2 | script: ci/run_ci.sh 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2017-2018, Ben van Leeuwen Autotechniek, https://www.benvanleeuwen.com/ 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions 5 | are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in 12 | the documentation and/or other materials provided with the 13 | distribution. 14 | 15 | 3. Neither the name of the copyright holder nor the names of its 16 | contributors may be used to endorse or promote products derived 17 | from this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 24 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 25 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 26 | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 27 | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY 29 | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 | POSSIBILITY OF SUCH DAMAGE. 31 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # dflash_to_eeprom [![Build Status](https://travis-ci.org/tomvleeuwen/dflash_to_eeprom.svg?branch=master)](https://travis-ci.org/tomvleeuwen/dflash_to_eeprom) 2 | Tool to fix corrupt MC9S12XEQ384 eeprom. 3 | 4 | # Background 5 | The "FRM3" and other Electronic Control Units contain the MC9S12XEQ384 microprocessor with integrated Flash. When the integrated Flash is used in eeprom emulation mode, like in the case of the FRM3, the settings can get corrupted making the ECU unable to access the eeprom again. The ECU can be repaired by programming the correct data in the (simulated) eeprom. 6 | 7 | # Usage 8 | This tool allows the corrupt data in the microprocessor to be read, even after the eeprom got corrupted. This is done by reading the d-flash contents from the microcontroller using an appropriate programmer (like xprog), after which this program can convert it to an eeprom image which can then be programmed to the simulated eeprom area again using the same programmer. 9 | 10 | # Internals 11 | This tool runs under the following assumptions: The Flash is used as a circular buffer, where each flash block can contain zero to 63 "eeprom commands", which "update" the data in the simulated eeprom. It is assumed that an eeprom word starts as 0xFF, and can be written by adding a command to the flash. It can be overwritten by adding another command to the flash (The flash cannot be erased at word-level, and the block can still contain valid commands for a different address, so it has to keep the old command). Thus, the order of commands matter. It is assumed that a block that has its header set to FFFFFFFE is prepared to become the next block to be written to. 12 | It is also assumed that a block that is not completely filled with commands is the current block, which shall be located just before the prepared block. If none of these conditions are found, it just searches for the longest chain of empty blocks (header starts with 0xFFFF and not 0xFACF), and assumes that these are the prepared blocks. 13 | 14 | # Magic 15 | This is all just based on looking to D-flash dumps, so there might be more magic. However, so far in all cases where this tool did not detect any errors, the resulting image worked fine. When the D-Flash image is corrupt, this script will tell you so. 16 | 17 | Note: This tool does not clear any error codes, short circuit counters, mileage or checksums. Therefore, in all cases you should clear the fault memory after the FRM3 is installed and in some cases it is wise to reset the short circuit counters. 18 | -------------------------------------------------------------------------------- /build.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | REM Simply call pyinstaller and rename the output file 3 | C:\Python27\Scripts\pyinstaller.exe gui.py --onefile 4 | move dist\gui.exe dflash_to_eee.exe 5 | rmdir dist 6 | -------------------------------------------------------------------------------- /ci/.gitignore: -------------------------------------------------------------------------------- 1 | results 2 | -------------------------------------------------------------------------------- /ci/input/dflash/10b2682a88a78962933abeab0543b2ab9bac09cd.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomvleeuwen/dflash_to_eeprom/1aea995181ea0726a0b2ff9cf40ecb541c0f2e99/ci/input/dflash/10b2682a88a78962933abeab0543b2ab9bac09cd.bin -------------------------------------------------------------------------------- /ci/input/dflash/14a0823be62fb1c822015c7c41aee861abd68967.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomvleeuwen/dflash_to_eeprom/1aea995181ea0726a0b2ff9cf40ecb541c0f2e99/ci/input/dflash/14a0823be62fb1c822015c7c41aee861abd68967.bin -------------------------------------------------------------------------------- /ci/input/dflash/161bfe72dfd5ada0cf9d1d766f476fce91afaa77.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomvleeuwen/dflash_to_eeprom/1aea995181ea0726a0b2ff9cf40ecb541c0f2e99/ci/input/dflash/161bfe72dfd5ada0cf9d1d766f476fce91afaa77.bin -------------------------------------------------------------------------------- /ci/input/dflash/1860cc88563a8692b921e2936b785f11a5920a07.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomvleeuwen/dflash_to_eeprom/1aea995181ea0726a0b2ff9cf40ecb541c0f2e99/ci/input/dflash/1860cc88563a8692b921e2936b785f11a5920a07.bin -------------------------------------------------------------------------------- /ci/input/dflash/1adc95bebe9eea8c112d40cd04ab7a8d75c4f961.bin: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ci/input/dflash/20bd1106278cfa9b9e481a650ed885d082dfb33d.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomvleeuwen/dflash_to_eeprom/1aea995181ea0726a0b2ff9cf40ecb541c0f2e99/ci/input/dflash/20bd1106278cfa9b9e481a650ed885d082dfb33d.bin -------------------------------------------------------------------------------- /ci/input/dflash/33cc32d2610fa9f52778ffaf16f91bbfe367a7af.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomvleeuwen/dflash_to_eeprom/1aea995181ea0726a0b2ff9cf40ecb541c0f2e99/ci/input/dflash/33cc32d2610fa9f52778ffaf16f91bbfe367a7af.bin -------------------------------------------------------------------------------- /ci/input/dflash/4208ada9b94692937991b4d801b67b54c03ba4da.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomvleeuwen/dflash_to_eeprom/1aea995181ea0726a0b2ff9cf40ecb541c0f2e99/ci/input/dflash/4208ada9b94692937991b4d801b67b54c03ba4da.bin -------------------------------------------------------------------------------- /ci/input/dflash/47ddffedfc002b8304e8bb75f426eca4e3dc3ef0.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomvleeuwen/dflash_to_eeprom/1aea995181ea0726a0b2ff9cf40ecb541c0f2e99/ci/input/dflash/47ddffedfc002b8304e8bb75f426eca4e3dc3ef0.bin -------------------------------------------------------------------------------- /ci/input/dflash/5040d7b8ca78260e3ce71212abae7c73d8328b2a.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomvleeuwen/dflash_to_eeprom/1aea995181ea0726a0b2ff9cf40ecb541c0f2e99/ci/input/dflash/5040d7b8ca78260e3ce71212abae7c73d8328b2a.bin -------------------------------------------------------------------------------- /ci/input/dflash/5188431849b4613152fd7bdba6a3ff0a4fd6424b.bin: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ci/input/dflash/5c3eb80066420002bc3dcc7ca4ab6efad7ed4ae5.bin: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ci/input/dflash/5e15893e86bf1457b252ebdb5e12ebc28727acac.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomvleeuwen/dflash_to_eeprom/1aea995181ea0726a0b2ff9cf40ecb541c0f2e99/ci/input/dflash/5e15893e86bf1457b252ebdb5e12ebc28727acac.bin -------------------------------------------------------------------------------- /ci/input/dflash/6219f7ff949c12e56e6db2539dc797ec93c5f3cf.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomvleeuwen/dflash_to_eeprom/1aea995181ea0726a0b2ff9cf40ecb541c0f2e99/ci/input/dflash/6219f7ff949c12e56e6db2539dc797ec93c5f3cf.bin -------------------------------------------------------------------------------- /ci/input/dflash/68271aa8c938f5e9f20221d92b827f3705729d17.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomvleeuwen/dflash_to_eeprom/1aea995181ea0726a0b2ff9cf40ecb541c0f2e99/ci/input/dflash/68271aa8c938f5e9f20221d92b827f3705729d17.bin -------------------------------------------------------------------------------- /ci/input/dflash/83062f511f231a09eca2fd2ede48c16b188849bd.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomvleeuwen/dflash_to_eeprom/1aea995181ea0726a0b2ff9cf40ecb541c0f2e99/ci/input/dflash/83062f511f231a09eca2fd2ede48c16b188849bd.bin -------------------------------------------------------------------------------- /ci/input/dflash/8bd0739686f58c8c87721906622572aeb1f84db8.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomvleeuwen/dflash_to_eeprom/1aea995181ea0726a0b2ff9cf40ecb541c0f2e99/ci/input/dflash/8bd0739686f58c8c87721906622572aeb1f84db8.bin -------------------------------------------------------------------------------- /ci/input/dflash/a0a100df53e4ab8b805a0311a8807cbedee2af1c.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomvleeuwen/dflash_to_eeprom/1aea995181ea0726a0b2ff9cf40ecb541c0f2e99/ci/input/dflash/a0a100df53e4ab8b805a0311a8807cbedee2af1c.bin -------------------------------------------------------------------------------- /ci/input/dflash/a9b164cc4d214e6622cf9c9ae4f5a8d38b34d267.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomvleeuwen/dflash_to_eeprom/1aea995181ea0726a0b2ff9cf40ecb541c0f2e99/ci/input/dflash/a9b164cc4d214e6622cf9c9ae4f5a8d38b34d267.bin -------------------------------------------------------------------------------- /ci/input/dflash/b6e0efd7f7f7e0b6ccd28913c1a06e4ca412a93c.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomvleeuwen/dflash_to_eeprom/1aea995181ea0726a0b2ff9cf40ecb541c0f2e99/ci/input/dflash/b6e0efd7f7f7e0b6ccd28913c1a06e4ca412a93c.bin -------------------------------------------------------------------------------- /ci/input/dflash/c68ad9c32a9fb8780260a22d4a678f3771a4ea9d.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomvleeuwen/dflash_to_eeprom/1aea995181ea0726a0b2ff9cf40ecb541c0f2e99/ci/input/dflash/c68ad9c32a9fb8780260a22d4a678f3771a4ea9d.bin -------------------------------------------------------------------------------- /ci/input/dflash/d124c43f4ea4d5e0be433b2ab82de56148d3a4ab.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomvleeuwen/dflash_to_eeprom/1aea995181ea0726a0b2ff9cf40ecb541c0f2e99/ci/input/dflash/d124c43f4ea4d5e0be433b2ab82de56148d3a4ab.bin -------------------------------------------------------------------------------- /ci/input/dflash/da39a3ee5e6b4b0d3255bfef95601890afd80709.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomvleeuwen/dflash_to_eeprom/1aea995181ea0726a0b2ff9cf40ecb541c0f2e99/ci/input/dflash/da39a3ee5e6b4b0d3255bfef95601890afd80709.bin -------------------------------------------------------------------------------- /ci/input/dflash/e8a3198ff010b0dfb5b038b51eb5f9aa15597122.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomvleeuwen/dflash_to_eeprom/1aea995181ea0726a0b2ff9cf40ecb541c0f2e99/ci/input/dflash/e8a3198ff010b0dfb5b038b51eb5f9aa15597122.bin -------------------------------------------------------------------------------- /ci/input/dflash/ed29ac2f668761431867bab869ae92a76326eea7.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomvleeuwen/dflash_to_eeprom/1aea995181ea0726a0b2ff9cf40ecb541c0f2e99/ci/input/dflash/ed29ac2f668761431867bab869ae92a76326eea7.bin -------------------------------------------------------------------------------- /ci/input/dflash/f1f3a6a6e23fa01d7d2ddd2614913b0d3adfba6d.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomvleeuwen/dflash_to_eeprom/1aea995181ea0726a0b2ff9cf40ecb541c0f2e99/ci/input/dflash/f1f3a6a6e23fa01d7d2ddd2614913b0d3adfba6d.bin -------------------------------------------------------------------------------- /ci/input/dflash/fdf2b40462e32ca2ee6b68111f35d50f2fa9c18e.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomvleeuwen/dflash_to_eeprom/1aea995181ea0726a0b2ff9cf40ecb541c0f2e99/ci/input/dflash/fdf2b40462e32ca2ee6b68111f35d50f2fa9c18e.bin -------------------------------------------------------------------------------- /ci/input/dflash/fef6aaf7d48908c9521c884b7844271e4739821b.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomvleeuwen/dflash_to_eeprom/1aea995181ea0726a0b2ff9cf40ecb541c0f2e99/ci/input/dflash/fef6aaf7d48908c9521c884b7844271e4739821b.bin -------------------------------------------------------------------------------- /ci/input/eee/10b2682a88a78962933abeab0543b2ab9bac09cd.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomvleeuwen/dflash_to_eeprom/1aea995181ea0726a0b2ff9cf40ecb541c0f2e99/ci/input/eee/10b2682a88a78962933abeab0543b2ab9bac09cd.bin -------------------------------------------------------------------------------- /ci/input/eee/161bfe72dfd5ada0cf9d1d766f476fce91afaa77.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomvleeuwen/dflash_to_eeprom/1aea995181ea0726a0b2ff9cf40ecb541c0f2e99/ci/input/eee/161bfe72dfd5ada0cf9d1d766f476fce91afaa77.bin -------------------------------------------------------------------------------- /ci/input/eee/1860cc88563a8692b921e2936b785f11a5920a07.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomvleeuwen/dflash_to_eeprom/1aea995181ea0726a0b2ff9cf40ecb541c0f2e99/ci/input/eee/1860cc88563a8692b921e2936b785f11a5920a07.bin -------------------------------------------------------------------------------- /ci/input/eee/1adc95bebe9eea8c112d40cd04ab7a8d75c4f961.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomvleeuwen/dflash_to_eeprom/1aea995181ea0726a0b2ff9cf40ecb541c0f2e99/ci/input/eee/1adc95bebe9eea8c112d40cd04ab7a8d75c4f961.bin -------------------------------------------------------------------------------- /ci/input/eee/20bd1106278cfa9b9e481a650ed885d082dfb33d.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomvleeuwen/dflash_to_eeprom/1aea995181ea0726a0b2ff9cf40ecb541c0f2e99/ci/input/eee/20bd1106278cfa9b9e481a650ed885d082dfb33d.bin -------------------------------------------------------------------------------- /ci/input/eee/33cc32d2610fa9f52778ffaf16f91bbfe367a7af.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomvleeuwen/dflash_to_eeprom/1aea995181ea0726a0b2ff9cf40ecb541c0f2e99/ci/input/eee/33cc32d2610fa9f52778ffaf16f91bbfe367a7af.bin -------------------------------------------------------------------------------- /ci/input/eee/4208ada9b94692937991b4d801b67b54c03ba4da.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomvleeuwen/dflash_to_eeprom/1aea995181ea0726a0b2ff9cf40ecb541c0f2e99/ci/input/eee/4208ada9b94692937991b4d801b67b54c03ba4da.bin -------------------------------------------------------------------------------- /ci/input/eee/47ddffedfc002b8304e8bb75f426eca4e3dc3ef0.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomvleeuwen/dflash_to_eeprom/1aea995181ea0726a0b2ff9cf40ecb541c0f2e99/ci/input/eee/47ddffedfc002b8304e8bb75f426eca4e3dc3ef0.bin -------------------------------------------------------------------------------- /ci/input/eee/5040d7b8ca78260e3ce71212abae7c73d8328b2a.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomvleeuwen/dflash_to_eeprom/1aea995181ea0726a0b2ff9cf40ecb541c0f2e99/ci/input/eee/5040d7b8ca78260e3ce71212abae7c73d8328b2a.bin -------------------------------------------------------------------------------- /ci/input/eee/5188431849b4613152fd7bdba6a3ff0a4fd6424b.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomvleeuwen/dflash_to_eeprom/1aea995181ea0726a0b2ff9cf40ecb541c0f2e99/ci/input/eee/5188431849b4613152fd7bdba6a3ff0a4fd6424b.bin -------------------------------------------------------------------------------- /ci/input/eee/5e15893e86bf1457b252ebdb5e12ebc28727acac.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomvleeuwen/dflash_to_eeprom/1aea995181ea0726a0b2ff9cf40ecb541c0f2e99/ci/input/eee/5e15893e86bf1457b252ebdb5e12ebc28727acac.bin -------------------------------------------------------------------------------- /ci/input/eee/6219f7ff949c12e56e6db2539dc797ec93c5f3cf.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomvleeuwen/dflash_to_eeprom/1aea995181ea0726a0b2ff9cf40ecb541c0f2e99/ci/input/eee/6219f7ff949c12e56e6db2539dc797ec93c5f3cf.bin -------------------------------------------------------------------------------- /ci/input/eee/68271aa8c938f5e9f20221d92b827f3705729d17.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomvleeuwen/dflash_to_eeprom/1aea995181ea0726a0b2ff9cf40ecb541c0f2e99/ci/input/eee/68271aa8c938f5e9f20221d92b827f3705729d17.bin -------------------------------------------------------------------------------- /ci/input/eee/83062f511f231a09eca2fd2ede48c16b188849bd.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomvleeuwen/dflash_to_eeprom/1aea995181ea0726a0b2ff9cf40ecb541c0f2e99/ci/input/eee/83062f511f231a09eca2fd2ede48c16b188849bd.bin -------------------------------------------------------------------------------- /ci/input/eee/8bd0739686f58c8c87721906622572aeb1f84db8.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomvleeuwen/dflash_to_eeprom/1aea995181ea0726a0b2ff9cf40ecb541c0f2e99/ci/input/eee/8bd0739686f58c8c87721906622572aeb1f84db8.bin -------------------------------------------------------------------------------- /ci/input/eee/a0a100df53e4ab8b805a0311a8807cbedee2af1c.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomvleeuwen/dflash_to_eeprom/1aea995181ea0726a0b2ff9cf40ecb541c0f2e99/ci/input/eee/a0a100df53e4ab8b805a0311a8807cbedee2af1c.bin -------------------------------------------------------------------------------- /ci/input/eee/b6e0efd7f7f7e0b6ccd28913c1a06e4ca412a93c.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomvleeuwen/dflash_to_eeprom/1aea995181ea0726a0b2ff9cf40ecb541c0f2e99/ci/input/eee/b6e0efd7f7f7e0b6ccd28913c1a06e4ca412a93c.bin -------------------------------------------------------------------------------- /ci/input/eee/c68ad9c32a9fb8780260a22d4a678f3771a4ea9d.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomvleeuwen/dflash_to_eeprom/1aea995181ea0726a0b2ff9cf40ecb541c0f2e99/ci/input/eee/c68ad9c32a9fb8780260a22d4a678f3771a4ea9d.bin -------------------------------------------------------------------------------- /ci/input/eee/d124c43f4ea4d5e0be433b2ab82de56148d3a4ab.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomvleeuwen/dflash_to_eeprom/1aea995181ea0726a0b2ff9cf40ecb541c0f2e99/ci/input/eee/d124c43f4ea4d5e0be433b2ab82de56148d3a4ab.bin -------------------------------------------------------------------------------- /ci/input/eee/e8a3198ff010b0dfb5b038b51eb5f9aa15597122.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomvleeuwen/dflash_to_eeprom/1aea995181ea0726a0b2ff9cf40ecb541c0f2e99/ci/input/eee/e8a3198ff010b0dfb5b038b51eb5f9aa15597122.bin -------------------------------------------------------------------------------- /ci/input/eee/ed29ac2f668761431867bab869ae92a76326eea7.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomvleeuwen/dflash_to_eeprom/1aea995181ea0726a0b2ff9cf40ecb541c0f2e99/ci/input/eee/ed29ac2f668761431867bab869ae92a76326eea7.bin -------------------------------------------------------------------------------- /ci/input/eee/f1f3a6a6e23fa01d7d2ddd2614913b0d3adfba6d.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomvleeuwen/dflash_to_eeprom/1aea995181ea0726a0b2ff9cf40ecb541c0f2e99/ci/input/eee/f1f3a6a6e23fa01d7d2ddd2614913b0d3adfba6d.bin -------------------------------------------------------------------------------- /ci/input/eee/fdf2b40462e32ca2ee6b68111f35d50f2fa9c18e.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomvleeuwen/dflash_to_eeprom/1aea995181ea0726a0b2ff9cf40ecb541c0f2e99/ci/input/eee/fdf2b40462e32ca2ee6b68111f35d50f2fa9c18e.bin -------------------------------------------------------------------------------- /ci/input/eee/fef6aaf7d48908c9521c884b7844271e4739821b.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomvleeuwen/dflash_to_eeprom/1aea995181ea0726a0b2ff9cf40ecb541c0f2e99/ci/input/eee/fef6aaf7d48908c9521c884b7844271e4739821b.bin -------------------------------------------------------------------------------- /ci/input/logs/10b2682a88a78962933abeab0543b2ab9bac09cd.bin: -------------------------------------------------------------------------------- 1 | INFO:root: 2 | 3 | VIN: B56ZFB4YYTI9H3SP0 4 | Production date: 27.09.2011 5 | Programming date: 06.11.2014 6 | HW-NR: 9206234 (Hardware part number) 7 | SW-NR: 9308375 (Updated part number) 8 | ZB-NR: 9287252 (Original part number) 9 | S: 9263792 (Original part number) 10 | 11 | -------------------------------------------------------------------------------- /ci/input/logs/14a0823be62fb1c822015c7c41aee861abd68967.bin: -------------------------------------------------------------------------------- 1 | WARNING:root:Inconsistency detected, last used block not followed by new blocks! 2 | WARNING:root:Using new blocks as reference! 3 | INFO:root: 4 | 5 | VIN: 7UVG9OJOLY101ZWX0 6 | Production date: 18.05.2011 7 | Programming date: ff.ff.ffff 8 | HW-NR: 3455163 (Hardware part number) 9 | SW-NR: ffffffffffff (Updated part number) 10 | ZB-NR: ffffffffffff (Original part number) 11 | S: 3456588 (Original part number) 12 | 13 | -------------------------------------------------------------------------------- /ci/input/logs/161bfe72dfd5ada0cf9d1d766f476fce91afaa77.bin: -------------------------------------------------------------------------------- 1 | WARNING:root:Found more than one set of new blocks! 2 | INFO:root: 3 | 4 | VIN: BJBJJ892CYBZY66OU 5 | Production date: 19.06.2011 6 | Programming date: 08.04.2013 7 | HW-NR: 3455163 (Hardware part number) 8 | SW-NR: 3457402 (Updated part number) 9 | ZB-NR: 3456588 (Original part number) 10 | S: 3456588 (Original part number) 11 | 12 | -------------------------------------------------------------------------------- /ci/input/logs/1860cc88563a8692b921e2936b785f11a5920a07.bin: -------------------------------------------------------------------------------- 1 | WARNING:root:No new blocks found! 2 | INFO:root: 3 | 4 | VIN: 7V0PPOT5G5GVRZH51 5 | Production date: 19.06.2011 6 | Programming date: 08.04.2013 7 | HW-NR: 3455163 (Hardware part number) 8 | SW-NR: 3457402 (Updated part number) 9 | ZB-NR: 3456588 (Original part number) 10 | S: 3456588 (Original part number) 11 | 12 | -------------------------------------------------------------------------------- /ci/input/logs/1adc95bebe9eea8c112d40cd04ab7a8d75c4f961.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomvleeuwen/dflash_to_eeprom/1aea995181ea0726a0b2ff9cf40ecb541c0f2e99/ci/input/logs/1adc95bebe9eea8c112d40cd04ab7a8d75c4f961.bin -------------------------------------------------------------------------------- /ci/input/logs/20bd1106278cfa9b9e481a650ed885d082dfb33d.bin: -------------------------------------------------------------------------------- 1 | INFO:root: 2 | 3 | VIN: E3AIT49Q8GC1WO0TH 4 | Production date: 17.02.2010 5 | Programming date: ff.ff.ffff 6 | HW-NR: 3455162 (Hardware part number) 7 | SW-NR: ffffffffffff (Updated part number) 8 | ZB-NR: ffffffffffff (Original part number) 9 | S: 3456034 (Original part number) 10 | 11 | -------------------------------------------------------------------------------- /ci/input/logs/33cc32d2610fa9f52778ffaf16f91bbfe367a7af.bin: -------------------------------------------------------------------------------- 1 | INFO:root: 2 | 3 | VIN: H3CJ1X7PM8I2HMD9H 4 | Production date: 16.06.2011 5 | Programming date: 10.01.2014 6 | HW-NR: 9206244 (Hardware part number) 7 | SW-NR: 9308368 (Updated part number) 8 | ZB-NR: 9249083 (Original part number) 9 | S: 9249083 (Original part number) 10 | 11 | -------------------------------------------------------------------------------- /ci/input/logs/4208ada9b94692937991b4d801b67b54c03ba4da.bin: -------------------------------------------------------------------------------- 1 | INFO:root: 2 | 3 | VIN: 83IM9D60QABCUS9S4 4 | Production date: 22.07.2010 5 | Programming date: 25.05.2012 6 | HW-NR: 9206233 (Hardware part number) 7 | SW-NR: 9287251 (Updated part number) 8 | ZB-NR: 9230433 (Original part number) 9 | S: 9230433 (Original part number) 10 | 11 | -------------------------------------------------------------------------------- /ci/input/logs/47ddffedfc002b8304e8bb75f426eca4e3dc3ef0.bin: -------------------------------------------------------------------------------- 1 | INFO:root: 2 | 3 | VIN: NRTW0WKRLL027OECQ 4 | Production date: 31.03.2010 5 | Programming date: 02.12.2013 6 | HW-NR: 9206233 (Hardware part number) 7 | SW-NR: 9308374 (Updated part number) 8 | ZB-NR: 9287251 (Original part number) 9 | S: 9230433 (Original part number) 10 | 11 | -------------------------------------------------------------------------------- /ci/input/logs/5040d7b8ca78260e3ce71212abae7c73d8328b2a.bin: -------------------------------------------------------------------------------- 1 | INFO:root: 2 | 3 | VIN: LQB9MHY6TWJNC28IH 4 | Production date: 25.04.2012 5 | Programming date: ff.ff.ffff 6 | HW-NR: 3455163 (Hardware part number) 7 | SW-NR: ffffffffffff (Updated part number) 8 | ZB-NR: ffffffffffff (Original part number) 9 | S: 3456987 (Original part number) 10 | 11 | -------------------------------------------------------------------------------- /ci/input/logs/5188431849b4613152fd7bdba6a3ff0a4fd6424b.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomvleeuwen/dflash_to_eeprom/1aea995181ea0726a0b2ff9cf40ecb541c0f2e99/ci/input/logs/5188431849b4613152fd7bdba6a3ff0a4fd6424b.bin -------------------------------------------------------------------------------- /ci/input/logs/5c3eb80066420002bc3dcc7ca4ab6efad7ed4ae5.bin: -------------------------------------------------------------------------------- 1 | ERROR:root:Unknown block type: 0x0000 2 | ERROR:root:Unknown block type: 0x0000 3 | Traceback (most recent call last): 4 | main() 5 | converter.convert(sys.argv[1], sys.argv[2]) 6 | self._read_file(dflash_filename) 7 | raise Exception("Input file too short") 8 | Exception: Input file too short 9 | -------------------------------------------------------------------------------- /ci/input/logs/5e15893e86bf1457b252ebdb5e12ebc28727acac.bin: -------------------------------------------------------------------------------- 1 | INFO:root: 2 | 3 | VIN: LF2QAZLAUKQEGY9BZ 4 | Production date: 19.06.2011 5 | Programming date: 08.04.2013 6 | HW-NR: 3455163 (Hardware part number) 7 | SW-NR: 3457402 (Updated part number) 8 | ZB-NR: 3456588 (Original part number) 9 | S: 3456588 (Original part number) 10 | 11 | -------------------------------------------------------------------------------- /ci/input/logs/6219f7ff949c12e56e6db2539dc797ec93c5f3cf.bin: -------------------------------------------------------------------------------- 1 | WARNING:root:No new blocks found! 2 | WARNING:root:No last block found! 3 | WARNING:root:No last or new blocks, using longest chain of empty blocks! 4 | INFO:root: 5 | 6 | VIN: RA22D0W4CON5OWQI3 7 | Production date: 19.06.2011 8 | Programming date: 08.04.2013 9 | HW-NR: 3455163 (Hardware part number) 10 | SW-NR: 3457402 (Updated part number) 11 | ZB-NR: 3456588 (Original part number) 12 | S: 3456588 (Original part number) 13 | 14 | -------------------------------------------------------------------------------- /ci/input/logs/68271aa8c938f5e9f20221d92b827f3705729d17.bin: -------------------------------------------------------------------------------- 1 | INFO:root: 2 | 3 | VIN: 1BR0ZA06JZBZ9YYHR 4 | Production date: 09.06.2011 5 | Programming date: 17.10.2013 6 | HW-NR: 9206243 (Hardware part number) 7 | SW-NR: 9308367 (Updated part number) 8 | ZB-NR: 9249082 (Original part number) 9 | S: 9249082 (Original part number) 10 | 11 | -------------------------------------------------------------------------------- /ci/input/logs/83062f511f231a09eca2fd2ede48c16b188849bd.bin: -------------------------------------------------------------------------------- 1 | INFO:root: 2 | 3 | VIN: QSNC1KXIXLNEWDX94 4 | Production date: 27.09.2011 5 | Programming date: 06.11.2014 6 | HW-NR: 9206234 (Hardware part number) 7 | SW-NR: 9308375 (Updated part number) 8 | ZB-NR: 9287252 (Original part number) 9 | S: 9263792 (Original part number) 10 | 11 | -------------------------------------------------------------------------------- /ci/input/logs/8bd0739686f58c8c87721906622572aeb1f84db8.bin: -------------------------------------------------------------------------------- 1 | INFO:root: 2 | 3 | VIN: PIANNSNJM0KY73DW5 4 | Production date: 19.06.2011 5 | Programming date: 08.04.2013 6 | HW-NR: 3455163 (Hardware part number) 7 | SW-NR: 3457402 (Updated part number) 8 | ZB-NR: 3456588 (Original part number) 9 | S: 3456588 (Original part number) 10 | 11 | -------------------------------------------------------------------------------- /ci/input/logs/a0a100df53e4ab8b805a0311a8807cbedee2af1c.bin: -------------------------------------------------------------------------------- 1 | INFO:root: 2 | 3 | VIN: ADEJKNLVA9F84230I 4 | Production date: 25.04.2012 5 | Programming date: ff.ff.ffff 6 | HW-NR: 3455163 (Hardware part number) 7 | SW-NR: ffffffffffff (Updated part number) 8 | ZB-NR: ffffffffffff (Original part number) 9 | S: 3456987 (Original part number) 10 | 11 | -------------------------------------------------------------------------------- /ci/input/logs/a9b164cc4d214e6622cf9c9ae4f5a8d38b34d267.bin: -------------------------------------------------------------------------------- 1 | Traceback (most recent call last): 2 | main() 3 | converter.convert(sys.argv[1], sys.argv[2]) 4 | self._read_file(dflash_filename) 5 | raise Exception("Input file too short") 6 | Exception: Input file too short 7 | -------------------------------------------------------------------------------- /ci/input/logs/b6e0efd7f7f7e0b6ccd28913c1a06e4ca412a93c.bin: -------------------------------------------------------------------------------- 1 | WARNING:root:Inconsistency detected, last used block not followed by new blocks! 2 | WARNING:root:Using new blocks as reference! 3 | INFO:root: 4 | 5 | VIN: CLW4FDL90L9JMAQM4 6 | Production date: 27.09.2011 7 | Programming date: 06.11.2014 8 | HW-NR: 9206234 (Hardware part number) 9 | SW-NR: 9308375 (Updated part number) 10 | ZB-NR: 9287252 (Original part number) 11 | S: 9263792 (Original part number) 12 | 13 | -------------------------------------------------------------------------------- /ci/input/logs/c68ad9c32a9fb8780260a22d4a678f3771a4ea9d.bin: -------------------------------------------------------------------------------- 1 | INFO:root: 2 | 3 | VIN: F93CJWO6MQ2U8K95A 4 | Production date: 22.07.2010 5 | Programming date: 25.05.2012 6 | HW-NR: 9206233 (Hardware part number) 7 | SW-NR: 9287251 (Updated part number) 8 | ZB-NR: 9230433 (Original part number) 9 | S: 9230433 (Original part number) 10 | 11 | -------------------------------------------------------------------------------- /ci/input/logs/d124c43f4ea4d5e0be433b2ab82de56148d3a4ab.bin: -------------------------------------------------------------------------------- 1 | INFO:root: 2 | 3 | VIN: BI1309YZZDCB8T2NK 4 | Production date: 19.06.2011 5 | Programming date: 08.04.2013 6 | HW-NR: 3455163 (Hardware part number) 7 | SW-NR: 3457402 (Updated part number) 8 | ZB-NR: 3456588 (Original part number) 9 | S: 3456588 (Original part number) 10 | 11 | -------------------------------------------------------------------------------- /ci/input/logs/da39a3ee5e6b4b0d3255bfef95601890afd80709.bin: -------------------------------------------------------------------------------- 1 | Traceback (most recent call last): 2 | main() 3 | converter.convert(sys.argv[1], sys.argv[2]) 4 | self._read_file(dflash_filename) 5 | raise Exception("Input file too short") 6 | Exception: Input file too short 7 | -------------------------------------------------------------------------------- /ci/input/logs/e8a3198ff010b0dfb5b038b51eb5f9aa15597122.bin: -------------------------------------------------------------------------------- 1 | INFO:root: 2 | 3 | VIN: FRJHNYY9CEIB4TMGB 4 | Production date: 26.10.2009 5 | Programming date: ff.ff.ffff 6 | HW-NR: 9206232 (Hardware part number) 7 | SW-NR: ffffffffffff (Updated part number) 8 | ZB-NR: ffffffffffff (Original part number) 9 | S: 9224617 (Original part number) 10 | 11 | -------------------------------------------------------------------------------- /ci/input/logs/ed29ac2f668761431867bab869ae92a76326eea7.bin: -------------------------------------------------------------------------------- 1 | WARNING:root:No last block found! 2 | INFO:root: 3 | 4 | VIN: 06WFEAR3BWZ1A10CC 5 | Production date: 19.06.2011 6 | Programming date: 08.04.2013 7 | HW-NR: 3455163 (Hardware part number) 8 | SW-NR: 3457402 (Updated part number) 9 | ZB-NR: 3456588 (Original part number) 10 | S: 3456588 (Original part number) 11 | 12 | -------------------------------------------------------------------------------- /ci/input/logs/f1f3a6a6e23fa01d7d2ddd2614913b0d3adfba6d.bin: -------------------------------------------------------------------------------- 1 | INFO:root: 2 | 3 | VIN: MEJQ9I5D479V4A7FD 4 | Production date: 08.07.2010 5 | Programming date: 14.02.2011 6 | HW-NR: 9206243 (Hardware part number) 7 | SW-NR: 9240529 (Updated part number) 8 | ZB-NR: 9241004 (Original part number) 9 | S: 9241004 (Original part number) 10 | 11 | -------------------------------------------------------------------------------- /ci/input/logs/fdf2b40462e32ca2ee6b68111f35d50f2fa9c18e.bin: -------------------------------------------------------------------------------- 1 | INFO:root: 2 | 3 | VIN: MEJQ9I5D479V4A7FD 4 | Production date: 08.07.2010 5 | Programming date: 14.02.2011 6 | HW-NR: 9206243 (Hardware part number) 7 | SW-NR: 9240529 (Updated part number) 8 | ZB-NR: 9241004 (Original part number) 9 | S: 9241004 (Original part number) 10 | 11 | -------------------------------------------------------------------------------- /ci/input/logs/fef6aaf7d48908c9521c884b7844271e4739821b.bin: -------------------------------------------------------------------------------- 1 | INFO:root: 2 | 3 | VIN: 0UT3FYTSZPCYNX1HM 4 | Production date: 27.09.2011 5 | Programming date: 06.11.2014 6 | HW-NR: 9206234 (Hardware part number) 7 | SW-NR: 9308375 (Updated part number) 8 | ZB-NR: 9287252 (Original part number) 9 | S: 9263792 (Original part number) 10 | 11 | -------------------------------------------------------------------------------- /ci/run_ci.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | cd $(dirname $0) 4 | 5 | rm -r results 6 | mkdir -p results/logs 7 | mkdir -p results/eee 8 | 9 | # Crude way to filter out any stacktraces from logfile: 10 | # Just ignore all lines that start with at least two spaces 11 | for file in $(ls input/dflash/) ; do 12 | echo "Converting ${file}" 13 | ../dflash_to_eee.py input/dflash/${file} results/eee/${file} 2>&1 | grep --text --invert-match "^ File" > results/logs/${file} 14 | done 15 | 16 | # Since we have set -e , a diff will automatically exit the script with an error. 17 | set -e 18 | for file in $(ls input/eee/) ; do 19 | echo "Checking results for ${file}" 20 | diff input/eee/${file} results/eee/${file} 21 | done 22 | 23 | # For now, just check if the logs match. 24 | for file in $(ls input/logs/) ; do 25 | echo "Checking logs for ${file}" 26 | diff input/logs/${file} results/logs/${file} 27 | done 28 | 29 | echo "All results match" 30 | -------------------------------------------------------------------------------- /dflash_to_eee.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | # -*- coding: utf-8 -*- 3 | # 4 | # Copyright 2017, Ben van Leeuwen Autotechniek, https://www.benvanleeuwen.com/ 5 | # 6 | # Redistribution and use in source and binary forms, with or without 7 | # modification, are permitted provided that the following conditions 8 | # are met: 9 | # 10 | # 1. Redistributions of source code must retain the above copyright 11 | # notice, this list of conditions and the following disclaimer. 12 | # 13 | # 2. Redistributions in binary form must reproduce the above copyright 14 | # notice, this list of conditions and the following disclaimer in 15 | # the documentation and/or other materials provided with the 16 | # distribution. 17 | # 18 | # 3. Neither the name of the copyright holder nor the names of its 19 | # contributors may be used to endorse or promote products derived 20 | # from this software without specific prior written permission. 21 | # 22 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 24 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 25 | # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 26 | # HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 27 | # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 28 | # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 29 | # OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 30 | # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 | # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY 32 | # WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33 | # POSSIBILITY OF SUCH DAMAGE. 34 | # 35 | 36 | ######################################################################### 37 | # # 38 | # DOCUMENTATION # 39 | # # 40 | # The "FRM3" and other Electronic Control Units contain the # 41 | # MC9S12XEQ384 microprocessor with integrated Flash. When the # 42 | # integrated Flash is used in eeprom emulation mode, like in the case # 43 | # of the FRM3, the settings can get corrupted making the ECU unable to # 44 | # access the eeprom again. The ECU can be repaired by programming the # 45 | # correct data in the (simulated) eeprom. # 46 | # # 47 | # This tool allows the corrupt data in the microprocessor to be read, # 48 | # even after the eeprom got corrupted. This is done by reading the # 49 | # d-flash contents from the microcontroller using an appropriate # 50 | # programmer (like xprog), after which this program can convert it to # 51 | # an eeprom image which can then be programmed to the simulated eeprom # 52 | # area again using the same programmer. # 53 | # 54 | # This script runs under the following assumptions: The Flash is used # 55 | # as a circular buffer, where each flash block can contain zero to 63 # 56 | # "eeprom commands", which "update" the data in the simulated eeprom. # 57 | # It is assumed that an eeprom word starts as 0xFF, and can be written # 58 | # by adding a command to the flash. It can be overwritten by adding # 59 | # another command to the flash (The flash cannot be erased at word- # 60 | # level, and the block can still contain valid commands for a different # 61 | # address, so it has to keep the old command). Thus, the order of # 62 | # commands matter. It is assumed that a block that has its header set # 63 | # to FFFFFFFE is prepared to become the next block to be written to. # 64 | # It is also assumed that a block that is not completely filled with # 65 | # commands is the current block, which shall be located just before the # 66 | # prepared block. If none of these conditions are found, it just # 67 | # searches for the longest chain of empty blocks (header starts with # 68 | # 0xFFFF and not 0xFACF), and assumes that these are the prepared # 69 | # blocks. # 70 | # # 71 | # This is all just based on looking to a D-flash dump, so there might # 72 | # be more magic. However, the resuling eeprom file looks reasonable, # 73 | # and it worked in all cases where this tool did not report an error. # 74 | # # 75 | ######################################################################### 76 | 77 | import sys 78 | import struct 79 | import logging 80 | from copy import copy 81 | 82 | 83 | class DFlashConverter(object): 84 | NB_BLOCKS = 128 # Number of flash erase blocks 85 | BLOCKSIZE = 256 # Number of bytes in one flash block 86 | HEADERSIZE = 4 # Size of block header. 87 | CMDSIZE = 4 # Number of bytes occupied by one eeprom update 88 | 89 | EESIZE = 2048 # Number of 2-byte words in the simulated eeprom 90 | 91 | BLOCK_VALID = 0xFACF 92 | BLOCK_EMPTY = 0xFFFF 93 | BLOCK_EMPTY_CLEARED = 0xFFFF 94 | CMD_MASK = 0xF800 95 | CMD_VALID = 0xB800 96 | CMD_EMPTY = 0xF800 97 | 98 | VALID = "VALID" 99 | LAST = "LAST" 100 | EMPTY = "EMPTY" 101 | NEW = "NEW" 102 | INVALID = "INVALID" 103 | 104 | 105 | def __init__(self): 106 | """ DFlashConverter: 107 | This object contains all the magic to convert the D-Flash to Eeprom image. 108 | """ 109 | self.block_types = [] 110 | self.block_data = [] 111 | self.endblock = None 112 | self.corrupt = None 113 | 114 | self.cmds_per_block = (self.BLOCKSIZE - self.HEADERSIZE) / self.CMDSIZE 115 | 116 | def _read_file(self, filename): 117 | """ Reads the d-flash file and stores the data in convenient lists 118 | of block types and block commands 119 | """ 120 | self.corrupt = False 121 | with open(filename, 'rb') as infile: 122 | self.block_data = [ [] for _ in xrange(self.NB_BLOCKS)] 123 | for blockid in xrange(self.NB_BLOCKS): 124 | 125 | infile.seek(blockid * self.BLOCKSIZE) 126 | blockheader = infile.read(self.HEADERSIZE) 127 | if len(blockheader) != 4: 128 | raise Exception("Input file too short") 129 | header = struct.unpack(">HH", blockheader) 130 | if header[0] == self.BLOCK_EMPTY: 131 | if header[1] == self.BLOCK_EMPTY_CLEARED: 132 | self.block_types.append(self.EMPTY) 133 | else: # Block has already been prepared. 134 | self.block_types.append(self.NEW) 135 | elif header[0] == self.BLOCK_VALID: 136 | # There seem to be different type of data blocks defined in header[1], 137 | # however I have currently no idea how to handle it. 138 | logging.debug("Data block id: %d, type: 0x%04X" % (blockid, header[1])) 139 | self.block_types.append(self.VALID) 140 | for blockitem in xrange(self.cmds_per_block): 141 | cmdread = infile.read(self.CMDSIZE) 142 | if len(cmdread) != 4: 143 | raise Exception("Input file too short") 144 | datapair = struct.unpack(">HH", cmdread) 145 | 146 | cmd = datapair[0] & self.CMD_MASK 147 | addr = datapair[0] & ~self.CMD_MASK 148 | data = datapair[1] 149 | 150 | if cmd == self.CMD_VALID: 151 | self.block_data[blockid].append((addr, data)) 152 | elif cmd == self.CMD_EMPTY: 153 | self.block_types[-1] = self.LAST 154 | else: 155 | logging.error("Unknown CMD type detected: 0x%02X" % cmd) 156 | self.corrupt = True 157 | else: 158 | logging.error("Unknown block type: 0x%04X" % header[0]) 159 | self.corrupt = True 160 | self.block_types.append(self.INVALID) 161 | 162 | def _find_new_blocks(self): 163 | """ Finds the "new" blocks and checks that they are all consequtive. 164 | Returns the last block before the "new" blocks since it can be 165 | used as "endblock" """ 166 | block_types = copy(self.block_types) 167 | 168 | # Append the new blocks at the start to the end of the list, so 169 | # we can easily loop through it without accounting for the 170 | # start - end split 171 | curr_block = 0 172 | while block_types[curr_block] == self.NEW or block_types[curr_block] == self.EMPTY: 173 | block_types.append(block_types[curr_block]) 174 | curr_block += 1 175 | if curr_block > self.NB_BLOCKS: 176 | raise Exception("All blocks seem to be new blocks") 177 | 178 | newblock = None 179 | ended = False 180 | 181 | for curr_block in xrange(curr_block, len(block_types)): 182 | if block_types[curr_block] == self.NEW: 183 | if newblock is None: 184 | newblock = curr_block 185 | elif ended: 186 | logging.warning("Found more than one set of new blocks!") 187 | return None 188 | elif block_types[curr_block] != self.EMPTY and newblock is not None: 189 | ended = True 190 | # Return the "endblock", which is the block just before the first newblock 191 | if newblock is None: 192 | logging.warning("No new blocks found!") 193 | return None 194 | return (newblock - 1) % self.NB_BLOCKS 195 | 196 | def _find_last_block(self): 197 | """ Finds the last block, e.g. the block that is valid but is not 198 | (completely) filled with data. Can be used as "endblock" """ 199 | # If there is exactly one "Last" block, simply return it. 200 | if self.block_types.count(self.LAST) == 1: 201 | return self.block_types.index(self.LAST) 202 | if self.block_types.count(self.LAST) == 0: 203 | logging.warning("No last block found!") 204 | return None 205 | logging.warning("More than one 'last' block found!") 206 | return None 207 | 208 | def _find_longest_empty(self): 209 | """ Finds the longest chain of empty block and returns the 210 | block just before that as lastblock, as a fallback mechanism. 211 | Returns the last block of the chain in case no empty block could 212 | be found. """ 213 | # It's still possible that there are "NEW" blocks that are not consequtive 214 | # Therefore, just find the longest chain of "NEW" and "EMPTY" blocks. 215 | now = 0 216 | longest = 0 217 | longest_block = None 218 | # We are lazy. Just concatenate blocks to itself so if the longest 219 | # chain of zero blocks covers the end and start we still see it. 220 | for blockid, block in enumerate(self.block_types+self.block_types): 221 | if block == self.EMPTY or block == self.NEW: 222 | now += 1 223 | else: 224 | now = 0 225 | 226 | if now > longest: 227 | longest = now 228 | longest_block = blockid 229 | if longest_block is None: 230 | return self.NB_BLOCKS - 1 231 | return (longest_block - longest) % self.NB_BLOCKS 232 | 233 | def _save_file(self, filename): 234 | """ Given that all the block data and endblock are known, start 235 | building the eeprom image and save it to a file and to a 236 | local array for analysis 237 | """ 238 | startblock = (self.endblock + 1) % self.NB_BLOCKS 239 | 240 | data = [0xFFFF] * self.EESIZE 241 | for block in range(startblock, self.NB_BLOCKS) + range(0, startblock): 242 | for item in self.block_data[block]: 243 | data[item[0]] = item[1] 244 | 245 | # We have collected the data. Now simply output it to a file. 246 | with open(filename, 'wb') as outfile: 247 | for word in data: 248 | outfile.write(struct.pack(">H", word)) 249 | 250 | self.data = data 251 | 252 | def _get_byte(self, addr): 253 | """ Get a single byte from the 16-bit eeprom data array, 254 | after it has been created by _save_file 255 | """ 256 | if addr % 2 == 1: 257 | return self.data[addr//2] & 0xFF 258 | return self.data[addr//2] >> 8 259 | 260 | def _get_info(self): 261 | """ Show info about the re-build image. Currently it only shows the 262 | VIN number 263 | """ 264 | result = "\n\n" 265 | 266 | if self.corrupt: 267 | result += "Corrupt D-Flash file detected! Results probably incorrect!\n" 268 | 269 | # VIN 270 | vin = "" 271 | for addr in xrange(0xFD3, 0xFE4): 272 | vin = vin + chr(self._get_byte(addr)) 273 | result += "VIN: %s\n" % vin 274 | 275 | # Mfg. date 276 | day = "%02x" % self._get_byte(0xFBE) 277 | month = "%02x" % self._get_byte(0xFBD) 278 | year = "%02x" % self._get_byte(0xFBB) + "%02x" % self._get_byte(0xFBC) 279 | result += "Production date: %s.%s.%s\n" % (day, month, year) 280 | 281 | # Original programming date - always equal to production date... 282 | # day = "%02x" % self._get_byte(0xFA0) 283 | # month = "%02x" % self._get_byte(0xF9F) 284 | # year = "%02x" % self._get_byte(0xF9D) + "%02x" % self._get_byte(0xF9E) 285 | # result += "MIF. date: %s.%s.%s\n" % (day, month, year) 286 | 287 | # Prog. date 288 | day = "%02x" % self._get_byte(0xF89) 289 | month = "%02x" % self._get_byte(0xF88) 290 | year = "%02x" % self._get_byte(0xF86) + "%02x" % self._get_byte(0xF87) 291 | result += "Programming date: %s.%s.%s\n" % (day, month, year) 292 | 293 | # Mfg. part no 294 | data = 0 295 | for byte in xrange(6): 296 | data = (data << 8) + self._get_byte(0xF97 + byte) 297 | result += "HW-NR: %07x (Hardware part number)\n" % data 298 | 299 | # MIF part no 300 | data = 0 301 | for byte in xrange(6): 302 | data = (data << 8) + self._get_byte(0xF8A + byte) 303 | result += "SW-NR: %07x (Updated part number)\n" % data 304 | 305 | # MIF part no 306 | data = 0 307 | for byte in xrange(6): 308 | data = (data << 8) + self._get_byte(0xF65 + byte) 309 | result += "ZB-NR: %07x (Original part number)\n" % data 310 | 311 | # Sticker part no? 312 | data = 0 313 | for byte in xrange(6): 314 | data = (data << 8) + self._get_byte(0xFBF + byte) 315 | result += "S: %07x (Original part number)\n" % data 316 | 317 | return result 318 | 319 | 320 | def convert(self, dflash_filename, ee_filename): 321 | """ Main function that converts dflash_filename to ee_filename 322 | and shows some info afterwards 323 | """ 324 | self._read_file(dflash_filename) 325 | self._find_endblock() 326 | self._save_file(ee_filename) 327 | logging.info(self._get_info()) 328 | 329 | def _find_endblock(self): 330 | endblock_new = self._find_new_blocks() 331 | endblock_last = self._find_last_block() 332 | 333 | if endblock_new is None: 334 | if endblock_last is None: 335 | logging.warning("No last or new blocks, using longest chain of empty blocks!") 336 | self.endblock = self._find_longest_empty() 337 | else: 338 | self.endblock = endblock_last 339 | else: 340 | # This whole if-statement is just here to generate the warning message. 341 | if endblock_last != endblock_new and endblock_last is not None: 342 | # It is allowed to have empty blocks between the last used and the new block. 343 | # Make sure we have a contineous set of blocks by appending the list to itself. 344 | block_types = self.block_types + self.block_types 345 | endblock_new_wrapped = endblock_new 346 | if endblock_new_wrapped < endblock_last: 347 | endblock_new_wrapped += len(self.block_types) 348 | if block_types[endblock_last+1:endblock_new_wrapped+1].count(self.EMPTY) != \ 349 | endblock_new_wrapped - endblock_last: 350 | logging.warning("Inconsistency detected, last used block not followed by new blocks!") 351 | logging.warning("Using new blocks as reference!") 352 | self.endblock = endblock_new 353 | 354 | 355 | def main(): 356 | """ No options, just call with dflash_filename and ee_filename...""" 357 | 358 | logging.getLogger().setLevel(logging.INFO) 359 | 360 | if len(sys.argv) != 3: 361 | print "Usage: %s " % sys.argv[0] 362 | sys.exit(1) 363 | 364 | converter = DFlashConverter() 365 | converter.convert(sys.argv[1], sys.argv[2]) 366 | 367 | if __name__ == "__main__": 368 | main() 369 | -------------------------------------------------------------------------------- /gui.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | # -*- coding: utf-8 -*- 3 | # 4 | # Copyright 2017-2018, Ben van Leeuwen Autotechniek, https://www.benvanleeuwen.com/ 5 | # 6 | # Redistribution and use in source and binary forms, with or without 7 | # modification, are permitted provided that the following conditions 8 | # are met: 9 | # 10 | # 1. Redistributions of source code must retain the above copyright 11 | # notice, this list of conditions and the following disclaimer. 12 | # 13 | # 2. Redistributions in binary form must reproduce the above copyright 14 | # notice, this list of conditions and the following disclaimer in 15 | # the documentation and/or other materials provided with the 16 | # distribution. 17 | # 18 | # 3. Neither the name of the copyright holder nor the names of its 19 | # contributors may be used to endorse or promote products derived 20 | # from this software without specific prior written permission. 21 | # 22 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 24 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 25 | # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 26 | # HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 27 | # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 28 | # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 29 | # OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 30 | # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 | # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY 32 | # WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33 | # POSSIBILITY OF SUCH DAMAGE. 34 | # 35 | import sys 36 | from dflash_to_eee import DFlashConverter 37 | import Tkinter, tkFileDialog, tkMessageBox 38 | 39 | USER_NOTES = """ 40 | NOTE: Ensure you write to EEE partition and not back to D-Flash! 41 | 42 | NOTE: Always verify after writing the image to the device!""" 43 | 44 | 45 | def main(): 46 | converter = DFlashConverter() 47 | 48 | root = Tkinter.Tk() 49 | root.withdraw() 50 | 51 | source_path = tkFileDialog.askopenfilename() 52 | try: 53 | converter._read_file(source_path) 54 | except Exception as error: 55 | tkMessageBox.showerror(title="Error reading file", message=str(error)) 56 | return -1 57 | 58 | try: 59 | converter._find_endblock() 60 | except Exception as error: 61 | tkMessageBox.showerror(title="Error converting file", message=str(error)) 62 | return -1 63 | 64 | dest_path = tkFileDialog.asksaveasfilename() 65 | try: 66 | converter._save_file(dest_path) 67 | except Exception as error: 68 | tkMessageBox.showerror(title="Error saving file", message=str(error)) 69 | return -1 70 | 71 | tkMessageBox.showinfo(title="Conversion complete", message=converter._get_info()) 72 | 73 | tkMessageBox.showwarning(title="Warning", message=USER_NOTES) 74 | 75 | if __name__ == "__main__": 76 | sys.exit(main()) 77 | -------------------------------------------------------------------------------- /webserver/convert.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | FRM3 D-Flash to EEPROM converter 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | Something went wrong, please go back to the main page

"; 18 | } 19 | else { 20 | if($_POST["storeagreed"] != "yes") { 21 | echo "

You can only use this tool if you agree to store the file on our servers.

"; 22 | } 23 | else { 24 | $size = $_FILES["dflashimage"]["size"]; 25 | if($size != $required_size) { 26 | echo "

Uploaded file is not the correct size! Please double check that you saved the complete D-Flash image

"; 27 | } 28 | else { 29 | /* The checks we can do in PHP seems to be passed. Save the file under its sha1sum and then execute the python script */ 30 | $sha1 = sha1_file($_FILES["dflashimage"]["tmp_name"]); 31 | $target = $target_path . "/" . $sha1 . ".bin"; 32 | $logfile = $logfile_path . "/" . $sha1 . ".txt"; 33 | if (!move_uploaded_file($_FILES["dflashimage"]["tmp_name"], $target)) { 34 | echo "

Error moving file to target. Please contact the administrator

"; 35 | } 36 | else { 37 | // Also use the sha1 of the source for the eeprom file, since we can't know that beforehand. 38 | $eepromfile = $result_path . "/" . $sha1 . ".bin"; 39 | 40 | $descriptorspec = array( 41 | 0 => array("pipe", "r"), // stdin 42 | 1 => array("pipe", "w"), // stdout 43 | 2 => array("pipe", "w"), // stderr 44 | ); 45 | $process = proc_open('../dflash_to_eee.py ' . $target . ' ' . $eepromfile, $descriptorspec, $pipes); 46 | 47 | $stdout = stream_get_contents($pipes[1]); 48 | fclose($pipes[1]); 49 | 50 | $stderr = stream_get_contents($pipes[2]); 51 | fclose($pipes[2]); 52 | 53 | $logfp = fopen($logfile, "w"); 54 | fwrite($logfp, $stdout); 55 | fwrite($logfp, $stderr); 56 | fclose($logfp); 57 | 58 | echo "

Conversion complete.

"; 59 | 60 | echo "

Logfile:

"; 61 | echo "
";
62 |                     echo($stdout);
63 |                     echo($stderr);
64 |                     echo "
"; 65 | 66 | echo "

Before downloading, ensure that the VIN is correct.

"; 67 | 68 | echo "

Download EEPROM image

"; 69 | 70 | echo "

Note: Ensure you write to EEE partition and not back to D-Flash!

"; 71 | echo "

Note: Always verify after writing the image to the device!

"; 72 | } 73 | } 74 | } 75 | } 76 | ?> 77 |

Source code

78 |

Offline version

79 |
80 | 81 | -------------------------------------------------------------------------------- /webserver/download.php: -------------------------------------------------------------------------------- 1 | 29 | -------------------------------------------------------------------------------- /webserver/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | FRM3 D-Flash to EEPROM converter 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 |

FRM3 D-Flash to EEPROM converter

14 |

Here you can simply upload your D-Flash image to have it converted to an Eeprom image for the FRM3.
15 | If you have no idea why you would need this, you don't need this.

16 |

This website stores all uploaded files for analysis. Note that the dump will contain the VIN number 17 | of your car, as well as mileage information and other data. The file is only saved with the intention 18 | to improve the conversion tool.

19 |
20 | Select the D-flash file to upload: 21 |
22 |
23 | 24 |
25 | 26 |

Source code

27 |

Offline version

28 |
29 | 30 | -------------------------------------------------------------------------------- /webserver/settings.php: -------------------------------------------------------------------------------- 1 | 7 | --------------------------------------------------------------------------------