diff --git a/.gitignore b/.gitignore index ca2f32a4a..1f868f724 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ *.log *.elf *.ihex +*.pyc obj_* symbols.* Makefile.target diff --git a/cpu/stm32w108/Makefile.stm32w108 b/cpu/stm32w108/Makefile.stm32w108 index 8c12ab882..9c7788134 100644 --- a/cpu/stm32w108/Makefile.stm32w108 +++ b/cpu/stm32w108/Makefile.stm32w108 @@ -168,7 +168,7 @@ endif -FLASHER = sudo $(CONTIKI)/tools/stm32w/stm32w_flasher/stm32w_flasher +FLASHER = sudo $(CONTIKI)/tools/stm32w/stm32w_flasher/py_files/stm32w_flasher.py # Check if we are running under Windows ifeq ($(HOST_OS),Windows) @@ -257,9 +257,7 @@ endif #IAR MOTELIST = $(CONTIKI)/tools/stm32w/motelist-linux -MOTES = $(shell $(MOTELIST) 2>&- | grep USB | \ - cut -f 4 -d \ | \ - perl -ne 'print $$1 . " " if(m-(/dev/\w+)-);') +MOTES = $(shell $(MOTELIST) 2>&- | awk '{print $$2}' | grep '\/') motelist: stm-motelist diff --git a/platform/mbxxx/Makefile.mbxxx b/platform/mbxxx/Makefile.mbxxx index 6925a231f..1a35c6d9a 100644 --- a/platform/mbxxx/Makefile.mbxxx +++ b/platform/mbxxx/Makefile.mbxxx @@ -22,7 +22,3 @@ ifeq ($(HOST_OS),Windows) SERIALDUMP = $(CONTIKI)/tools/stm32w/serialdump-windows endif - - -login: - $(SERIALDUMP) -b115200 -d10000 $(PORT) diff --git a/tools/stm32w/motelist-linux b/tools/stm32w/motelist-linux index 5a6be5f53..2181b8467 100755 --- a/tools/stm32w/motelist-linux +++ b/tools/stm32w/motelist-linux @@ -24,7 +24,9 @@ my %Opt = ( usb => 0, method => "auto", kernel => "auto", - dev_prefix => [ "/dev/usb/tts/", "/dev/ttyUSB", "/dev/tts/USB" ], + usb_dev_prefix => [ "/dev/usb/tts/", "/dev/ttyUSB", "/dev/tts/USB" ], + acm_dev_prefix => [ "/dev/ttyACM" ], + dev_prefix => undef, usbserial => "sudo cat /proc/tty/driver/usbserial |", ); @@ -61,7 +63,8 @@ sub scan_sysfs { # Scan /sys/bus/usb/drivers/usb for FTDI devices my @ftdidevs = - grep { ($_->{UsbVendor}||"") eq "0403" && ($_->{UsbProduct}||"") eq "6001" && ($_->{UsbBcdDevice}||"") eq "0600"} + grep { (($_->{UsbVendor}||"") eq "0403" && ($_->{UsbProduct}||"") eq "6001" && ($_->{UsbBcdDevice}||"") eq "0600") || + (($_->{UsbVendor}||"") eq "0483" && ($_->{UsbProduct}||"") eq "5741")} map { { SysPath => $_, UsbVendor => snarf("$_/idVendor",1), @@ -90,9 +93,19 @@ sub scan_sysfs { my $port = "$syspath/$f->{SysDev}:1.0"; ($f->{DriverName} = readlink("$port/driver")) =~ s{^.*/}{} if -l "$port/driver"; - ($f->{SerialDevName} = (glob("$port/tty*"),undef)[0]) =~ s{^.*/}{}; + ($f->{SerialDevName} = (glob("$port/tty/tty* $port/tty*"),undef)[0]) =~ s{^.*/}{}; $f->{SerialDevNum} = $1 if $f->{SerialDevName} =~ /(\d+)/; - $f->{SerialDevName} = getSerialDevName( $f->{SerialDevNum} ) || " (none)"; + my $dev_prefix = $Opt{dev_prefix}; + if (not defined $dev_prefix) + { + if ( $f->{SerialDevName} =~ ".*ACM.*" ) { + $dev_prefix = $Opt{acm_dev_prefix} + } + else { + $dev_prefix = $Opt{usb_dev_prefix} + } + } + $f->{SerialDevName} = getSerialDevName($dev_prefix, $f->{SerialDevNum} ) || " (none)"; } return @ftdidevs; @@ -115,6 +128,12 @@ sub scan_procfs { $usbtree{usbkey($tts->{path})}{usbserial} = $tts if defined $tts->{path}; } + my $dev_prefix = $Opt{dev_prefix}; + if (not defined $dev_prefix) + { + $dev_prefix = $Opt{usb_dev_prefix} + } + my @ftdidevs = map { { UsbVendor => $_->{Vendor}, UsbProduct => $_->{ProdID}, @@ -127,7 +146,7 @@ sub scan_procfs { UsbPath => (($Opt{kernel} eq "2.4") ? $_->{usbserial}{path} : $_->{usbpath}), DriverName => $_->{driver}, SerialDevNum => $_->{usbserial}{tts}, - SerialDevName => getSerialDevName($_->{usbserial}{tts}) || " (none)", + SerialDevName => getSerialDevName($dev_prefix, $_->{usbserial}{tts}) || " (none)", } } grep { ($_->{Vendor}||"") eq "0403" && ($_->{ProdID}||"") eq "6001" && ($_->{BcdDevice}||"") eq "0600"} values %usbtree; @@ -194,17 +213,18 @@ sub usbkey { # first one that actually exists. # sub getSerialDevName { + my $dev_prefix = shift; my $devnum = shift; my $devname = undef; if( defined $devnum ) { - if( ref($Opt{dev_prefix}) eq "ARRAY" ) { + if( ref($dev_prefix) eq "ARRAY" ) { $devname = $devnum; - for my $prefix (@{$Opt{dev_prefix}}) { + for my $prefix (@{$dev_prefix}) { my $file = $prefix . $devnum; if( -e $file ) { $devname = $file; last; } } } else { - $devname = $Opt{dev_prefix} . $devnum; + $devname = $dev_prefix . $devnum; } } return $devname; diff --git a/tools/stm32w/stm32w_flasher/py_files/file_utils.py b/tools/stm32w/stm32w_flasher/py_files/file_utils.py new file mode 100644 index 000000000..174d8a0b1 --- /dev/null +++ b/tools/stm32w/stm32w_flasher/py_files/file_utils.py @@ -0,0 +1,83 @@ + +# See comment in stm32w_flasher.py. +# Extraction and little adaptation performed by E.Duble (CNRS, LIG). + +import struct + + +class Error(Exception): + """Base class for exceptions in this module.""" + args = None + message = None + +class FileFormatError(Error): + """ + Exception raised for errors in the file format + + Attributes: + filename -- filename with unknown format + message -- format error message + + """ + args = None + message = None + def __init__(self, filename, message): + self.filename = filename + self.message = message + + +class fileFormatReader(object): + def __init__(self, filename, startAddress=None): + self.filename = filename + self.startAddress = startAddress + + def getRawBinary(self): + fileContent = None + bytes = None + f = open(self.filename, 'rb') + if self.filename[-4:] == '.bin': + bytesRaw = f.read() + bytes = [] + bytes.extend(struct.unpack(('B' * len(bytesRaw)), bytesRaw)) + f.close() + else: + if self.filename[-4:] == '.s37': + fillChar = 255 + fileContent = f.readlines() + f.close() + startAddress = None + currentAddress = None + bytes = [] + for line in fileContent: + if line[:2] == 'S3': + count = int(line[2:4], 16) + if startAddress is None: + startAddress = int(line[4:12], 16) + currentAddress = startAddress + address = int(line[4:12], 16) + if currentAddress < address: + bytes = (bytes + ([fillChar] * (address - currentAddress))) + currentAddress = address + else: + if currentAddress > address: + raise FileFormatError(self.filename, 'S37, Non progressing addresses detected') + for i in range((count - 5)): + bytes = (bytes + [int(line[(12 + (i * 2)):((12 + (i * 2)) + 2)], 16)]) + continue + currentAddress = (currentAddress + (count - 5)) + continue + else: + if line[:2] == 'S0': + continue + else: + if line[:2] == 'S7': + break + else: + raise FileFormatError(self.filename, 'S37: unknown field type') + self.startAddress = startAddress + else: + raise FileFormatError(self.filename, 'Unknown extension') + return (self.startAddress, bytes) + + + diff --git a/tools/stm32w/stm32w_flasher/py_files/messages.py b/tools/stm32w/stm32w_flasher/py_files/messages.py new file mode 100644 index 000000000..d1bd0e03e --- /dev/null +++ b/tools/stm32w/stm32w_flasher/py_files/messages.py @@ -0,0 +1,25 @@ + +# See comment in stm32w_flasher.py. +# Extraction and little adaptation performed by E.Duble (CNRS, LIG). + +import sys + + +def errorMessage(msg, header=True): + if header: + sys.stderr.write('ERROR: ') + sys.stderr.write(msg) + sys.stderr.flush() + +def infoMessage(msg, header=True): + if header: + sys.stdout.write('INFO: ') + sys.stdout.write(msg) + sys.stdout.flush() + +def warningMessage(msg, header=True): + if header: + sys.stderr.write('WARNING: ') + sys.stderr.write(msg) + sys.stderr.flush() + diff --git a/tools/stm32w/stm32w_flasher/py_files/prodeng.py b/tools/stm32w/stm32w_flasher/py_files/prodeng.py new file mode 100644 index 000000000..2004cefa8 --- /dev/null +++ b/tools/stm32w/stm32w_flasher/py_files/prodeng.py @@ -0,0 +1,287 @@ + +# See comment in stm32w_flasher.py. +# Extraction and little adaptation performed by E.Duble (CNRS, LIG). + +ASCII = 2 +ASCII_REVERSED = 19 +AUTO_U16_CHECKSUM = 15 +AUTO_U16_CRC = 16 +BOOTLOADER_CODE = 20 +CIB_Mapping = None +DATE = 1 +DIE_ID = 18 +DIE_REV = 5 +EUI64 = 10 +FIB_Mapping = None +FIB_VERSION = 12 +FLASH_SIZE = 21 +FPEC_TIMING = 14 +MANUFACTURER_INFO = 17 +PART_NUMBER = 6 +PART_SUFFIX = 7 +RAM_SIZE = 13 +READ_PROTECTION = 22 +STACK_TYPE = 8 +TEST_PROGRAM_INFO = 9 +U16 = 0 +U8 = 4 +VOLTAGE = 11 +WRITE_PROTECTION = 23 +X_Y_TSMC = 3 +bootloader = {'cut 1.2v2': [0, 2, 0, 32, 21, 7, 4, 8, 125, 0, 4, 8, 125, 0, 4, 8, 167, 15, 2, 0, 0, 0, 0, 0, 0, 8, 4, 8, 0, 0, 0, 8, 0, 2, 0, 32, 169, 1, 4, 8, 141, 2, 4, 8, 95, 234, 0, 13, 112, 71, 79, 240, 0, 81, 8, 96, 223, 248, 188, 6, 68, 242, 68, 65, 1, 96, 0, 34, 130, 96, 223, 248, 184, 6, 1, 96, 223, 248, 180, 6, 66, 97, 130, 97, 130, 96, 2, 96, 223, 248, 160, 6, 2, 96, 66, 96, 98, 182, 112, 71, 128, 181, 255, 247, 228, 255, 2, 72, 2, 73, 1, 96, 1, 189, 0, 191, 12, 237, 0, 224, 4, 0, 250, 5, 0, 72, 241, 231, 21, 1, 15, 240, 8, 73, 8, 96, 200, 104, 16, 240, 4, 15, 251, 208, 200, 104, 16, 240, 64, 15, 251, 208, 112, 71, 3, 72, 193, 104, 17, 240, 2, 15, 251, 208, 0, 104, 112, 71, 60, 200, 0, 64, 248, 181, 5, 70, 12, 0, 67, 191, 0, 38, 32, 70, 68, 66, 38, 70, 0, 39, 255, 247, 236, 255, 120, 85, 70, 64, 127, 28, 188, 66, 248, 210, 255, 247, 229, 255, 134, 66, 4, 208, 31, 32, 255, 247, 213, 255, 0, 32, 242, 189, 96, 28, 242, 189, 128, 181, 0, 240, 96, 249, 111, 240, 2, 1, 0, 168, 255, 247, 221, 255, 4, 40, 2, 208, 79, 240, 255, 48, 2, 189, 0, 240, 84, 249, 0, 152, 0, 186, 2, 189, 0, 0, 223, 248, 252, 21, 136, 66, 4, 211, 176, 241, 32, 47, 1, 210, 2, 32, 112, 71, 176, 241, 0, 111, 4, 211, 9, 73, 136, 66, 1, 210, 4, 32, 112, 71, 158, 73, 136, 66, 4, 211, 6, 73, 136, 66, 6, 210, 8, 32, 112, 71, 5, 73, 136, 66, 1, 211, 16, 32, 112, 71, 1, 32, 112, 71, 0, 0, 2, 8, 0, 10, 4, 8, 0, 0, 4, 8, 9, 72, 10, 73, 1, 96, 10, 74, 2, 96, 65, 96, 66, 96, 16, 73, 1, 34, 10, 96, 74, 104, 18, 240, 1, 15, 251, 208, 129, 104, 17, 240, 1, 15, 251, 209, 112, 71, 0, 191, 4, 128, 0, 64, 35, 1, 103, 69, 171, 137, 239, 205, 6, 72, 65, 104, 17, 240, 2, 15, 251, 209, 0, 33, 1, 96, 2, 72, 128, 33, 1, 96, 112, 71, 0, 191, 16, 128, 0, 64, 44, 64, 0, 64, 45, 233, 248, 67, 128, 70, 12, 70, 21, 70, 0, 38, 71, 70, 0, 45, 88, 208, 8, 240, 1, 0, 5, 240, 1, 1, 8, 67, 1, 208, 1, 32, 15, 224, 64, 70, 255, 247, 156, 255, 129, 70, 5, 235, 8, 0, 64, 30, 255, 247, 150, 255, 64, 234, 9, 0, 4, 40, 4, 208, 8, 40, 2, 208, 2, 32, 189, 232, 242, 131, 255, 247, 177, 255, 0, 32, 106, 73, 1, 224, 191, 28, 128, 28, 168, 66, 50, 210, 59, 136, 2, 25, 82, 120, 16, 248, 4, 128, 8, 235, 2, 34, 146, 178, 147, 66, 241, 208, 79, 246, 255, 120, 67, 69, 1, 208, 19, 0, 33, 209, 96, 75, 159, 66, 5, 211, 24, 75, 159, 66, 2, 210, 79, 244, 4, 115, 1, 224, 64, 242, 1, 35, 75, 96, 58, 128, 10, 104, 18, 240, 1, 15, 251, 209, 32, 34, 10, 96, 10, 104, 18, 240, 20, 15, 212, 208, 8, 104, 16, 240, 16, 15, 20, 191, 4, 38, 5, 38, 16, 32, 8, 96, 4, 32, 8, 96, 0, 224, 6, 38, 255, 247, 143, 255, 11, 224, 0, 32, 0, 224, 64, 28, 152, 66, 6, 210, 23, 248, 1, 27, 2, 93, 145, 66, 247, 208, 7, 32, 178, 231, 48, 70, 176, 231, 16, 8, 4, 8, 45, 233, 248, 67, 4, 70, 8, 70, 0, 39, 129, 10, 141, 2, 225, 178, 1, 41, 42, 209, 4, 38, 79, 240, 0, 104, 79, 244, 0, 73, 20, 244, 128, 127, 27, 208, 255, 247, 80, 255, 58, 72, 70, 96, 225, 178, 2, 41, 0, 209, 133, 96, 70, 240, 64, 1, 65, 96, 1, 104, 17, 240, 1, 15, 251, 209, 32, 33, 1, 96, 1, 104, 17, 240, 16, 15, 2, 208, 16, 33, 1, 96, 4, 39, 255, 247, 82, 255, 0, 47, 41, 209, 20, 244, 0, 127, 38, 208, 0, 32, 79, 240, 255, 50, 26, 224, 2, 41, 10, 209, 255, 247, 5, 255, 4, 40, 1, 208, 2, 32, 15, 224, 2, 38, 168, 70, 79, 244, 128, 121, 204, 231, 224, 178, 3, 40, 6, 209, 79, 244, 8, 118, 223, 248, 136, 128, 79, 240, 128, 9, 194, 231, 3, 32, 189, 232, 242, 131, 64, 28, 72, 69, 5, 210, 88, 248, 4, 27, 145, 66, 248, 208, 7, 32, 244, 231, 56, 70, 242, 231, 16, 181, 130, 176, 4, 70, 0, 240, 47, 248, 28, 177, 0, 32, 141, 248, 0, 0, 18, 224, 165, 32, 141, 248, 0, 0, 255, 247, 251, 254, 16, 76, 79, 244, 4, 112, 96, 96, 15, 72, 165, 33, 1, 128, 0, 33, 64, 242, 3, 16, 255, 247, 139, 255, 4, 32, 32, 96, 157, 248, 0, 0, 192, 67, 141, 248, 1, 0, 2, 35, 2, 34, 0, 169, 6, 72, 255, 247, 12, 255, 0, 40, 12, 191, 121, 32, 31, 32, 255, 247, 116, 254, 19, 189, 0, 0, 12, 128, 0, 64, 0, 8, 4, 8, 121, 32, 107, 230, 45, 233, 240, 67, 195, 176, 193, 72, 0, 104, 193, 73, 136, 66, 2, 208, 192, 72, 255, 247, 81, 254, 205, 72, 1, 104, 33, 240, 240, 1, 65, 240, 128, 1, 1, 96, 129, 104, 65, 240, 32, 1, 129, 96, 200, 73, 2, 34, 10, 96, 185, 74, 83, 109, 67, 240, 1, 3, 83, 101, 19, 104, 64, 242, 220, 85, 20, 104, 228, 26, 36, 3, 36, 11, 172, 66, 249, 211, 0, 35, 83, 101, 10, 104, 66, 240, 1, 2, 10, 96, 64, 104, 16, 240, 32, 15, 2, 208, 174, 72, 255, 247, 40, 254, 186, 73, 8, 104, 32, 240, 240, 0, 64, 240, 144, 0, 8, 96, 170, 72, 32, 34, 2, 101, 79, 244, 128, 114, 130, 97, 100, 34, 130, 96, 1, 34, 2, 96, 138, 104, 18, 240, 4, 15, 251, 208, 16, 33, 1, 98, 163, 73, 10, 104, 18, 240, 4, 15, 251, 208, 4, 34, 10, 96, 10, 104, 18, 240, 4, 15, 251, 208, 129, 107, 140, 28, 0, 33, 1, 101, 129, 97, 129, 96, 1, 96, 1, 98, 229, 8, 93, 45, 2, 210, 153, 72, 255, 247, 248, 253, 163, 72, 69, 97, 161, 8, 1, 240, 1, 1, 129, 97, 2, 33, 129, 96, 1, 33, 1, 96, 255, 247, 142, 255, 146, 76, 223, 248, 120, 130, 13, 241, 8, 9, 8, 224, 22, 248, 9, 0, 240, 85, 118, 28, 174, 66, 249, 211, 121, 32, 255, 247, 237, 253, 255, 247, 246, 253, 7, 70, 255, 247, 243, 253, 120, 64, 255, 40, 0, 208, 255, 39, 135, 72, 0, 104, 16, 240, 2, 15, 3, 208, 17, 47, 1, 211, 131, 47, 22, 211, 56, 0, 21, 208, 1, 47, 19, 208, 2, 47, 17, 208, 17, 47, 28, 208, 33, 47, 56, 208, 49, 47, 84, 208, 67, 47, 116, 208, 99, 47, 0, 240, 163, 128, 130, 47, 0, 240, 206, 128, 146, 47, 0, 240, 207, 128, 218, 224, 255, 247, 83, 255, 62, 93, 3, 224, 48, 93, 255, 247, 188, 253, 118, 28, 56, 25, 64, 120, 134, 66, 247, 211, 197, 231, 255, 247, 227, 253, 7, 70, 255, 247, 243, 253, 5, 70, 255, 247, 185, 253, 6, 70, 255, 247, 182, 253, 112, 64, 255, 40, 13, 209, 1, 45, 11, 208, 255, 247, 54, 255, 117, 28, 0, 38, 174, 66, 178, 210, 23, 248, 1, 11, 255, 247, 156, 253, 118, 28, 247, 231, 31, 32, 168, 231, 255, 247, 197, 253, 7, 70, 255, 247, 213, 253, 16, 47, 6, 210, 255, 247, 33, 255, 94, 72, 192, 25, 255, 247, 123, 253, 156, 231, 16, 240, 6, 15, 236, 208, 125, 104, 255, 247, 22, 255, 89, 72, 255, 247, 88, 253, 89, 72, 7, 96, 56, 104, 255, 247, 80, 253, 168, 71, 140, 231, 255, 247, 167, 253, 7, 70, 255, 247, 183, 253, 6, 70, 255, 247, 125, 253, 0, 240, 180, 248, 5, 70, 165, 177, 120, 25, 64, 30, 255, 247, 172, 253, 48, 67, 2, 40, 1, 209, 0, 38, 114, 231, 22, 240, 12, 15, 199, 208, 43, 70, 42, 70, 2, 169, 56, 70, 255, 247, 238, 253, 0, 40, 63, 244, 105, 175, 189, 231, 255, 247, 232, 254, 31, 37, 255, 247, 94, 253, 7, 70, 254, 47, 16, 211, 12, 191, 64, 242, 3, 54, 64, 242, 1, 54, 255, 247, 84, 253, 120, 64, 255, 40, 28, 209, 0, 33, 48, 70, 255, 247, 70, 254, 184, 185, 121, 37, 21, 224, 57, 70, 0, 240, 130, 248, 7, 0, 16, 208, 121, 37, 0, 38, 22, 248, 9, 0, 128, 2, 0, 241, 0, 97, 64, 242, 2, 48, 255, 247, 51, 254, 8, 177, 31, 37, 2, 224, 118, 28, 190, 66, 240, 211, 40, 70, 55, 231, 255, 247, 183, 254, 255, 247, 46, 253, 0, 240, 101, 248, 0, 40, 40, 208, 0, 33, 0, 38, 1, 35, 22, 248, 9, 32, 32, 42, 5, 210, 3, 250, 2, 242, 17, 67, 118, 28, 134, 66, 245, 211, 134, 66, 21, 211, 0, 38, 176, 0, 33, 250, 0, 240, 192, 178, 0, 170, 195, 67, 179, 84, 178, 24, 80, 112, 182, 28, 8, 46, 243, 211, 8, 35, 8, 34, 0, 169, 25, 72, 255, 247, 143, 253, 0, 40, 63, 244, 10, 175, 94, 231, 1, 32, 255, 247, 84, 254, 7, 231, 64, 70, 2, 224, 0, 33, 64, 248, 4, 27, 18, 73, 136, 66, 249, 211, 0, 32, 255, 247, 72, 254, 16, 72, 90, 231, 31, 32, 246, 230, 150, 7, 4, 8, 1, 0, 2, 0, 20, 1, 15, 240, 56, 32, 0, 64, 19, 1, 15, 240, 0, 240, 0, 64, 4, 168, 0, 64, 17, 1, 15, 240, 60, 7, 4, 8, 28, 128, 0, 64, 0, 1, 15, 240, 16, 1, 15, 240, 8, 237, 0, 224, 8, 8, 4, 8, 255, 31, 0, 32, 18, 1, 15, 240, 4, 176, 0, 64, 28, 64, 0, 64, 0, 180, 0, 64, 84, 200, 0, 64, 0, 2, 0, 32, 1, 70, 0, 191, 2, 168, 203, 228, 6, 72, 1, 33, 1, 96, 114, 182, 5, 72, 6, 73, 0, 34, 1, 224, 64, 248, 4, 43, 136, 66, 251, 211, 255, 247, 62, 190, 32, 64, 0, 64, 0, 0, 0, 32, 0, 2, 0, 32, 4, 16, 19, 22, 10, 2, 0, 1, 2, 17, 33, 49, 67, 99, 130, 146, 2, 0, 0, 1, 9, 169, 0, 0], 'cut 1.2v3': [0, 2, 0, 32, 21, 7, 4, 8, 125, 0, 4, 8, 125, 0, 4, 8, 167, 15, 3, 0, 0, 0, 0, 0, 0, 8, 4, 8, 0, 0, 0, 8, 0, 2, 0, 32, 169, 1, 4, 8, 141, 2, 4, 8, 95, 234, 0, 13, 112, 71, 79, 240, 0, 81, 8, 96, 223, 248, 188, 6, 68, 242, 68, 65, 1, 96, 0, 34, 130, 96, 223, 248, 184, 6, 1, 96, 223, 248, 180, 6, 66, 97, 130, 97, 130, 96, 2, 96, 223, 248, 160, 6, 2, 96, 66, 96, 98, 182, 112, 71, 128, 181, 255, 247, 228, 255, 2, 72, 2, 73, 1, 96, 1, 189, 0, 191, 12, 237, 0, 224, 4, 0, 250, 5, 0, 72, 241, 231, 21, 1, 15, 240, 8, 73, 8, 96, 200, 104, 16, 240, 4, 15, 251, 208, 200, 104, 16, 240, 64, 15, 251, 208, 112, 71, 3, 72, 193, 104, 17, 240, 2, 15, 251, 208, 0, 104, 112, 71, 60, 200, 0, 64, 248, 181, 5, 70, 12, 0, 67, 191, 0, 38, 32, 70, 68, 66, 38, 70, 0, 39, 255, 247, 236, 255, 120, 85, 70, 64, 127, 28, 188, 66, 248, 210, 255, 247, 229, 255, 134, 66, 4, 208, 31, 32, 255, 247, 213, 255, 0, 32, 242, 189, 96, 28, 242, 189, 128, 181, 0, 240, 96, 249, 111, 240, 2, 1, 0, 168, 255, 247, 221, 255, 4, 40, 2, 208, 79, 240, 255, 48, 2, 189, 0, 240, 84, 249, 0, 152, 0, 186, 2, 189, 0, 0, 223, 248, 252, 21, 136, 66, 4, 211, 176, 241, 32, 47, 1, 210, 2, 32, 112, 71, 176, 241, 0, 111, 4, 211, 9, 73, 136, 66, 1, 210, 4, 32, 112, 71, 158, 73, 136, 66, 4, 211, 6, 73, 136, 66, 6, 210, 8, 32, 112, 71, 5, 73, 136, 66, 1, 211, 16, 32, 112, 71, 1, 32, 112, 71, 0, 0, 2, 8, 0, 10, 4, 8, 0, 0, 4, 8, 9, 72, 10, 73, 1, 96, 10, 74, 2, 96, 65, 96, 66, 96, 16, 73, 1, 34, 10, 96, 74, 104, 18, 240, 1, 15, 251, 208, 129, 104, 17, 240, 1, 15, 251, 209, 112, 71, 0, 191, 4, 128, 0, 64, 35, 1, 103, 69, 171, 137, 239, 205, 6, 72, 65, 104, 17, 240, 2, 15, 251, 209, 0, 33, 1, 96, 2, 72, 128, 33, 1, 96, 112, 71, 0, 191, 16, 128, 0, 64, 44, 64, 0, 64, 45, 233, 248, 67, 128, 70, 12, 70, 21, 70, 0, 38, 71, 70, 0, 45, 88, 208, 8, 240, 1, 0, 5, 240, 1, 1, 8, 67, 1, 208, 1, 32, 15, 224, 64, 70, 255, 247, 156, 255, 129, 70, 5, 235, 8, 0, 64, 30, 255, 247, 150, 255, 64, 234, 9, 0, 4, 40, 4, 208, 8, 40, 2, 208, 2, 32, 189, 232, 242, 131, 255, 247, 177, 255, 0, 32, 106, 73, 1, 224, 191, 28, 128, 28, 168, 66, 50, 210, 59, 136, 2, 25, 82, 120, 16, 248, 4, 128, 8, 235, 2, 34, 146, 178, 147, 66, 241, 208, 79, 246, 255, 120, 67, 69, 1, 208, 19, 0, 33, 209, 96, 75, 159, 66, 5, 211, 24, 75, 159, 66, 2, 210, 79, 244, 4, 115, 1, 224, 64, 242, 1, 35, 75, 96, 58, 128, 10, 104, 18, 240, 1, 15, 251, 209, 32, 34, 10, 96, 10, 104, 18, 240, 20, 15, 212, 208, 8, 104, 16, 240, 16, 15, 20, 191, 4, 38, 5, 38, 16, 32, 8, 96, 4, 32, 8, 96, 0, 224, 6, 38, 255, 247, 143, 255, 11, 224, 0, 32, 0, 224, 64, 28, 152, 66, 6, 210, 23, 248, 1, 27, 2, 93, 145, 66, 247, 208, 7, 32, 178, 231, 48, 70, 176, 231, 16, 8, 4, 8, 45, 233, 248, 67, 4, 70, 8, 70, 0, 39, 129, 10, 141, 2, 225, 178, 1, 41, 42, 209, 4, 38, 79, 240, 0, 104, 79, 244, 0, 73, 20, 244, 128, 127, 27, 208, 255, 247, 80, 255, 58, 72, 70, 96, 225, 178, 2, 41, 0, 209, 133, 96, 70, 240, 64, 1, 65, 96, 1, 104, 17, 240, 1, 15, 251, 209, 32, 33, 1, 96, 1, 104, 17, 240, 16, 15, 2, 208, 16, 33, 1, 96, 4, 39, 255, 247, 82, 255, 0, 47, 41, 209, 20, 244, 0, 127, 38, 208, 0, 32, 79, 240, 255, 50, 26, 224, 2, 41, 10, 209, 255, 247, 5, 255, 4, 40, 1, 208, 2, 32, 15, 224, 2, 38, 168, 70, 79, 244, 128, 121, 204, 231, 224, 178, 3, 40, 6, 209, 79, 244, 8, 118, 223, 248, 136, 128, 79, 240, 128, 9, 194, 231, 3, 32, 189, 232, 242, 131, 64, 28, 72, 69, 5, 210, 88, 248, 4, 27, 145, 66, 248, 208, 7, 32, 244, 231, 56, 70, 242, 231, 16, 181, 130, 176, 4, 70, 0, 240, 47, 248, 28, 177, 0, 32, 141, 248, 0, 0, 18, 224, 165, 32, 141, 248, 0, 0, 255, 247, 251, 254, 16, 76, 79, 244, 4, 112, 96, 96, 15, 72, 165, 33, 1, 128, 0, 33, 64, 242, 3, 16, 255, 247, 139, 255, 4, 32, 32, 96, 157, 248, 0, 0, 192, 67, 141, 248, 1, 0, 2, 35, 2, 34, 0, 169, 6, 72, 255, 247, 12, 255, 0, 40, 12, 191, 121, 32, 31, 32, 255, 247, 116, 254, 19, 189, 0, 0, 12, 128, 0, 64, 0, 8, 4, 8, 121, 32, 107, 230, 45, 233, 240, 67, 195, 176, 193, 72, 0, 104, 193, 73, 136, 66, 2, 208, 192, 72, 255, 247, 81, 254, 205, 72, 1, 104, 33, 240, 240, 1, 65, 240, 128, 1, 1, 96, 129, 104, 65, 240, 32, 1, 129, 96, 200, 73, 2, 34, 10, 96, 185, 74, 83, 109, 67, 240, 1, 3, 83, 101, 19, 104, 64, 242, 220, 85, 20, 104, 228, 26, 36, 3, 36, 11, 172, 66, 249, 211, 0, 35, 83, 101, 10, 104, 66, 240, 1, 2, 10, 96, 64, 104, 16, 240, 32, 15, 2, 208, 174, 72, 255, 247, 40, 254, 186, 73, 8, 104, 32, 240, 240, 0, 64, 240, 144, 0, 8, 96, 170, 72, 32, 34, 2, 101, 79, 244, 128, 114, 130, 97, 100, 34, 130, 96, 1, 34, 2, 96, 138, 104, 18, 240, 4, 15, 251, 208, 16, 33, 1, 98, 163, 73, 10, 104, 18, 240, 4, 15, 251, 208, 4, 34, 10, 96, 10, 104, 18, 240, 4, 15, 251, 208, 129, 107, 140, 28, 0, 33, 1, 101, 129, 97, 129, 96, 1, 96, 1, 98, 229, 8, 93, 45, 2, 210, 153, 72, 255, 247, 248, 253, 163, 72, 69, 97, 161, 8, 1, 240, 1, 1, 129, 97, 2, 33, 129, 96, 1, 33, 1, 96, 255, 247, 142, 255, 146, 76, 223, 248, 120, 130, 13, 241, 8, 9, 8, 224, 22, 248, 9, 0, 240, 85, 118, 28, 174, 66, 249, 211, 121, 32, 255, 247, 237, 253, 255, 247, 246, 253, 7, 70, 255, 247, 243, 253, 120, 64, 255, 40, 0, 208, 255, 39, 135, 72, 0, 104, 16, 240, 2, 15, 3, 208, 17, 47, 1, 211, 131, 47, 22, 211, 56, 0, 21, 208, 1, 47, 19, 208, 2, 47, 17, 208, 17, 47, 28, 208, 33, 47, 56, 208, 49, 47, 84, 208, 67, 47, 116, 208, 99, 47, 0, 240, 163, 128, 130, 47, 0, 240, 206, 128, 146, 47, 0, 240, 207, 128, 218, 224, 255, 247, 83, 255, 62, 93, 3, 224, 48, 93, 255, 247, 188, 253, 118, 28, 56, 25, 64, 120, 134, 66, 247, 211, 197, 231, 255, 247, 227, 253, 7, 70, 255, 247, 243, 253, 5, 70, 255, 247, 185, 253, 6, 70, 255, 247, 182, 253, 112, 64, 255, 40, 13, 209, 1, 45, 11, 208, 255, 247, 54, 255, 117, 28, 0, 38, 174, 66, 178, 210, 23, 248, 1, 11, 255, 247, 156, 253, 118, 28, 247, 231, 31, 32, 168, 231, 255, 247, 197, 253, 7, 70, 255, 247, 213, 253, 16, 47, 6, 210, 255, 247, 33, 255, 94, 72, 192, 25, 255, 247, 123, 253, 156, 231, 16, 240, 6, 15, 236, 208, 125, 104, 255, 247, 22, 255, 89, 72, 255, 247, 88, 253, 89, 72, 7, 96, 56, 104, 255, 247, 80, 253, 168, 71, 140, 231, 255, 247, 167, 253, 7, 70, 255, 247, 183, 253, 6, 70, 255, 247, 125, 253, 0, 240, 180, 248, 5, 70, 165, 177, 120, 25, 64, 30, 255, 247, 172, 253, 48, 67, 2, 40, 1, 209, 0, 38, 114, 231, 22, 240, 12, 15, 199, 208, 43, 70, 42, 70, 2, 169, 56, 70, 255, 247, 238, 253, 0, 40, 63, 244, 105, 175, 189, 231, 255, 247, 232, 254, 31, 37, 255, 247, 94, 253, 7, 70, 254, 47, 16, 211, 12, 191, 64, 242, 3, 54, 64, 242, 1, 54, 255, 247, 84, 253, 120, 64, 255, 40, 28, 209, 0, 33, 48, 70, 255, 247, 70, 254, 184, 185, 121, 37, 21, 224, 57, 70, 0, 240, 130, 248, 7, 0, 16, 208, 121, 37, 0, 38, 22, 248, 9, 0, 128, 2, 0, 241, 0, 97, 64, 242, 2, 48, 255, 247, 51, 254, 8, 177, 31, 37, 2, 224, 118, 28, 190, 66, 240, 211, 40, 70, 55, 231, 255, 247, 183, 254, 255, 247, 46, 253, 0, 240, 101, 248, 0, 40, 40, 208, 0, 33, 0, 38, 1, 35, 22, 248, 9, 32, 32, 42, 5, 210, 3, 250, 2, 242, 17, 67, 118, 28, 134, 66, 245, 211, 134, 66, 21, 211, 0, 38, 176, 0, 33, 250, 0, 240, 192, 178, 0, 170, 195, 67, 179, 84, 178, 24, 80, 112, 182, 28, 8, 46, 243, 211, 8, 35, 8, 34, 0, 169, 25, 72, 255, 247, 143, 253, 0, 40, 63, 244, 10, 175, 94, 231, 1, 32, 255, 247, 84, 254, 7, 231, 64, 70, 2, 224, 0, 33, 64, 248, 4, 27, 18, 73, 136, 66, 249, 211, 0, 32, 255, 247, 72, 254, 16, 72, 90, 231, 31, 32, 246, 230, 150, 7, 4, 8, 1, 0, 2, 0, 20, 1, 15, 240, 56, 32, 0, 64, 19, 1, 15, 240, 0, 240, 0, 64, 4, 168, 0, 64, 17, 1, 15, 240, 72, 7, 4, 8, 28, 128, 0, 64, 0, 1, 15, 240, 16, 1, 15, 240, 8, 237, 0, 224, 8, 8, 4, 8, 255, 31, 0, 32, 18, 1, 15, 240, 4, 176, 0, 64, 28, 64, 0, 64, 0, 180, 0, 64, 84, 200, 0, 64, 0, 2, 0, 32, 1, 70, 0, 191, 2, 168, 203, 228, 8, 72, 64, 242, 7, 49, 1, 96, 7, 72, 1, 33, 1, 96, 114, 182, 6, 72, 7, 73, 0, 34, 1, 224, 64, 248, 4, 43, 136, 66, 251, 211, 255, 247, 58, 190, 24, 0, 0, 64, 32, 64, 0, 64, 0, 0, 0, 32, 0, 2, 0, 32, 4, 16, 19, 22, 10, 3, 0, 1, 2, 17, 33, 49, 67, 99, 130, 146, 3, 0, 0, 1, 9, 168, 0, 0], 'cut 1.0v2': [0, 2, 0, 32, 17, 7, 4, 8, 125, 0, 4, 8, 125, 0, 4, 8, 167, 15, 2, 0, 0, 0, 0, 0, 0, 8, 4, 8, 0, 0, 0, 8, 0, 2, 0, 32, 169, 1, 4, 8, 141, 2, 4, 8, 95, 234, 0, 13, 112, 71, 79, 240, 0, 81, 8, 96, 223, 248, 184, 6, 68, 242, 68, 65, 1, 96, 0, 34, 130, 96, 223, 248, 180, 6, 1, 96, 223, 248, 176, 6, 66, 97, 130, 97, 130, 96, 2, 96, 223, 248, 156, 6, 2, 96, 66, 96, 98, 182, 112, 71, 128, 181, 255, 247, 228, 255, 2, 72, 2, 73, 1, 96, 1, 189, 0, 191, 12, 237, 0, 224, 4, 0, 250, 5, 0, 72, 241, 231, 21, 1, 15, 240, 8, 73, 8, 96, 200, 104, 16, 240, 4, 15, 251, 208, 200, 104, 16, 240, 64, 15, 251, 208, 112, 71, 3, 72, 193, 104, 17, 240, 2, 15, 251, 208, 0, 104, 112, 71, 60, 200, 0, 64, 248, 181, 5, 70, 12, 0, 67, 191, 0, 38, 32, 70, 68, 66, 38, 70, 0, 39, 255, 247, 236, 255, 120, 85, 70, 64, 127, 28, 188, 66, 248, 210, 255, 247, 229, 255, 134, 66, 4, 208, 31, 32, 255, 247, 213, 255, 0, 32, 242, 189, 96, 28, 242, 189, 128, 181, 0, 240, 96, 249, 111, 240, 2, 1, 0, 168, 255, 247, 221, 255, 4, 40, 2, 208, 79, 240, 255, 48, 2, 189, 0, 240, 84, 249, 0, 152, 0, 186, 2, 189, 0, 0, 223, 248, 248, 21, 136, 66, 4, 211, 176, 241, 32, 47, 1, 210, 2, 32, 112, 71, 176, 241, 0, 111, 4, 211, 9, 73, 136, 66, 1, 210, 4, 32, 112, 71, 158, 73, 136, 66, 4, 211, 6, 73, 136, 66, 6, 210, 8, 32, 112, 71, 5, 73, 136, 66, 1, 211, 16, 32, 112, 71, 1, 32, 112, 71, 0, 0, 2, 8, 0, 10, 4, 8, 0, 0, 4, 8, 9, 72, 10, 73, 1, 96, 10, 74, 2, 96, 65, 96, 66, 96, 16, 73, 1, 34, 10, 96, 74, 104, 18, 240, 1, 15, 251, 208, 129, 104, 17, 240, 1, 15, 251, 209, 112, 71, 0, 191, 4, 128, 0, 64, 35, 1, 103, 69, 171, 137, 239, 205, 6, 72, 65, 104, 17, 240, 2, 15, 251, 209, 0, 33, 1, 96, 2, 72, 128, 33, 1, 96, 112, 71, 0, 191, 16, 128, 0, 64, 44, 64, 0, 64, 45, 233, 248, 67, 128, 70, 12, 70, 21, 70, 0, 38, 71, 70, 0, 45, 88, 208, 8, 240, 1, 0, 5, 240, 1, 1, 8, 67, 1, 208, 1, 32, 15, 224, 64, 70, 255, 247, 156, 255, 129, 70, 5, 235, 8, 0, 64, 30, 255, 247, 150, 255, 64, 234, 9, 0, 4, 40, 4, 208, 8, 40, 2, 208, 2, 32, 189, 232, 242, 131, 255, 247, 177, 255, 0, 32, 106, 73, 1, 224, 191, 28, 128, 28, 168, 66, 50, 210, 59, 136, 2, 25, 82, 120, 16, 248, 4, 128, 8, 235, 2, 34, 146, 178, 147, 66, 241, 208, 79, 246, 255, 120, 67, 69, 1, 208, 19, 0, 33, 209, 96, 75, 159, 66, 5, 211, 24, 75, 159, 66, 2, 210, 79, 244, 4, 115, 1, 224, 64, 242, 1, 35, 75, 96, 58, 128, 10, 104, 18, 240, 1, 15, 251, 209, 32, 34, 10, 96, 10, 104, 18, 240, 20, 15, 212, 208, 8, 104, 16, 240, 16, 15, 20, 191, 4, 38, 5, 38, 16, 32, 8, 96, 4, 32, 8, 96, 0, 224, 6, 38, 255, 247, 143, 255, 11, 224, 0, 32, 0, 224, 64, 28, 152, 66, 6, 210, 23, 248, 1, 27, 2, 93, 145, 66, 247, 208, 7, 32, 178, 231, 48, 70, 176, 231, 16, 8, 4, 8, 45, 233, 248, 67, 4, 70, 8, 70, 0, 39, 129, 10, 141, 2, 225, 178, 1, 41, 42, 209, 4, 38, 79, 240, 0, 104, 79, 244, 0, 73, 20, 244, 128, 127, 27, 208, 255, 247, 80, 255, 58, 72, 70, 96, 225, 178, 2, 41, 0, 209, 133, 96, 70, 240, 64, 1, 65, 96, 1, 104, 17, 240, 1, 15, 251, 209, 32, 33, 1, 96, 1, 104, 17, 240, 16, 15, 2, 208, 16, 33, 1, 96, 4, 39, 255, 247, 82, 255, 0, 47, 41, 209, 20, 244, 0, 127, 38, 208, 0, 32, 79, 240, 255, 50, 26, 224, 2, 41, 10, 209, 255, 247, 5, 255, 4, 40, 1, 208, 2, 32, 15, 224, 2, 38, 168, 70, 79, 244, 128, 121, 204, 231, 224, 178, 3, 40, 6, 209, 79, 244, 8, 118, 223, 248, 136, 128, 79, 240, 128, 9, 194, 231, 3, 32, 189, 232, 242, 131, 64, 28, 72, 69, 5, 210, 88, 248, 4, 27, 145, 66, 248, 208, 7, 32, 244, 231, 56, 70, 242, 231, 16, 181, 130, 176, 4, 70, 0, 240, 47, 248, 28, 177, 0, 32, 141, 248, 0, 0, 18, 224, 165, 32, 141, 248, 0, 0, 255, 247, 251, 254, 16, 76, 79, 244, 4, 112, 96, 96, 15, 72, 165, 33, 1, 128, 0, 33, 64, 242, 3, 16, 255, 247, 139, 255, 4, 32, 32, 96, 157, 248, 0, 0, 192, 67, 141, 248, 1, 0, 2, 35, 2, 34, 0, 169, 6, 72, 255, 247, 12, 255, 0, 40, 12, 191, 121, 32, 31, 32, 255, 247, 116, 254, 19, 189, 0, 0, 12, 128, 0, 64, 0, 8, 4, 8, 121, 32, 107, 230, 45, 233, 240, 67, 195, 176, 193, 72, 0, 104, 1, 40, 2, 208, 192, 72, 255, 247, 82, 254, 204, 72, 1, 104, 33, 240, 240, 1, 65, 240, 128, 1, 1, 96, 129, 104, 65, 240, 32, 1, 129, 96, 200, 73, 2, 34, 10, 96, 184, 74, 83, 109, 67, 240, 1, 3, 83, 101, 19, 104, 64, 242, 220, 85, 20, 104, 228, 26, 36, 3, 36, 11, 172, 66, 249, 211, 0, 35, 83, 101, 10, 104, 66, 240, 1, 2, 10, 96, 64, 104, 16, 240, 32, 15, 2, 208, 173, 72, 255, 247, 41, 254, 186, 73, 8, 104, 32, 240, 240, 0, 64, 240, 144, 0, 8, 96, 169, 72, 32, 34, 2, 101, 79, 244, 128, 114, 130, 97, 100, 34, 130, 96, 1, 34, 2, 96, 138, 104, 18, 240, 4, 15, 251, 208, 16, 33, 1, 98, 162, 73, 10, 104, 18, 240, 4, 15, 251, 208, 4, 34, 10, 96, 10, 104, 18, 240, 4, 15, 251, 208, 129, 107, 140, 28, 0, 33, 1, 101, 129, 97, 129, 96, 1, 96, 1, 98, 229, 8, 93, 45, 2, 210, 152, 72, 255, 247, 249, 253, 163, 72, 69, 97, 161, 8, 1, 240, 1, 1, 129, 97, 2, 33, 129, 96, 1, 33, 1, 96, 255, 247, 143, 255, 146, 76, 223, 248, 116, 130, 13, 241, 8, 9, 8, 224, 22, 248, 9, 0, 240, 85, 118, 28, 174, 66, 249, 211, 121, 32, 255, 247, 238, 253, 255, 247, 247, 253, 7, 70, 255, 247, 244, 253, 120, 64, 255, 40, 0, 208, 255, 39, 135, 72, 0, 104, 16, 240, 2, 15, 3, 208, 17, 47, 1, 211, 131, 47, 22, 211, 56, 0, 21, 208, 1, 47, 19, 208, 2, 47, 17, 208, 17, 47, 28, 208, 33, 47, 56, 208, 49, 47, 84, 208, 67, 47, 116, 208, 99, 47, 0, 240, 163, 128, 130, 47, 0, 240, 206, 128, 146, 47, 0, 240, 207, 128, 218, 224, 255, 247, 84, 255, 62, 93, 3, 224, 48, 93, 255, 247, 189, 253, 118, 28, 56, 25, 64, 120, 134, 66, 247, 211, 197, 231, 255, 247, 228, 253, 7, 70, 255, 247, 244, 253, 5, 70, 255, 247, 186, 253, 6, 70, 255, 247, 183, 253, 112, 64, 255, 40, 13, 209, 1, 45, 11, 208, 255, 247, 55, 255, 117, 28, 0, 38, 174, 66, 178, 210, 23, 248, 1, 11, 255, 247, 157, 253, 118, 28, 247, 231, 31, 32, 168, 231, 255, 247, 198, 253, 7, 70, 255, 247, 214, 253, 16, 47, 6, 210, 255, 247, 34, 255, 93, 72, 192, 25, 255, 247, 124, 253, 156, 231, 16, 240, 6, 15, 236, 208, 125, 104, 255, 247, 23, 255, 89, 72, 255, 247, 89, 253, 88, 72, 7, 96, 56, 104, 255, 247, 81, 253, 168, 71, 140, 231, 255, 247, 168, 253, 7, 70, 255, 247, 184, 253, 6, 70, 255, 247, 126, 253, 0, 240, 179, 248, 5, 70, 165, 177, 120, 25, 64, 30, 255, 247, 173, 253, 48, 67, 2, 40, 1, 209, 0, 38, 114, 231, 22, 240, 12, 15, 199, 208, 43, 70, 42, 70, 2, 169, 56, 70, 255, 247, 239, 253, 0, 40, 63, 244, 105, 175, 189, 231, 255, 247, 233, 254, 31, 37, 255, 247, 95, 253, 7, 70, 254, 47, 16, 211, 12, 191, 64, 242, 3, 54, 64, 242, 1, 54, 255, 247, 85, 253, 120, 64, 255, 40, 28, 209, 0, 33, 48, 70, 255, 247, 71, 254, 184, 185, 121, 37, 21, 224, 57, 70, 0, 240, 129, 248, 7, 0, 16, 208, 121, 37, 0, 38, 22, 248, 9, 0, 128, 2, 0, 241, 0, 97, 64, 242, 2, 48, 255, 247, 52, 254, 8, 177, 31, 37, 2, 224, 118, 28, 190, 66, 240, 211, 40, 70, 55, 231, 255, 247, 184, 254, 255, 247, 47, 253, 0, 240, 100, 248, 0, 40, 40, 208, 0, 33, 0, 38, 1, 35, 22, 248, 9, 32, 32, 42, 5, 210, 3, 250, 2, 242, 17, 67, 118, 28, 134, 66, 245, 211, 134, 66, 21, 211, 0, 38, 176, 0, 33, 250, 0, 240, 192, 178, 0, 170, 195, 67, 179, 84, 178, 24, 80, 112, 182, 28, 8, 46, 243, 211, 8, 35, 8, 34, 0, 169, 25, 72, 255, 247, 144, 253, 0, 40, 63, 244, 10, 175, 94, 231, 1, 32, 255, 247, 85, 254, 7, 231, 64, 70, 2, 224, 0, 33, 64, 248, 4, 27, 18, 73, 136, 66, 249, 211, 0, 32, 255, 247, 73, 254, 16, 72, 90, 231, 31, 32, 246, 230, 0, 191, 150, 7, 4, 8, 20, 1, 15, 240, 56, 32, 0, 64, 19, 1, 15, 240, 0, 240, 0, 64, 4, 168, 0, 64, 17, 1, 15, 240, 56, 7, 4, 8, 28, 128, 0, 64, 0, 1, 15, 240, 16, 1, 15, 240, 8, 237, 0, 224, 8, 8, 4, 8, 255, 31, 0, 32, 18, 1, 15, 240, 4, 176, 0, 64, 28, 64, 0, 64, 0, 180, 0, 64, 84, 200, 0, 64, 0, 2, 0, 32, 1, 70, 0, 191, 2, 168, 205, 228, 6, 72, 1, 33, 1, 96, 114, 182, 5, 72, 6, 73, 0, 34, 1, 224, 64, 248, 4, 43, 136, 66, 251, 211, 255, 247, 64, 190, 32, 64, 0, 64, 0, 0, 0, 32, 0, 2, 0, 32, 4, 16, 19, 22, 10, 2, 0, 1, 2, 17, 33, 49, 67, 99, 130, 146, 2, 0, 0, 1, 9, 169, 0, 0], 'cut 1.3v3': [0, 2, 0, 32, 25, 7, 4, 8, 125, 0, 4, 8, 125, 0, 4, 8, 167, 15, 3, 0, 0, 0, 0, 0, 0, 8, 4, 8, 0, 0, 0, 8, 0, 2, 0, 32, 169, 1, 4, 8, 141, 2, 4, 8, 95, 234, 0, 13, 112, 71, 79, 240, 0, 81, 8, 96, 223, 248, 192, 6, 68, 242, 68, 65, 1, 96, 0, 34, 130, 96, 223, 248, 188, 6, 1, 96, 223, 248, 184, 6, 66, 97, 130, 97, 130, 96, 2, 96, 223, 248, 164, 6, 2, 96, 66, 96, 98, 182, 112, 71, 128, 181, 255, 247, 228, 255, 2, 72, 2, 73, 1, 96, 1, 189, 0, 191, 12, 237, 0, 224, 4, 0, 250, 5, 0, 72, 241, 231, 21, 1, 15, 240, 8, 73, 8, 96, 200, 104, 16, 240, 4, 15, 251, 208, 200, 104, 16, 240, 64, 15, 251, 208, 112, 71, 3, 72, 193, 104, 17, 240, 2, 15, 251, 208, 0, 104, 112, 71, 60, 200, 0, 64, 248, 181, 5, 70, 12, 0, 67, 191, 0, 38, 32, 70, 68, 66, 38, 70, 0, 39, 255, 247, 236, 255, 120, 85, 70, 64, 127, 28, 188, 66, 248, 210, 255, 247, 229, 255, 134, 66, 4, 208, 31, 32, 255, 247, 213, 255, 0, 32, 242, 189, 96, 28, 242, 189, 128, 181, 0, 240, 96, 249, 111, 240, 2, 1, 0, 168, 255, 247, 221, 255, 4, 40, 2, 208, 79, 240, 255, 48, 2, 189, 0, 240, 84, 249, 0, 152, 0, 186, 2, 189, 0, 0, 223, 248, 0, 22, 136, 66, 4, 211, 176, 241, 32, 47, 1, 210, 2, 32, 112, 71, 176, 241, 0, 111, 4, 211, 9, 73, 136, 66, 1, 210, 4, 32, 112, 71, 158, 73, 136, 66, 4, 211, 6, 73, 136, 66, 6, 210, 8, 32, 112, 71, 5, 73, 136, 66, 1, 211, 16, 32, 112, 71, 1, 32, 112, 71, 0, 0, 2, 8, 0, 10, 4, 8, 0, 0, 4, 8, 9, 72, 10, 73, 1, 96, 10, 74, 2, 96, 65, 96, 66, 96, 16, 73, 1, 34, 10, 96, 74, 104, 18, 240, 1, 15, 251, 208, 129, 104, 17, 240, 1, 15, 251, 209, 112, 71, 0, 191, 4, 128, 0, 64, 35, 1, 103, 69, 171, 137, 239, 205, 6, 72, 65, 104, 17, 240, 2, 15, 251, 209, 0, 33, 1, 96, 2, 72, 128, 33, 1, 96, 112, 71, 0, 191, 16, 128, 0, 64, 44, 64, 0, 64, 45, 233, 248, 67, 128, 70, 12, 70, 21, 70, 0, 38, 71, 70, 0, 45, 88, 208, 8, 240, 1, 0, 5, 240, 1, 1, 8, 67, 1, 208, 1, 32, 15, 224, 64, 70, 255, 247, 156, 255, 129, 70, 5, 235, 8, 0, 64, 30, 255, 247, 150, 255, 64, 234, 9, 0, 4, 40, 4, 208, 8, 40, 2, 208, 2, 32, 189, 232, 242, 131, 255, 247, 177, 255, 0, 32, 106, 73, 1, 224, 191, 28, 128, 28, 168, 66, 50, 210, 59, 136, 2, 25, 82, 120, 16, 248, 4, 128, 8, 235, 2, 34, 146, 178, 147, 66, 241, 208, 79, 246, 255, 120, 67, 69, 1, 208, 19, 0, 33, 209, 96, 75, 159, 66, 5, 211, 24, 75, 159, 66, 2, 210, 79, 244, 4, 115, 1, 224, 64, 242, 1, 35, 75, 96, 58, 128, 10, 104, 18, 240, 1, 15, 251, 209, 32, 34, 10, 96, 10, 104, 18, 240, 20, 15, 212, 208, 8, 104, 16, 240, 16, 15, 20, 191, 4, 38, 5, 38, 16, 32, 8, 96, 4, 32, 8, 96, 0, 224, 6, 38, 255, 247, 143, 255, 11, 224, 0, 32, 0, 224, 64, 28, 152, 66, 6, 210, 23, 248, 1, 27, 2, 93, 145, 66, 247, 208, 7, 32, 178, 231, 48, 70, 176, 231, 16, 8, 4, 8, 45, 233, 248, 67, 4, 70, 8, 70, 0, 39, 129, 10, 141, 2, 225, 178, 1, 41, 42, 209, 4, 38, 79, 240, 0, 104, 79, 244, 0, 73, 20, 244, 128, 127, 27, 208, 255, 247, 80, 255, 58, 72, 70, 96, 225, 178, 2, 41, 0, 209, 133, 96, 70, 240, 64, 1, 65, 96, 1, 104, 17, 240, 1, 15, 251, 209, 32, 33, 1, 96, 1, 104, 17, 240, 16, 15, 2, 208, 16, 33, 1, 96, 4, 39, 255, 247, 82, 255, 0, 47, 41, 209, 20, 244, 0, 127, 38, 208, 0, 32, 79, 240, 255, 50, 26, 224, 2, 41, 10, 209, 255, 247, 5, 255, 4, 40, 1, 208, 2, 32, 15, 224, 2, 38, 168, 70, 79, 244, 128, 121, 204, 231, 224, 178, 3, 40, 6, 209, 79, 244, 8, 118, 223, 248, 136, 128, 79, 240, 128, 9, 194, 231, 3, 32, 189, 232, 242, 131, 64, 28, 72, 69, 5, 210, 88, 248, 4, 27, 145, 66, 248, 208, 7, 32, 244, 231, 56, 70, 242, 231, 16, 181, 130, 176, 4, 70, 0, 240, 47, 248, 28, 177, 0, 32, 141, 248, 0, 0, 18, 224, 165, 32, 141, 248, 0, 0, 255, 247, 251, 254, 16, 76, 79, 244, 4, 112, 96, 96, 15, 72, 165, 33, 1, 128, 0, 33, 64, 242, 3, 16, 255, 247, 139, 255, 4, 32, 32, 96, 157, 248, 0, 0, 192, 67, 141, 248, 1, 0, 2, 35, 2, 34, 0, 169, 6, 72, 255, 247, 12, 255, 0, 40, 12, 191, 121, 32, 31, 32, 255, 247, 116, 254, 19, 189, 0, 0, 12, 128, 0, 64, 0, 8, 4, 8, 121, 32, 107, 230, 45, 233, 240, 67, 195, 176, 194, 72, 0, 104, 0, 2, 0, 10, 193, 73, 136, 66, 2, 208, 192, 72, 255, 247, 79, 254, 205, 72, 1, 104, 33, 240, 240, 1, 65, 240, 128, 1, 1, 96, 129, 104, 65, 240, 32, 1, 129, 96, 200, 73, 2, 34, 10, 96, 185, 74, 83, 109, 67, 240, 1, 3, 83, 101, 19, 104, 64, 242, 220, 85, 20, 104, 228, 26, 36, 3, 36, 11, 172, 66, 249, 211, 0, 35, 83, 101, 10, 104, 66, 240, 1, 2, 10, 96, 64, 104, 16, 240, 32, 15, 2, 208, 174, 72, 255, 247, 38, 254, 186, 73, 8, 104, 32, 240, 240, 0, 64, 240, 144, 0, 8, 96, 170, 72, 32, 34, 2, 101, 79, 244, 128, 114, 130, 97, 100, 34, 130, 96, 1, 34, 2, 96, 138, 104, 18, 240, 4, 15, 251, 208, 16, 33, 1, 98, 163, 73, 10, 104, 18, 240, 4, 15, 251, 208, 4, 34, 10, 96, 10, 104, 18, 240, 4, 15, 251, 208, 129, 107, 140, 28, 0, 33, 1, 101, 129, 97, 129, 96, 1, 96, 1, 98, 229, 8, 93, 45, 2, 210, 153, 72, 255, 247, 246, 253, 163, 72, 69, 97, 161, 8, 1, 240, 1, 1, 129, 97, 2, 33, 129, 96, 1, 33, 1, 96, 255, 247, 140, 255, 146, 76, 223, 248, 120, 130, 13, 241, 8, 9, 8, 224, 22, 248, 9, 0, 240, 85, 118, 28, 174, 66, 249, 211, 121, 32, 255, 247, 235, 253, 255, 247, 244, 253, 7, 70, 255, 247, 241, 253, 120, 64, 255, 40, 0, 208, 255, 39, 135, 72, 0, 104, 16, 240, 2, 15, 3, 208, 17, 47, 1, 211, 131, 47, 22, 211, 56, 0, 21, 208, 1, 47, 19, 208, 2, 47, 17, 208, 17, 47, 28, 208, 33, 47, 56, 208, 49, 47, 84, 208, 67, 47, 116, 208, 99, 47, 0, 240, 163, 128, 130, 47, 0, 240, 206, 128, 146, 47, 0, 240, 207, 128, 218, 224, 255, 247, 81, 255, 62, 93, 3, 224, 48, 93, 255, 247, 186, 253, 118, 28, 56, 25, 64, 120, 134, 66, 247, 211, 197, 231, 255, 247, 225, 253, 7, 70, 255, 247, 241, 253, 5, 70, 255, 247, 183, 253, 6, 70, 255, 247, 180, 253, 112, 64, 255, 40, 13, 209, 1, 45, 11, 208, 255, 247, 52, 255, 117, 28, 0, 38, 174, 66, 178, 210, 23, 248, 1, 11, 255, 247, 154, 253, 118, 28, 247, 231, 31, 32, 168, 231, 255, 247, 195, 253, 7, 70, 255, 247, 211, 253, 16, 47, 6, 210, 255, 247, 31, 255, 94, 72, 192, 25, 255, 247, 121, 253, 156, 231, 16, 240, 6, 15, 236, 208, 125, 104, 255, 247, 20, 255, 89, 72, 255, 247, 86, 253, 89, 72, 7, 96, 56, 104, 255, 247, 78, 253, 168, 71, 140, 231, 255, 247, 165, 253, 7, 70, 255, 247, 181, 253, 6, 70, 255, 247, 123, 253, 0, 240, 180, 248, 5, 70, 165, 177, 120, 25, 64, 30, 255, 247, 170, 253, 48, 67, 2, 40, 1, 209, 0, 38, 114, 231, 22, 240, 12, 15, 199, 208, 43, 70, 42, 70, 2, 169, 56, 70, 255, 247, 236, 253, 0, 40, 63, 244, 105, 175, 189, 231, 255, 247, 230, 254, 31, 37, 255, 247, 92, 253, 7, 70, 254, 47, 16, 211, 12, 191, 64, 242, 3, 54, 64, 242, 1, 54, 255, 247, 82, 253, 120, 64, 255, 40, 28, 209, 0, 33, 48, 70, 255, 247, 68, 254, 184, 185, 121, 37, 21, 224, 57, 70, 0, 240, 130, 248, 7, 0, 16, 208, 121, 37, 0, 38, 22, 248, 9, 0, 128, 2, 0, 241, 0, 97, 64, 242, 2, 48, 255, 247, 49, 254, 8, 177, 31, 37, 2, 224, 118, 28, 190, 66, 240, 211, 40, 70, 55, 231, 255, 247, 181, 254, 255, 247, 44, 253, 0, 240, 101, 248, 0, 40, 40, 208, 0, 33, 0, 38, 1, 35, 22, 248, 9, 32, 32, 42, 5, 210, 3, 250, 2, 242, 17, 67, 118, 28, 134, 66, 245, 211, 134, 66, 21, 211, 0, 38, 176, 0, 33, 250, 0, 240, 192, 178, 0, 170, 195, 67, 179, 84, 178, 24, 80, 112, 182, 28, 8, 46, 243, 211, 8, 35, 8, 34, 0, 169, 25, 72, 255, 247, 141, 253, 0, 40, 63, 244, 10, 175, 94, 231, 1, 32, 255, 247, 82, 254, 7, 231, 64, 70, 2, 224, 0, 33, 64, 248, 4, 27, 18, 73, 136, 66, 249, 211, 0, 32, 255, 247, 70, 254, 16, 72, 90, 231, 31, 32, 246, 230, 150, 7, 4, 8, 1, 0, 3, 0, 20, 1, 15, 240, 56, 32, 0, 64, 19, 1, 15, 240, 0, 240, 0, 64, 4, 168, 0, 64, 17, 1, 15, 240, 76, 7, 4, 8, 28, 128, 0, 64, 0, 1, 15, 240, 16, 1, 15, 240, 8, 237, 0, 224, 8, 8, 4, 8, 255, 31, 0, 32, 18, 1, 15, 240, 4, 176, 0, 64, 28, 64, 0, 64, 0, 180, 0, 64, 84, 200, 0, 64, 0, 2, 0, 32, 1, 70, 0, 191, 2, 168, 201, 228, 8, 72, 64, 242, 7, 49, 1, 96, 7, 72, 1, 33, 1, 96, 114, 182, 6, 72, 7, 73, 0, 34, 1, 224, 64, 248, 4, 43, 136, 66, 251, 211, 255, 247, 56, 190, 24, 0, 0, 64, 32, 64, 0, 64, 0, 0, 0, 32, 0, 2, 0, 32, 4, 16, 19, 22, 10, 3, 0, 1, 2, 17, 33, 49, 67, 99, 130, 146, 3, 0, 0, 1, 9, 168, 0, 0], 'cut 1.1v2': [0, 2, 0, 32, 17, 7, 4, 8, 125, 0, 4, 8, 125, 0, 4, 8, 167, 15, 2, 0, 0, 0, 0, 0, 0, 8, 4, 8, 0, 0, 0, 8, 0, 2, 0, 32, 169, 1, 4, 8, 141, 2, 4, 8, 95, 234, 0, 13, 112, 71, 79, 240, 0, 81, 8, 96, 223, 248, 184, 6, 68, 242, 68, 65, 1, 96, 0, 34, 130, 96, 223, 248, 180, 6, 1, 96, 223, 248, 176, 6, 66, 97, 130, 97, 130, 96, 2, 96, 223, 248, 156, 6, 2, 96, 66, 96, 98, 182, 112, 71, 128, 181, 255, 247, 228, 255, 2, 72, 2, 73, 1, 96, 1, 189, 0, 191, 12, 237, 0, 224, 4, 0, 250, 5, 0, 72, 241, 231, 21, 1, 15, 240, 8, 73, 8, 96, 200, 104, 16, 240, 4, 15, 251, 208, 200, 104, 16, 240, 64, 15, 251, 208, 112, 71, 3, 72, 193, 104, 17, 240, 2, 15, 251, 208, 0, 104, 112, 71, 60, 200, 0, 64, 248, 181, 5, 70, 12, 0, 67, 191, 0, 38, 32, 70, 68, 66, 38, 70, 0, 39, 255, 247, 236, 255, 120, 85, 70, 64, 127, 28, 188, 66, 248, 210, 255, 247, 229, 255, 134, 66, 4, 208, 31, 32, 255, 247, 213, 255, 0, 32, 242, 189, 96, 28, 242, 189, 128, 181, 0, 240, 96, 249, 111, 240, 2, 1, 0, 168, 255, 247, 221, 255, 4, 40, 2, 208, 79, 240, 255, 48, 2, 189, 0, 240, 84, 249, 0, 152, 0, 186, 2, 189, 0, 0, 223, 248, 248, 21, 136, 66, 4, 211, 176, 241, 32, 47, 1, 210, 2, 32, 112, 71, 176, 241, 0, 111, 4, 211, 9, 73, 136, 66, 1, 210, 4, 32, 112, 71, 158, 73, 136, 66, 4, 211, 6, 73, 136, 66, 6, 210, 8, 32, 112, 71, 5, 73, 136, 66, 1, 211, 16, 32, 112, 71, 1, 32, 112, 71, 0, 0, 2, 8, 0, 10, 4, 8, 0, 0, 4, 8, 9, 72, 10, 73, 1, 96, 10, 74, 2, 96, 65, 96, 66, 96, 16, 73, 1, 34, 10, 96, 74, 104, 18, 240, 1, 15, 251, 208, 129, 104, 17, 240, 1, 15, 251, 209, 112, 71, 0, 191, 4, 128, 0, 64, 35, 1, 103, 69, 171, 137, 239, 205, 6, 72, 65, 104, 17, 240, 2, 15, 251, 209, 0, 33, 1, 96, 2, 72, 128, 33, 1, 96, 112, 71, 0, 191, 16, 128, 0, 64, 44, 64, 0, 64, 45, 233, 248, 67, 128, 70, 12, 70, 21, 70, 0, 38, 71, 70, 0, 45, 88, 208, 8, 240, 1, 0, 5, 240, 1, 1, 8, 67, 1, 208, 1, 32, 15, 224, 64, 70, 255, 247, 156, 255, 129, 70, 5, 235, 8, 0, 64, 30, 255, 247, 150, 255, 64, 234, 9, 0, 4, 40, 4, 208, 8, 40, 2, 208, 2, 32, 189, 232, 242, 131, 255, 247, 177, 255, 0, 32, 106, 73, 1, 224, 191, 28, 128, 28, 168, 66, 50, 210, 59, 136, 2, 25, 82, 120, 16, 248, 4, 128, 8, 235, 2, 34, 146, 178, 147, 66, 241, 208, 79, 246, 255, 120, 67, 69, 1, 208, 19, 0, 33, 209, 96, 75, 159, 66, 5, 211, 24, 75, 159, 66, 2, 210, 79, 244, 4, 115, 1, 224, 64, 242, 1, 35, 75, 96, 58, 128, 10, 104, 18, 240, 1, 15, 251, 209, 32, 34, 10, 96, 10, 104, 18, 240, 20, 15, 212, 208, 8, 104, 16, 240, 16, 15, 20, 191, 4, 38, 5, 38, 16, 32, 8, 96, 4, 32, 8, 96, 0, 224, 6, 38, 255, 247, 143, 255, 11, 224, 0, 32, 0, 224, 64, 28, 152, 66, 6, 210, 23, 248, 1, 27, 2, 93, 145, 66, 247, 208, 7, 32, 178, 231, 48, 70, 176, 231, 16, 8, 4, 8, 45, 233, 248, 67, 4, 70, 8, 70, 0, 39, 129, 10, 141, 2, 225, 178, 1, 41, 42, 209, 4, 38, 79, 240, 0, 104, 79, 244, 0, 73, 20, 244, 128, 127, 27, 208, 255, 247, 80, 255, 58, 72, 70, 96, 225, 178, 2, 41, 0, 209, 133, 96, 70, 240, 64, 1, 65, 96, 1, 104, 17, 240, 1, 15, 251, 209, 32, 33, 1, 96, 1, 104, 17, 240, 16, 15, 2, 208, 16, 33, 1, 96, 4, 39, 255, 247, 82, 255, 0, 47, 41, 209, 20, 244, 0, 127, 38, 208, 0, 32, 79, 240, 255, 50, 26, 224, 2, 41, 10, 209, 255, 247, 5, 255, 4, 40, 1, 208, 2, 32, 15, 224, 2, 38, 168, 70, 79, 244, 128, 121, 204, 231, 224, 178, 3, 40, 6, 209, 79, 244, 8, 118, 223, 248, 136, 128, 79, 240, 128, 9, 194, 231, 3, 32, 189, 232, 242, 131, 64, 28, 72, 69, 5, 210, 88, 248, 4, 27, 145, 66, 248, 208, 7, 32, 244, 231, 56, 70, 242, 231, 16, 181, 130, 176, 4, 70, 0, 240, 47, 248, 28, 177, 0, 32, 141, 248, 0, 0, 18, 224, 165, 32, 141, 248, 0, 0, 255, 247, 251, 254, 16, 76, 79, 244, 4, 112, 96, 96, 15, 72, 165, 33, 1, 128, 0, 33, 64, 242, 3, 16, 255, 247, 139, 255, 4, 32, 32, 96, 157, 248, 0, 0, 192, 67, 141, 248, 1, 0, 2, 35, 2, 34, 0, 169, 6, 72, 255, 247, 12, 255, 0, 40, 12, 191, 121, 32, 31, 32, 255, 247, 116, 254, 19, 189, 0, 0, 12, 128, 0, 64, 0, 8, 4, 8, 121, 32, 107, 230, 45, 233, 240, 67, 195, 176, 193, 72, 0, 104, 176, 241, 1, 31, 2, 208, 191, 72, 255, 247, 81, 254, 204, 72, 1, 104, 33, 240, 240, 1, 65, 240, 128, 1, 1, 96, 129, 104, 65, 240, 32, 1, 129, 96, 199, 73, 2, 34, 10, 96, 184, 74, 83, 109, 67, 240, 1, 3, 83, 101, 19, 104, 64, 242, 220, 85, 20, 104, 228, 26, 36, 3, 36, 11, 172, 66, 249, 211, 0, 35, 83, 101, 10, 104, 66, 240, 1, 2, 10, 96, 64, 104, 16, 240, 32, 15, 2, 208, 173, 72, 255, 247, 40, 254, 185, 73, 8, 104, 32, 240, 240, 0, 64, 240, 144, 0, 8, 96, 169, 72, 32, 34, 2, 101, 79, 244, 128, 114, 130, 97, 100, 34, 130, 96, 1, 34, 2, 96, 138, 104, 18, 240, 4, 15, 251, 208, 16, 33, 1, 98, 162, 73, 10, 104, 18, 240, 4, 15, 251, 208, 4, 34, 10, 96, 10, 104, 18, 240, 4, 15, 251, 208, 129, 107, 140, 28, 0, 33, 1, 101, 129, 97, 129, 96, 1, 96, 1, 98, 229, 8, 93, 45, 2, 210, 152, 72, 255, 247, 248, 253, 162, 72, 69, 97, 161, 8, 1, 240, 1, 1, 129, 97, 2, 33, 129, 96, 1, 33, 1, 96, 255, 247, 142, 255, 145, 76, 223, 248, 116, 130, 13, 241, 8, 9, 8, 224, 22, 248, 9, 0, 240, 85, 118, 28, 174, 66, 249, 211, 121, 32, 255, 247, 237, 253, 255, 247, 246, 253, 7, 70, 255, 247, 243, 253, 120, 64, 255, 40, 0, 208, 255, 39, 134, 72, 0, 104, 16, 240, 2, 15, 3, 208, 17, 47, 1, 211, 131, 47, 22, 211, 56, 0, 21, 208, 1, 47, 19, 208, 2, 47, 17, 208, 17, 47, 28, 208, 33, 47, 56, 208, 49, 47, 84, 208, 67, 47, 116, 208, 99, 47, 0, 240, 163, 128, 130, 47, 0, 240, 206, 128, 146, 47, 0, 240, 207, 128, 218, 224, 255, 247, 83, 255, 62, 93, 3, 224, 48, 93, 255, 247, 188, 253, 118, 28, 56, 25, 64, 120, 134, 66, 247, 211, 197, 231, 255, 247, 227, 253, 7, 70, 255, 247, 243, 253, 5, 70, 255, 247, 185, 253, 6, 70, 255, 247, 182, 253, 112, 64, 255, 40, 13, 209, 1, 45, 11, 208, 255, 247, 54, 255, 117, 28, 0, 38, 174, 66, 178, 210, 23, 248, 1, 11, 255, 247, 156, 253, 118, 28, 247, 231, 31, 32, 168, 231, 255, 247, 197, 253, 7, 70, 255, 247, 213, 253, 16, 47, 6, 210, 255, 247, 33, 255, 93, 72, 192, 25, 255, 247, 123, 253, 156, 231, 16, 240, 6, 15, 236, 208, 125, 104, 255, 247, 22, 255, 88, 72, 255, 247, 88, 253, 88, 72, 7, 96, 56, 104, 255, 247, 80, 253, 168, 71, 140, 231, 255, 247, 167, 253, 7, 70, 255, 247, 183, 253, 6, 70, 255, 247, 125, 253, 0, 240, 178, 248, 5, 70, 165, 177, 120, 25, 64, 30, 255, 247, 172, 253, 48, 67, 2, 40, 1, 209, 0, 38, 114, 231, 22, 240, 12, 15, 199, 208, 43, 70, 42, 70, 2, 169, 56, 70, 255, 247, 238, 253, 0, 40, 63, 244, 105, 175, 189, 231, 255, 247, 232, 254, 31, 37, 255, 247, 94, 253, 7, 70, 254, 47, 16, 211, 12, 191, 64, 242, 3, 54, 64, 242, 1, 54, 255, 247, 84, 253, 120, 64, 255, 40, 28, 209, 0, 33, 48, 70, 255, 247, 70, 254, 184, 185, 121, 37, 21, 224, 57, 70, 0, 240, 128, 248, 7, 0, 16, 208, 121, 37, 0, 38, 22, 248, 9, 0, 128, 2, 0, 241, 0, 97, 64, 242, 2, 48, 255, 247, 51, 254, 8, 177, 31, 37, 2, 224, 118, 28, 190, 66, 240, 211, 40, 70, 55, 231, 255, 247, 183, 254, 255, 247, 46, 253, 0, 240, 99, 248, 0, 40, 40, 208, 0, 33, 0, 38, 1, 35, 22, 248, 9, 32, 32, 42, 5, 210, 3, 250, 2, 242, 17, 67, 118, 28, 134, 66, 245, 211, 134, 66, 21, 211, 0, 38, 176, 0, 33, 250, 0, 240, 192, 178, 0, 170, 195, 67, 179, 84, 178, 24, 80, 112, 182, 28, 8, 46, 243, 211, 8, 35, 8, 34, 0, 169, 24, 72, 255, 247, 143, 253, 0, 40, 63, 244, 10, 175, 94, 231, 1, 32, 255, 247, 84, 254, 7, 231, 64, 70, 2, 224, 0, 33, 64, 248, 4, 27, 17, 73, 136, 66, 249, 211, 0, 32, 255, 247, 72, 254, 15, 72, 90, 231, 31, 32, 246, 230, 150, 7, 4, 8, 20, 1, 15, 240, 56, 32, 0, 64, 19, 1, 15, 240, 0, 240, 0, 64, 4, 168, 0, 64, 17, 1, 15, 240, 56, 7, 4, 8, 28, 128, 0, 64, 0, 1, 15, 240, 16, 1, 15, 240, 8, 237, 0, 224, 8, 8, 4, 8, 255, 31, 0, 32, 18, 1, 15, 240, 4, 176, 0, 64, 28, 64, 0, 64, 0, 180, 0, 64, 84, 200, 0, 64, 0, 2, 0, 32, 1, 70, 0, 191, 2, 168, 205, 228, 6, 72, 1, 33, 1, 96, 114, 182, 5, 72, 6, 73, 0, 34, 1, 224, 64, 248, 4, 43, 136, 66, 251, 211, 255, 247, 64, 190, 32, 64, 0, 64, 0, 0, 0, 32, 0, 2, 0, 32, 4, 16, 19, 22, 10, 2, 0, 1, 2, 17, 33, 49, 67, 99, 130, 146, 2, 0, 0, 1, 9, 169, 0, 0]} +bootloader_cut_1_0v2 = [0, 2, 0, 32, 17, 7, 4, 8, 125, 0, 4, 8, 125, 0, 4, 8, 167, 15, 2, 0, 0, 0, 0, 0, 0, 8, 4, 8, 0, 0, 0, 8, 0, 2, 0, 32, 169, 1, 4, 8, 141, 2, 4, 8, 95, 234, 0, 13, 112, 71, 79, 240, 0, 81, 8, 96, 223, 248, 184, 6, 68, 242, 68, 65, 1, 96, 0, 34, 130, 96, 223, 248, 180, 6, 1, 96, 223, 248, 176, 6, 66, 97, 130, 97, 130, 96, 2, 96, 223, 248, 156, 6, 2, 96, 66, 96, 98, 182, 112, 71, 128, 181, 255, 247, 228, 255, 2, 72, 2, 73, 1, 96, 1, 189, 0, 191, 12, 237, 0, 224, 4, 0, 250, 5, 0, 72, 241, 231, 21, 1, 15, 240, 8, 73, 8, 96, 200, 104, 16, 240, 4, 15, 251, 208, 200, 104, 16, 240, 64, 15, 251, 208, 112, 71, 3, 72, 193, 104, 17, 240, 2, 15, 251, 208, 0, 104, 112, 71, 60, 200, 0, 64, 248, 181, 5, 70, 12, 0, 67, 191, 0, 38, 32, 70, 68, 66, 38, 70, 0, 39, 255, 247, 236, 255, 120, 85, 70, 64, 127, 28, 188, 66, 248, 210, 255, 247, 229, 255, 134, 66, 4, 208, 31, 32, 255, 247, 213, 255, 0, 32, 242, 189, 96, 28, 242, 189, 128, 181, 0, 240, 96, 249, 111, 240, 2, 1, 0, 168, 255, 247, 221, 255, 4, 40, 2, 208, 79, 240, 255, 48, 2, 189, 0, 240, 84, 249, 0, 152, 0, 186, 2, 189, 0, 0, 223, 248, 248, 21, 136, 66, 4, 211, 176, 241, 32, 47, 1, 210, 2, 32, 112, 71, 176, 241, 0, 111, 4, 211, 9, 73, 136, 66, 1, 210, 4, 32, 112, 71, 158, 73, 136, 66, 4, 211, 6, 73, 136, 66, 6, 210, 8, 32, 112, 71, 5, 73, 136, 66, 1, 211, 16, 32, 112, 71, 1, 32, 112, 71, 0, 0, 2, 8, 0, 10, 4, 8, 0, 0, 4, 8, 9, 72, 10, 73, 1, 96, 10, 74, 2, 96, 65, 96, 66, 96, 16, 73, 1, 34, 10, 96, 74, 104, 18, 240, 1, 15, 251, 208, 129, 104, 17, 240, 1, 15, 251, 209, 112, 71, 0, 191, 4, 128, 0, 64, 35, 1, 103, 69, 171, 137, 239, 205, 6, 72, 65, 104, 17, 240, 2, 15, 251, 209, 0, 33, 1, 96, 2, 72, 128, 33, 1, 96, 112, 71, 0, 191, 16, 128, 0, 64, 44, 64, 0, 64, 45, 233, 248, 67, 128, 70, 12, 70, 21, 70, 0, 38, 71, 70, 0, 45, 88, 208, 8, 240, 1, 0, 5, 240, 1, 1, 8, 67, 1, 208, 1, 32, 15, 224, 64, 70, 255, 247, 156, 255, 129, 70, 5, 235, 8, 0, 64, 30, 255, 247, 150, 255, 64, 234, 9, 0, 4, 40, 4, 208, 8, 40, 2, 208, 2, 32, 189, 232, 242, 131, 255, 247, 177, 255, 0, 32, 106, 73, 1, 224, 191, 28, 128, 28, 168, 66, 50, 210, 59, 136, 2, 25, 82, 120, 16, 248, 4, 128, 8, 235, 2, 34, 146, 178, 147, 66, 241, 208, 79, 246, 255, 120, 67, 69, 1, 208, 19, 0, 33, 209, 96, 75, 159, 66, 5, 211, 24, 75, 159, 66, 2, 210, 79, 244, 4, 115, 1, 224, 64, 242, 1, 35, 75, 96, 58, 128, 10, 104, 18, 240, 1, 15, 251, 209, 32, 34, 10, 96, 10, 104, 18, 240, 20, 15, 212, 208, 8, 104, 16, 240, 16, 15, 20, 191, 4, 38, 5, 38, 16, 32, 8, 96, 4, 32, 8, 96, 0, 224, 6, 38, 255, 247, 143, 255, 11, 224, 0, 32, 0, 224, 64, 28, 152, 66, 6, 210, 23, 248, 1, 27, 2, 93, 145, 66, 247, 208, 7, 32, 178, 231, 48, 70, 176, 231, 16, 8, 4, 8, 45, 233, 248, 67, 4, 70, 8, 70, 0, 39, 129, 10, 141, 2, 225, 178, 1, 41, 42, 209, 4, 38, 79, 240, 0, 104, 79, 244, 0, 73, 20, 244, 128, 127, 27, 208, 255, 247, 80, 255, 58, 72, 70, 96, 225, 178, 2, 41, 0, 209, 133, 96, 70, 240, 64, 1, 65, 96, 1, 104, 17, 240, 1, 15, 251, 209, 32, 33, 1, 96, 1, 104, 17, 240, 16, 15, 2, 208, 16, 33, 1, 96, 4, 39, 255, 247, 82, 255, 0, 47, 41, 209, 20, 244, 0, 127, 38, 208, 0, 32, 79, 240, 255, 50, 26, 224, 2, 41, 10, 209, 255, 247, 5, 255, 4, 40, 1, 208, 2, 32, 15, 224, 2, 38, 168, 70, 79, 244, 128, 121, 204, 231, 224, 178, 3, 40, 6, 209, 79, 244, 8, 118, 223, 248, 136, 128, 79, 240, 128, 9, 194, 231, 3, 32, 189, 232, 242, 131, 64, 28, 72, 69, 5, 210, 88, 248, 4, 27, 145, 66, 248, 208, 7, 32, 244, 231, 56, 70, 242, 231, 16, 181, 130, 176, 4, 70, 0, 240, 47, 248, 28, 177, 0, 32, 141, 248, 0, 0, 18, 224, 165, 32, 141, 248, 0, 0, 255, 247, 251, 254, 16, 76, 79, 244, 4, 112, 96, 96, 15, 72, 165, 33, 1, 128, 0, 33, 64, 242, 3, 16, 255, 247, 139, 255, 4, 32, 32, 96, 157, 248, 0, 0, 192, 67, 141, 248, 1, 0, 2, 35, 2, 34, 0, 169, 6, 72, 255, 247, 12, 255, 0, 40, 12, 191, 121, 32, 31, 32, 255, 247, 116, 254, 19, 189, 0, 0, 12, 128, 0, 64, 0, 8, 4, 8, 121, 32, 107, 230, 45, 233, 240, 67, 195, 176, 193, 72, 0, 104, 1, 40, 2, 208, 192, 72, 255, 247, 82, 254, 204, 72, 1, 104, 33, 240, 240, 1, 65, 240, 128, 1, 1, 96, 129, 104, 65, 240, 32, 1, 129, 96, 200, 73, 2, 34, 10, 96, 184, 74, 83, 109, 67, 240, 1, 3, 83, 101, 19, 104, 64, 242, 220, 85, 20, 104, 228, 26, 36, 3, 36, 11, 172, 66, 249, 211, 0, 35, 83, 101, 10, 104, 66, 240, 1, 2, 10, 96, 64, 104, 16, 240, 32, 15, 2, 208, 173, 72, 255, 247, 41, 254, 186, 73, 8, 104, 32, 240, 240, 0, 64, 240, 144, 0, 8, 96, 169, 72, 32, 34, 2, 101, 79, 244, 128, 114, 130, 97, 100, 34, 130, 96, 1, 34, 2, 96, 138, 104, 18, 240, 4, 15, 251, 208, 16, 33, 1, 98, 162, 73, 10, 104, 18, 240, 4, 15, 251, 208, 4, 34, 10, 96, 10, 104, 18, 240, 4, 15, 251, 208, 129, 107, 140, 28, 0, 33, 1, 101, 129, 97, 129, 96, 1, 96, 1, 98, 229, 8, 93, 45, 2, 210, 152, 72, 255, 247, 249, 253, 163, 72, 69, 97, 161, 8, 1, 240, 1, 1, 129, 97, 2, 33, 129, 96, 1, 33, 1, 96, 255, 247, 143, 255, 146, 76, 223, 248, 116, 130, 13, 241, 8, 9, 8, 224, 22, 248, 9, 0, 240, 85, 118, 28, 174, 66, 249, 211, 121, 32, 255, 247, 238, 253, 255, 247, 247, 253, 7, 70, 255, 247, 244, 253, 120, 64, 255, 40, 0, 208, 255, 39, 135, 72, 0, 104, 16, 240, 2, 15, 3, 208, 17, 47, 1, 211, 131, 47, 22, 211, 56, 0, 21, 208, 1, 47, 19, 208, 2, 47, 17, 208, 17, 47, 28, 208, 33, 47, 56, 208, 49, 47, 84, 208, 67, 47, 116, 208, 99, 47, 0, 240, 163, 128, 130, 47, 0, 240, 206, 128, 146, 47, 0, 240, 207, 128, 218, 224, 255, 247, 84, 255, 62, 93, 3, 224, 48, 93, 255, 247, 189, 253, 118, 28, 56, 25, 64, 120, 134, 66, 247, 211, 197, 231, 255, 247, 228, 253, 7, 70, 255, 247, 244, 253, 5, 70, 255, 247, 186, 253, 6, 70, 255, 247, 183, 253, 112, 64, 255, 40, 13, 209, 1, 45, 11, 208, 255, 247, 55, 255, 117, 28, 0, 38, 174, 66, 178, 210, 23, 248, 1, 11, 255, 247, 157, 253, 118, 28, 247, 231, 31, 32, 168, 231, 255, 247, 198, 253, 7, 70, 255, 247, 214, 253, 16, 47, 6, 210, 255, 247, 34, 255, 93, 72, 192, 25, 255, 247, 124, 253, 156, 231, 16, 240, 6, 15, 236, 208, 125, 104, 255, 247, 23, 255, 89, 72, 255, 247, 89, 253, 88, 72, 7, 96, 56, 104, 255, 247, 81, 253, 168, 71, 140, 231, 255, 247, 168, 253, 7, 70, 255, 247, 184, 253, 6, 70, 255, 247, 126, 253, 0, 240, 179, 248, 5, 70, 165, 177, 120, 25, 64, 30, 255, 247, 173, 253, 48, 67, 2, 40, 1, 209, 0, 38, 114, 231, 22, 240, 12, 15, 199, 208, 43, 70, 42, 70, 2, 169, 56, 70, 255, 247, 239, 253, 0, 40, 63, 244, 105, 175, 189, 231, 255, 247, 233, 254, 31, 37, 255, 247, 95, 253, 7, 70, 254, 47, 16, 211, 12, 191, 64, 242, 3, 54, 64, 242, 1, 54, 255, 247, 85, 253, 120, 64, 255, 40, 28, 209, 0, 33, 48, 70, 255, 247, 71, 254, 184, 185, 121, 37, 21, 224, 57, 70, 0, 240, 129, 248, 7, 0, 16, 208, 121, 37, 0, 38, 22, 248, 9, 0, 128, 2, 0, 241, 0, 97, 64, 242, 2, 48, 255, 247, 52, 254, 8, 177, 31, 37, 2, 224, 118, 28, 190, 66, 240, 211, 40, 70, 55, 231, 255, 247, 184, 254, 255, 247, 47, 253, 0, 240, 100, 248, 0, 40, 40, 208, 0, 33, 0, 38, 1, 35, 22, 248, 9, 32, 32, 42, 5, 210, 3, 250, 2, 242, 17, 67, 118, 28, 134, 66, 245, 211, 134, 66, 21, 211, 0, 38, 176, 0, 33, 250, 0, 240, 192, 178, 0, 170, 195, 67, 179, 84, 178, 24, 80, 112, 182, 28, 8, 46, 243, 211, 8, 35, 8, 34, 0, 169, 25, 72, 255, 247, 144, 253, 0, 40, 63, 244, 10, 175, 94, 231, 1, 32, 255, 247, 85, 254, 7, 231, 64, 70, 2, 224, 0, 33, 64, 248, 4, 27, 18, 73, 136, 66, 249, 211, 0, 32, 255, 247, 73, 254, 16, 72, 90, 231, 31, 32, 246, 230, 0, 191, 150, 7, 4, 8, 20, 1, 15, 240, 56, 32, 0, 64, 19, 1, 15, 240, 0, 240, 0, 64, 4, 168, 0, 64, 17, 1, 15, 240, 56, 7, 4, 8, 28, 128, 0, 64, 0, 1, 15, 240, 16, 1, 15, 240, 8, 237, 0, 224, 8, 8, 4, 8, 255, 31, 0, 32, 18, 1, 15, 240, 4, 176, 0, 64, 28, 64, 0, 64, 0, 180, 0, 64, 84, 200, 0, 64, 0, 2, 0, 32, 1, 70, 0, 191, 2, 168, 205, 228, 6, 72, 1, 33, 1, 96, 114, 182, 5, 72, 6, 73, 0, 34, 1, 224, 64, 248, 4, 43, 136, 66, 251, 211, 255, 247, 64, 190, 32, 64, 0, 64, 0, 0, 0, 32, 0, 2, 0, 32, 4, 16, 19, 22, 10, 2, 0, 1, 2, 17, 33, 49, 67, 99, 130, 146, 2, 0, 0, 1, 9, 169, 0, 0] +bootloader_cut_1_1v2 = [0, 2, 0, 32, 17, 7, 4, 8, 125, 0, 4, 8, 125, 0, 4, 8, 167, 15, 2, 0, 0, 0, 0, 0, 0, 8, 4, 8, 0, 0, 0, 8, 0, 2, 0, 32, 169, 1, 4, 8, 141, 2, 4, 8, 95, 234, 0, 13, 112, 71, 79, 240, 0, 81, 8, 96, 223, 248, 184, 6, 68, 242, 68, 65, 1, 96, 0, 34, 130, 96, 223, 248, 180, 6, 1, 96, 223, 248, 176, 6, 66, 97, 130, 97, 130, 96, 2, 96, 223, 248, 156, 6, 2, 96, 66, 96, 98, 182, 112, 71, 128, 181, 255, 247, 228, 255, 2, 72, 2, 73, 1, 96, 1, 189, 0, 191, 12, 237, 0, 224, 4, 0, 250, 5, 0, 72, 241, 231, 21, 1, 15, 240, 8, 73, 8, 96, 200, 104, 16, 240, 4, 15, 251, 208, 200, 104, 16, 240, 64, 15, 251, 208, 112, 71, 3, 72, 193, 104, 17, 240, 2, 15, 251, 208, 0, 104, 112, 71, 60, 200, 0, 64, 248, 181, 5, 70, 12, 0, 67, 191, 0, 38, 32, 70, 68, 66, 38, 70, 0, 39, 255, 247, 236, 255, 120, 85, 70, 64, 127, 28, 188, 66, 248, 210, 255, 247, 229, 255, 134, 66, 4, 208, 31, 32, 255, 247, 213, 255, 0, 32, 242, 189, 96, 28, 242, 189, 128, 181, 0, 240, 96, 249, 111, 240, 2, 1, 0, 168, 255, 247, 221, 255, 4, 40, 2, 208, 79, 240, 255, 48, 2, 189, 0, 240, 84, 249, 0, 152, 0, 186, 2, 189, 0, 0, 223, 248, 248, 21, 136, 66, 4, 211, 176, 241, 32, 47, 1, 210, 2, 32, 112, 71, 176, 241, 0, 111, 4, 211, 9, 73, 136, 66, 1, 210, 4, 32, 112, 71, 158, 73, 136, 66, 4, 211, 6, 73, 136, 66, 6, 210, 8, 32, 112, 71, 5, 73, 136, 66, 1, 211, 16, 32, 112, 71, 1, 32, 112, 71, 0, 0, 2, 8, 0, 10, 4, 8, 0, 0, 4, 8, 9, 72, 10, 73, 1, 96, 10, 74, 2, 96, 65, 96, 66, 96, 16, 73, 1, 34, 10, 96, 74, 104, 18, 240, 1, 15, 251, 208, 129, 104, 17, 240, 1, 15, 251, 209, 112, 71, 0, 191, 4, 128, 0, 64, 35, 1, 103, 69, 171, 137, 239, 205, 6, 72, 65, 104, 17, 240, 2, 15, 251, 209, 0, 33, 1, 96, 2, 72, 128, 33, 1, 96, 112, 71, 0, 191, 16, 128, 0, 64, 44, 64, 0, 64, 45, 233, 248, 67, 128, 70, 12, 70, 21, 70, 0, 38, 71, 70, 0, 45, 88, 208, 8, 240, 1, 0, 5, 240, 1, 1, 8, 67, 1, 208, 1, 32, 15, 224, 64, 70, 255, 247, 156, 255, 129, 70, 5, 235, 8, 0, 64, 30, 255, 247, 150, 255, 64, 234, 9, 0, 4, 40, 4, 208, 8, 40, 2, 208, 2, 32, 189, 232, 242, 131, 255, 247, 177, 255, 0, 32, 106, 73, 1, 224, 191, 28, 128, 28, 168, 66, 50, 210, 59, 136, 2, 25, 82, 120, 16, 248, 4, 128, 8, 235, 2, 34, 146, 178, 147, 66, 241, 208, 79, 246, 255, 120, 67, 69, 1, 208, 19, 0, 33, 209, 96, 75, 159, 66, 5, 211, 24, 75, 159, 66, 2, 210, 79, 244, 4, 115, 1, 224, 64, 242, 1, 35, 75, 96, 58, 128, 10, 104, 18, 240, 1, 15, 251, 209, 32, 34, 10, 96, 10, 104, 18, 240, 20, 15, 212, 208, 8, 104, 16, 240, 16, 15, 20, 191, 4, 38, 5, 38, 16, 32, 8, 96, 4, 32, 8, 96, 0, 224, 6, 38, 255, 247, 143, 255, 11, 224, 0, 32, 0, 224, 64, 28, 152, 66, 6, 210, 23, 248, 1, 27, 2, 93, 145, 66, 247, 208, 7, 32, 178, 231, 48, 70, 176, 231, 16, 8, 4, 8, 45, 233, 248, 67, 4, 70, 8, 70, 0, 39, 129, 10, 141, 2, 225, 178, 1, 41, 42, 209, 4, 38, 79, 240, 0, 104, 79, 244, 0, 73, 20, 244, 128, 127, 27, 208, 255, 247, 80, 255, 58, 72, 70, 96, 225, 178, 2, 41, 0, 209, 133, 96, 70, 240, 64, 1, 65, 96, 1, 104, 17, 240, 1, 15, 251, 209, 32, 33, 1, 96, 1, 104, 17, 240, 16, 15, 2, 208, 16, 33, 1, 96, 4, 39, 255, 247, 82, 255, 0, 47, 41, 209, 20, 244, 0, 127, 38, 208, 0, 32, 79, 240, 255, 50, 26, 224, 2, 41, 10, 209, 255, 247, 5, 255, 4, 40, 1, 208, 2, 32, 15, 224, 2, 38, 168, 70, 79, 244, 128, 121, 204, 231, 224, 178, 3, 40, 6, 209, 79, 244, 8, 118, 223, 248, 136, 128, 79, 240, 128, 9, 194, 231, 3, 32, 189, 232, 242, 131, 64, 28, 72, 69, 5, 210, 88, 248, 4, 27, 145, 66, 248, 208, 7, 32, 244, 231, 56, 70, 242, 231, 16, 181, 130, 176, 4, 70, 0, 240, 47, 248, 28, 177, 0, 32, 141, 248, 0, 0, 18, 224, 165, 32, 141, 248, 0, 0, 255, 247, 251, 254, 16, 76, 79, 244, 4, 112, 96, 96, 15, 72, 165, 33, 1, 128, 0, 33, 64, 242, 3, 16, 255, 247, 139, 255, 4, 32, 32, 96, 157, 248, 0, 0, 192, 67, 141, 248, 1, 0, 2, 35, 2, 34, 0, 169, 6, 72, 255, 247, 12, 255, 0, 40, 12, 191, 121, 32, 31, 32, 255, 247, 116, 254, 19, 189, 0, 0, 12, 128, 0, 64, 0, 8, 4, 8, 121, 32, 107, 230, 45, 233, 240, 67, 195, 176, 193, 72, 0, 104, 176, 241, 1, 31, 2, 208, 191, 72, 255, 247, 81, 254, 204, 72, 1, 104, 33, 240, 240, 1, 65, 240, 128, 1, 1, 96, 129, 104, 65, 240, 32, 1, 129, 96, 199, 73, 2, 34, 10, 96, 184, 74, 83, 109, 67, 240, 1, 3, 83, 101, 19, 104, 64, 242, 220, 85, 20, 104, 228, 26, 36, 3, 36, 11, 172, 66, 249, 211, 0, 35, 83, 101, 10, 104, 66, 240, 1, 2, 10, 96, 64, 104, 16, 240, 32, 15, 2, 208, 173, 72, 255, 247, 40, 254, 185, 73, 8, 104, 32, 240, 240, 0, 64, 240, 144, 0, 8, 96, 169, 72, 32, 34, 2, 101, 79, 244, 128, 114, 130, 97, 100, 34, 130, 96, 1, 34, 2, 96, 138, 104, 18, 240, 4, 15, 251, 208, 16, 33, 1, 98, 162, 73, 10, 104, 18, 240, 4, 15, 251, 208, 4, 34, 10, 96, 10, 104, 18, 240, 4, 15, 251, 208, 129, 107, 140, 28, 0, 33, 1, 101, 129, 97, 129, 96, 1, 96, 1, 98, 229, 8, 93, 45, 2, 210, 152, 72, 255, 247, 248, 253, 162, 72, 69, 97, 161, 8, 1, 240, 1, 1, 129, 97, 2, 33, 129, 96, 1, 33, 1, 96, 255, 247, 142, 255, 145, 76, 223, 248, 116, 130, 13, 241, 8, 9, 8, 224, 22, 248, 9, 0, 240, 85, 118, 28, 174, 66, 249, 211, 121, 32, 255, 247, 237, 253, 255, 247, 246, 253, 7, 70, 255, 247, 243, 253, 120, 64, 255, 40, 0, 208, 255, 39, 134, 72, 0, 104, 16, 240, 2, 15, 3, 208, 17, 47, 1, 211, 131, 47, 22, 211, 56, 0, 21, 208, 1, 47, 19, 208, 2, 47, 17, 208, 17, 47, 28, 208, 33, 47, 56, 208, 49, 47, 84, 208, 67, 47, 116, 208, 99, 47, 0, 240, 163, 128, 130, 47, 0, 240, 206, 128, 146, 47, 0, 240, 207, 128, 218, 224, 255, 247, 83, 255, 62, 93, 3, 224, 48, 93, 255, 247, 188, 253, 118, 28, 56, 25, 64, 120, 134, 66, 247, 211, 197, 231, 255, 247, 227, 253, 7, 70, 255, 247, 243, 253, 5, 70, 255, 247, 185, 253, 6, 70, 255, 247, 182, 253, 112, 64, 255, 40, 13, 209, 1, 45, 11, 208, 255, 247, 54, 255, 117, 28, 0, 38, 174, 66, 178, 210, 23, 248, 1, 11, 255, 247, 156, 253, 118, 28, 247, 231, 31, 32, 168, 231, 255, 247, 197, 253, 7, 70, 255, 247, 213, 253, 16, 47, 6, 210, 255, 247, 33, 255, 93, 72, 192, 25, 255, 247, 123, 253, 156, 231, 16, 240, 6, 15, 236, 208, 125, 104, 255, 247, 22, 255, 88, 72, 255, 247, 88, 253, 88, 72, 7, 96, 56, 104, 255, 247, 80, 253, 168, 71, 140, 231, 255, 247, 167, 253, 7, 70, 255, 247, 183, 253, 6, 70, 255, 247, 125, 253, 0, 240, 178, 248, 5, 70, 165, 177, 120, 25, 64, 30, 255, 247, 172, 253, 48, 67, 2, 40, 1, 209, 0, 38, 114, 231, 22, 240, 12, 15, 199, 208, 43, 70, 42, 70, 2, 169, 56, 70, 255, 247, 238, 253, 0, 40, 63, 244, 105, 175, 189, 231, 255, 247, 232, 254, 31, 37, 255, 247, 94, 253, 7, 70, 254, 47, 16, 211, 12, 191, 64, 242, 3, 54, 64, 242, 1, 54, 255, 247, 84, 253, 120, 64, 255, 40, 28, 209, 0, 33, 48, 70, 255, 247, 70, 254, 184, 185, 121, 37, 21, 224, 57, 70, 0, 240, 128, 248, 7, 0, 16, 208, 121, 37, 0, 38, 22, 248, 9, 0, 128, 2, 0, 241, 0, 97, 64, 242, 2, 48, 255, 247, 51, 254, 8, 177, 31, 37, 2, 224, 118, 28, 190, 66, 240, 211, 40, 70, 55, 231, 255, 247, 183, 254, 255, 247, 46, 253, 0, 240, 99, 248, 0, 40, 40, 208, 0, 33, 0, 38, 1, 35, 22, 248, 9, 32, 32, 42, 5, 210, 3, 250, 2, 242, 17, 67, 118, 28, 134, 66, 245, 211, 134, 66, 21, 211, 0, 38, 176, 0, 33, 250, 0, 240, 192, 178, 0, 170, 195, 67, 179, 84, 178, 24, 80, 112, 182, 28, 8, 46, 243, 211, 8, 35, 8, 34, 0, 169, 24, 72, 255, 247, 143, 253, 0, 40, 63, 244, 10, 175, 94, 231, 1, 32, 255, 247, 84, 254, 7, 231, 64, 70, 2, 224, 0, 33, 64, 248, 4, 27, 17, 73, 136, 66, 249, 211, 0, 32, 255, 247, 72, 254, 15, 72, 90, 231, 31, 32, 246, 230, 150, 7, 4, 8, 20, 1, 15, 240, 56, 32, 0, 64, 19, 1, 15, 240, 0, 240, 0, 64, 4, 168, 0, 64, 17, 1, 15, 240, 56, 7, 4, 8, 28, 128, 0, 64, 0, 1, 15, 240, 16, 1, 15, 240, 8, 237, 0, 224, 8, 8, 4, 8, 255, 31, 0, 32, 18, 1, 15, 240, 4, 176, 0, 64, 28, 64, 0, 64, 0, 180, 0, 64, 84, 200, 0, 64, 0, 2, 0, 32, 1, 70, 0, 191, 2, 168, 205, 228, 6, 72, 1, 33, 1, 96, 114, 182, 5, 72, 6, 73, 0, 34, 1, 224, 64, 248, 4, 43, 136, 66, 251, 211, 255, 247, 64, 190, 32, 64, 0, 64, 0, 0, 0, 32, 0, 2, 0, 32, 4, 16, 19, 22, 10, 2, 0, 1, 2, 17, 33, 49, 67, 99, 130, 146, 2, 0, 0, 1, 9, 169, 0, 0] +bootloader_cut_1_2v2 = [0, 2, 0, 32, 21, 7, 4, 8, 125, 0, 4, 8, 125, 0, 4, 8, 167, 15, 2, 0, 0, 0, 0, 0, 0, 8, 4, 8, 0, 0, 0, 8, 0, 2, 0, 32, 169, 1, 4, 8, 141, 2, 4, 8, 95, 234, 0, 13, 112, 71, 79, 240, 0, 81, 8, 96, 223, 248, 188, 6, 68, 242, 68, 65, 1, 96, 0, 34, 130, 96, 223, 248, 184, 6, 1, 96, 223, 248, 180, 6, 66, 97, 130, 97, 130, 96, 2, 96, 223, 248, 160, 6, 2, 96, 66, 96, 98, 182, 112, 71, 128, 181, 255, 247, 228, 255, 2, 72, 2, 73, 1, 96, 1, 189, 0, 191, 12, 237, 0, 224, 4, 0, 250, 5, 0, 72, 241, 231, 21, 1, 15, 240, 8, 73, 8, 96, 200, 104, 16, 240, 4, 15, 251, 208, 200, 104, 16, 240, 64, 15, 251, 208, 112, 71, 3, 72, 193, 104, 17, 240, 2, 15, 251, 208, 0, 104, 112, 71, 60, 200, 0, 64, 248, 181, 5, 70, 12, 0, 67, 191, 0, 38, 32, 70, 68, 66, 38, 70, 0, 39, 255, 247, 236, 255, 120, 85, 70, 64, 127, 28, 188, 66, 248, 210, 255, 247, 229, 255, 134, 66, 4, 208, 31, 32, 255, 247, 213, 255, 0, 32, 242, 189, 96, 28, 242, 189, 128, 181, 0, 240, 96, 249, 111, 240, 2, 1, 0, 168, 255, 247, 221, 255, 4, 40, 2, 208, 79, 240, 255, 48, 2, 189, 0, 240, 84, 249, 0, 152, 0, 186, 2, 189, 0, 0, 223, 248, 252, 21, 136, 66, 4, 211, 176, 241, 32, 47, 1, 210, 2, 32, 112, 71, 176, 241, 0, 111, 4, 211, 9, 73, 136, 66, 1, 210, 4, 32, 112, 71, 158, 73, 136, 66, 4, 211, 6, 73, 136, 66, 6, 210, 8, 32, 112, 71, 5, 73, 136, 66, 1, 211, 16, 32, 112, 71, 1, 32, 112, 71, 0, 0, 2, 8, 0, 10, 4, 8, 0, 0, 4, 8, 9, 72, 10, 73, 1, 96, 10, 74, 2, 96, 65, 96, 66, 96, 16, 73, 1, 34, 10, 96, 74, 104, 18, 240, 1, 15, 251, 208, 129, 104, 17, 240, 1, 15, 251, 209, 112, 71, 0, 191, 4, 128, 0, 64, 35, 1, 103, 69, 171, 137, 239, 205, 6, 72, 65, 104, 17, 240, 2, 15, 251, 209, 0, 33, 1, 96, 2, 72, 128, 33, 1, 96, 112, 71, 0, 191, 16, 128, 0, 64, 44, 64, 0, 64, 45, 233, 248, 67, 128, 70, 12, 70, 21, 70, 0, 38, 71, 70, 0, 45, 88, 208, 8, 240, 1, 0, 5, 240, 1, 1, 8, 67, 1, 208, 1, 32, 15, 224, 64, 70, 255, 247, 156, 255, 129, 70, 5, 235, 8, 0, 64, 30, 255, 247, 150, 255, 64, 234, 9, 0, 4, 40, 4, 208, 8, 40, 2, 208, 2, 32, 189, 232, 242, 131, 255, 247, 177, 255, 0, 32, 106, 73, 1, 224, 191, 28, 128, 28, 168, 66, 50, 210, 59, 136, 2, 25, 82, 120, 16, 248, 4, 128, 8, 235, 2, 34, 146, 178, 147, 66, 241, 208, 79, 246, 255, 120, 67, 69, 1, 208, 19, 0, 33, 209, 96, 75, 159, 66, 5, 211, 24, 75, 159, 66, 2, 210, 79, 244, 4, 115, 1, 224, 64, 242, 1, 35, 75, 96, 58, 128, 10, 104, 18, 240, 1, 15, 251, 209, 32, 34, 10, 96, 10, 104, 18, 240, 20, 15, 212, 208, 8, 104, 16, 240, 16, 15, 20, 191, 4, 38, 5, 38, 16, 32, 8, 96, 4, 32, 8, 96, 0, 224, 6, 38, 255, 247, 143, 255, 11, 224, 0, 32, 0, 224, 64, 28, 152, 66, 6, 210, 23, 248, 1, 27, 2, 93, 145, 66, 247, 208, 7, 32, 178, 231, 48, 70, 176, 231, 16, 8, 4, 8, 45, 233, 248, 67, 4, 70, 8, 70, 0, 39, 129, 10, 141, 2, 225, 178, 1, 41, 42, 209, 4, 38, 79, 240, 0, 104, 79, 244, 0, 73, 20, 244, 128, 127, 27, 208, 255, 247, 80, 255, 58, 72, 70, 96, 225, 178, 2, 41, 0, 209, 133, 96, 70, 240, 64, 1, 65, 96, 1, 104, 17, 240, 1, 15, 251, 209, 32, 33, 1, 96, 1, 104, 17, 240, 16, 15, 2, 208, 16, 33, 1, 96, 4, 39, 255, 247, 82, 255, 0, 47, 41, 209, 20, 244, 0, 127, 38, 208, 0, 32, 79, 240, 255, 50, 26, 224, 2, 41, 10, 209, 255, 247, 5, 255, 4, 40, 1, 208, 2, 32, 15, 224, 2, 38, 168, 70, 79, 244, 128, 121, 204, 231, 224, 178, 3, 40, 6, 209, 79, 244, 8, 118, 223, 248, 136, 128, 79, 240, 128, 9, 194, 231, 3, 32, 189, 232, 242, 131, 64, 28, 72, 69, 5, 210, 88, 248, 4, 27, 145, 66, 248, 208, 7, 32, 244, 231, 56, 70, 242, 231, 16, 181, 130, 176, 4, 70, 0, 240, 47, 248, 28, 177, 0, 32, 141, 248, 0, 0, 18, 224, 165, 32, 141, 248, 0, 0, 255, 247, 251, 254, 16, 76, 79, 244, 4, 112, 96, 96, 15, 72, 165, 33, 1, 128, 0, 33, 64, 242, 3, 16, 255, 247, 139, 255, 4, 32, 32, 96, 157, 248, 0, 0, 192, 67, 141, 248, 1, 0, 2, 35, 2, 34, 0, 169, 6, 72, 255, 247, 12, 255, 0, 40, 12, 191, 121, 32, 31, 32, 255, 247, 116, 254, 19, 189, 0, 0, 12, 128, 0, 64, 0, 8, 4, 8, 121, 32, 107, 230, 45, 233, 240, 67, 195, 176, 193, 72, 0, 104, 193, 73, 136, 66, 2, 208, 192, 72, 255, 247, 81, 254, 205, 72, 1, 104, 33, 240, 240, 1, 65, 240, 128, 1, 1, 96, 129, 104, 65, 240, 32, 1, 129, 96, 200, 73, 2, 34, 10, 96, 185, 74, 83, 109, 67, 240, 1, 3, 83, 101, 19, 104, 64, 242, 220, 85, 20, 104, 228, 26, 36, 3, 36, 11, 172, 66, 249, 211, 0, 35, 83, 101, 10, 104, 66, 240, 1, 2, 10, 96, 64, 104, 16, 240, 32, 15, 2, 208, 174, 72, 255, 247, 40, 254, 186, 73, 8, 104, 32, 240, 240, 0, 64, 240, 144, 0, 8, 96, 170, 72, 32, 34, 2, 101, 79, 244, 128, 114, 130, 97, 100, 34, 130, 96, 1, 34, 2, 96, 138, 104, 18, 240, 4, 15, 251, 208, 16, 33, 1, 98, 163, 73, 10, 104, 18, 240, 4, 15, 251, 208, 4, 34, 10, 96, 10, 104, 18, 240, 4, 15, 251, 208, 129, 107, 140, 28, 0, 33, 1, 101, 129, 97, 129, 96, 1, 96, 1, 98, 229, 8, 93, 45, 2, 210, 153, 72, 255, 247, 248, 253, 163, 72, 69, 97, 161, 8, 1, 240, 1, 1, 129, 97, 2, 33, 129, 96, 1, 33, 1, 96, 255, 247, 142, 255, 146, 76, 223, 248, 120, 130, 13, 241, 8, 9, 8, 224, 22, 248, 9, 0, 240, 85, 118, 28, 174, 66, 249, 211, 121, 32, 255, 247, 237, 253, 255, 247, 246, 253, 7, 70, 255, 247, 243, 253, 120, 64, 255, 40, 0, 208, 255, 39, 135, 72, 0, 104, 16, 240, 2, 15, 3, 208, 17, 47, 1, 211, 131, 47, 22, 211, 56, 0, 21, 208, 1, 47, 19, 208, 2, 47, 17, 208, 17, 47, 28, 208, 33, 47, 56, 208, 49, 47, 84, 208, 67, 47, 116, 208, 99, 47, 0, 240, 163, 128, 130, 47, 0, 240, 206, 128, 146, 47, 0, 240, 207, 128, 218, 224, 255, 247, 83, 255, 62, 93, 3, 224, 48, 93, 255, 247, 188, 253, 118, 28, 56, 25, 64, 120, 134, 66, 247, 211, 197, 231, 255, 247, 227, 253, 7, 70, 255, 247, 243, 253, 5, 70, 255, 247, 185, 253, 6, 70, 255, 247, 182, 253, 112, 64, 255, 40, 13, 209, 1, 45, 11, 208, 255, 247, 54, 255, 117, 28, 0, 38, 174, 66, 178, 210, 23, 248, 1, 11, 255, 247, 156, 253, 118, 28, 247, 231, 31, 32, 168, 231, 255, 247, 197, 253, 7, 70, 255, 247, 213, 253, 16, 47, 6, 210, 255, 247, 33, 255, 94, 72, 192, 25, 255, 247, 123, 253, 156, 231, 16, 240, 6, 15, 236, 208, 125, 104, 255, 247, 22, 255, 89, 72, 255, 247, 88, 253, 89, 72, 7, 96, 56, 104, 255, 247, 80, 253, 168, 71, 140, 231, 255, 247, 167, 253, 7, 70, 255, 247, 183, 253, 6, 70, 255, 247, 125, 253, 0, 240, 180, 248, 5, 70, 165, 177, 120, 25, 64, 30, 255, 247, 172, 253, 48, 67, 2, 40, 1, 209, 0, 38, 114, 231, 22, 240, 12, 15, 199, 208, 43, 70, 42, 70, 2, 169, 56, 70, 255, 247, 238, 253, 0, 40, 63, 244, 105, 175, 189, 231, 255, 247, 232, 254, 31, 37, 255, 247, 94, 253, 7, 70, 254, 47, 16, 211, 12, 191, 64, 242, 3, 54, 64, 242, 1, 54, 255, 247, 84, 253, 120, 64, 255, 40, 28, 209, 0, 33, 48, 70, 255, 247, 70, 254, 184, 185, 121, 37, 21, 224, 57, 70, 0, 240, 130, 248, 7, 0, 16, 208, 121, 37, 0, 38, 22, 248, 9, 0, 128, 2, 0, 241, 0, 97, 64, 242, 2, 48, 255, 247, 51, 254, 8, 177, 31, 37, 2, 224, 118, 28, 190, 66, 240, 211, 40, 70, 55, 231, 255, 247, 183, 254, 255, 247, 46, 253, 0, 240, 101, 248, 0, 40, 40, 208, 0, 33, 0, 38, 1, 35, 22, 248, 9, 32, 32, 42, 5, 210, 3, 250, 2, 242, 17, 67, 118, 28, 134, 66, 245, 211, 134, 66, 21, 211, 0, 38, 176, 0, 33, 250, 0, 240, 192, 178, 0, 170, 195, 67, 179, 84, 178, 24, 80, 112, 182, 28, 8, 46, 243, 211, 8, 35, 8, 34, 0, 169, 25, 72, 255, 247, 143, 253, 0, 40, 63, 244, 10, 175, 94, 231, 1, 32, 255, 247, 84, 254, 7, 231, 64, 70, 2, 224, 0, 33, 64, 248, 4, 27, 18, 73, 136, 66, 249, 211, 0, 32, 255, 247, 72, 254, 16, 72, 90, 231, 31, 32, 246, 230, 150, 7, 4, 8, 1, 0, 2, 0, 20, 1, 15, 240, 56, 32, 0, 64, 19, 1, 15, 240, 0, 240, 0, 64, 4, 168, 0, 64, 17, 1, 15, 240, 60, 7, 4, 8, 28, 128, 0, 64, 0, 1, 15, 240, 16, 1, 15, 240, 8, 237, 0, 224, 8, 8, 4, 8, 255, 31, 0, 32, 18, 1, 15, 240, 4, 176, 0, 64, 28, 64, 0, 64, 0, 180, 0, 64, 84, 200, 0, 64, 0, 2, 0, 32, 1, 70, 0, 191, 2, 168, 203, 228, 6, 72, 1, 33, 1, 96, 114, 182, 5, 72, 6, 73, 0, 34, 1, 224, 64, 248, 4, 43, 136, 66, 251, 211, 255, 247, 62, 190, 32, 64, 0, 64, 0, 0, 0, 32, 0, 2, 0, 32, 4, 16, 19, 22, 10, 2, 0, 1, 2, 17, 33, 49, 67, 99, 130, 146, 2, 0, 0, 1, 9, 169, 0, 0] +bootloader_cut_1_2v3 = [0, 2, 0, 32, 21, 7, 4, 8, 125, 0, 4, 8, 125, 0, 4, 8, 167, 15, 3, 0, 0, 0, 0, 0, 0, 8, 4, 8, 0, 0, 0, 8, 0, 2, 0, 32, 169, 1, 4, 8, 141, 2, 4, 8, 95, 234, 0, 13, 112, 71, 79, 240, 0, 81, 8, 96, 223, 248, 188, 6, 68, 242, 68, 65, 1, 96, 0, 34, 130, 96, 223, 248, 184, 6, 1, 96, 223, 248, 180, 6, 66, 97, 130, 97, 130, 96, 2, 96, 223, 248, 160, 6, 2, 96, 66, 96, 98, 182, 112, 71, 128, 181, 255, 247, 228, 255, 2, 72, 2, 73, 1, 96, 1, 189, 0, 191, 12, 237, 0, 224, 4, 0, 250, 5, 0, 72, 241, 231, 21, 1, 15, 240, 8, 73, 8, 96, 200, 104, 16, 240, 4, 15, 251, 208, 200, 104, 16, 240, 64, 15, 251, 208, 112, 71, 3, 72, 193, 104, 17, 240, 2, 15, 251, 208, 0, 104, 112, 71, 60, 200, 0, 64, 248, 181, 5, 70, 12, 0, 67, 191, 0, 38, 32, 70, 68, 66, 38, 70, 0, 39, 255, 247, 236, 255, 120, 85, 70, 64, 127, 28, 188, 66, 248, 210, 255, 247, 229, 255, 134, 66, 4, 208, 31, 32, 255, 247, 213, 255, 0, 32, 242, 189, 96, 28, 242, 189, 128, 181, 0, 240, 96, 249, 111, 240, 2, 1, 0, 168, 255, 247, 221, 255, 4, 40, 2, 208, 79, 240, 255, 48, 2, 189, 0, 240, 84, 249, 0, 152, 0, 186, 2, 189, 0, 0, 223, 248, 252, 21, 136, 66, 4, 211, 176, 241, 32, 47, 1, 210, 2, 32, 112, 71, 176, 241, 0, 111, 4, 211, 9, 73, 136, 66, 1, 210, 4, 32, 112, 71, 158, 73, 136, 66, 4, 211, 6, 73, 136, 66, 6, 210, 8, 32, 112, 71, 5, 73, 136, 66, 1, 211, 16, 32, 112, 71, 1, 32, 112, 71, 0, 0, 2, 8, 0, 10, 4, 8, 0, 0, 4, 8, 9, 72, 10, 73, 1, 96, 10, 74, 2, 96, 65, 96, 66, 96, 16, 73, 1, 34, 10, 96, 74, 104, 18, 240, 1, 15, 251, 208, 129, 104, 17, 240, 1, 15, 251, 209, 112, 71, 0, 191, 4, 128, 0, 64, 35, 1, 103, 69, 171, 137, 239, 205, 6, 72, 65, 104, 17, 240, 2, 15, 251, 209, 0, 33, 1, 96, 2, 72, 128, 33, 1, 96, 112, 71, 0, 191, 16, 128, 0, 64, 44, 64, 0, 64, 45, 233, 248, 67, 128, 70, 12, 70, 21, 70, 0, 38, 71, 70, 0, 45, 88, 208, 8, 240, 1, 0, 5, 240, 1, 1, 8, 67, 1, 208, 1, 32, 15, 224, 64, 70, 255, 247, 156, 255, 129, 70, 5, 235, 8, 0, 64, 30, 255, 247, 150, 255, 64, 234, 9, 0, 4, 40, 4, 208, 8, 40, 2, 208, 2, 32, 189, 232, 242, 131, 255, 247, 177, 255, 0, 32, 106, 73, 1, 224, 191, 28, 128, 28, 168, 66, 50, 210, 59, 136, 2, 25, 82, 120, 16, 248, 4, 128, 8, 235, 2, 34, 146, 178, 147, 66, 241, 208, 79, 246, 255, 120, 67, 69, 1, 208, 19, 0, 33, 209, 96, 75, 159, 66, 5, 211, 24, 75, 159, 66, 2, 210, 79, 244, 4, 115, 1, 224, 64, 242, 1, 35, 75, 96, 58, 128, 10, 104, 18, 240, 1, 15, 251, 209, 32, 34, 10, 96, 10, 104, 18, 240, 20, 15, 212, 208, 8, 104, 16, 240, 16, 15, 20, 191, 4, 38, 5, 38, 16, 32, 8, 96, 4, 32, 8, 96, 0, 224, 6, 38, 255, 247, 143, 255, 11, 224, 0, 32, 0, 224, 64, 28, 152, 66, 6, 210, 23, 248, 1, 27, 2, 93, 145, 66, 247, 208, 7, 32, 178, 231, 48, 70, 176, 231, 16, 8, 4, 8, 45, 233, 248, 67, 4, 70, 8, 70, 0, 39, 129, 10, 141, 2, 225, 178, 1, 41, 42, 209, 4, 38, 79, 240, 0, 104, 79, 244, 0, 73, 20, 244, 128, 127, 27, 208, 255, 247, 80, 255, 58, 72, 70, 96, 225, 178, 2, 41, 0, 209, 133, 96, 70, 240, 64, 1, 65, 96, 1, 104, 17, 240, 1, 15, 251, 209, 32, 33, 1, 96, 1, 104, 17, 240, 16, 15, 2, 208, 16, 33, 1, 96, 4, 39, 255, 247, 82, 255, 0, 47, 41, 209, 20, 244, 0, 127, 38, 208, 0, 32, 79, 240, 255, 50, 26, 224, 2, 41, 10, 209, 255, 247, 5, 255, 4, 40, 1, 208, 2, 32, 15, 224, 2, 38, 168, 70, 79, 244, 128, 121, 204, 231, 224, 178, 3, 40, 6, 209, 79, 244, 8, 118, 223, 248, 136, 128, 79, 240, 128, 9, 194, 231, 3, 32, 189, 232, 242, 131, 64, 28, 72, 69, 5, 210, 88, 248, 4, 27, 145, 66, 248, 208, 7, 32, 244, 231, 56, 70, 242, 231, 16, 181, 130, 176, 4, 70, 0, 240, 47, 248, 28, 177, 0, 32, 141, 248, 0, 0, 18, 224, 165, 32, 141, 248, 0, 0, 255, 247, 251, 254, 16, 76, 79, 244, 4, 112, 96, 96, 15, 72, 165, 33, 1, 128, 0, 33, 64, 242, 3, 16, 255, 247, 139, 255, 4, 32, 32, 96, 157, 248, 0, 0, 192, 67, 141, 248, 1, 0, 2, 35, 2, 34, 0, 169, 6, 72, 255, 247, 12, 255, 0, 40, 12, 191, 121, 32, 31, 32, 255, 247, 116, 254, 19, 189, 0, 0, 12, 128, 0, 64, 0, 8, 4, 8, 121, 32, 107, 230, 45, 233, 240, 67, 195, 176, 193, 72, 0, 104, 193, 73, 136, 66, 2, 208, 192, 72, 255, 247, 81, 254, 205, 72, 1, 104, 33, 240, 240, 1, 65, 240, 128, 1, 1, 96, 129, 104, 65, 240, 32, 1, 129, 96, 200, 73, 2, 34, 10, 96, 185, 74, 83, 109, 67, 240, 1, 3, 83, 101, 19, 104, 64, 242, 220, 85, 20, 104, 228, 26, 36, 3, 36, 11, 172, 66, 249, 211, 0, 35, 83, 101, 10, 104, 66, 240, 1, 2, 10, 96, 64, 104, 16, 240, 32, 15, 2, 208, 174, 72, 255, 247, 40, 254, 186, 73, 8, 104, 32, 240, 240, 0, 64, 240, 144, 0, 8, 96, 170, 72, 32, 34, 2, 101, 79, 244, 128, 114, 130, 97, 100, 34, 130, 96, 1, 34, 2, 96, 138, 104, 18, 240, 4, 15, 251, 208, 16, 33, 1, 98, 163, 73, 10, 104, 18, 240, 4, 15, 251, 208, 4, 34, 10, 96, 10, 104, 18, 240, 4, 15, 251, 208, 129, 107, 140, 28, 0, 33, 1, 101, 129, 97, 129, 96, 1, 96, 1, 98, 229, 8, 93, 45, 2, 210, 153, 72, 255, 247, 248, 253, 163, 72, 69, 97, 161, 8, 1, 240, 1, 1, 129, 97, 2, 33, 129, 96, 1, 33, 1, 96, 255, 247, 142, 255, 146, 76, 223, 248, 120, 130, 13, 241, 8, 9, 8, 224, 22, 248, 9, 0, 240, 85, 118, 28, 174, 66, 249, 211, 121, 32, 255, 247, 237, 253, 255, 247, 246, 253, 7, 70, 255, 247, 243, 253, 120, 64, 255, 40, 0, 208, 255, 39, 135, 72, 0, 104, 16, 240, 2, 15, 3, 208, 17, 47, 1, 211, 131, 47, 22, 211, 56, 0, 21, 208, 1, 47, 19, 208, 2, 47, 17, 208, 17, 47, 28, 208, 33, 47, 56, 208, 49, 47, 84, 208, 67, 47, 116, 208, 99, 47, 0, 240, 163, 128, 130, 47, 0, 240, 206, 128, 146, 47, 0, 240, 207, 128, 218, 224, 255, 247, 83, 255, 62, 93, 3, 224, 48, 93, 255, 247, 188, 253, 118, 28, 56, 25, 64, 120, 134, 66, 247, 211, 197, 231, 255, 247, 227, 253, 7, 70, 255, 247, 243, 253, 5, 70, 255, 247, 185, 253, 6, 70, 255, 247, 182, 253, 112, 64, 255, 40, 13, 209, 1, 45, 11, 208, 255, 247, 54, 255, 117, 28, 0, 38, 174, 66, 178, 210, 23, 248, 1, 11, 255, 247, 156, 253, 118, 28, 247, 231, 31, 32, 168, 231, 255, 247, 197, 253, 7, 70, 255, 247, 213, 253, 16, 47, 6, 210, 255, 247, 33, 255, 94, 72, 192, 25, 255, 247, 123, 253, 156, 231, 16, 240, 6, 15, 236, 208, 125, 104, 255, 247, 22, 255, 89, 72, 255, 247, 88, 253, 89, 72, 7, 96, 56, 104, 255, 247, 80, 253, 168, 71, 140, 231, 255, 247, 167, 253, 7, 70, 255, 247, 183, 253, 6, 70, 255, 247, 125, 253, 0, 240, 180, 248, 5, 70, 165, 177, 120, 25, 64, 30, 255, 247, 172, 253, 48, 67, 2, 40, 1, 209, 0, 38, 114, 231, 22, 240, 12, 15, 199, 208, 43, 70, 42, 70, 2, 169, 56, 70, 255, 247, 238, 253, 0, 40, 63, 244, 105, 175, 189, 231, 255, 247, 232, 254, 31, 37, 255, 247, 94, 253, 7, 70, 254, 47, 16, 211, 12, 191, 64, 242, 3, 54, 64, 242, 1, 54, 255, 247, 84, 253, 120, 64, 255, 40, 28, 209, 0, 33, 48, 70, 255, 247, 70, 254, 184, 185, 121, 37, 21, 224, 57, 70, 0, 240, 130, 248, 7, 0, 16, 208, 121, 37, 0, 38, 22, 248, 9, 0, 128, 2, 0, 241, 0, 97, 64, 242, 2, 48, 255, 247, 51, 254, 8, 177, 31, 37, 2, 224, 118, 28, 190, 66, 240, 211, 40, 70, 55, 231, 255, 247, 183, 254, 255, 247, 46, 253, 0, 240, 101, 248, 0, 40, 40, 208, 0, 33, 0, 38, 1, 35, 22, 248, 9, 32, 32, 42, 5, 210, 3, 250, 2, 242, 17, 67, 118, 28, 134, 66, 245, 211, 134, 66, 21, 211, 0, 38, 176, 0, 33, 250, 0, 240, 192, 178, 0, 170, 195, 67, 179, 84, 178, 24, 80, 112, 182, 28, 8, 46, 243, 211, 8, 35, 8, 34, 0, 169, 25, 72, 255, 247, 143, 253, 0, 40, 63, 244, 10, 175, 94, 231, 1, 32, 255, 247, 84, 254, 7, 231, 64, 70, 2, 224, 0, 33, 64, 248, 4, 27, 18, 73, 136, 66, 249, 211, 0, 32, 255, 247, 72, 254, 16, 72, 90, 231, 31, 32, 246, 230, 150, 7, 4, 8, 1, 0, 2, 0, 20, 1, 15, 240, 56, 32, 0, 64, 19, 1, 15, 240, 0, 240, 0, 64, 4, 168, 0, 64, 17, 1, 15, 240, 72, 7, 4, 8, 28, 128, 0, 64, 0, 1, 15, 240, 16, 1, 15, 240, 8, 237, 0, 224, 8, 8, 4, 8, 255, 31, 0, 32, 18, 1, 15, 240, 4, 176, 0, 64, 28, 64, 0, 64, 0, 180, 0, 64, 84, 200, 0, 64, 0, 2, 0, 32, 1, 70, 0, 191, 2, 168, 203, 228, 8, 72, 64, 242, 7, 49, 1, 96, 7, 72, 1, 33, 1, 96, 114, 182, 6, 72, 7, 73, 0, 34, 1, 224, 64, 248, 4, 43, 136, 66, 251, 211, 255, 247, 58, 190, 24, 0, 0, 64, 32, 64, 0, 64, 0, 0, 0, 32, 0, 2, 0, 32, 4, 16, 19, 22, 10, 3, 0, 1, 2, 17, 33, 49, 67, 99, 130, 146, 3, 0, 0, 1, 9, 168, 0, 0] +bootloader_cut_1_3v3 = [0, 2, 0, 32, 25, 7, 4, 8, 125, 0, 4, 8, 125, 0, 4, 8, 167, 15, 3, 0, 0, 0, 0, 0, 0, 8, 4, 8, 0, 0, 0, 8, 0, 2, 0, 32, 169, 1, 4, 8, 141, 2, 4, 8, 95, 234, 0, 13, 112, 71, 79, 240, 0, 81, 8, 96, 223, 248, 192, 6, 68, 242, 68, 65, 1, 96, 0, 34, 130, 96, 223, 248, 188, 6, 1, 96, 223, 248, 184, 6, 66, 97, 130, 97, 130, 96, 2, 96, 223, 248, 164, 6, 2, 96, 66, 96, 98, 182, 112, 71, 128, 181, 255, 247, 228, 255, 2, 72, 2, 73, 1, 96, 1, 189, 0, 191, 12, 237, 0, 224, 4, 0, 250, 5, 0, 72, 241, 231, 21, 1, 15, 240, 8, 73, 8, 96, 200, 104, 16, 240, 4, 15, 251, 208, 200, 104, 16, 240, 64, 15, 251, 208, 112, 71, 3, 72, 193, 104, 17, 240, 2, 15, 251, 208, 0, 104, 112, 71, 60, 200, 0, 64, 248, 181, 5, 70, 12, 0, 67, 191, 0, 38, 32, 70, 68, 66, 38, 70, 0, 39, 255, 247, 236, 255, 120, 85, 70, 64, 127, 28, 188, 66, 248, 210, 255, 247, 229, 255, 134, 66, 4, 208, 31, 32, 255, 247, 213, 255, 0, 32, 242, 189, 96, 28, 242, 189, 128, 181, 0, 240, 96, 249, 111, 240, 2, 1, 0, 168, 255, 247, 221, 255, 4, 40, 2, 208, 79, 240, 255, 48, 2, 189, 0, 240, 84, 249, 0, 152, 0, 186, 2, 189, 0, 0, 223, 248, 0, 22, 136, 66, 4, 211, 176, 241, 32, 47, 1, 210, 2, 32, 112, 71, 176, 241, 0, 111, 4, 211, 9, 73, 136, 66, 1, 210, 4, 32, 112, 71, 158, 73, 136, 66, 4, 211, 6, 73, 136, 66, 6, 210, 8, 32, 112, 71, 5, 73, 136, 66, 1, 211, 16, 32, 112, 71, 1, 32, 112, 71, 0, 0, 2, 8, 0, 10, 4, 8, 0, 0, 4, 8, 9, 72, 10, 73, 1, 96, 10, 74, 2, 96, 65, 96, 66, 96, 16, 73, 1, 34, 10, 96, 74, 104, 18, 240, 1, 15, 251, 208, 129, 104, 17, 240, 1, 15, 251, 209, 112, 71, 0, 191, 4, 128, 0, 64, 35, 1, 103, 69, 171, 137, 239, 205, 6, 72, 65, 104, 17, 240, 2, 15, 251, 209, 0, 33, 1, 96, 2, 72, 128, 33, 1, 96, 112, 71, 0, 191, 16, 128, 0, 64, 44, 64, 0, 64, 45, 233, 248, 67, 128, 70, 12, 70, 21, 70, 0, 38, 71, 70, 0, 45, 88, 208, 8, 240, 1, 0, 5, 240, 1, 1, 8, 67, 1, 208, 1, 32, 15, 224, 64, 70, 255, 247, 156, 255, 129, 70, 5, 235, 8, 0, 64, 30, 255, 247, 150, 255, 64, 234, 9, 0, 4, 40, 4, 208, 8, 40, 2, 208, 2, 32, 189, 232, 242, 131, 255, 247, 177, 255, 0, 32, 106, 73, 1, 224, 191, 28, 128, 28, 168, 66, 50, 210, 59, 136, 2, 25, 82, 120, 16, 248, 4, 128, 8, 235, 2, 34, 146, 178, 147, 66, 241, 208, 79, 246, 255, 120, 67, 69, 1, 208, 19, 0, 33, 209, 96, 75, 159, 66, 5, 211, 24, 75, 159, 66, 2, 210, 79, 244, 4, 115, 1, 224, 64, 242, 1, 35, 75, 96, 58, 128, 10, 104, 18, 240, 1, 15, 251, 209, 32, 34, 10, 96, 10, 104, 18, 240, 20, 15, 212, 208, 8, 104, 16, 240, 16, 15, 20, 191, 4, 38, 5, 38, 16, 32, 8, 96, 4, 32, 8, 96, 0, 224, 6, 38, 255, 247, 143, 255, 11, 224, 0, 32, 0, 224, 64, 28, 152, 66, 6, 210, 23, 248, 1, 27, 2, 93, 145, 66, 247, 208, 7, 32, 178, 231, 48, 70, 176, 231, 16, 8, 4, 8, 45, 233, 248, 67, 4, 70, 8, 70, 0, 39, 129, 10, 141, 2, 225, 178, 1, 41, 42, 209, 4, 38, 79, 240, 0, 104, 79, 244, 0, 73, 20, 244, 128, 127, 27, 208, 255, 247, 80, 255, 58, 72, 70, 96, 225, 178, 2, 41, 0, 209, 133, 96, 70, 240, 64, 1, 65, 96, 1, 104, 17, 240, 1, 15, 251, 209, 32, 33, 1, 96, 1, 104, 17, 240, 16, 15, 2, 208, 16, 33, 1, 96, 4, 39, 255, 247, 82, 255, 0, 47, 41, 209, 20, 244, 0, 127, 38, 208, 0, 32, 79, 240, 255, 50, 26, 224, 2, 41, 10, 209, 255, 247, 5, 255, 4, 40, 1, 208, 2, 32, 15, 224, 2, 38, 168, 70, 79, 244, 128, 121, 204, 231, 224, 178, 3, 40, 6, 209, 79, 244, 8, 118, 223, 248, 136, 128, 79, 240, 128, 9, 194, 231, 3, 32, 189, 232, 242, 131, 64, 28, 72, 69, 5, 210, 88, 248, 4, 27, 145, 66, 248, 208, 7, 32, 244, 231, 56, 70, 242, 231, 16, 181, 130, 176, 4, 70, 0, 240, 47, 248, 28, 177, 0, 32, 141, 248, 0, 0, 18, 224, 165, 32, 141, 248, 0, 0, 255, 247, 251, 254, 16, 76, 79, 244, 4, 112, 96, 96, 15, 72, 165, 33, 1, 128, 0, 33, 64, 242, 3, 16, 255, 247, 139, 255, 4, 32, 32, 96, 157, 248, 0, 0, 192, 67, 141, 248, 1, 0, 2, 35, 2, 34, 0, 169, 6, 72, 255, 247, 12, 255, 0, 40, 12, 191, 121, 32, 31, 32, 255, 247, 116, 254, 19, 189, 0, 0, 12, 128, 0, 64, 0, 8, 4, 8, 121, 32, 107, 230, 45, 233, 240, 67, 195, 176, 194, 72, 0, 104, 0, 2, 0, 10, 193, 73, 136, 66, 2, 208, 192, 72, 255, 247, 79, 254, 205, 72, 1, 104, 33, 240, 240, 1, 65, 240, 128, 1, 1, 96, 129, 104, 65, 240, 32, 1, 129, 96, 200, 73, 2, 34, 10, 96, 185, 74, 83, 109, 67, 240, 1, 3, 83, 101, 19, 104, 64, 242, 220, 85, 20, 104, 228, 26, 36, 3, 36, 11, 172, 66, 249, 211, 0, 35, 83, 101, 10, 104, 66, 240, 1, 2, 10, 96, 64, 104, 16, 240, 32, 15, 2, 208, 174, 72, 255, 247, 38, 254, 186, 73, 8, 104, 32, 240, 240, 0, 64, 240, 144, 0, 8, 96, 170, 72, 32, 34, 2, 101, 79, 244, 128, 114, 130, 97, 100, 34, 130, 96, 1, 34, 2, 96, 138, 104, 18, 240, 4, 15, 251, 208, 16, 33, 1, 98, 163, 73, 10, 104, 18, 240, 4, 15, 251, 208, 4, 34, 10, 96, 10, 104, 18, 240, 4, 15, 251, 208, 129, 107, 140, 28, 0, 33, 1, 101, 129, 97, 129, 96, 1, 96, 1, 98, 229, 8, 93, 45, 2, 210, 153, 72, 255, 247, 246, 253, 163, 72, 69, 97, 161, 8, 1, 240, 1, 1, 129, 97, 2, 33, 129, 96, 1, 33, 1, 96, 255, 247, 140, 255, 146, 76, 223, 248, 120, 130, 13, 241, 8, 9, 8, 224, 22, 248, 9, 0, 240, 85, 118, 28, 174, 66, 249, 211, 121, 32, 255, 247, 235, 253, 255, 247, 244, 253, 7, 70, 255, 247, 241, 253, 120, 64, 255, 40, 0, 208, 255, 39, 135, 72, 0, 104, 16, 240, 2, 15, 3, 208, 17, 47, 1, 211, 131, 47, 22, 211, 56, 0, 21, 208, 1, 47, 19, 208, 2, 47, 17, 208, 17, 47, 28, 208, 33, 47, 56, 208, 49, 47, 84, 208, 67, 47, 116, 208, 99, 47, 0, 240, 163, 128, 130, 47, 0, 240, 206, 128, 146, 47, 0, 240, 207, 128, 218, 224, 255, 247, 81, 255, 62, 93, 3, 224, 48, 93, 255, 247, 186, 253, 118, 28, 56, 25, 64, 120, 134, 66, 247, 211, 197, 231, 255, 247, 225, 253, 7, 70, 255, 247, 241, 253, 5, 70, 255, 247, 183, 253, 6, 70, 255, 247, 180, 253, 112, 64, 255, 40, 13, 209, 1, 45, 11, 208, 255, 247, 52, 255, 117, 28, 0, 38, 174, 66, 178, 210, 23, 248, 1, 11, 255, 247, 154, 253, 118, 28, 247, 231, 31, 32, 168, 231, 255, 247, 195, 253, 7, 70, 255, 247, 211, 253, 16, 47, 6, 210, 255, 247, 31, 255, 94, 72, 192, 25, 255, 247, 121, 253, 156, 231, 16, 240, 6, 15, 236, 208, 125, 104, 255, 247, 20, 255, 89, 72, 255, 247, 86, 253, 89, 72, 7, 96, 56, 104, 255, 247, 78, 253, 168, 71, 140, 231, 255, 247, 165, 253, 7, 70, 255, 247, 181, 253, 6, 70, 255, 247, 123, 253, 0, 240, 180, 248, 5, 70, 165, 177, 120, 25, 64, 30, 255, 247, 170, 253, 48, 67, 2, 40, 1, 209, 0, 38, 114, 231, 22, 240, 12, 15, 199, 208, 43, 70, 42, 70, 2, 169, 56, 70, 255, 247, 236, 253, 0, 40, 63, 244, 105, 175, 189, 231, 255, 247, 230, 254, 31, 37, 255, 247, 92, 253, 7, 70, 254, 47, 16, 211, 12, 191, 64, 242, 3, 54, 64, 242, 1, 54, 255, 247, 82, 253, 120, 64, 255, 40, 28, 209, 0, 33, 48, 70, 255, 247, 68, 254, 184, 185, 121, 37, 21, 224, 57, 70, 0, 240, 130, 248, 7, 0, 16, 208, 121, 37, 0, 38, 22, 248, 9, 0, 128, 2, 0, 241, 0, 97, 64, 242, 2, 48, 255, 247, 49, 254, 8, 177, 31, 37, 2, 224, 118, 28, 190, 66, 240, 211, 40, 70, 55, 231, 255, 247, 181, 254, 255, 247, 44, 253, 0, 240, 101, 248, 0, 40, 40, 208, 0, 33, 0, 38, 1, 35, 22, 248, 9, 32, 32, 42, 5, 210, 3, 250, 2, 242, 17, 67, 118, 28, 134, 66, 245, 211, 134, 66, 21, 211, 0, 38, 176, 0, 33, 250, 0, 240, 192, 178, 0, 170, 195, 67, 179, 84, 178, 24, 80, 112, 182, 28, 8, 46, 243, 211, 8, 35, 8, 34, 0, 169, 25, 72, 255, 247, 141, 253, 0, 40, 63, 244, 10, 175, 94, 231, 1, 32, 255, 247, 82, 254, 7, 231, 64, 70, 2, 224, 0, 33, 64, 248, 4, 27, 18, 73, 136, 66, 249, 211, 0, 32, 255, 247, 70, 254, 16, 72, 90, 231, 31, 32, 246, 230, 150, 7, 4, 8, 1, 0, 3, 0, 20, 1, 15, 240, 56, 32, 0, 64, 19, 1, 15, 240, 0, 240, 0, 64, 4, 168, 0, 64, 17, 1, 15, 240, 76, 7, 4, 8, 28, 128, 0, 64, 0, 1, 15, 240, 16, 1, 15, 240, 8, 237, 0, 224, 8, 8, 4, 8, 255, 31, 0, 32, 18, 1, 15, 240, 4, 176, 0, 64, 28, 64, 0, 64, 0, 180, 0, 64, 84, 200, 0, 64, 0, 2, 0, 32, 1, 70, 0, 191, 2, 168, 201, 228, 8, 72, 64, 242, 7, 49, 1, 96, 7, 72, 1, 33, 1, 96, 114, 182, 6, 72, 7, 73, 0, 34, 1, 224, 64, 248, 4, 43, 136, 66, 251, 211, 255, 247, 56, 190, 24, 0, 0, 64, 32, 64, 0, 64, 0, 0, 0, 32, 0, 2, 0, 32, 4, 16, 19, 22, 10, 3, 0, 1, 2, 17, 33, 49, 67, 99, 130, 146, 3, 0, 0, 1, 9, 168, 0, 0] +cibDecoder = None +fibDecoder = None + +class IBDecoder(object): + def __init__(self, baseAddress, decodeInfo): + self.baseAddress = baseAddress + self.decodeInfo = [] + for i in decodeInfo: + CName = None + if len(i) > 6: + CName = (i[6]) + self.decodeInfo = (self.decodeInfo + [IBEntry((i[0]), (i[1]), (i[2]), (i[3]), (i[4]), (i[5]), CName)]) + + def decodeRawData(self, rawData): + for i in self.decodeInfo: + i.rawData = rawData[(i.address - (self.baseAddress & 65535)):((i.address - (self.baseAddress & 65535)) + i.length)] + autoData = None + if i.name == 'Die Info Checksum': + autoData = rawData[1918:1936] + else: + if i.name == 'Configuration Info Checksum': + autoData = rawData[1942:30710] + item0, item1 = i.type.decode(i.rawData, i.validRange, autoData, rawData) + i.valid = item0 + i.value = item1 + + +class IBEntry(object): + def __init__(self, name, address, length, description, validRange, type, CName=None): + self.name = name + self.address = address + self.length = length + self.description = description + self.validRange = validRange + self.type = type + self.value = None + self.CName = CName + self.rawData = None + self.valid = None + + +class VALUE(object): + def __init__(self, type): + self.type = type + + def decode(self, data, validRange, autoData=None, rawData=None): + valid = True + minVal, maxVal = validRangeMinMax(validRange) + if minVal != None: + tempValue = 0 + for i in range(len(data)): + tempValue = (tempValue + ((data[i]) << (8 * i))) + continue + if (tempValue < minVal or tempValue > maxVal): + valid = False + if self.type == U16: + retVal = ('0x%04X' % ((data[0]) + ((data[1]) << 8))) + else: + if self.type == DATE: + tmp = ((data[0]) + ((data[1]) << 8)) + try: + retVal = time.strftime('%a, %d %b %Y', time.localtime(((tmp * 24) * 3600))) + except: + retVal = 'Invalid' + else: + if self.type == ASCII_REVERSED: + retVal = ''.join(('%c' % a) for a in reversed(data)) + else: + if self.type == ASCII: + try: + dataTemp = data[:data.index(255)] + except ValueError: + dataTemp = data + retVal = ''.join(('%c' % a) for a in dataTemp) + else: + if self.type == X_Y_TSMC: + retVal = ('x = %d, y = %d' % ((data[1]), (data[0]))) + else: + if self.type == U8: + retVal = ('0x%02X' % (data[0])) + else: + if self.type == DIE_REV: + dieRevMap = ['cut 1.0', 'cut 1.1', 'cut 1.2', 'cut 1.3'] + try: + retVal = (dieRevMap[(data[0])]) + except: + retVal = 'Unknown' + else: + if self.type == MANUFACTURER_INFO: + manufacturerInfoMap = ['Ember', 'STMicroelectronics'] + try: + retVal = (manufacturerInfoMap[(data[0])]) + except: + retVal = 'Unknown' + else: + if self.type == DIE_ID: + dieIdMap = ['Stromboli'] + try: + retVal = (dieIdMap[(data[0])]) + except: + retVal = 'Unknown' + else: + if self.type == PART_NUMBER: + partNumberMap = ['STM32W108C', 'STM32W108H'] + try: + retVal = (partNumberMap[(data[0])]) + except: + retVal = 'Unknown' + else: + if self.type == PART_SUFFIX: + partNumberSuffix = ['', 'ES'] + try: + retVal = (partNumberSuffix[(data[0])]) + except: + retVal = 'Unknown' + else: + if self.type == STACK_TYPE: + tmp = [] + if ((data[0]) & 1): + tmp = (tmp + ['SimpleMAC']) + if ((data[0]) & 2): + tmp = (tmp + ['RF4CE']) + if ((data[0]) & 128): + tmp = (tmp + ['EmberZNet']) + retVal = ','.join(('%s' % a) for a in tmp) + else: + if self.type == TEST_PROGRAM_INFO: + retVal = ('Tester = %d, revision %d.%d' % ((data[3]), ((data[0]) + ((data[1]) << 8)), (data[2]))) + else: + if self.type == EUI64: + retVal = ('0x' + ''.join(('%02X' % a) for a in reversed(data))) + else: + if self.type == VOLTAGE: + tmp = (((data[0]) + ((data[1]) << 8)) / 10000.0) + retVal = ('%.04f V' % tmp) + else: + if self.type == FIB_VERSION: + if (data[0]) != ((~(data[1])) & 255): + retVal = 'Version invalid' + else: + retVal = ('Version %d' % (data[1])) + else: + if self.type == RAM_SIZE: + if ((data[0]) != ((~(data[1])) & 255) or (data[0]) != 2): + retVal = 'Invalid RAM size' + else: + retVal = '8KB RAM' + else: + if self.type == FLASH_SIZE: + if ((data[0]) != ((~(data[1])) & 255) or (data[0]) != 128): + retVal = 'Invalid Flash size' + else: + retVal = '128KB FLASH' + else: + if self.type == READ_PROTECTION: + if ((data[0]) != ((~(data[1])) & 255) and (data[0]) != 255): + retVal = 'Invalid value' + else: + if ((data[0]) == 165 and (data[1]) == 90): + retVal = 'Read protection not active' + else: + retVal = 'Read protection active' + else: + if self.type == WRITE_PROTECTION: + if (data[0]) != ((~(data[1])) & 255): + retVal = 'Invalid value' + else: + if (data[0]) == 255: + retVal = 'Write protection not active' + else: + retVal = 'Write protection active' + else: + if self.type == FPEC_TIMING: + if ((data[0]) != ((~(data[1])) & 255) or (data[1]) != 170): + retVal = 'Invalid' + else: + retVal = '19us program, 20ms erase' + else: + if self.type == AUTO_U16_CHECKSUM: + tmp = ((data[0]) + ((data[1]) << 8)) + checkSum = 0 + for i in range(len(autoData)): + checkSum = (checkSum + (autoData[i])) + continue + checkSum = (checkSum & 65535) + if tmp != checkSum: + valid = False + retVal = ('0x%04X (0x%04x)' % (tmp, checkSum)) + else: + retVal = ('0x%04X' % tmp) + else: + if self.type == AUTO_U16_CRC: + tmp = ((data[0]) + ((data[1]) << 8)) + crc = 65535 + for i in range(len(autoData)): + crc = crc16((autoData[i]), crc) + continue + if tmp != crc: + valid = False + retVal = ('0x%04X (0x%04x)' % (tmp, crc)) + else: + retVal = ('0x%04X' % tmp) + else: + if self.type == BOOTLOADER_CODE: + dieRev = (rawData[1944]) + dieRevMap = ['cut 1.0', 'cut 1.1', 'cut 1.2', 'cut 1.3'] + try: + rev = (dieRevMap[dieRev]) + except: + rev = 'cut x.x' + if data != ([255] * len(data)): + blCut = 'invalid' + else: + blCut = 'not present' + for key in bootloader.keys(): + bl = (bootloader[key]) + if bl == data[0:len(bl)]: + blCut = key[:-2] + break + else: + continue + retVal = (('Bootloader ' + blCut) + (' (Version %d)' % (data[18]))) + if rev != blCut: + valid = False + retVal = (retVal + (' die rev is ' + rev)) + else: + retVal = None + return (valid, retVal) + + + +def crc16(byte, crc): + byte = (byte & 255) + crc = (crc & 65535) + crc = ((crc >> 8) | (crc << 8)) + crc = (crc ^ byte) + crc = (crc ^ ((crc & 255) >> 4)) + crc = (crc ^ ((crc << 8) << 4)) + crc = (crc ^ (((crc & 255) << 4) << 1)) + return (crc & 65535) + +def validRangeMinMax(validRange): + minValue, maxValue = (None, None) + if validRange != 'Not specified': + tmp = validRange.split('-') + minValue = int((tmp[0]), 16) + maxValue = minValue + if len(tmp) > 1: + maxValue = int((tmp[1]), 16) + return (minValue, maxValue) + diff --git a/tools/stm32w/stm32w_flasher/py_files/rs232_interface.py b/tools/stm32w/stm32w_flasher/py_files/rs232_interface.py new file mode 100644 index 000000000..ae9c9d3b0 --- /dev/null +++ b/tools/stm32w/stm32w_flasher/py_files/rs232_interface.py @@ -0,0 +1,1058 @@ + +# See comment in stm32w_flasher.py. +# Extraction and little adaptation performed by E.Duble (CNRS, LIG). + +import ftdi +import os +import serial +import struct +import subprocess +import sys +import time +import ymodem +from messages import errorMessage +from file_utils import fileFormatReader +from messages import infoMessage +from messages import warningMessage + +ACK = 121 +BOOTLOADER_COMMAND_BAUDRATE = 50 +CBUS_IOMODE = 10 +FT232R_PRODUCT = 24577 +FT232R_VENDOR = 1027 +NAK = 31 +STM32F103_PRODUCT = 22337 +STM32F103_PRODUCT_OLD = 22336 +STM32F103_VENDOR = 1155 +StringTypes = None +TIMEOUT_TO_SWITCH_BETWEEN_APPLICATION_AND_BOOTLOADER = 10 +commands = {'WRITE': [49, 3], 'GO': [33, 3], 'GET_ID': [2, 5], 'ERASE': [67, 2], 'GET': [0, 2], 'READ': [17, 259], 'WRITE_INCREMENTAL': [54, 2], 'GET_VERSION': [1, 5], 'READOUT_PROTECT': [130, 2], 'READOUT_UNPROTECT': [146, 2]} +pcIfHandle = None +rs232PortsList = None + +class FTDI_Interface(object): + def __init__(self, port): + self.port = port + self.resetValue = None + self.nBootValue = None + + def close(self): + return None + + def getFTDIIdFromComPort(self, port): + returnValue = None + deviceIDs = None + mapping = self.mapComPortsToFTDIId() + if deviceIDs == None: + returnValue = (mapping[port]) + else: + for id in deviceIDs: + if (mapping[port]) == id: + returnValue = id + break + else: + continue + if returnValue is None: + for id in deviceIDs: + if (mapping[port]).upper() == id.upper(): + returnValue = id + break + else: + continue + return returnValue + + def getFTDIIdFromDevPort(self, port): + command = (('for udi in `hal-find-by-capability --capability serial`\n do\n parent=`hal-get-property --udi ${udi} --key "info.parent"`\n device=`hal-get-property --udi ${udi} --key "linux.device_file"`\n grandpa=`hal-get-property --udi ${parent} --key "info.parent"`\n serial=`hal-get-property --udi ${grandpa} --key "usb_device.serial" 2>/dev/null`\n if [ "${device}" = "' + port) + '" ]\n then\n printf "%s" "${serial}"\n break\n fi\n done ') + p = subprocess.Popen([command], shell=True, stdout=subprocess.PIPE) + out = p.communicate() + return (out[0]) + + def guessResetDirection(self, h): + if (self.resetValue is None or self.nBootValue is None): + CBUS_2 = 4 + CBUS_0 = 1 + RESET_LINE = CBUS_2 + GPIO5_LINE = CBUS_0 + resetLow = ((RESET_LINE << 4) | 0) + resetHigh = ((RESET_LINE << 4) | RESET_LINE) + GPIO5Low = ((GPIO5_LINE << 4) | 0) + GPIO5High = ((GPIO5_LINE << 4) | GPIO5_LINE) + h.usb_write_timeout = 1000 + h.usb_read_timeout = 1000 + ret = ftdi.ftdi_set_baudrate(h, 115200) + ret = (ret + ftdi.ftdi_setflowctrl(h, ftdi.SIO_DISABLE_FLOW_CTRL)) + ret = (ret + ftdi.ftdi_set_line_property(h, ftdi.BITS_8, ftdi.STOP_BIT_1, ftdi.NONE)) + for i in range(2): + if (i % 2) == 0: + resetValue = resetHigh + nbootValue = GPIO5High + else: + resetValue = resetLow + nbootValue = GPIO5Low + ftdi.ftdi_set_bitmode(h, resetValue, ftdi.BITMODE_CBUS) + time.sleep(0.10000000000000001) + ftdi.ftdi_set_bitmode(h, nbootValue, ftdi.BITMODE_CBUS) + time.sleep(0.10000000000000001) + ftdi.ftdi_set_bitmode(h, 0, ftdi.BITMODE_CBUS) + ftdi.ftdi_usb_purge_rx_buffer(h) + ftdi.ftdi_usb_purge_tx_buffer(h) + ftdi.ftdi_write_data(h, struct.pack('B', 127), 1) + startTime = time.time() + inbuff = '\x00' + nbyte_rcvd = 0 + while (nbyte_rcvd == 0 and (time.time() - startTime) < 1): + nbyte_rcvd = ftdi.ftdi_read_data(h, inbuff, 1) + continue + if nbyte_rcvd > 0: + reply = struct.unpack('B', inbuff) + if (reply[0]) == 121: + self.resetValue = resetValue + self.nBootValue = nbootValue + break + else: + continue + continue + return (self.resetValue, self.nBootValue) + + def open(self): + return 0 + + def reset(self, bootloader=False): + handle = ftdi.ftdi_context() + if ftdi.ftdi_init(handle) < 0: + print 'Initialization error.', + print + sys.exit(-1) + serialnum = self.getFTDIIdFromDevPort(self.port) + if subprocess.call(['rmmod', 'ftdi_sio']) != 0: + print 'Close all processes that may access serial ports. You may also need to run the program as root.', + print + sys.exit(-1) + error = ftdi.ftdi_usb_open_desc(handle, FT232R_VENDOR, FT232R_PRODUCT, None, serialnum) + if error < 0: + print ('Unable to open port. Error:' + str(error)), + print + subprocess.call(['modprobe', 'ftdi_sio']) + sys.exit(-1) + item0, item1 = self.guessResetDirection(handle) + resetValue = item0 + nBootValue = item1 + if (resetValue, nBootValue) == (None, None): + ftdi.ftdi_usb_close(handle) + subprocess.call(['modprobe', 'ftdi_sio']) + return 1 + else: + ftdi.ftdi_set_bitmode(handle, resetValue, ftdi.BITMODE_CBUS) + time.sleep(0.5) + if bootloader: + ftdi.ftdi_set_bitmode(handle, nBootValue, ftdi.BITMODE_CBUS) + time.sleep(0.10000000000000001) + ftdi.ftdi_set_bitmode(handle, 0, ftdi.BITMODE_CBUS) + ftdi.ftdi_usb_close(handle) + subprocess.call(['modprobe', 'ftdi_sio']) + time.sleep(1) + return None + + def setNBOOT(self, value=1): + returnValue = True + return returnValue + + +class STBL(object): + def __init__(self, serialPort, inputFile=None, startAddress=None, verboseMode=None, packetSize=256, serialMode=True): + self.serialPort = serialPort + self.inputFile = inputFile + self.startAddress = startAddress + self.verbose = verboseMode + self.packetSize = packetSize + self.serialMode = serialMode + + def bootloaderInit(self): + returnValue = True + if (returnValue and self.serialMode): + reply = None + if self.verbose: + infoMessage('Sending byte 7f\n') + self.serialPort.write(struct.pack('B', 127)) + startTime = time.time() + while (self.serialPort.inWaiting() == 0 and (time.time() - startTime) < 1): + continue + r = self.serialPort.read(1) + if r: + reply = struct.unpack(('B' * len(r)), r) + else: + reply = None + if self.verbose: + infoMessage(("Reply received '%s'\n" % hexString(reply))) + if reply == None: + errorMessage('No reply received\n') + returnValue = False + else: + if (reply[0]) != ACK: + errorMessage(('Unexpected reply %s\n' % hexString(reply))) + returnValue = False + if returnValue: + reply = self.sendCommand('GET', [], 2) + if (len(reply) < 4 or ((reply[0]) != ACK or (reply[-1]) != ACK)): + errorMessage(('Unexpected reply %s\n' % hexString(reply))) + returnValue = False + else: + if self.verbose: + infoMessage(('Bootloader version %d.%d\n' % (((reply[2]) & 15), ((reply[2]) >> 4)))) + if returnValue: + reply = self.sendCommand('GET_ID') + if (len(reply) == 0 or ((reply[0]) != ACK or (reply[-1]) != ACK)): + errorMessage(('Unexpected reply %s\n' % hexString(reply))) + returnValue = False + else: + if self.verbose: + infoMessage((('Product ID = 0x' + ''.join(('%02X' % a) for a in reply[2:-1])) + '\n')) + return returnValue + + def checksum(self, packet): + if len(packet) > 1: + checksum = 0 + for p in packet: + checksum = (checksum ^ p) + continue + else: + checksum = ((~(packet[0])) & 255) + return checksum + + def enableReadProtection(self, enable): + returnValue = True + if enable == False: + reply = self.sendCommand('READOUT_UNPROTECT') + if reply != [ACK, ACK]: + errorMessage((('Unexpected reply (' + ','.join(('%02x' % a) for a in reply)) + ') \n')) + returnValue = False + else: + item0, item1 = self.memoryRead(134481920, 512) + returnValue = item0 + cibData = item1 + if returnValue: + reply = self.sendCommand('ERASE', [[254]], timeout=5) + if reply != [ACK, ACK]: + errorMessage(('Unexpected reply %s\n' % repr(reply))) + returnValue = False + if returnValue: + arg1 = u32ToArray(134481922) + arg1.reverse() + packet = cibData[2:256] + packet = ([(len(packet) - 1)] + packet) + reply = self.sendCommand('WRITE', [arg1, packet], 5) + if reply != [ACK, ACK, ACK]: + errorMessage((('Unexpected reply (' + ','.join(('%02x' % a) for a in reply)) + ') \n')) + returnValue = False + if returnValue: + arg1 = u32ToArray(134482176) + arg1.reverse() + packet = cibData[256:] + packet = ([(len(packet) - 1)] + packet) + reply = self.sendCommand('WRITE', [arg1, packet], 5) + if reply != [ACK, ACK, ACK]: + errorMessage((('Unexpected reply (' + ','.join(('%02x' % a) for a in reply)) + ') \n')) + returnValue = False + if returnValue: + reply = self.sendCommand('READOUT_PROTECT') + if reply != [ACK, ACK]: + errorMessage((('Unexpected reply (' + ','.join(('%02x' % a) for a in reply)) + ') \n')) + returnValue = False + return returnValue + + def eraseUserFlash(self): + returnValue = True + reply = self.sendCommand('ERASE', [[255]], timeout=5) + if reply != [ACK, ACK]: + errorMessage(('Unexpected reply %s\n' % repr(reply))) + returnValue = False + return returnValue + + def isReadProtectionActive(self): + returnValue, memread = self.memoryRead(134479872, 4) + return (not returnValue) + + def loadFile(self, inputFile=None, startAddress=None, progressReport=None, doErase=True): + if inputFile is not None: + self.inputFile = inputFile + if startAddress is not None: + self.startAddress = startAddress + returnValue = True + f = fileFormatReader(self.inputFile, self.startAddress) + try: + item0, item1 = f.getRawBinary() + self.startAddress = item0 + file_content = item1 + except IOError: + errorMessage((('File ' + self.inputFile) + ' open failed\n')) + returnValue = False + if returnValue: + file_size = len(file_content) + packet = [] + address = self.startAddress + pages = int(((file_size + 1023) / 1024)) + startPage = (((self.startAddress & 4294966272L) - 134217728) / 1024) + eraseArg = ([(pages - 1)] + range(startPage, (startPage + pages), 1)) + infoMessage(('Erasing pages from %d to %d...' % (startPage, ((startPage + pages) - 1)))) + if ('STM32W_FLASHER_JLINK_DONT_ERASE' in os.environ or (not doErase)): + infoMessage('(skipped)', False) + else: + reply = self.sendCommand('ERASE', [eraseArg], timeout=10) + if reply != [ACK, ACK]: + errorMessage(('Unexpected reply %s\n' % repr(reply))) + returnValue = False + if returnValue: + infoMessage('done\n', False) + size = 0 + while returnValue: + packet = [] + packet_size = self.packetSize + packet_string = file_content[size:(size + packet_size)] + packet_size = len(packet_string) + if packet_size == 0: + infoMessage('\n') + break + else: + size = (size + packet_size) + packet.extend(packet_string) + if (len(packet) % 2) != 0: + packet = (packet + [255]) + packet = ([(len(packet) - 1)] + packet) + if progressReport: + progressReport(size, file_size) + else: + infoMessage(('Programming %05d/%05d\r' % (size, file_size))) + arg1 = u32ToArray(address) + arg1.reverse() + if (self.serialMode or size == packet_size): + reply = self.sendCommand('WRITE', [arg1, packet]) + if reply != [ACK, ACK, ACK]: + errorMessage(('\n\n+Unexpected reply %s, packet_size=%d\n' % (repr(reply), packet_size))) + returnValue = False + else: + retries = 0 + MAX_RETRIES = 3 + while returnValue: + reply = self.sendCommand('WRITE_INCREMENTAL', [packet]) + if reply != [ACK, ACK]: + retries = (retries + 1) + if retries > MAX_RETRIES: + errorMessage(('\n\nUnexpected reply %s, packet_size=%d\n' % (repr(reply), packet_size))) + returnValue = False + break + else: + errorMessage(('\n\nUnexpected reply %s, packet_size=%d\n' % (repr(reply), packet_size))) + infoMessage('Retrying...\n') + continue + else: + break + address = (address + packet_size) + continue + if returnValue: + if progressReport == None: + infoMessage('Done\n') + return returnValue + + def memoryRead(self, address, size): + returnValue = True + currentSize = 0 + memRead = [] + while (returnValue and currentSize < size): + + packet_size = min(self.packetSize, (size - currentSize)) + arg1 = u32ToArray((address + currentSize)) + arg1.reverse() + reply = self.sendCommand('READ', [arg1, [(packet_size - 1)]]) + if reply == [NAK]: + returnValue = False + else: + if reply[:3] != [ACK, ACK, ACK]: + errorMessage(('\n\nXXUnexpected reply %s, packet_size=%d\n' % (repr(reply), packet_size))) + returnValue = False + else: + memRead = (memRead + reply[3:]) + currentSize = (currentSize + packet_size) + continue + return (returnValue, memRead) + + def programCibData(self, cibData): + returnValue = True + if returnValue: + reply = self.sendCommand('ERASE', [[254]], timeout=5) + if reply != [ACK, ACK]: + errorMessage(('Unexpected reply %s\n' % repr(reply))) + returnValue = False + if returnValue: + arg1 = u32ToArray(134481920) + arg1.reverse() + packet = cibData[:256] + packet = ([(len(packet) - 1)] + packet) + reply = self.sendCommand('WRITE', [arg1, packet], 5) + if reply != [ACK, ACK, ACK]: + errorMessage((('Unexpected reply (' + ','.join(('%02x' % a) for a in reply)) + ') \n')) + returnValue = False + if returnValue: + arg1 = u32ToArray(134482176) + arg1.reverse() + packet = cibData[256:] + packet = ([(len(packet) - 1)] + packet) + reply = self.sendCommand('WRITE', [arg1, packet], 5) + if reply != [ACK, ACK, ACK]: + errorMessage((('Unexpected reply (' + ','.join(('%02x' % a) for a in reply)) + ') \n')) + returnValue = False + return returnValue + + def programUserFlash(self, inputFile, startAddress=134217728, progressReport=None, doErase=True): + return self.loadFile(inputFile, startAddress, progressReport, doErase) + + def sendCommand(self, command, args=[], timeout=2, traceCommands=False): + def timedRead(port, timeout, serialMode, bytes=1): + reply = [] + r = '' + for byte in range(bytes): + startTime = time.time() + r1 = '' + while (time.time() - startTime) < timeout: + r1 = port.read(1) + if len(r1) > 0: + r = (r + r1) + startTime = time.time() + break + else: + if serialMode: + continue + else: + time.sleep(0.001) + continue + if len(r1) == 0: + break + else: + continue + if len(r) > 0: + reply.extend(struct.unpack(('B' * len(r)), r)) + return reply + reply = [] + error = False + if command in commands: + item0, item1 = (commands[command]) + commandID = item0 + replyLength = item1 + if command == 'READ': + replyLength = (((args[1])[0]) + 4) + else: + error = True + if error: + pass + else: + if traceCommands: + infoMessage(('Sending command: %02x %02x\n' % (commandID, (255 - commandID)))) + self.serialPort.write(struct.pack('BB', commandID, (255 - commandID))) + r = timedRead(self.serialPort, timeout, self.serialMode, 1) + reply = (reply + r) + if (len(r) != 1 or (r[0]) != ACK): + error = True + if error: + pass + else: + for arg in args: + arg = (arg + [self.checksum(arg)]) + if traceCommands: + infoMessage((('Sending arg:' + ','.join(('%02x' % a) for a in arg)) + '\n')) + self.serialPort.write(struct.pack(('B' * len(arg)), *arg)) + r = timedRead(self.serialPort, timeout, self.serialMode, 1) + reply = (reply + r) + if (len(r) != 1 or (r[0]) != ACK): + error = True + break + else: + continue + if ((not error) and len(reply) < replyLength): + reply = (reply + timedRead(self.serialPort, timeout, self.serialMode, (replyLength - len(reply)))) + if (command == 'GET' and len(reply) == replyLength): + reply = (reply + timedRead(self.serialPort, timeout, self.serialMode, ((reply[1]) + 2))) + if traceCommands: + infoMessage(('Reply was %s\n' % hexString(reply))) + return reply + + def setPort(self, serialPort): + self.serialPort = serialPort + + def startApplication(self, startAddress=134217728): + returnValue = True + if (self.startAddress is not None and startAddress != 0): + startAddress = self.startAddress + arg1 = u32ToArray(startAddress) + arg1.reverse() + reply = self.sendCommand('GO', [arg1]) + if reply != [ACK, ACK, ACK]: + errorMessage(('\n\nUnexpected reply %s\n' % repr(reply))) + returnValue = False + return returnValue + + def verifyFile(self, inputFile=None, startAddress=None, progressReport=None): + if inputFile is not None: + self.inputFile = inputFile + if startAddress is not None: + self.startAddress = startAddress + returnValue = True + f = fileFormatReader(self.inputFile, self.startAddress) + try: + item0, item1 = f.getRawBinary() + self.startAddress = item0 + file_content = item1 + except IOError: + errorMessage((('File ' + self.inputFile) + ' open failed\n')) + returnValue = False + if returnValue: + file_size = len(file_content) + packet = [] + address = self.startAddress + size = 0 + errors = 0 + while returnValue: + packet = [] + packet_size = self.packetSize + packet_string = file_content[size:(size + packet_size)] + packet_size = len(packet_string) + if packet_size == 0: + infoMessage('\n') + break + else: + size = (size + packet_size) + packet.extend(packet_string) + if progressReport: + progressReport(size, file_size) + else: + infoMessage(('Verifying %05d/%05d\r' % (size, file_size))) + arg1 = u32ToArray(address) + arg1.reverse() + reply = self.sendCommand('READ', [arg1, [(len(packet) - 1)]]) + if reply[:3] != [ACK, ACK, ACK]: + errorMessage(('\n\nUnexpected reply %s, packet_size=%d\n' % (repr(reply), packet_size))) + returnValue = False + if len(reply[3:]) != len(packet): + errorMessage(('Invalid data read, expected length = %d, received bytes = %d\n' % (len(packet), len(reply[3:])))) + returnValue = False + if (returnValue and reply[3:] != packet): + returnValue = False + infoMessage('Verify failed \n') + infoMessage(('%-8s: %5s %5s\n' % ('Addr', 'Flash', 'file'))) + for i in range(len(packet)): + if (reply[(3 + i)]) != (packet[i]): + infoMessage(('%08x: %02x %02x\n' % ((address + i), (reply[(i + 3)]), (packet[i])))) + errors = (errors + 1) + if errors > 64: + break + else: + continue + else: + continue + address = (address + packet_size) + continue + if returnValue: + if progressReport == None: + infoMessage('Done\n') + return returnValue + + def verifyFlash(self, inputFile, startAddress=134217728, progressReport=None): + return self.verifyFile(inputFile, startAddress, progressReport) + + +class STM32F_Interface(object): + APP_RUNNING = 1 + BL_RUNNING = 0 + DOWNLOAD_BL_IMAGE = 10 + DOWNLOAD_IMAGE = 5 + FAIL = 0 + FIRMWARE_VERSION_NONE = 4294967295L + GET_APP_VERSION = 3 + GET_BL_VERSION = 9 + GET_CODE_TYPE = 2 + IS_APP_PRESENT = 4 + IS_BL_VERSION_OLD = 11 + OK = 1 + REPLY_START_BYTE = 187 + RUN_APPLICATION = 6 + RUN_BOOTLOADER = 7 + SET_nBOOTMODE = 1 + SET_nRESET = 0 + START_BYTE = 170 + STOP_BYTE = 85 + UNKNOWN_COMMAND = 15 + UPLOAD_IMAGE = 8 + replyLength = [4, 4, 4, 7, 4, 4, 4, 4, 4, 7, 4, 4] + def __init__(self, port, firmwareName): + self.port = port + self.bootloaderPort = port + self.firmwareName = firmwareName + self.serialPort = None + + def close(self): + if self.serialPort: + self.serialPort.close() + + def getBootloaderFirmwareVersion(self): + returnValue = self.FIRMWARE_VERSION_NONE + reply = self.sendCommand(self.GET_BL_VERSION) + if reply: + returnValue = ((((reply[2]) + ((reply[3]) << 8)) + ((reply[4]) << 16)) + ((reply[5]) << 24)) + return returnValue + + def getFirmwareType(self): + returnValue = None + reply = self.sendCommand(self.GET_CODE_TYPE) + if reply: + returnValue = (reply[2]) + return returnValue + + def getFirmwareVersion(self): + returnValue = self.FIRMWARE_VERSION_NONE + reply = self.sendCommand(self.GET_APP_VERSION) + if reply: + returnValue = ((((reply[2]) + ((reply[3]) << 8)) + ((reply[4]) << 16)) + ((reply[5]) << 24)) + return returnValue + + def getFirmwareVersionFromFile(self, filename=None, stringMode=False): + version = None + if filename is None: + filename = self.firmwareName + f = open(filename) + f.seek(28, 0) + tag = f.read(4) + versionValue = f.read(4) + versionValue = struct.unpack(('B' * len(versionValue)), versionValue) + f.close() + if tag == '\xaaU\xaaU': + version = ((((versionValue[0]) + ((versionValue[1]) << 8)) + ((versionValue[2]) << 16)) + ((versionValue[3]) << 24)) + if stringMode: + version = self.versionInStringFormat(version) + return version + + def isBootloaderFirmwareVersionOld(self): + returnValue = False + reply = self.sendCommand(self.IS_BL_VERSION_OLD) + if reply: + returnValue = (reply[2]) == self.FAIL + return returnValue + + def isFirmwarePresent(self): + returnValue = None + reply = self.sendCommand(self.IS_APP_PRESENT) + if reply: + returnValue = (reply[2]) + return returnValue + + def isSTMicroelectronics(self, port): + return port in self.getSTMPorts() + + def mapSTMCompositeComPortToBootloaderCOMPort(self, port): + warningMessage('The following procedure may fail if there are other attached USB devices.\nIn this case, try to unplug all the devices and insert only the one to be programmed, then run the command again.\n') + return port + + def open(self): + error = 0 + try: + self.serialPort = serial.Serial(port=self.port, baudrate=BOOTLOADER_COMMAND_BAUDRATE, timeout=1) + time.sleep(0.10000000000000001) + self.serialPort.flushInput() + except: + errorMessage((('Trouble opening port : ' + repr(self.port)) + '\n')) + error = 1 + return error + + def reset(self, bootloader=False): + returnValue = True + if returnValue: + reply = self.sendCommand(self.SET_nBOOTMODE, [1]) + returnValue = reply != None + if returnValue: + reply = self.sendCommand(self.SET_nRESET, [0]) + returnValue = reply != None + if returnValue: + if bootloader: + reply = self.sendCommand(self.SET_nBOOTMODE, [0]) + returnValue = reply != None + time.sleep(0.10000000000000001) + if returnValue: + reply = self.sendCommand(self.SET_nRESET, [1]) + returnValue = reply != None + time.sleep(0.10000000000000001) + time.sleep(0.10000000000000001) + return returnValue + + def runBootloader(self): + returnValue = None + reply = self.sendCommand(self.RUN_BOOTLOADER, [], True) + if reply: + commandReturnValue = (reply[2]) + time.sleep(TIMEOUT_TO_SWITCH_BETWEEN_APPLICATION_AND_BOOTLOADER) + for i in range(5): + try: + self.serialPort = serial.Serial(port=self.bootloaderPort, baudrate=BOOTLOADER_COMMAND_BAUDRATE, timeout=1) + self.serialPort = checkSerialPort(self.bootloaderPort, self.serialPort) + time.sleep(0.5) + self.serialPort.flushInput() + if self.serialPort is None: + returnValue = None + else: + returnValue = commandReturnValue + break + except Exception, inst: + errorMessage((' '.join(repr(a) for a in inst.args) + '\n')) + time.sleep(0.5) + continue + return returnValue + + def runFirmware(self): + returnValue = None + reply = self.sendCommand(self.RUN_APPLICATION, [], True) + if reply: + commandReturnValue = (reply[2]) + time.sleep(TIMEOUT_TO_SWITCH_BETWEEN_APPLICATION_AND_BOOTLOADER) + for i in range(5): + try: + self.serialPort = serial.Serial(port=self.port, baudrate=BOOTLOADER_COMMAND_BAUDRATE, timeout=1) + self.serialPort = checkSerialPort(self.port, self.serialPort) + if self.serialPort is None: + returnValue = None + else: + returnValue = commandReturnValue + break + except Exception, inst: + errorMessage((' '.join(repr(a) for a in inst.args) + '\n')) + time.sleep(0.5) + continue + return returnValue + + def sendCommand(self, command, args=[], closePort=False): + verbose = False + returnValue = None + if command == self.DOWNLOAD_IMAGE: + filename = (args[0]) + args = [] + replyLength = self.replyLength + packet = (([self.START_BYTE, (1 + len(args)), command] + args) + [self.STOP_BYTE]) + if verbose: + print '==>', + print ':'.join(('%02X' % a) for a in packet), + print + packedCommand = struct.pack(('B' * len(packet)), *packet) + self.serialPort.write(packedCommand) + if command == self.DOWNLOAD_IMAGE: + yModem = ymodem.Ymodem(self.serialPort, None) + if yModem.loadFile(filename): + returnValue = None + r = self.serialPort.read((replyLength[command])) + if closePort: + self.serialPort.close() + if len(r) == (replyLength[command]): + reply = struct.unpack(('B' * len(r)), r) + if ((reply[0]) == self.REPLY_START_BYTE and ((reply[1]) == ((replyLength[command]) - 3) and (reply[-1]) == self.STOP_BYTE)): + returnValue = reply + if verbose: + if r: + reply = struct.unpack(('B' * len(r)), r) + print '<==', + print ':'.join(('%02X' % a) for a in reply), + print + else: + print '<==', + print + return returnValue + + def setNBOOT(self, value=1): + returnValue = True + if returnValue: + reply = self.sendCommand(self.SET_nBOOTMODE, [value]) + returnValue = reply != None + return returnValue + + def upgradeBootloaderFirmwareVersion(self): + returnValue = True + reply = self.sendCommand(self.DOWNLOAD_BL_IMAGE) + if reply: + returnValue = (reply[2]) == self.OK + else: + returnValue = False + return returnValue + + def upgradeFirmwareVersion(self, filename=None): + returnValue = True + if filename is None: + filename = self.firmwareName + if returnValue: + firmwareType = self.getFirmwareType() + if firmwareType == self.APP_RUNNING: + reply = self.runBootloader() + if reply is None: + returnValue = False + else: + if firmwareType == self.BL_RUNNING: + pass + else: + returnValue = False + if returnValue: + if self.getFirmwareType() != self.BL_RUNNING: + errorMessage('Unable to read from port, please use a USB HUB 1.1 and rerun the command\n') + returnValue = False + else: + reply = self.sendCommand(self.DOWNLOAD_IMAGE, [filename]) + returnValue = (reply[2]) == self.OK + return returnValue + + def versionInStringFormat(self, version): + return ('%d.%d.%d' % (((version >> 16) & 255), ((version >> 8) & 255), (version & 255))) + + +class rs232Interface(object): + def __init__(self, port, noReset=False, rfMode=False, eui64=0): + self.port = port + self.noReset = noReset + self.rfMode = rfMode + self.eui64 = eui64 + self.serialPort = None + self.portType = portType(port) + if self.portType == 'FTDI': + self.portHandle = FTDI_Interface(port) + else: + if self.portType == 'STM32': + firmwareName = 'CompositeForSTM32W.bin' + if 'STM32W_FLASHER_FORCE_FIRMWARE_NAME' in os.environ: + firmwareName = (os.environ['STM32W_FLASHER_FORCE_FIRMWARE_NAME']) + flasher_py_files = os.path.dirname(os.path.abspath(sys.argv[0])) + firmware_dir = os.path.dirname(flasher_py_files) # parent directory + self.portHandle = STM32F_Interface(port, os.path.join(firmware_dir, firmwareName)) + + def closePort(self): + self.serialPort.close() + + def enableReadProtection(self, flag): + return self.STBL.enableReadProtection(flag) + + def eraseUserFlash(self): + return self.STBL.eraseUserFlash() + + def init(self, checkFirmwareImage=True): + error = 0 + if self.noReset: + if self.rfMode: + error = self.reset(False) + time.sleep(0.10000000000000001) + else: + error = 0 + else: + error = self.reset(True, checkFirmwareImage) + if error == 1: + errorMessage((('Trouble while resetting board on port : ' + repr(self.port)) + '\n')) + if error == 0: + error = self.openPort() + if error == 0: + if self.rfMode: + self.packetSize = 96 + def sendBinary(port, data, length): + for i in range(length): + port.write(chr(((data >> (i * 8)) & 255))) + continue + sendBinary(self.serialPort, self.eui64, 8) + sendBinary(self.serialPort, 45067, 2) + sendBinary(self.serialPort, 15, 1) + time.sleep(0.5) + while self.serialPort.inWaiting() > 0: + sys.stdout.write(self.serialPort.read(self.serialPort.inWaiting())) + continue + else: + self.packetSize = 256 + self.STBL = STBL(self.serialPort, packetSize=self.packetSize, serialMode=(not self.rfMode)) + if self.STBL is not None: + tmp = self.STBL.bootloaderInit() + if tmp: + pass + else: + error = 1 + return error + + def isReadProtectionActive(self): + return self.STBL.isReadProtectionActive() + + def memoryRead(self, address, size): + return self.STBL.memoryRead(address, size) + + def openPort(self): + error = 0 + try: + self.serialPort = serial.Serial(port=self.port, bytesize=8, baudrate=115200, parity='N', timeout=0) + except: + errorMessage((('Trouble opening port : ' + repr(self.port)) + '\n')) + error = 1 + return error + + def programCibData(self, cibData): + return self.STBL.programCibData(cibData) + + def programUserFlash(self, inputFile, startAddress=134217728, progressReport=None, doErase=True): + return self.STBL.programUserFlash(inputFile, startAddress, progressReport, doErase) + + def reset(self, bootloader=False, checkSTM32FFirmware=True): + returnValue = 0 + if self.portType == 'FTDI': + self.portHandle.reset(bootloader) + else: + if self.portType == 'STM32': + returnValue = self.portHandle.open() + if checkSTM32FFirmware: + if returnValue == 0: + firmwareVersionCurrent = self.portHandle.getFirmwareVersionFromFile(stringMode=False) + if returnValue == 0: + firmwareType = self.portHandle.getFirmwareType() + if (firmwareType is None or (firmwareType != self.portHandle.BL_RUNNING and firmwareType != self.portHandle.APP_RUNNING)): + errorMessage('Failed to get firmware type: Invalid reply\n') + returnValue = 1 + if returnValue == 0: + firmwareVersion = self.portHandle.getFirmwareVersion() + if firmwareVersion is None: + errorMessage('Failed to get firmware version:Invalid reply\n') + returnValue = 1 + else: + if (firmwareVersion & 4278190080L): + firmwareVersion = self.portHandle.FIRMWARE_VERSION_NONE + if returnValue == 0: + bootloaderFirmwareVersion = self.portHandle.getBootloaderFirmwareVersion() + if bootloaderFirmwareVersion is None: + errorMessage('Failed to get bootloader firmware version:Invalid reply\n') + returnValue = 1 + if bootloaderFirmwareVersion == self.portHandle.FIRMWARE_VERSION_NONE: + self.portHandle.bootloaderPort = self.portHandle.mapSTMCompositeComPortToBootloaderCOMPort(self.portHandle.port) + if returnValue == 0: + if (firmwareType == self.portHandle.BL_RUNNING and (firmwareVersion != self.portHandle.FIRMWARE_VERSION_NONE and firmwareVersion >= firmwareVersionCurrent)): + if bootloaderFirmwareVersion == self.portHandle.FIRMWARE_VERSION_NONE: + errorMessage('Please unplug and replug the board to the PC\n') + returnValue = 2 + else: + result = self.portHandle.runFirmware() + if result is not self.portHandle.OK: + errorMessage('Failed to run firmware: Invalid reply\n') + returnValue = 1 + if returnValue == 0: + if (firmwareVersion == self.portHandle.FIRMWARE_VERSION_NONE or firmwareVersion < firmwareVersionCurrent): + if firmwareVersion == self.portHandle.FIRMWARE_VERSION_NONE: + infoMessage(('Missing STM32F103 firmware, upgrading to version %s\n' % self.portHandle.getFirmwareVersionFromFile(stringMode=True))) + else: + infoMessage(('Old STM32F103 firmware version %s, upgrading to version %s\n' % (self.portHandle.versionInStringFormat(firmwareVersion), self.portHandle.getFirmwareVersionFromFile(stringMode=True)))) + warningMessage('Changing firmware version can break backward compatibility and older version of stm32w_flasher may not work\n') + if self.portHandle.upgradeFirmwareVersion(): + if ((firmwareVersion == self.portHandle.FIRMWARE_VERSION_NONE or firmwareVersion < 131072) and firmwareVersionCurrent >= 131072): + errorMessage(('Switching to firmware %s may change your COM port number, please unplug and replug your USB device and re-run this command again\n' % self.portHandle.getFirmwareVersionFromFile(stringMode=True))) + returnValue = 2 + else: + result = self.portHandle.runFirmware() + if result is not self.portHandle.OK: + errorMessage('Failed to run firmware: Invalid reply\n') + returnValue = 1 + else: + errorMessage('Failed to upgrade firmware version: Invalid reply\n') + returnValue = 1 + if returnValue == 0: + firmwareVersion = self.portHandle.getFirmwareVersion() + if firmwareVersion is None: + errorMessage('Invalid reply\n') + returnValue = 1 + if returnValue == 0: + if firmwareVersion >= 131076: + if self.portHandle.isBootloaderFirmwareVersionOld(): + infoMessage('Upgrading STM32F Bootloader firmware\n') + if self.portHandle.upgradeBootloaderFirmwareVersion(): + pass + else: + errorMessage('Upgrade of the STM32F bootloader failed. This is a CRITICAL error and your board may brick your board\n') + returnValue = 1 + if returnValue == 0: + if firmwareVersion > firmwareVersionCurrent: + warningMessage('Device firmware is more recent than expected. Are you using an old version of this software ?\n') + if returnValue == 0: + result = self.portHandle.reset(bootloader) + if result is None: + errorMessage('Failed to reset STM32W: Invalid reply\n') + returnValue = 1 + self.portHandle.close() + else: + errorMessage(('Failed to detect port type for %s\n' % self.port)) + returnValue = 1 + return returnValue + + def setNBOOT(self, value): + returnValue = 0 + if (self.portHandle and self.portType == 'STM32'): + self.portHandle.open() + returnValue = self.portHandle.setNBOOT(value) + self.portHandle.close() + return returnValue + + def startApplication(self, address=134217728): + if self.noReset is False: + self.closePort() + self.setNBOOT(1) + self.openPort() + self.STBL.setPort(self.serialPort) + return self.STBL.startApplication(address) + + def terminate(self): + if self.noReset is False: + self.closePort() + self.setNBOOT(1) + self.openPort() + + def verifyFlash(self, inputFile, startAddress, progressReport): + return self.STBL.verifyFlash(inputFile, startAddress, progressReport) + + + +def checkSerialPort(portName, serialPort): + returnValue = serialPort + try: + serialPort.write(' ') + except serial.serialutil.SerialException, inst: + errorMessage((' '.join(repr(a) for a in inst.args) + '\n')) + infoMessage('Write to serial port failed: please try a different USB port or a USB hub 1.1\n') + returnValue = None + return returnValue + +def getAvailableSerialPorts(refreshList=True): + global rs232PortsList + if (refreshList or rs232PortsList is None): + returnValue = {} + id = [{ 'vendor': FT232R_VENDOR , 'product': FT232R_PRODUCT , 'type': 'FTDI' }, { 'vendor': STM32F103_VENDOR , 'product': STM32F103_PRODUCT , 'type': 'STM32' }, { 'vendor': STM32F103_VENDOR , 'product': STM32F103_PRODUCT_OLD , 'type': 'STM32' }] + for i in range(len(id)): + command = (((('for udi in `hal-find-by-capability --capability serial`\n do\n parent=`hal-get-property --udi ${udi} --key "info.parent"`\n device=`hal-get-property --udi ${udi} --key "linux.device_file"`\n serial=`hal-get-property --udi ${parent} --key "usb.serial" 2>/dev/null`\n vendor=`hal-get-property --udi ${parent} --key "usb.vendor_id" 2>/dev/null`\n product=`hal-get-property --udi ${parent} --key "usb.product_id" 2>/dev/null`\n if [ "${vendor}" = "' + str(((id[i])['vendor']))) + '" ] && [ "${product}" = "') + str(((id[i])['product']))) + '" ]\n then\n printf "%s %s\n" "${device}" "${serial}"\n fi\n done') + p = subprocess.Popen([command], shell=True, stdout=subprocess.PIPE) + out = p.communicate() + for line in (out[0]).splitlines(): + device_serial = line.split(' ') + returnValue[(device_serial[0])] = [((id[i])['type']), (device_serial[1])] + continue + continue + rs232PortsList = returnValue + return rs232PortsList + +def getFirstAvailableSerialPort(): + returnValue = None + ports = getAvailableSerialPorts(False) + if ports != {}: + returnValue = (sorted(ports.keys())[0]) + return returnValue + +def hexString(reply): + if reply is None: + return '' + else: + return ' '.join(('%02x' % a) for a in reply) + +def portType(port): + returnValue = None + ports = getAvailableSerialPorts(False) + if port in ports: + returnValue = ((ports[port])[0]) + return returnValue + +def u32ToArray(v): + return [(v & 255), ((v >> 8) & 255), ((v >> 16) & 255), ((v >> 24) & 255)] + diff --git a/tools/stm32w/stm32w_flasher/py_files/stm32w_flasher.py b/tools/stm32w/stm32w_flasher/py_files/stm32w_flasher.py new file mode 100755 index 000000000..4f486408a --- /dev/null +++ b/tools/stm32w/stm32w_flasher/py_files/stm32w_flasher.py @@ -0,0 +1,279 @@ +#!/usr/bin/env python +import optparse, os, sys, time + +# The binary file at [contiki]/tools/stm32w/stm32w_flasher/stm32w_flasher +# contained python code. +# This binary file did not work anymore on Ubuntu 12.04, so +# it was replaced by this extracted python code, as discussed +# with people at ST Crolles (France). +# +# Extraction and little adaptation performed by E.Duble (CNRS, LIG). + +try: + import serial + import ftdi +except: + print 'Python modules serial and ftdi could not be loaded.' + print 'Please install these dependencies:' + print '(On Ubuntu) $ sudo apt-get install python-serial python-ftdi' + sys.exit(-1) + +from messages import infoMessage, errorMessage +from rs232_interface import rs232Interface, getFirstAvailableSerialPort + +versionMajor = 2 +versionMinor = 0 +versionPatch = 1 +versionQualifier = "b2" +version = "%d.%d.%d%s"%(versionMajor, versionMinor, versionPatch, versionQualifier) + +commandTable = [ + ['-i', '--interface', 'store', " specify flasher interface (default rs232)",None], + ['-p', '--port', 'store', ": specify rs232 port or auto mode (only relevant if interface selected is rs232 or rf)", None], + ['-f', '--flash-image', 'store_true', "program flash"], + ['-a', '--address', 'store', "0xHHHHHHHH specify baseaddress (only relevat for .bin images)", "0x08000000"], + ['-v', '--verify', 'store_true', "verify flash content against file", False], + #['-d', '--device-info', 'store_true', 'print information about the STM32W device', False], + ['-r', '--reset', 'store_true', 'Reset device', False], + ['-s', '--start', 'store_true', 'Start application', False], + ['-m', '--masserase', 'store_true', 'Erase user flash (masserase)', False], + ['-b', '--bootloader-mode', 'store_true', 'Device is already in bootloader mode.(Only relevant for rs232 interface)', False], + ['-e', '--eui64', 'store', "0xHHHHHHHHHHHHHHHH specify EUI64 (only relevat for rf interface)", "0xFFFFFFFFFFFFFFFF"], + ['', '--enable-readout-protection', 'store', "<0|1> Disable or enable readout protection", None], + ['', '--set-write-protection', 'store', "0xHHHHHHHH Set write protection to hex value (each bit set to zero is protecting 4K)" , "0xFFFFFFFF"], + ] + +def initCommandLineParser(): + """Create a command-line parser and return it. + """ + USAGE = '%prog [option...] [filename{.s37|.bin}] ...' + DESCR = """ Flash programming utility for STM32W108 device """ + + parser = optparse.OptionParser(usage=USAGE, description=DESCR, + version='%%prog %s' % version) + + for item in commandTable: + if len(item) > 4: + default = item[4] + else: + default = None + parser.add_option(item[0], item[1], action=item[2], help=item[3], default=default) + + return parser + +def getFileVersionDate(fname): + returnValue = "" + return returnValue + +def initInterface (interface, port, noReset=False, rfMode=False, eui64=0): + returnValue = rs232Interface(port, noReset, rfMode, eui64) + if returnValue.init(): + returnValue = None + return returnValue + +def terminateInterface(interface): + if (isinstance(interface, rs232Interface)): + interface.terminate() + +def flashImage (interface, inputFile, startAddress, doErase=True): + def progressReport(size, fileSize): + infoMessage ("Programming %05d/%05d\r"%(size,fileSize)) + infoMessage ("Programming user flash\n") + if not interface.programUserFlash(inputFile, startAddress, progressReport, doErase): + infoMessage("Failed \n") + else: + infoMessage("Done \n") + +def verifyFlashImage (interface, inputFile, startAddress): + def progressReport(size, fileSize): + infoMessage ("Verifying %05d/%05d\r"%(size,fileSize)) + + infoMessage ("Verifying user flash\n") + if not interface.verifyFlash(inputFile, startAddress, progressReport): + infoMessage("Failed \n") + else: + infoMessage("Done \n") + +def resetDevice (interface): + infoMessage ("Resetting device\n") + + returnValue = not interface.startApplication(0) + + if (returnValue): + infoMessage("Failed \n") + else: + infoMessage("Done \n") + +def startApplication (interface, startAddress): + infoMessage ("Starting application from address: %08x\n"%startAddress) + if not interface.startApplication(startAddress): + infoMessage("Failed \n") + else: + infoMessage("Done \n") + +def eraseUserFlash (interface): + infoMessage ("Erasing user flash (mass erase)\n") + if not interface.eraseUserFlash(): + infoMessage("Failed \n") + else: + infoMessage("Done \n") + +def printBanner(): + infoMessage ("STM32W flasher utility version %s\n"%version) + +if __name__ == '__main__': + + try: + absolutePath = os.path.abspath(sys.argv[0]) + if "frozen" in dir(sys): + version += " " + getFileVersionDate(sys.executable) + else: + version += "-" + time.strftime("%Y%m%d",time.localtime(os.stat(absolutePath).st_ctime)) + + version += " for Linux" + + interfaceHandle = None + printBanner() + + parser = initCommandLineParser() + (options, args) = parser.parse_args() + rfMode = False + + # Check command line option + if (len(args) == 1): + if (len(sys.argv) == 2): + # No option means flashing by default + options.flash_image = True + options.image = args[0] + + if (len(args) > 1): + parser.print_help() + sys.exit(-1) + + if (len(sys.argv) == 1): + parser.print_help() + sys.exit(0) + + if (options.interface is None): + # Set defualt for interface + if (options.port is None): + options.interface = "rs232" + options.port = "auto" + else: + options.interface = "rs232" + elif (options.interface == "rf"): + rfMode = True + options.address = "0x08003000" + options.interface = "rs232" + options.bootloader_mode = True + + options.interface = options.interface.lower() + + if ((options.interface == "rs232") and (options.port == None)): + parser.print_help() + sys.exit(-1) + + if (options.interface != "rs232" and options.interface != "jlink"): + parser.print_help() + sys.exit(-1) + + startAddress = int(options.address,16) + + if (options.interface == "rs232"): + optionArg = options.port.upper() + if (optionArg == "AUTO"): + port = getFirstAvailableSerialPort() + if port is None: + errorMessage ("Unable to find serial port in auto mode: no STM32W boards detected\n") + sys.exit(-1) + infoMessage ("Auto mode selected serial port: %s\n"%port) + elif (options.port[:4] == "/dev"): ## For Linux + port = options.port + else: + try: + port = int(optionArg) + except ValueError: + errorMessage("Invalid port: %s\n"%options.port) + sys.exit(-1) + else: + port = None + + if (options.interface == "jlink"): + errorMessage("JLink not yet supported.\n") + sys.exit(-1) + + if (options.start and options.reset): + errorMessage ("Only one option between -s (--start) and -r (--reset) may be specified") + sys.exit(-1) + + interfaceHandle = initInterface(options.interface, port, options.bootloader_mode, rfMode, int(options.eui64, 16)) + + if interfaceHandle is None: + errorMessage("Error while initiliazing interface\n") + sys.exit(-1) + + readoutProtection = interfaceHandle.isReadProtectionActive() + + if readoutProtection: + infoMessage("!Warning: Readout protection is active\n") + + options.device_info = False + + if (options.masserase): + eraseUserFlash(interfaceHandle) + + if (options.enable_readout_protection is not None): + if (options.enable_readout_protection == "1"): + if not readoutProtection: + infoMessage("Enabling readout protection\n") + interfaceHandle.enableReadProtection(True) + infoMessage("Done\n") + else: + infoMessage("Readout protection already enabled, no action\n") + + elif (options.enable_readout_protection == "0"): + if readoutProtection: + infoMessage("Disabling readout protection (this will clear user flash and CIB)\n") + interfaceHandle.enableReadProtection(False) + infoMessage("Done\n") + else: + infoMessage("Readout protection already disaabled, no action\n") + else: + errorMessage("Invalid value for --enable-readout-protection\n") + terminateInterface(interfaceHandle) + sys.exit(-1) + + if options.flash_image: + flashImage(interfaceHandle, options.image, startAddress, not options.masserase) + + if options.verify and not readoutProtection: + verifyFlashImage(interfaceHandle, options.image, startAddress) + + + if (options.start): + startApplication(interfaceHandle, startAddress) + + if (options.reset): + resetDevice(interfaceHandle) + + terminateInterface(interfaceHandle) + + sys.exit (0) + + except KeyboardInterrupt: + infoMessage ("User break\n") + terminateInterface(interfaceHandle) + sys.exit(-1) + + except Exception, inst: + if not ("frozen" in dir(sys)): + raise + else: + errorMessage("Internal error\n") + errorMessage("%s\n"%repr(type(inst))) # the exception instance + errorMessage("%s\n"%repr(inst.args)) # arguments stored in .args + if interfaceHandle: + terminateInterface(interfaceHandle) + sys.exit(-1) + + diff --git a/tools/stm32w/stm32w_flasher/py_files/ymodem.py b/tools/stm32w/stm32w_flasher/py_files/ymodem.py new file mode 100644 index 000000000..c51159f84 --- /dev/null +++ b/tools/stm32w/stm32w_flasher/py_files/ymodem.py @@ -0,0 +1,241 @@ + +# See comment in stm32w_flasher.py. +# Extraction and little adaptation performed by E.Duble (CNRS, LIG). + +import os +import serial +import struct +import time +from messages import errorMessage +from messages import infoMessage + + +class Ymodem(): + ABORT1 = 65 + ABORT2 = 97 + ACK = 6 + CA = 24 + CRC16 = 67 + EOT = 4 + NAK = 21 + PACKET_1K_SIZE = 1024 + PACKET_HEADER = 3 + PACKET_OVERHEAD = 5 + PACKET_SIZE = 128 + PACKET_TRAILER = 2 + SOH = 1 + STATE_DONE = 6 + STATE_READY = 2 + STATE_SEND_EOT = 3 + STATE_SEND_SESSION_DONE = 4 + STATE_START_APPLICATION = 5 + STATE_WAITING_ACK = 1 + STATE_WAITING_CRC16 = 0 + STX = 2 + YMODEM_RX_TO_TX = 2 + YMODEM_TX_TO_RX = 0 + YMODEM_TX_TO_RX2 = 1 + def Crc16X(self, packet, count): + j = 0 + crc = 0 + for j in range(count): + crc = (crc ^ ((packet[j]) << 8)) + for i in range(8): + if (crc & 32768): + crc = ((crc << 1) ^ 4129) + continue + else: + crc = (crc << 1) + continue + continue + return crc + + def __init__(self, serialPort, port, updateAction=None): + self.serialPort = serialPort + self.updateAction = updateAction + self.port = port + return None + + def bootloaderInit(self): + returnValue = False + systemRestartPacket = [170, 1, 7, 85] + self.serialPort.write(struct.pack(('B' * len(systemRestartPacket)), *systemRestartPacket)) + self.serialPort.close() + time.sleep(5) + self.serialPort = serial.Serial(port, 10, timeout=4) + self.serialPort.flushInput() + systemRestartPacket = [170, 1, 5, 85] + self.serialPort.write(struct.pack(('B' * len(systemRestartPacket)), *systemRestartPacket)) + self.serialPort.read(4) + for i in range(10): + startTime = time.time() + while (time.time() - startTime) < 0.5: + if self.serialPort.inWaiting() > 0: + c = self.serialPort.read(1) + c = (struct.unpack('B', c)[0]) + if c == ord('C'): + returnValue = True + break + time.sleep(0.01) + continue + continue + return returnValue + + def getByte(self): + data = None + if self.serialPort.inWaiting() > 0: + data = (struct.unpack('B', self.serialPort.read(1))[0]) + if data: + pass + return data + + def loadFile(self, name): + returnValue = True + state = self.STATE_WAITING_CRC16 + filename = os.path.basename(name) + startTime = time.time() + try: + f = open(name, 'rb') + infoMessage((('File ' + name) + ' opened\n')) + f.seek(0, 2) + file_size = f.tell() + f.seek(0, 0) + packet_number = 0 + loop_counter = 1 + size = file_size + retry = 0 + packet = [] + prevState = self.STATE_READY + while True: + newState = state + if state == self.STATE_WAITING_CRC16: + if self.updateAction: + self.updateAction((file_size - max(size, 0)), file_size) + data = self.getByte() + if data == self.CRC16: + newState = self.STATE_READY + else: + if state == self.STATE_WAITING_ACK: + if self.updateAction: + self.updateAction((file_size - max(size, 0)), file_size) + data = self.getByte() + if data is not None: + if data == self.ACK: + if prevState == self.STATE_READY: + retry = 0 + if loop_counter > 1: + size = (size - packet_size) + packet_number = ((packet_number + 1) % 256) + loop_counter = (loop_counter + 1) + packet_done = True + if self.updateAction: + self.updateAction((file_size - max(size, 0)), file_size) + else: + infoMessage(('Sent %05d/%05d\r' % ((file_size - max(size, 0)), file_size))) + newState = self.STATE_READY + else: + if prevState == self.STATE_SEND_EOT: + newState = self.STATE_SEND_SESSION_DONE + else: + if prevState == self.STATE_SEND_SESSION_DONE: + newState = self.STATE_START_APPLICATION + else: + if data == self.CA: + errorMessage('Transaction aborted by client\n') + newState = self.STATE_DONE + else: + if data == self.CRC16: + pass + else: + if prevState == self.STATE_READY: + infoMessage('Retrying\n') + retry = (retry + 1) + if retry > 3: + errorMessage('Too many retry exiting\n') + newState = self.STATE_DONE + else: + newState = self.STATE_READY + else: + if state == self.STATE_READY: + if size <= 0: + newState = self.STATE_SEND_EOT + else: + if retry == 0: + packet = [] + if loop_counter == 1: + packet.extend(struct.unpack(('%uB' % len(filename)), filename)) + packet = (packet + [0]) + size_string = ('%d ' % file_size) + packet.extend(struct.unpack(('%uB' % len(size_string)), size_string)) + packet_size = self.PACKET_SIZE + else: + packet_size = self.PACKET_1K_SIZE + packet_string = f.read(packet_size) + packet.extend(struct.unpack(('%uB' % len(packet_string)), packet_string)) + packet = (packet + ([0] * (packet_size - len(packet)))) + if self.sendYModemPacket(packet, packet_number): + newState = self.STATE_DONE + else: + newState = self.STATE_WAITING_ACK + else: + if state == self.STATE_SEND_EOT: + if self.updateAction: + self.updateAction((file_size - max(size, 0)), file_size) + else: + infoMessage(('Sent %05d/%05d\r' % ((file_size - max(size, 0)), file_size))) + self.sendByte(self.EOT) + newState = self.STATE_WAITING_ACK + else: + if state == self.STATE_SEND_SESSION_DONE: + self.sendYModemPacket(([0] * 128), 0) + newState = self.STATE_WAITING_ACK + else: + if state == self.STATE_START_APPLICATION: + self.startApplication() + newState = self.STATE_DONE + else: + if state == self.STATE_DONE: + returnValue = False + endTime = time.time() + infoMessage('\nDone\n') + break + else: + errorMessage(('Unknonw state = %d' % state)) + newState = self.STATE_DONE + if state != newState: + prevState = state + state = newState + continue + else: + continue + return returnValue + except: + errorMessage((('File ' + name) + ' open failed\n')) + if self.updateAction: + self.updateAction(0, 0) + return returnValue + + def sendByte(self, byte): + self.serialPort.write(struct.pack('B', byte)) + return None + + def sendYModemPacket(self, myPacket, packet_number): + returnValue = 0 + packet = myPacket[:] + packet_crc = self.Crc16X(packet, len(packet)) + packet.append(((packet_crc >> 8) & 255)) + packet.append((packet_crc & 255)) + packet.insert(0, (255 - packet_number)) + packet.insert(0, packet_number) + if len(myPacket) == self.PACKET_SIZE: + packet.insert(0, self.SOH) + else: + packet.insert(0, self.STX) + self.serialPort.write(struct.pack(('B' * len(packet)), *packet)) + return returnValue + + def startApplication(self): + return None + + + diff --git a/tools/stm32w/stm32w_flasher/stm32w_flasher b/tools/stm32w/stm32w_flasher/stm32w_flasher deleted file mode 100755 index 883f9d60a..000000000 Binary files a/tools/stm32w/stm32w_flasher/stm32w_flasher and /dev/null differ