├── schematicc.gif ├── Test ├── PL2303HX_baud.gif ├── floader825x.bin ├── README.md └── ComSwireFlasher825x.py ├── LICENSE ├── README.md ├── ComSwireWriter826x.py ├── ComSwireWriter825x.py ├── ComSwireReader825x.py ├── USBCOMFlashTx.html └── TLSR825xComFlasher.py /schematicc.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvvx/TlsrComSwireWriter/HEAD/schematicc.gif -------------------------------------------------------------------------------- /Test/PL2303HX_baud.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvvx/TlsrComSwireWriter/HEAD/Test/PL2303HX_baud.gif -------------------------------------------------------------------------------- /Test/floader825x.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvvx/TlsrComSwireWriter/HEAD/Test/floader825x.bin -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /Test/README.md: -------------------------------------------------------------------------------- 1 | # TlsrComSwireRW 2 | TLSR825x COM port Swire Utility 3 | 4 | ### Telink SWIRE simulation on a COM port. 5 | 6 | Using only the COM port and TLSR825x chips. 7 | 8 | ![SCH](https://github.com/pvvx/TlsrComSwireWriter/blob/master/schematicc.gif) 9 | 10 | 11 | The project was closed without starting. 12 | 13 | Low polling speed when reading the USB COM port on some chips - 3 ms per byte. 14 | 15 | An incomplete example is attached. 16 | 17 | Tested on Prolific PL-2303HX USB-COM chip: 18 | 19 | ![PL2303HXBAUD](https://github.com/pvvx/TlsrComSwireWriter/blob/master/Test/PL2303HX_baud.gif) 20 | 21 | 22 | #### Samples: 23 | > **Read Flash:** python.exe ComSwireFlasher825x.py -p COM11 -a 0 -s 256 -t 70 24 | ``` 25 | ======================================================= 26 | TLSR825x ComSwireFlasher Utility version 19.11.20(test) 27 | ------------------------------------------------------- 28 | Open COM3, 921600 baud... 29 | Reset module (RTS low)... 30 | Activate (70 ms)... 31 | Load to 0x840000... 32 | Bin bytes writen: 1188 33 | CPU go Start... 34 | SWire speed for CLK 24.0 MHz... ok. 35 | ------------------------------------------------------- 36 | Floader id: 78353238, ver: 0.0.0.5, bufsize: 12288 37 | ChipID: 0x5562, ver: 0x02 38 | Flash JEDEC ID: C86013, Size: 512 kbytes 39 | ------------------------------------------------------- 40 | Read Flash from 0x000000 to 0x000100... 41 | Outfile: out.bin 42 | ------------------------------------------------------- 43 | Done! 44 | ``` 45 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # TlsrComSwireWriter 2 | TLSR826x/825x COM port Swire Writer Utility 3 | 4 | 5 | ### Telink SWIRE simulation on a COM port. 6 | 7 | Using only the COM port, downloads and runs the program in SRAM for TLSR826x or TLSR825x chips. 8 | 9 | ![SCH](https://github.com/pvvx/TlsrComSwireWriter/blob/master/schematicc.gif) 10 | 11 | Don't forget to connect GND. 12 | 13 | If the module does not have a RESET pin from the chip, then the RTS signal from the COM port can be connected as the module power supply - connect it to +3.3 V of the module. 14 | 15 | If the module has a RESET pin, then it is advisable to connect the module power supply to +3.3 V, and connect RESET to RTS. 16 | 17 | 18 | 19 | usage: ComSwireWriter [-h] [--port PORT] [--tact TACT] [--file FILE] [--baud BAUD] 20 | 21 | TLSR826x ComSwireWriter Utility version 21.02.20 22 | 23 | optional arguments: 24 | -h, --help show this help message and exit 25 | --port PORT, -p PORT Serial port device (default: COM1) 26 | --tact TACT, -t TACT Time Activation ms (0-off, default: 600 ms) 27 | --file FILE, -f FILE Filename to load (default: floader.bin) 28 | --baud BAUD, -b BAUD UART Baud Rate (default: 230400) 29 | 30 | Added TLSR825xComFlasher: 31 | 32 | usage: TLSR825xComFlasher.py [-h] [-p PORT] [-t TACT] [-c CLK] [-b BAUD] [-r] 33 | [-d] 34 | {rf,wf,es,ea} ... 35 | 36 | TLSR825x Flasher version 00.00.02 37 | 38 | positional arguments: 39 | {rf,wf,es,ea} TLSR825xComFlasher {command} -h for additional help 40 | rf Read Flash to binary file 41 | wf Write file to Flash with sectors erases 42 | es Erase Region (sectors) of Flash 43 | ea Erase All Flash 44 | 45 | optional arguments: 46 | -h, --help show this help message and exit 47 | -p PORT, --port PORT Serial port device (default: COM1) 48 | -t TACT, --tact TACT Time Activation ms (0-off, default: 0 ms) 49 | -c CLK, --clk CLK SWire CLK (default: auto, 0 - auto) 50 | -b BAUD, --baud BAUD UART Baud Rate (default: 921600, min: 340000) 51 | -r, --run CPU Run (post main processing) 52 | -d, --debug Debug info 53 | 54 | 55 | Warning: 56 | - Does not work on USB-COM adapters that have LEDs on at the RX input. 57 | - Does not work on USB-COM adapters that have FTDI chip 58 | 59 | #### Samples: 60 | > **Write full flash:** python.exe TLSR825xComFlasher.py -p COM3 -t 70 wf 0 Original_full_flash_Xiaomi_LYWSD03MMC.bin 61 | ``` 62 | ======================================================= 63 | TLSR825x Flasher version 00.00.02 64 | ------------------------------------------------------- 65 | Open COM3, 921600 baud... 66 | Reset module (RTS low)... 67 | Activate (70 ms)... 68 | UART-SWS 92160 baud. SW-CLK ~23.0 MHz(?) 69 | Inputfile: Original_full_flash_Xiaomi_LYWSD03MMC.bin 70 | Write Flash data 0x00000000 to 0x00080000... 71 | ------------------------------------------------------- 72 | Worked Time: 48.761 sec 73 | Done! 74 | ``` 75 | -------------------------------------------------------------------------------- /ComSwireWriter826x.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | ### ComSwireWriter.py ### 4 | ### Autor: pvvx ### 5 | 6 | import sys 7 | import struct 8 | import serial 9 | import platform 10 | import time 11 | import argparse 12 | import os 13 | import io 14 | 15 | __progname__ = 'TLSR826x ComSwireWriter Utility' 16 | __filename__ = 'ComSwireWriter' 17 | __version__ = "25.02.20" 18 | 19 | class FatalError(RuntimeError): 20 | def __init__(self, message): 21 | RuntimeError.__init__(self, message) 22 | 23 | @staticmethod 24 | def WithResult(message, result): 25 | message += " (result was %s)" % hexify(result) 26 | return FatalError(message) 27 | 28 | def arg_auto_int(x): 29 | return int(x, 0) 30 | 31 | def sws_code_blk(blk): 32 | pkt=[] 33 | d = bytearray([0xd8,0xdf,0xdf,0xdf,0xdf]) 34 | for el in blk: 35 | if (el & 0x80) != 0: 36 | d[0] &= 0x1f 37 | if (el & 0x40) != 0: 38 | d[1] &= 0xf8 39 | if (el & 0x20) != 0: 40 | d[1] &= 0x1f 41 | if (el & 0x10) != 0: 42 | d[2] &= 0xf8 43 | if (el & 0x08) != 0: 44 | d[2] &= 0x1f 45 | if (el & 0x04) != 0: 46 | d[3] &= 0xf8 47 | if (el & 0x02) != 0: 48 | d[3] &= 0x1f 49 | if (el & 0x01) != 0: 50 | d[4] &= 0xf8 51 | pkt += d 52 | d = bytearray([0xdf,0xdf,0xdf,0xdf,0xdf]) 53 | return pkt 54 | 55 | def sws_rd_addr(addr): 56 | return sws_code_blk(bytearray([0x5a, (addr>>8)&0xff, addr & 0xff, 0x80])) 57 | def sws_code_end(): 58 | return sws_code_blk([0xff]) 59 | def sws_wr_addr(addr, data): 60 | return sws_code_blk(bytearray([0x5a, (addr>>8)&0xff, addr & 0xff, 0x00]) + bytearray(data)) + sws_code_blk([0xff]) 61 | 62 | def main(): 63 | parser = argparse.ArgumentParser(description='%s version %s' % (__progname__, __version__), prog=__filename__) 64 | parser.add_argument( 65 | '--port', '-p', 66 | help='Serial port device (default: COM1)', 67 | default='COM1') 68 | parser.add_argument( 69 | '--tact','-t', 70 | help='Time Activation ms (0-off, default: 600 ms)', 71 | type=arg_auto_int, 72 | default=600) 73 | parser.add_argument( 74 | '--file','-f', 75 | help='Filename to load (default: floader.bin)', 76 | default='floader.bin') 77 | parser.add_argument( 78 | '--baud','-b', 79 | help='UART Baud Rate (default: 230400)', 80 | type=arg_auto_int, 81 | default=230400) 82 | 83 | args = parser.parse_args() 84 | print('%s version %s' % (__progname__, __version__)) 85 | print('------------------------------------------------') 86 | print ('Open %s, %d baud...' % (args.port, args.baud)) 87 | try: 88 | serialPort = serial.Serial(args.port, args.baud, \ 89 | serial.EIGHTBITS,\ 90 | serial.PARITY_NONE, \ 91 | serial.STOPBITS_ONE) 92 | # serialPort.flushInput() 93 | # serialPort.flushOutput() 94 | serialPort.timeout = 100*12/args.baud 95 | except: 96 | print ('Error: Open %s, %d baud!' % (args.port, args.baud)) 97 | sys.exit(1) 98 | #-------------------------------- 99 | try: 100 | stream = open(args.file, 'rb') 101 | size = os.path.getsize(args.file) 102 | except: 103 | serialPort.close 104 | print('Error: Not open input file <%s>!' % args.file) 105 | sys.exit(2) 106 | if size < 1: 107 | stream.close 108 | serialPort.close 109 | print('Error: File size = 0!') 110 | sys.exit(3) 111 | warn = 0 112 | #-------------------------------- 113 | # issue reset-to-bootloader: 114 | # RTS = either RESET (active low = chip in reset) 115 | # DTR = active low 116 | print('Reset module (RTS low)...') 117 | serialPort.setDTR(True) 118 | serialPort.setRTS(True) 119 | time.sleep(0.05) 120 | serialPort.setDTR(False) 121 | serialPort.setRTS(False) 122 | #-------------------------------- 123 | # Stop CPU|: [0x0602]=5 124 | print('Activate (%d ms)...' % args.tact) 125 | tact = args.tact/1000.0 126 | blk = sws_wr_addr(0x0602, bytearray([5])) 127 | byteSent = serialPort.write(blk) 128 | if args.tact != 0: 129 | t1 = time.time() 130 | while time.time()-t1 < tact: 131 | for i in range(5): 132 | byteSent += serialPort.write(blk) 133 | serialPort.reset_input_buffer() 134 | time.sleep(byteSent*12/args.baud - tact) 135 | while len(serialPort.read(1000)): 136 | continue 137 | #-------------------------------- 138 | # Set SWS speed low: [0x00b2]=50 139 | byteSent = serialPort.write(sws_wr_addr(0x00b2, [45])) 140 | read = serialPort.read(byteSent+33) 141 | byteRead = len(read) 142 | if byteRead != byteSent: 143 | byteSent = 0 144 | warn += 1 145 | print('Warning: Wrong RX-TX connection?') 146 | #-------------------------------- 147 | # Test read bytes [0x00b2] 148 | byteSent += serialPort.write(sws_rd_addr(0x00b2)) 149 | # start read 150 | byteSent += serialPort.write([0xff]) 151 | read = serialPort.read(byteSent-byteRead+33) 152 | byteRead += len(read) 153 | if byteRead <= byteSent: 154 | print('Warning: Pin RX no connection to the module?') 155 | warn += 1 156 | else: 157 | print('Connection...') 158 | # stop read 159 | byteSent += serialPort.write(sws_code_end()) 160 | read = serialPort.read(byteSent-byteRead+33) 161 | byteRead += len(read) 162 | #-------------------------------- 163 | # Load floader.bin 164 | binWrite = 0 165 | rdsize = 0x100 166 | addr = 0x8000 167 | print('Load <%s> to 0x%04x...' % (args.file, addr)) 168 | while size > 0: 169 | print('\r0x%04x' % addr, end = '') 170 | data = stream.read(rdsize) 171 | if not data: # end of stream 172 | print('send: at EOF') 173 | break 174 | byteSent += serialPort.write(sws_wr_addr(addr, data)) 175 | serialPort.reset_input_buffer() 176 | binWrite += len(data) 177 | addr += len(data) 178 | size -= len(data) 179 | stream.close 180 | print('\rBin bytes writen:', binWrite) 181 | print('CPU go Start...') 182 | byteSent += serialPort.write(sws_wr_addr(0x0602, [0x88])) # cpu go Start 183 | serialPort.close 184 | print('COM bytes sent:', byteSent) 185 | print('------------------------------------------------') 186 | if warn == 0: 187 | print('Done!') 188 | else: 189 | print('(%d) Warning' % warn) 190 | sys.exit(0) 191 | 192 | if __name__ == '__main__': 193 | main() 194 | -------------------------------------------------------------------------------- /ComSwireWriter825x.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | ### ComSwireWriter.py ### 4 | ### Autor: pvvx ### 5 | 6 | import sys 7 | import struct 8 | import serial 9 | import platform 10 | import time 11 | import argparse 12 | import os 13 | import io 14 | 15 | __progname__ = 'TLSR825x ComSwireWriter Utility' 16 | __filename__ = 'ComSwireWriter' 17 | __version__ = "10.11.20" 18 | 19 | class FatalError(RuntimeError): 20 | def __init__(self, message): 21 | RuntimeError.__init__(self, message) 22 | 23 | @staticmethod 24 | def WithResult(message, result): 25 | message += " (result was %s)" % hexify(result) 26 | return FatalError(message) 27 | 28 | def arg_auto_int(x): 29 | return int(x, 0) 30 | 31 | def sws_code_blk(blk): 32 | pkt=[] 33 | d = bytearray([0xd8,0xdf,0xdf,0xdf,0xdf]) 34 | for el in blk: 35 | if (el & 0x80) != 0: 36 | d[0] &= 0x1f 37 | if (el & 0x40) != 0: 38 | d[1] &= 0xf8 39 | if (el & 0x20) != 0: 40 | d[1] &= 0x1f 41 | if (el & 0x10) != 0: 42 | d[2] &= 0xf8 43 | if (el & 0x08) != 0: 44 | d[2] &= 0x1f 45 | if (el & 0x04) != 0: 46 | d[3] &= 0xf8 47 | if (el & 0x02) != 0: 48 | d[3] &= 0x1f 49 | if (el & 0x01) != 0: 50 | d[4] &= 0xf8 51 | pkt += d 52 | d = bytearray([0xdf,0xdf,0xdf,0xdf,0xdf]) 53 | return pkt 54 | 55 | def sws_rd_addr(addr): 56 | return sws_code_blk(bytearray([0x5a, (addr>>16)&0xff, (addr>>8)&0xff, addr & 0xff, 0x80])) 57 | def sws_code_end(): 58 | return sws_code_blk([0xff]) 59 | def sws_wr_addr(addr, data): 60 | return sws_code_blk(bytearray([0x5a, (addr>>16)&0xff, (addr>>8)&0xff, addr & 0xff, 0x00]) + bytearray(data)) + sws_code_blk([0xff]) 61 | 62 | def main(): 63 | parser = argparse.ArgumentParser(description='%s version %s' % (__progname__, __version__), prog=__filename__) 64 | parser.add_argument( 65 | '--port', '-p', 66 | help='Serial port device (default: COM1)', 67 | default='COM1') 68 | parser.add_argument( 69 | '--tact','-t', 70 | help='Time Activation ms (0-off, default: 600 ms)', 71 | type=arg_auto_int, 72 | default=600) 73 | parser.add_argument( 74 | '--file','-f', 75 | help='Filename to load (default: floader.bin)', 76 | default='floader.bin') 77 | parser.add_argument( 78 | '--baud','-b', 79 | help='UART Baud Rate (default: 230400)', 80 | type=arg_auto_int, 81 | default=230400) 82 | 83 | args = parser.parse_args() 84 | print('================================================') 85 | print('%s version %s' % (__progname__, __version__)) 86 | print('------------------------------------------------') 87 | print ('Open %s, %d baud...' % (args.port, args.baud)) 88 | try: 89 | serialPort = serial.Serial(args.port, args.baud, \ 90 | serial.EIGHTBITS,\ 91 | serial.PARITY_NONE, \ 92 | serial.STOPBITS_ONE) 93 | # serialPort.flushInput() 94 | # serialPort.flushOutput() 95 | serialPort.timeout = 100*12/args.baud 96 | except: 97 | print ('Error: Open %s, %d baud!' % (args.port, args.baud)) 98 | sys.exit(1) 99 | #-------------------------------- 100 | try: 101 | stream = open(args.file, 'rb') 102 | size = os.path.getsize(args.file) 103 | except: 104 | serialPort.close 105 | print('Error: Not open input file <%s>!' % args.file) 106 | sys.exit(2) 107 | if size < 1: 108 | stream.close 109 | serialPort.close 110 | print('Error: File size = 0!') 111 | sys.exit(3) 112 | warn = 0 113 | #-------------------------------- 114 | # issue reset-to-bootloader: 115 | # RTS = either RESET (active low = chip in reset) 116 | # DTR = active low 117 | print('Reset module (RTS low)...') 118 | serialPort.setDTR(True) 119 | serialPort.setRTS(True) 120 | time.sleep(0.05) 121 | serialPort.setDTR(False) 122 | serialPort.setRTS(False) 123 | #-------------------------------- 124 | # Stop CPU|: [0x0602]=5 125 | print('Activate (%d ms)...' % args.tact) 126 | tact = args.tact/1000.0 127 | blk = sws_wr_addr(0x0602, bytearray([5])) 128 | byteSent = serialPort.write(blk) 129 | if args.tact != 0: 130 | t1 = time.time() 131 | while time.time()-t1 < tact: 132 | for i in range(5): 133 | byteSent += serialPort.write(blk) 134 | serialPort.reset_input_buffer() 135 | time.sleep(byteSent*12/args.baud) 136 | while len(serialPort.read(1000)): 137 | continue 138 | #-------------------------------- 139 | # Set SWS speed low: [0x00b2]=50 140 | byteSent = serialPort.write(sws_wr_addr(0x00b2, [45])) 141 | read = serialPort.read(byteSent+33) 142 | byteRead = len(read) 143 | if byteRead != byteSent: 144 | byteSent = 0 145 | warn += 1 146 | print('Warning: Wrong RX-TX connection?') 147 | #-------------------------------- 148 | # Test read bytes [0x00b2] 149 | byteSent += serialPort.write(sws_rd_addr(0x00b2)) 150 | # start read 151 | byteSent += serialPort.write([0xff]) 152 | read = serialPort.read(byteSent-byteRead+33) 153 | byteRead += len(read) 154 | if byteRead <= byteSent: 155 | print('Warning: Pin RX no connection to the module?') 156 | warn += 1 157 | else: 158 | print('Connection...') 159 | # stop read 160 | byteSent += serialPort.write(sws_code_end()) 161 | read = serialPort.read(byteSent-byteRead+33) 162 | byteRead += len(read) 163 | #-------------------------------- 164 | # Load floader.bin 165 | binWrite = 0 166 | rdsize = 0x100 167 | addr = 0x40000 168 | print('Load <%s> to 0x%04x...' % (args.file, addr)) 169 | while size > 0: 170 | print('\r0x%04x' % addr, end = '') 171 | data = stream.read(rdsize) 172 | if not data: # end of stream 173 | print('send: at EOF') 174 | break 175 | byteSent += serialPort.write(sws_wr_addr(addr, data)) 176 | serialPort.reset_input_buffer() 177 | binWrite += len(data) 178 | addr += len(data) 179 | size -= len(data) 180 | stream.close 181 | print('\rBin bytes writen:', binWrite) 182 | print('CPU go Start...') 183 | byteSent += serialPort.write(sws_wr_addr(0x0602, [0x88])) # cpu go Start 184 | serialPort.close 185 | print('COM bytes sent:', byteSent) 186 | print('------------------------------------------------') 187 | if warn == 0: 188 | print('Done!') 189 | else: 190 | print('(%d) Warning' % warn) 191 | sys.exit(0) 192 | 193 | if __name__ == '__main__': 194 | main() 195 | -------------------------------------------------------------------------------- /ComSwireReader825x.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | ### ComSwireWriter.py ### 4 | ### Autor: pvvx ### 5 | 6 | import sys 7 | import struct 8 | import serial 9 | import platform 10 | import time 11 | import argparse 12 | import os 13 | import io 14 | 15 | __progname__ = 'TLSR825x ComSwireReader Utility' 16 | __filename__ = 'ComSwireReader' 17 | __version__ = "20.11.20" 18 | 19 | COMPORT_MIN_BAUD_RATE=340000 20 | COMPORT_DEF_BAUD_RATE=921600 21 | USBCOMPORT_BAD_BAUD_RATE=11700000 22 | 23 | debug = False 24 | bit8mask = 0x20 25 | 26 | class FatalError(RuntimeError): 27 | def __init__(self, message): 28 | RuntimeError.__init__(self, message) 29 | @staticmethod 30 | def WithResult(message, result): 31 | message += " (result was %s)" % hexify(result) 32 | return FatalError(message) 33 | def arg_auto_int(x): 34 | return int(x, 0) 35 | def hex_dump(addr, blk): 36 | print('%06x: ' % addr, end='') 37 | for i in range(len(blk)): 38 | if (i+1) % 16 == 0: 39 | print('%02x ' % blk[i]) 40 | if i < len(blk) - 1: 41 | print('%06x: ' % (addr + i + 1), end='') 42 | else: 43 | print('%02x ' % blk[i], end='') 44 | if len(blk) % 16 != 0: 45 | print('') 46 | # encode data (blk) into 10-bit swire words 47 | def sws_encode_blk(blk): 48 | pkt=[] 49 | d = bytearray(10) # word swire 10 bits 50 | d[0] = 0x80 # start bit byte cmd swire = 1 51 | for el in blk: 52 | m = 0x80 # mask bit 53 | idx = 1 54 | while m != 0: 55 | if (el & m) != 0: 56 | d[idx] = 0x80 57 | else: 58 | d[idx] = 0xfe 59 | idx += 1 60 | m >>= 1 61 | d[9] = 0xfe # stop bit swire = 0 62 | pkt += d 63 | d[0] = 0xfe # start bit next byte swire = 0 64 | return pkt 65 | # decode 9 bit swire response to byte (blk) 66 | def sws_decode_blk(blk): 67 | if (len(blk) == 9) and ((blk[8] & 0xfe) == 0xfe): 68 | bitmask = bit8mask 69 | data = 0; 70 | for el in range(8): 71 | data <<= 1 72 | if (blk[el] & bitmask) == 0: 73 | data |= 1 74 | bitmask = 0x10 75 | #print('0x%02x' % data) 76 | return data 77 | #print('Error blk:', blk) 78 | return None 79 | # encode a part of the read-by-address command (before the data read start bit) into 10-bit swire words 80 | def sws_rd_addr(addr): 81 | return sws_encode_blk(bytearray([0x5a, (addr>>16)&0xff, (addr>>8)&0xff, addr & 0xff, 0x80])) 82 | # encode command stop into 10-bit swire words 83 | def sws_code_end(): 84 | return sws_encode_blk([0xff]) 85 | # encode the command for writing data into 10-bit swire words 86 | def sws_wr_addr(addr, data): 87 | return sws_encode_blk(bytearray([0x5a, (addr>>16)&0xff, (addr>>8)&0xff, addr & 0xff, 0x00]) + bytearray(data)) + sws_encode_blk([0xff]) 88 | # send block to USB-COM 89 | def wr_usbcom_blk(serialPort, blk): 90 | # USB-COM chips throttle the stream into blocks at high speed! 91 | if serialPort.baudrate > USBCOMPORT_BAD_BAUD_RATE: 92 | i = 0 93 | s = 60 94 | l = len(blk) 95 | while i < l: 96 | if l - i < s: 97 | s = l - i 98 | i += serialPort.write(blk[i:i+s]) 99 | return i 100 | return serialPort.write(blk) 101 | # send and receive block to USB-COM 102 | def rd_wr_usbcom_blk(serialPort, blk): 103 | i = wr_usbcom_blk(serialPort, blk) 104 | return i == len(serialPort.read(i)) 105 | # send swire command write to USB-COM 106 | def sws_wr_addr_usbcom(serialPort, addr, data): 107 | return wr_usbcom_blk(serialPort, sws_wr_addr(addr, data)) 108 | # send and receive swire command write to USB-COM 109 | def rd_sws_wr_addr_usbcom(serialPort, addr, data): 110 | i = wr_usbcom_blk(serialPort, sws_wr_addr(addr, data)) 111 | return i == len(serialPort.read(i)) 112 | # send and receive swire command read to USB-COM 113 | def sws_read_data(serialPort, addr, size): 114 | # A serialPort.timeout must be set ! 115 | serialPort.timeout = 0.01 116 | # send addr and flag read 117 | rd_wr_usbcom_blk(serialPort, sws_rd_addr(addr)) 118 | out=[] 119 | # read size bytes 120 | for i in range(size): 121 | # send bit start read byte 122 | serialPort.write([0xfe]) 123 | # read 9 bits swire, decode read byte 124 | blk = serialPort.read(9) 125 | # Added retry reading for Prolific PL-2303HX and ... 126 | if len(blk) < 9: 127 | blk += serialPort.read(10-len(blk)) 128 | x = sws_decode_blk(blk) 129 | if x != None: 130 | out += [x] 131 | else: 132 | if debug: 133 | print('\r\nDebug: read swire byte:') 134 | hex_dump(addr+i, blk) 135 | # send stop read 136 | rd_wr_usbcom_blk(serialPort, sws_code_end()) 137 | out = None 138 | break 139 | # send stop read 140 | rd_wr_usbcom_blk(serialPort, sws_code_end()) 141 | return out 142 | # set sws speed according to clk frequency and serialPort baud 143 | def set_sws_speed(serialPort, clk): 144 | #-------------------------------- 145 | # Set register[0x00b2] 146 | print('SWire speed for CLK %.1f MHz... ' % (clk/1000000), end='') 147 | swsdiv = int(round(clk*2/serialPort.baudrate)) 148 | if swsdiv > 0x7f: 149 | print('Low UART baud rate!') 150 | return False 151 | byteSent = sws_wr_addr_usbcom(serialPort, 0x00b2, [swsdiv]) 152 | # print('Test SWM/SWS %d/%d baud...' % (int(serialPort.baudrate/5),int(clk/5/swsbaud))) 153 | read = serialPort.read(byteSent) 154 | if len(read) != byteSent: 155 | if serialPort.baudrate > USBCOMPORT_BAD_BAUD_RATE and byteSent > 64 and len(read) >= 64 and len(read) < byteSent: 156 | print('\n\r!!!!!!!!!!!!!!!!!!!BAD USB-UART Chip!!!!!!!!!!!!!!!!!!!') 157 | print('UART Output:') 158 | hex_dump(0,sws_wr_addr(0x00b2, [swsdiv])) 159 | print('UART Input:') 160 | hex_dump(0,read) 161 | print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!') 162 | return False 163 | print('\n\rError: Wrong RX-TX connection!') 164 | return False 165 | #-------------------------------- 166 | # Test read register[0x00b2] 167 | x = sws_read_data(serialPort, 0x00b2, 1) 168 | #print(x) 169 | if x != None and x[0] == swsdiv: 170 | print('ok.') 171 | if debug: 172 | print('Debug: UART-SWS %d baud. SW-CLK ~%.1f MHz' % (int(serialPort.baudrate/10), serialPort.baudrate*swsdiv/2000000)) 173 | print('Debug: swdiv = 0x%02x' % (swsdiv)) 174 | return True 175 | #-------------------------------- 176 | # Set default register[0x00b2] 177 | rd_sws_wr_addr_usbcom(serialPort, 0x00b2, 0x05) 178 | print('no') 179 | return False 180 | # auto set sws speed according to serialport baud 181 | def set_sws_auto_speed(serialPort): 182 | #--------------------------------------------------- 183 | # swsbaud = Fclk/5/register[0x00b2] 184 | # register[0x00b2] = Fclk/5/swsbaud 185 | # swsbaud = serialPort.baudrate/10 186 | # register[0x00b2] = Fclk*2/serialPort.baudrate 187 | # Fclk = 16000000..48000000 Hz 188 | # serialPort.baudrate = 460800..3000000 bits/s 189 | # register[0x00b2] = swsdiv = 10..208 190 | #--------------------------------------------------- 191 | serialPort.timeout = 0.01 # A serialPort.timeout must be set ! 192 | if debug: 193 | swsdiv_def = int(round(24000000*2/serialPort.baudrate)) 194 | print('Debug: default swdiv for 24 MHz = %d (0x%02x)' % (swsdiv_def, swsdiv_def)) 195 | swsdiv = int(round(16000000*2/serialPort.baudrate)) 196 | if swsdiv > 0x7f: 197 | print('Low UART baud rate!') 198 | return False 199 | swsdiv_max = int(round(48000000*2/serialPort.baudrate)) 200 | #bit8m = (bit8mask + (bit8mask<<1) + (bit8mask<<2))&0xff 201 | bit8m = 0x80 #((~(bit8mask-1))<<1)&0xff 202 | while swsdiv <= swsdiv_max: 203 | # register[0x00b2] = swsdiv 204 | rd_sws_wr_addr_usbcom(serialPort, 0x00b2, [swsdiv]) 205 | # send addr and flag read 206 | rd_wr_usbcom_blk(serialPort, sws_rd_addr(0x00b2)) 207 | # start read data 208 | serialPort.write([0xfe]) 209 | # read 9 bits data 210 | blk = serialPort.read(9) 211 | # Added retry reading for Prolific PL-2303HX and ... 212 | if len(blk) < 9: 213 | blk += serialPort.read(9-len(blk)) 214 | # send stop read 215 | rd_wr_usbcom_blk(serialPort, sws_code_end()) 216 | if debug: 217 | print('Debug (read data):') 218 | hex_dump(swsdiv, blk) 219 | if len(blk) == 9 and blk[8] == 0xfe: 220 | cmp = sws_encode_blk([swsdiv]) 221 | if debug: 222 | print('Debug (check data):') 223 | hex_dump(swsdiv+0xccc00, sws_encode_blk([swsdiv])) 224 | if (blk[0]&bit8m) == bit8m and blk[1] == cmp[2] and blk[2] == cmp[3] and blk[4] == cmp[5] and blk[6] == cmp[7] and blk[7] == cmp[8]: 225 | print('UART-SWS %d baud. SW-CLK ~%.1f MHz(?)' % (int(serialPort.baudrate/10), serialPort.baudrate*swsdiv/2000000)) 226 | return True 227 | swsdiv += 1 228 | if swsdiv > 0x7f: 229 | print('Low UART baud rate!') 230 | break 231 | #-------------------------------- 232 | # Set default register[0x00b2] 233 | rd_sws_wr_addr_usbcom(serialPort, 0x00b2, 0x05) 234 | return False 235 | def activate(serialPort, tact_ms): 236 | #-------------------------------- 237 | # issue reset-to-bootloader: 238 | # RTS = either RESET (active low = chip in reset) 239 | # DTR = active low 240 | print('Reset module (RTS low)...') 241 | serialPort.setDTR(True) 242 | serialPort.setRTS(True) 243 | time.sleep(0.05) 244 | serialPort.setDTR(False) 245 | serialPort.setRTS(False) 246 | #-------------------------------- 247 | # Stop CPU|: [0x0602]=5 248 | print('Activate (%d ms)...' % tact_ms) 249 | sws_wr_addr_usbcom(serialPort, 0x06f, 0x20) # soft reset mcu 250 | blk = sws_wr_addr(0x0602, 0x05) 251 | if tact_ms > 0: 252 | tact = tact_ms/1000.0 253 | t1 = time.time() 254 | while time.time()-t1 < tact: 255 | for i in range(5): 256 | wr_usbcom_blk(serialPort, blk) 257 | serialPort.reset_input_buffer() 258 | #-------------------------------- 259 | # Duplication with syncronization 260 | time.sleep(0.01) 261 | serialPort.reset_input_buffer() 262 | rd_wr_usbcom_blk(serialPort, sws_code_end()) 263 | rd_wr_usbcom_blk(serialPort, blk) 264 | time.sleep(0.01) 265 | serialPort.reset_input_buffer() 266 | 267 | def main(): 268 | comport_def_name='COM1' 269 | if platform == "linux" or platform == "linux2": 270 | comport_def_name = '/dev/ttyS0' 271 | #elif platform == "darwin": 272 | #elif platform == "win32": 273 | #else: 274 | parser = argparse.ArgumentParser(description='%s version %s' % (__progname__, __version__), prog=__filename__) 275 | parser.add_argument( 276 | '--port', '-p', 277 | help='Serial port device (default: '+comport_def_name+')', 278 | default=comport_def_name) 279 | parser.add_argument( 280 | '--tact','-t', 281 | help='Time Activation ms (0-off, default: 0 ms)', 282 | type=arg_auto_int, 283 | default=0) 284 | parser.add_argument( 285 | '--clk','-c', 286 | help='SWire CLK (default: 24 MHz, 0 - auto)', 287 | type=arg_auto_int, 288 | default=24) 289 | parser.add_argument( 290 | '--baud','-b', 291 | help='UART Baud Rate (default: '+str(COMPORT_DEF_BAUD_RATE)+', min: '+str(COMPORT_MIN_BAUD_RATE)+')', 292 | type=arg_auto_int, 293 | default=COMPORT_DEF_BAUD_RATE) 294 | parser.add_argument( 295 | '--address','-a', 296 | help='SWire addres (default: 0x06bc (PC))', 297 | type=arg_auto_int, 298 | default=0x06bc) 299 | parser.add_argument( 300 | '--size','-s', 301 | help='Size data (default: 4)', 302 | type=arg_auto_int, 303 | default=4) 304 | parser.add_argument( 305 | '--debug','-d', 306 | help='Debug info', 307 | action="store_true") 308 | 309 | args = parser.parse_args() 310 | global debug 311 | debug = args.debug 312 | global bit8mask 313 | if args.baud > 1000000: 314 | bit8mask = 0x40 315 | if args.baud > 3000000: 316 | bit8mask = 0x80 317 | print('=======================================================') 318 | print('%s version %s' % (__progname__, __version__)) 319 | print('-------------------------------------------------------') 320 | if(args.baud < COMPORT_MIN_BAUD_RATE): 321 | print ('The minimum speed of the COM port is %d baud!' % COMPORT_MIN_BAUD_RATE) 322 | sys.exit(1) 323 | print ('Open %s, %d baud...' % (args.port, args.baud)) 324 | try: 325 | serialPort = serial.Serial(args.port,args.baud) 326 | serialPort.reset_input_buffer() 327 | # serialPort.flushInput() 328 | # serialPort.flushOutput() 329 | serialPort.timeout = 0.05 330 | except: 331 | print ('Error: Open %s, %d baud!' % (args.port, args.baud)) 332 | sys.exit(1) 333 | if args.tact != 0: 334 | # activate 335 | activate(serialPort, args.tact); 336 | if args.clk == 0: 337 | # auto speed 338 | if not set_sws_auto_speed(serialPort): 339 | print('Chip sleep? -> Use reset chip (RTS-RST): see option --tact') 340 | sys.exit(1) 341 | else: 342 | # Set SWS Speed = CLK/5/[0xb2] bits/s 343 | if not set_sws_speed(serialPort, args.clk * 1000000): 344 | if not set_sws_speed(serialPort, 16000000): 345 | if not set_sws_speed(serialPort, 24000000): 346 | if not set_sws_speed(serialPort, 32000000): 347 | if not set_sws_speed(serialPort, 48000000): 348 | print('Chip sleep? -> Use reset chip (RTS-RST): see option --tact') 349 | sys.exit(1) 350 | print('-------------------------------------------------------') 351 | # print('Connection...') 352 | serialPort.timeout = 0.05 # A serialPort.timeout must be set ! 353 | #-------------------------------- 354 | # Read swire addres[size] 355 | blk = sws_read_data(serialPort, args.address, args.size) 356 | #-------------------------------- 357 | # Set default register[0x00b2] 358 | # serialPort.read(serialPort.write(sws_wr_addr(0x00b2, 0x05))) 359 | # print('------------------------------------------------') 360 | if blk != None: 361 | hex_dump(args.address, blk) 362 | print('-------------------------------------------------------') 363 | print('Done!') 364 | sys.exit(0) 365 | print('Read data Error!') 366 | sys.exit(1) 367 | 368 | if __name__ == '__main__': 369 | main() 370 | -------------------------------------------------------------------------------- /USBCOMFlashTx.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | TLSR825x USB-COM Flash Writer (TX-SWS only!) 7 | 8 | 9 |

TLSR825x USB-COM Flash Writer v0.1 (TX-SWS only!)

10 |

11 | 1. USB-COM: 12 | Baud: 13 | Atime: 14 |

15 | 2. Select Firmware:

16 | 3. Open COM & Select file

17 |

18 |
19 |
20 | 21 | 375 | 376 | -------------------------------------------------------------------------------- /Test/ComSwireFlasher825x.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | ### ComSwireFlasher.py ### 4 | ### Autor: pvvx ### 5 | 6 | import sys 7 | import struct 8 | import serial 9 | import platform 10 | import time 11 | import argparse 12 | import os 13 | import io 14 | 15 | __progname__ = 'TLSR825x ComSwireFlasher Utility' 16 | __filename__ = 'ComSwireFlasher' 17 | __version__ = "20.11.20(test)" 18 | 19 | #typedef struct { // Start values: 20 | # volatile u32 faddr; //[+0] = flash jedec id 21 | # volatile u32 pbuf; //[+4] = buffer addr 22 | # volatile u16 count; //[+8] = buffer size 23 | # volatile u16 cmd; //[+10] 24 | # volatile u16 iack; //[+12] = Version, in BCD 0x1234 = 1.2.3.4 25 | # volatile u16 oack; //[+14] != 0 -> Start ok 26 | #} sext; 27 | class floader_ext: 28 | faddr = 0 29 | pbuf = 0 30 | count = 0 31 | cmd = 0 32 | iack = -1 33 | oack = -1 34 | jedecid = 0 35 | fsize = 0 36 | ver = 0 37 | cid = 0 38 | chip = '?' 39 | 40 | COMPORT_MIN_BAUD_RATE=340000 41 | COMPORT_DEF_BAUD_RATE=921600 42 | USBCOMPORT_BAD_BAUD_RATE=700000 43 | 44 | ext = floader_ext() 45 | 46 | debug = False 47 | bit8mask = 0x20 48 | 49 | class FatalError(RuntimeError): 50 | def __init__(self, message): 51 | RuntimeError.__init__(self, message) 52 | @staticmethod 53 | def WithResult(message, result): 54 | message += " (result was %s)" % hexify(result) 55 | return FatalError(message) 56 | def arg_auto_int(x): 57 | return int(x, 0) 58 | def hex_dump(addr, blk): 59 | print('%06x: ' % addr, end='') 60 | for i in range(len(blk)): 61 | if (i+1) % 16 == 0: 62 | print('%02x ' % blk[i]) 63 | if i < len(blk) - 1: 64 | print('%06x: ' % (addr + i + 1), end='') 65 | else: 66 | print('%02x ' % blk[i], end='') 67 | if len(blk) % 16 != 0: 68 | print('') 69 | # encode data (blk) into 10-bit swire words 70 | def sws_encode_blk(blk): 71 | pkt=[] 72 | d = bytearray(10) # word swire 10 bits 73 | d[0] = 0x80 # start bit byte cmd swire = 1 74 | for el in blk: 75 | m = 0x80 # mask bit 76 | idx = 1 77 | while m != 0: 78 | if (el & m) != 0: 79 | d[idx] = 0x80 80 | else: 81 | d[idx] = 0xfe 82 | idx += 1 83 | m >>= 1 84 | d[9] = 0xfe # stop bit swire = 0 85 | pkt += d 86 | d[0] = 0xfe # start bit next byte swire = 0 87 | return pkt 88 | # decode 9 bit swire response to byte (blk) 89 | def sws_decode_blk(blk): 90 | if (len(blk) == 9) and ((blk[8] & 0xfe) == 0xfe): 91 | bitmask = bit8mask 92 | data = 0; 93 | for el in range(8): 94 | data <<= 1 95 | if (blk[el] & bitmask) == 0: 96 | data |= 1 97 | bitmask = 0x10 98 | #print('0x%02x' % data) 99 | return data 100 | #print('Error blk:', blk) 101 | return None 102 | # encode a part of the read-by-address command (before the data read start bit) into 10-bit swire words 103 | def sws_rd_addr(addr): 104 | return sws_encode_blk(bytearray([0x5a, (addr>>16)&0xff, (addr>>8)&0xff, addr & 0xff, 0x80])) 105 | # encode command stop into 10-bit swire words 106 | def sws_code_end(): 107 | return sws_encode_blk([0xff]) 108 | # encode the command for writing data into 10-bit swire words 109 | def sws_wr_addr(addr, data): 110 | return sws_encode_blk(bytearray([0x5a, (addr>>16)&0xff, (addr>>8)&0xff, addr & 0xff, 0x00]) + bytearray(data)) + sws_encode_blk([0xff]) 111 | # send block to USB-COM 112 | def wr_usbcom_blk(serialPort, blk): 113 | # USB-COM chips throttle the stream into blocks at high speed! 114 | if serialPort.baudrate > USBCOMPORT_BAD_BAUD_RATE: 115 | i = 0 116 | s = 60 117 | l = len(blk) 118 | while i < l: 119 | if l - i < s: 120 | s = l - i 121 | i += serialPort.write(blk[i:i+s]) 122 | return i 123 | return serialPort.write(blk) 124 | # send and receive block to USB-COM 125 | def rd_wr_usbcom_blk(serialPort, blk): 126 | i = wr_usbcom_blk(serialPort, blk) 127 | return i == len(serialPort.read(i)) 128 | # send swire command write to USB-COM 129 | def sws_wr_addr_usbcom(serialPort, addr, data): 130 | return wr_usbcom_blk(serialPort, sws_wr_addr(addr, data)) 131 | # send and receive swire command write to USB-COM 132 | def rd_sws_wr_addr_usbcom(serialPort, addr, data): 133 | i = wr_usbcom_blk(serialPort, sws_wr_addr(addr, data)) 134 | return i == len(serialPort.read(i)) 135 | # send and receive swire command read to USB-COM 136 | def sws_read_data(serialPort, addr, size): 137 | # A serialPort.timeout must be set ! 138 | serialPort.timeout = 0.05 139 | # send addr and flag read 140 | rd_wr_usbcom_blk(serialPort, sws_rd_addr(addr)) 141 | out=[] 142 | # read size bytes 143 | for i in range(size): 144 | # send bit start read byte 145 | serialPort.write([0xfe]) 146 | # read 9 bits swire, decode read byte 147 | blk = serialPort.read(9) 148 | # Added retry reading for Prolific PL-2303HX and ... 149 | if len(blk) < 9: 150 | blk += serialPort.read(9-len(blk)) 151 | x = sws_decode_blk(blk) 152 | if x != None: 153 | out += [x] 154 | else: 155 | if debug: 156 | print('\r\nDebug: read swire byte:') 157 | hex_dump(addr+i, blk) 158 | # send stop read 159 | rd_wr_usbcom_blk(serialPort, sws_code_end()) 160 | out = None 161 | break 162 | # send stop read 163 | rd_wr_usbcom_blk(serialPort, sws_code_end()) 164 | return out 165 | def sws_read_dword(serialPort, addr): 166 | blk = sws_read_data(serialPort, addr, 4) 167 | if blk != None: 168 | #return struct.unpack(' 0x7f: 178 | print('Low UART baud rate!') 179 | return False 180 | byteSent = sws_wr_addr_usbcom(serialPort, 0x00b2, [swsdiv]) 181 | # print('Test SWM/SWS %d/%d baud...' % (int(serialPort.baudrate/5),int(clk/5/swsbaud))) 182 | read = serialPort.read(byteSent) 183 | if len(read) != byteSent: 184 | if serialPort.baudrate > USBCOMPORT_BAD_BAUD_RATE and byteSent > 64 and len(read) >= 64 and len(read) < byteSent: 185 | print('\n\r!!!!!!!!!!!!!!!!!!!BAD USB-UART Chip!!!!!!!!!!!!!!!!!!!') 186 | print('UART Output:') 187 | hex_dump(0,sws_wr_addr(0x00b2, [swsdiv])) 188 | print('UART Input:') 189 | hex_dump(0,read) 190 | print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!') 191 | return False 192 | print('\n\rError: Wrong RX-TX connection!') 193 | return False 194 | #-------------------------------- 195 | # Test read register[0x00b2] 196 | x = sws_read_data(serialPort, 0x00b2, 1) 197 | #print(x) 198 | if x != None and x[0] == swsdiv: 199 | print('ok.') 200 | if debug: 201 | print('Debug: UART-SWS %d baud. SW-CLK ~%.1f MHz' % (int(serialPort.baudrate/10), serialPort.baudrate*swsdiv/2000000)) 202 | print('Debug: swdiv = 0x%02x' % (swsdiv)) 203 | return True 204 | #-------------------------------- 205 | # Set default register[0x00b2] 206 | rd_sws_wr_addr_usbcom(serialPort, 0x00b2, 0x05) 207 | print('no') 208 | return False 209 | # auto set sws speed according to serialport baud 210 | def set_sws_auto_speed(serialPort): 211 | #--------------------------------------------------- 212 | # swsbaud = Fclk/5/register[0x00b2] 213 | # register[0x00b2] = Fclk/5/swsbaud 214 | # swsbaud = serialPort.baudrate/10 215 | # register[0x00b2] = Fclk*2/serialPort.baudrate 216 | # Fclk = 16000000..48000000 Hz 217 | # serialPort.baudrate = 460800..3000000 bits/s 218 | # register[0x00b2] = swsdiv = 10..208 219 | #--------------------------------------------------- 220 | serialPort.timeout = 0.05 # A serialPort.timeout must be set ! 221 | if debug: 222 | swsdiv_def = int(round(24000000*2/serialPort.baudrate)) 223 | print('Debug: default swdiv for 24 MHz = %d (0x%02x)' % (swsdiv_def, swsdiv_def)) 224 | swsdiv = int(round(16000000*2/serialPort.baudrate)) 225 | if swsdiv > 0x7f: 226 | print('Low UART baud rate!') 227 | return False 228 | swsdiv_max = int(round(48000000*2/serialPort.baudrate)) 229 | #bit8m = (bit8mask + (bit8mask<<1) + (bit8mask<<2))&0xff 230 | bit8m = ((~(bit8mask-1))<<1)&0xff 231 | while swsdiv <= swsdiv_max: 232 | # register[0x00b2] = swsdiv 233 | rd_sws_wr_addr_usbcom(serialPort, 0x00b2, [swsdiv]) 234 | # send addr and flag read 235 | rd_wr_usbcom_blk(serialPort, sws_rd_addr(0x00b2)) 236 | # start read data 237 | serialPort.write([0xfe]) 238 | # read 9 bits data 239 | blk = serialPort.read(9) 240 | # Added retry reading for Prolific PL-2303HX and ... 241 | if len(blk) < 9: 242 | blk += serialPort.read(9-len(blk)) 243 | # send stop read 244 | rd_wr_usbcom_blk(serialPort, sws_code_end()) 245 | if debug: 246 | print('Debug (read data):') 247 | hex_dump(swsdiv, blk) 248 | if len(blk) == 9 and blk[8] == 0xfe: 249 | cmp = sws_encode_blk([swsdiv]) 250 | if debug: 251 | print('Debug (check data):') 252 | hex_dump(swsdiv+0xccc00, sws_encode_blk([swsdiv])) 253 | if (blk[0]&bit8m) == bit8m and blk[1] == cmp[2] and blk[2] == cmp[3] and blk[4] == cmp[5] and blk[6] == cmp[7] and blk[7] == cmp[8]: 254 | print('UART-SWS %d baud. SW-CLK ~%.1f MHz(?)' % (int(serialPort.baudrate/10), serialPort.baudrate*swsdiv/2000000)) 255 | return True 256 | swsdiv += 1 257 | if swsdiv > 0x7f: 258 | print('Low UART baud rate!') 259 | break 260 | #-------------------------------- 261 | # Set default register[0x00b2] 262 | rd_sws_wr_addr_usbcom(serialPort, 0x00b2, 0x05) 263 | return False 264 | def activate(serialPort, tact_ms): 265 | #-------------------------------- 266 | # issue reset-to-bootloader: 267 | # RTS = either RESET (active low = chip in reset) 268 | # DTR = active low 269 | print('Reset module (RTS low)...') 270 | serialPort.setDTR(True) 271 | serialPort.setRTS(True) 272 | time.sleep(0.05) 273 | serialPort.setDTR(False) 274 | serialPort.setRTS(False) 275 | #-------------------------------- 276 | # Stop CPU|: [0x0602]=5 277 | print('Activate (%d ms)...' % tact_ms) 278 | sws_wr_addr_usbcom(serialPort, 0x06f, 0x20) # soft reset mcu 279 | blk = sws_wr_addr(0x0602, 0x05) 280 | if tact_ms > 0: 281 | tact = tact_ms/1000.0 282 | t1 = time.time() 283 | while time.time()-t1 < tact: 284 | for i in range(5): 285 | wr_usbcom_blk(serialPort, blk) 286 | serialPort.reset_input_buffer() 287 | #-------------------------------- 288 | # Duplication with syncronization 289 | time.sleep(0.01) 290 | serialPort.reset_input_buffer() 291 | rd_wr_usbcom_blk(serialPort, sws_code_end()) 292 | rd_wr_usbcom_blk(serialPort, blk) 293 | time.sleep(0.01) 294 | serialPort.reset_input_buffer() 295 | 296 | def ReadBlockFlash(serialPort, stream, faddr, size): 297 | global ext 298 | ext.cmd = 0x03 299 | ext.count = 1024 300 | ext.faddr = faddr 301 | while size > 0: 302 | if ext.count > size: 303 | ext.count = size 304 | print('\rRead from 0x%06x...' % ext.faddr, end = '') 305 | ext.iack += 1 306 | blk = struct.pack('>8) 315 | blk = sws_read_data(serialPort, ext.pbuf, ext.count) 316 | if blk == None: 317 | print(' Error') 318 | return False 319 | stream.write(bytearray(blk)); 320 | #hex_dump(address, blk) 321 | #print('ok', end='') 322 | size -= ext.count 323 | ext.faddr += ext.count 324 | print('\r \r', end = '') 325 | return True 326 | #-------------------------------- 327 | # Main() 328 | def main(): 329 | global ext 330 | comport_def_name='COM1' 331 | if platform == "linux" or platform == "linux2": 332 | comport_def_name = '/dev/ttyS0' 333 | #elif platform == "darwin": 334 | #elif platform == "win32": 335 | #else: 336 | parser = argparse.ArgumentParser(description='%s version %s' % (__progname__, __version__), prog=__filename__) 337 | parser.add_argument( 338 | '--port', '-p', 339 | help='Serial port device (default: COM1)', 340 | default='COM1') 341 | parser.add_argument( 342 | '--tact','-t', 343 | help='Time Activation ms (0-off, default: 0 ms)', 344 | type=arg_auto_int, 345 | default=0) 346 | parser.add_argument( 347 | '--clk','-c', 348 | help='SWire CLK (default: 24 MHz)', 349 | type=arg_auto_int, 350 | default=24) 351 | parser.add_argument( 352 | '--baud','-b', 353 | help='UART Baud Rate (default: 921600, min: 460800)', 354 | type=arg_auto_int, 355 | default=921600) 356 | parser.add_argument( 357 | '--file','-f', 358 | help='Filename to load (default: floader825x.bin)', 359 | default='floader825x.bin') 360 | parser.add_argument( 361 | '--address','-a', 362 | help='Flash addres (default: 0))', 363 | type=arg_auto_int, 364 | default=0) 365 | parser.add_argument( 366 | '--size','-s', 367 | help='Size data (default: 524288)', 368 | type=arg_auto_int, 369 | default=524288) 370 | parser.add_argument( 371 | '--debug','-d', 372 | help='Debug info', 373 | action="store_true") 374 | 375 | args = parser.parse_args() 376 | global debug 377 | debug = args.debug 378 | global bit8mask 379 | if args.baud > 1000000: 380 | bit8mask = 0x40 381 | if args.baud > 3000000: 382 | bit8mask = 0x80 383 | print('=======================================================') 384 | print('%s version %s' % (__progname__, __version__)) 385 | print('-------------------------------------------------------') 386 | if(args.baud < COMPORT_MIN_BAUD_RATE): 387 | print ('The minimum speed of the COM port is %d baud!' % COMPORT_MIN_BAUD_RATE) 388 | sys.exit(1) 389 | print ('Open %s, %d baud...' % (args.port, args.baud)) 390 | try: 391 | serialPort = serial.Serial(args.port, args.baud, \ 392 | serial.EIGHTBITS,\ 393 | serial.PARITY_NONE, \ 394 | serial.STOPBITS_ONE) 395 | serialPort.reset_input_buffer() 396 | # serialPort.flushInput() 397 | # serialPort.flushOutput() 398 | serialPort.timeout = 0.05 399 | except: 400 | print ('Error: Open %s, %d baud!' % (args.port, args.baud)) 401 | sys.exit(1) 402 | if args.tact != 0: 403 | #-------------------------------- 404 | # Open floder file 405 | try: 406 | stream = open(args.file, 'rb') 407 | size = os.path.getsize(args.file) 408 | except: 409 | serialPort.close 410 | print('Error: Not open input file <%s>!' % args.file) 411 | sys.exit(2) 412 | if size < 1: 413 | stream.close 414 | serialPort.close 415 | print('Error: File size = 0!') 416 | sys.exit(3) 417 | #-------------------------------- 418 | # activate 419 | activate(serialPort, args.tact); 420 | 421 | #-------------------------------- 422 | # Load floader.bin 423 | binWrite = 0 424 | rdsize = 0x80 425 | addr = 0x840000 426 | print('Load <%s> to 0x%06x...' % (args.file, addr)) 427 | while size > 0: 428 | print('\r0x%06x' % addr, end = '') 429 | data = stream.read(rdsize) 430 | if not data: # end of stream 431 | print('send: at EOF') 432 | break 433 | sws_wr_addr_usbcom(serialPort, addr, data) 434 | binWrite += len(data) 435 | addr += len(data) 436 | size -= len(data) 437 | serialPort.reset_input_buffer() 438 | stream.close 439 | print('\rBin bytes writen:', binWrite) 440 | print('CPU go Start...') 441 | sws_wr_addr_usbcom(serialPort, 0x0602, b'\x88') # cpu go Start 442 | time.sleep(0.05) 443 | serialPort.flushInput() 444 | serialPort.flushOutput() 445 | serialPort.reset_input_buffer() 446 | serialPort.reset_output_buffer() 447 | 448 | if args.clk == 0: 449 | # auto speed 450 | if not set_sws_auto_speed(serialPort): 451 | print('Chip sleep? -> Use reset chip (RTS-RST): see option --tact') 452 | sys.exit(1) 453 | else: 454 | # Set SWS Speed = CLK/5/[0xb2] bits/s 455 | if not set_sws_speed(serialPort, args.clk * 1000000): 456 | if not set_sws_speed(serialPort, 16000000): 457 | if not set_sws_speed(serialPort, 24000000): 458 | if not set_sws_speed(serialPort, 32000000): 459 | if not set_sws_speed(serialPort, 48000000): 460 | print('Chip sleep? -> Use reset chip (RTS-RST): see option --tact') 461 | sys.exit(1) 462 | 463 | print('-------------------------------------------------------') 464 | # print('Connection...') 465 | serialPort.timeout = 0.05 # A serialPort.timeout must be set ! 466 | # test id floader 467 | lid = sws_read_dword(serialPort, 0x40014) 468 | if lid == None: 469 | print('Swire Error!') 470 | sys.exit(1) 471 | if lid != 0x78353238: 472 | print('Warning: Unknown floader!') 473 | sys.exit(1) 474 | # Test CPU Program Counter (Running?) 475 | pc = sws_read_dword(serialPort, 0x06bc) 476 | if pc == None: 477 | print('Swire Error!') 478 | sys.exit(1) 479 | if debug: 480 | print('CPU PC: %08x' % pc) 481 | if pc == 0: 482 | print('Warning: CPU is in reset and stop state! Restart CPU...' ) 483 | rd_sws_wr_addr_usbcom(serialPort,0x0602, [0x88]) # cpu go 484 | time.sleep(0.03) 485 | if debug: 486 | print('CPU pc: %08x' % sws_read_dword(serialPort, 0x06bc)) 487 | # Read floader config 488 | #ext = floader_ext() 489 | ext.addr = sws_read_dword(serialPort, 0x40004) 490 | #print('ext.addr: %08x' % ext.addr) 491 | if ext.addr == None or ext.addr < 0x840000 or ext.addr > 0x84fff0: 492 | print('Floder format or download error!') 493 | sys.exit(1) 494 | blk = sws_read_data(serialPort, ext.addr, 16) 495 | if blk == None: 496 | print('Swire Error!') 497 | sys.exit(1) 498 | #hex_dump(ext.addr, blk) 499 | (ext.faddr, ext.pbuf, ext.count, ext.cmd, ext.iack, ext.oack) = struct.unpack('>12)&0x0f,(ext.ver>>8)&0x0f,(ext.ver>>4)&0x0f, ext.ver&0x0f, ext.count)) 511 | ext.cid = sws_read_dword(serialPort, 0x07c) 512 | if ext.cid == None: 513 | print('Swire Error!') 514 | sys.exit(1) 515 | print('ChipID: 0x%04x, ver: 0x%02x' % (ext.cid>>16, (ext.cid>>8)&0xff) ) 516 | #if cid == 0x5562: 517 | # chip = 'TLSR8253?' 518 | # else: 519 | # chip = '?' 520 | ext.jedecid = (ext.faddr>>8)&0xffff00 | (ext.faddr&0xff) 521 | ext.fsize = (1<<(ext.jedecid&0xff))>>10 522 | print('Flash JEDEC ID: %06X, Size: %d kbytes' % (ext.jedecid, ext.fsize)) 523 | #?????????? 524 | pc = sws_read_dword(serialPort, 0x06bc) 525 | if pc == None: 526 | print('Swire Error!') 527 | sys.exit(1) 528 | if debug: 529 | print('CPU PC: %08x' % pc) 530 | if pc == 0: 531 | print('CPU PC: %08x - CPU Not Runing!' % pc) 532 | sys.exit(1) 533 | #-------------------------------- 534 | # Info read swire addres[size] 535 | print('-------------------------------------------------------') 536 | #blk = sws_read_blk(serialPort, args.address, args.size) 537 | print('Read Flash from 0x%06x to 0x%06x...' % (args.address, args.address+args.size)) 538 | print('Outfile: %s' % 'out.bin') 539 | try: 540 | stream = open('out.bin', 'wb') 541 | except: 542 | print('Error: Not open Outfile file <%s>!' % 'out.bin') 543 | sys.exit(2) 544 | if not ReadBlockFlash(serialPort, stream, args.address, args.size): 545 | stream.close 546 | serialPort.close 547 | sys.exit(5) 548 | stream.close 549 | print('-------------------------------------------------------') 550 | print('Done!') 551 | sys.exit(0) 552 | 553 | if __name__ == '__main__': 554 | main() 555 | -------------------------------------------------------------------------------- /TLSR825xComFlasher.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | ### ComSwireWriter.py ### 4 | ### Autor: pvvx ### 5 | ### Edited: Aaron Christophel ATCnetz.de ### 6 | ### Edit : Pila ### 7 | 8 | import sys 9 | import signal 10 | import struct 11 | import serial 12 | import platform 13 | import time 14 | import argparse 15 | import os 16 | import io 17 | import serial.tools.list_ports 18 | 19 | __progname__ = 'TLSR825x Flasher' 20 | __version__ = "29.11.24" 21 | 22 | COMPORT_MIN_BAUD_RATE=340000 23 | COMPORT_DEF_BAUD_RATE=921600 24 | USBCOMPORT_BAD_BAUD_RATE=460800 25 | 26 | FLASH_SECTOR_SIZE = 4096 27 | 28 | debug = False 29 | bit8mask = 0x20 30 | 31 | class FatalError(RuntimeError): 32 | def __init__(self, message): 33 | RuntimeError.__init__(self, message) 34 | @staticmethod 35 | def WithResult(message, result): 36 | message += " (result was %s)" % hexify(result) 37 | return FatalError(message) 38 | def signal_handler(signal, frame): 39 | print() 40 | print('Keyboard Break!') 41 | sys.exit(0) 42 | def arg_auto_int(x): 43 | return int(x, 0) 44 | def hex_dump(addr, blk): 45 | print('%06x: ' % addr, end='') 46 | for i in range(len(blk)): 47 | if (i+1) % 16 == 0: 48 | print('%02x ' % blk[i]) 49 | if i < len(blk) - 1: 50 | print('%06x: ' % (addr + i + 1), end='') 51 | else: 52 | print('%02x ' % blk[i], end='') 53 | if len(blk) % 16 != 0: 54 | print('') 55 | # encode data (blk) into 10-bit swire words 56 | def sws_encode_blk(blk): 57 | pkt=[] 58 | d = bytearray(10) # word swire 10 bits 59 | d[0] = 0x80 # start bit byte cmd swire = 1 60 | for el in blk: 61 | m = 0x80 # mask bit 62 | idx = 1 63 | while m != 0: 64 | if (el & m) != 0: 65 | d[idx] = 0x80 66 | else: 67 | d[idx] = 0xfe 68 | idx += 1 69 | m >>= 1 70 | d[9] = 0xfe # stop bit swire = 0 71 | pkt += d 72 | d[0] = 0xfe # start bit next byte swire = 0 73 | return pkt 74 | # decode 9 bit swire response to byte (blk) 75 | def sws_decode_blk(blk): 76 | if (len(blk) == 9) and ((blk[8] & 0xfe) == 0xfe): 77 | bitmask = bit8mask 78 | data = 0; 79 | for el in range(8): 80 | data <<= 1 81 | if (blk[el] & bitmask) == 0: 82 | data |= 1 83 | bitmask = 0x10 84 | #print('0x%02x' % data) 85 | return data 86 | #print('Error blk:', blk) 87 | return None 88 | # encode a part of the read-by-address command (before the data read start bit) into 10-bit swire words 89 | def sws_rd_addr(addr): 90 | return sws_encode_blk(bytearray([0x5a, (addr>>16)&0xff, (addr>>8)&0xff, addr & 0xff, 0x80])) 91 | # encode command stop into 10-bit swire words 92 | def sws_code_end(): 93 | return sws_encode_blk([0xff]) 94 | # encode the command for writing data into 10-bit swire words 95 | def sws_wr_addr(addr, data): 96 | return sws_encode_blk(bytearray([0x5a, (addr>>16)&0xff, (addr>>8)&0xff, addr & 0xff, 0x00]) + bytearray(data)) + sws_encode_blk([0xff]) 97 | # send block to USB-COM 98 | def wr_usbcom_blk(serialPort, blk): 99 | # USB-COM chips throttle the stream into blocks at high speed! 100 | # Swire is transmitted by 10 bytes of UART. 101 | # The packet must be a multiple of these 10 bytes. 102 | # Max block USB2.0 64 bytes -> the packet will be 60 bytes. 103 | if serialPort.baudrate > USBCOMPORT_BAD_BAUD_RATE: 104 | i = 0 105 | s = 60 106 | l = len(blk) 107 | while i < l: 108 | if l - i < s: 109 | s = l - i 110 | i += serialPort.write(blk[i:i+s]) 111 | serialPort.flush() 112 | return i 113 | return serialPort.write(blk) 114 | # send and receive block to USB-COM 115 | def rd_wr_usbcom_blk(serialPort, blk): 116 | i = wr_usbcom_blk(serialPort, blk) 117 | return i == len(serialPort.read(i)) 118 | # send swire command write to USB-COM 119 | def sws_wr_addr_usbcom(serialPort, addr, data): 120 | return wr_usbcom_blk(serialPort, sws_wr_addr(addr, data)) 121 | # send and receive swire command write to USB-COM 122 | def rd_sws_wr_addr_usbcom(serialPort, addr, data): 123 | i = wr_usbcom_blk(serialPort, sws_wr_addr(addr, data)) 124 | return i == len(serialPort.read(i)) 125 | # send swire data in fifo mode 126 | def rd_sws_fifo_wr_usbcom(serialPort, addr, data): 127 | rd_sws_wr_addr_usbcom(serialPort, 0x00b3, bytearray([0x80])) # [0xb3]=0x80 ext.SWS into fifo mode 128 | rd_sws_wr_addr_usbcom(serialPort, addr, data) # send all data to one register (no increment address - fifo mode) 129 | rd_sws_wr_addr_usbcom(serialPort, 0x00b3, bytearray([0x00])) # [0xb3]=0x00 ext.SWS into normal(ram) mode 130 | # send and receive swire command read to USB-COM 131 | def sws_read_data(serialPort, addr, size = 1): 132 | time.sleep(0.05) 133 | serialPort.reset_input_buffer() 134 | # send addr and flag read 135 | rd_wr_usbcom_blk(serialPort, sws_rd_addr(addr)) 136 | out = [] 137 | # read size bytes 138 | for i in range(size): 139 | # send bit start read byte 140 | serialPort.write([0xfe]) 141 | # read 9 bits swire, decode read byte 142 | blk = serialPort.read(9) 143 | # Added retry reading for Prolific PL-2303HX and ... 144 | if len(blk) < 9: 145 | blk += serialPort.read(10-len(blk)) 146 | x = sws_decode_blk(blk) 147 | if x != None: 148 | out += [x] 149 | else: 150 | if debug: 151 | print('\r\nDebug: read swire byte:') 152 | hex_dump(addr+i, blk) 153 | # send stop read 154 | rd_wr_usbcom_blk(serialPort, sws_code_end()) 155 | out = None 156 | break 157 | # send stop read 158 | rd_wr_usbcom_blk(serialPort, sws_code_end()) 159 | return out 160 | # set sws speed according to clk frequency and serialPort baud 161 | def set_sws_speed(serialPort, clk): 162 | #-------------------------------- 163 | # Set register[0x00b2] 164 | print('SWire speed for CLK %.1f MHz... ' % (clk/1000000), end='') 165 | swsdiv = int(round(clk*2/serialPort.baudrate)) 166 | if swsdiv > 0x7f: 167 | print('Low UART baud rate!') 168 | return False 169 | byteSent = sws_wr_addr_usbcom(serialPort, 0x00b2, [swsdiv]) 170 | # print('Test SWM/SWS %d/%d baud...' % (int(serialPort.baudrate/5),int(clk/5/swsbaud))) 171 | read = serialPort.read(byteSent) 172 | if len(read) != byteSent: 173 | if serialPort.baudrate > USBCOMPORT_BAD_BAUD_RATE and byteSent > 64 and len(read) >= 64 and len(read) < byteSent: 174 | print('\n\r!!!!!!!!!!!!!!!!!!!BAD USB-UART Chip!!!!!!!!!!!!!!!!!!!') 175 | print('UART Output:') 176 | hex_dump(0,sws_wr_addr(0x00b2, [swsdiv])) 177 | print('UART Input:') 178 | hex_dump(0,read) 179 | print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!') 180 | return False 181 | print('\n\rError: Wrong RX-TX connection!') 182 | return False 183 | #-------------------------------- 184 | # Test read register[0x00b2] 185 | x = sws_read_data(serialPort, 0x00b2) 186 | #print(x) 187 | if x != None and x[0] == swsdiv: 188 | print('ok.') 189 | if debug: 190 | print('Debug: UART-SWS %d baud. SW-CLK ~%.1f MHz' % (int(serialPort.baudrate/10), serialPort.baudrate*swsdiv/2000000)) 191 | print('Debug: swdiv = 0x%02x' % (swsdiv)) 192 | return True 193 | #-------------------------------- 194 | # Set default register[0x00b2] 195 | rd_sws_wr_addr_usbcom(serialPort, 0x00b2, 0x05) 196 | print('no') 197 | return False 198 | # auto set sws speed according to serialport baud 199 | def set_sws_auto_speed(serialPort): 200 | #--------------------------------------------------- 201 | # swsbaud = Fclk/5/register[0x00b2] 202 | # register[0x00b2] = Fclk/5/swsbaud 203 | # swsbaud = serialPort.baudrate/10 204 | # register[0x00b2] = Fclk*2/serialPort.baudrate 205 | # Fclk = 16000000..48000000 Hz 206 | # serialPort.baudrate = 460800..3000000 bits/s 207 | # register[0x00b2] = swsdiv = 10..208 208 | #--------------------------------------------------- 209 | #serialPort.timeout = 0.01 # A serialPort.timeout must be set ! 210 | if debug: 211 | swsdiv_def = int(round(24000000*2/serialPort.baudrate)) 212 | print('Debug: default swdiv for 24 MHz = %d (0x%02x)' % (swsdiv_def, swsdiv_def)) 213 | swsdiv = int(round(16000000*2/serialPort.baudrate)) 214 | if swsdiv > 0x7f: 215 | print('Low UART baud rate!') 216 | return False 217 | swsdiv_max = int(round(48000000*2/serialPort.baudrate)) 218 | #bit8m = (bit8mask + (bit8mask<<1) + (bit8mask<<2))&0xff 219 | bit8m = ((~(bit8mask-1))<<1)&0xff 220 | while swsdiv <= swsdiv_max: 221 | # register[0x00b2] = swsdiv 222 | rd_sws_wr_addr_usbcom(serialPort, 0x00b2, bytearray([swsdiv])) 223 | # send addr and flag read 224 | rd_wr_usbcom_blk(serialPort, sws_rd_addr(0x00b2)) 225 | # start read data 226 | serialPort.write([0xfe]) 227 | # read 9 bits data 228 | blk = serialPort.read(9) 229 | # Added retry reading for Prolific PL-2303HX and ... 230 | if len(blk) < 9: 231 | blk += serialPort.read(9-len(blk)) 232 | # send stop read 233 | rd_wr_usbcom_blk(serialPort, sws_code_end()) 234 | if debug: 235 | print('Debug (read data):') 236 | hex_dump(swsdiv, blk) 237 | if len(blk) == 9 and blk[8] == 0xfe: 238 | cmp = sws_encode_blk([swsdiv]) 239 | if debug: 240 | print('Debug (check data):') 241 | hex_dump(swsdiv+0xccc00, sws_encode_blk([swsdiv])) 242 | print('bit mask: 0x%02x' % (bit8m)) 243 | if (blk[0]&bit8m) == bit8m and blk[1] == cmp[2] and blk[2] == cmp[3] and blk[4] == cmp[5] and blk[6] == cmp[7] and blk[7] == cmp[8]: 244 | ''' 245 | swsdiv += 1 246 | rd_sws_wr_addr_usbcom(serialPort, 0x00b2, bytearray([swsdiv])) 247 | data = sws_read_data(serialPort, 0x00b2, 1) 248 | if data == None or data[0] != swsdiv: 249 | swsdiv -= 1 250 | if debug: 251 | print('swsdiv:', swsdiv) 252 | break 253 | rd_sws_wr_addr_usbcom(serialPort, 0x00b2, bytearray([swsdiv])) 254 | ''' 255 | print('UART-SWS %d baud. SW-CLK ~%.1f MHz(?)' % (int(serialPort.baudrate/10), serialPort.baudrate*swsdiv/2000000)) 256 | return True 257 | swsdiv += 1 258 | if swsdiv > 0x7f: 259 | print('Low UART baud rate!') 260 | break 261 | #-------------------------------- 262 | # Set default register[0x00b2] 263 | rd_sws_wr_addr_usbcom(serialPort, 0x00b2, bytearray([0x05])) 264 | return False 265 | def activate(serialPort, tact_ms): 266 | #-------------------------------- 267 | # issue reset-to-bootloader: 268 | # RTS = either RESET (active low = chip in reset) 269 | # DTR = active low 270 | print('Reset module (RTS low)...') 271 | serialPort.setDTR(True) 272 | serialPort.setRTS(True) 273 | time.sleep(0.05) 274 | serialPort.setDTR(False) 275 | serialPort.setRTS(False) 276 | #-------------------------------- 277 | # Stop CPU|: [0x0602]=5 278 | print('Activate (%d ms)...' % tact_ms) 279 | sws_wr_addr_usbcom(serialPort, 0x06f, bytearray([0x20])) # soft reset mcu 280 | blk = sws_wr_addr(0x0602, bytearray([0x05])) 281 | if tact_ms > 0: 282 | tact = tact_ms/1000.0 283 | t1 = time.time() 284 | while time.time()-t1 < tact: 285 | for i in range(5): 286 | wr_usbcom_blk(serialPort, blk) 287 | serialPort.reset_input_buffer() 288 | #-------------------------------- 289 | # Duplication with syncronization 290 | time.sleep(0.01) 291 | serialPort.reset_input_buffer() 292 | rd_wr_usbcom_blk(serialPort, sws_code_end()) 293 | rd_wr_usbcom_blk(serialPort, blk) 294 | time.sleep(0.01) 295 | serialPort.reset_input_buffer() 296 | 297 | def FlashReadBlock(serialPort, stream, offset = 0, size = 0x80000): 298 | offset &= 0x00ffffff 299 | rdsize = 0x100 300 | while size > 0: 301 | if rdsize > size: 302 | rdsize = size 303 | print('\rRead from 0x%06x...' % offset, end = '') 304 | rd_sws_wr_addr_usbcom(serialPort, 0x0b3, bytearray([0x80])) # [0xb3]=0x80 ext.SWS into fifo mode 305 | rd_sws_wr_addr_usbcom(serialPort, 0x0d, bytearray([0x00])) # SPI set cns low 306 | # send all data to one register (not increment address - fifo mode), cmd flash rd, addr, + launch first read 307 | rd_sws_wr_addr_usbcom(serialPort, 0x0c, bytearray([0x03, (offset >> 16) & 0xffff, (offset >> 8) & 0xff, offset & 0xff, 0])) 308 | rd_sws_wr_addr_usbcom(serialPort, 0x0d, bytearray([0x0A])) # [0x0d]=0x0a SPI set auto read mode & cns low 309 | # read all data from one register (not increment address - fifo mode) 310 | data = sws_read_data(serialPort, 0x0c, rdsize) 311 | rd_sws_wr_addr_usbcom(serialPort, 0x0d, bytearray([0x01])) # SPI set cns high 312 | rd_sws_wr_addr_usbcom(serialPort, 0x0b3, bytearray([0x00])) # [0xb3]=0x00 ext.SWS into normal(ram) mode 313 | if data == None or len(data) != rdsize: 314 | print('\rError Read Flash data at 0x%06x! ' % offset) 315 | return False 316 | stream.write(bytearray(data)) 317 | size -= rdsize 318 | offset += rdsize 319 | print('\r \r', end = '') 320 | return True 321 | def FlashReady(serialPort, count = 33): 322 | for _ in range(count): 323 | rd_sws_wr_addr_usbcom(serialPort, 0x0d, bytearray([0x00])) # SPI set cns low 324 | rd_sws_wr_addr_usbcom(serialPort, 0x0c, bytearray([0x05])) # Flash cmd rd status 325 | data = sws_read_data(serialPort, 0x0c) 326 | rd_sws_wr_addr_usbcom(serialPort, 0x0d, bytearray([0x01])) # SPI set cns high 327 | if data == None: 328 | print('\rError Read Flash Status! (%d) ' %(_)) 329 | return False 330 | if (data[0] & 0x01) == 0: 331 | return True 332 | print('\rTimeout! Flash status 0x%02x! ' % data[0]) 333 | return False 334 | def FlashWriteEnable(serialPort): 335 | rd_sws_wr_addr_usbcom(serialPort, 0x0d, bytearray([0x00])) # cns low 336 | rd_sws_wr_addr_usbcom(serialPort, 0x0c, bytearray([0x06])) # Flash cmd write enable 337 | rd_sws_wr_addr_usbcom(serialPort, 0x0d, bytearray([0x01])) # cns high 338 | def FlashUnlock(serialPort): 339 | FlashWriteEnable(serialPort) 340 | rd_sws_wr_addr_usbcom(serialPort, 0x0d, bytearray([0x00])) # cns low 341 | rd_sws_wr_addr_usbcom(serialPort, 0x0c, bytearray([0x01])) # Flash cmd wr status 342 | rd_sws_wr_addr_usbcom(serialPort, 0x0c, bytearray([0x00])) # data: 0 343 | rd_sws_wr_addr_usbcom(serialPort, 0x0d, bytearray([0x01])) # cns high 344 | return FlashReady(serialPort) 345 | def FlashWriteAddr(serialPort, addr, data): 346 | FlashWriteEnable(serialPort) 347 | rd_sws_wr_addr_usbcom(serialPort, 0x0d, bytearray([0x00])) # cns low 348 | # Flash cmd write + addr + data 349 | rd_sws_fifo_wr_usbcom(serialPort, 0x0c, bytearray([0x02, (addr >> 16) & 0xffff, (addr >> 8) & 0xff, addr & 0xff]) + bytearray(data)) 350 | rd_sws_wr_addr_usbcom(serialPort, 0x0d, bytearray([0x01])) # cns high 351 | return FlashReady(serialPort) 352 | def FlashEraseAll(serialPort): 353 | FlashWriteEnable(serialPort) 354 | rd_sws_wr_addr_usbcom(serialPort, 0x0d, bytearray([0x00])) # cns low 355 | rd_sws_fifo_wr_usbcom(serialPort, 0x0c, bytearray([0x60])) # Flash cmd erase all 356 | rd_sws_wr_addr_usbcom(serialPort, 0x0d, bytearray([0x01])) # cns high 357 | return FlashReady(serialPort, 1000) 358 | def FlashEraseSectors(serialPort, offset = 0, size = 1): 359 | offset &= ~(FLASH_SECTOR_SIZE-1) 360 | size = (size + FLASH_SECTOR_SIZE-1) & (~(FLASH_SECTOR_SIZE-1)) 361 | while size > 0: 362 | print('\rErase Sector at 0x%06x...' % offset, end = '') 363 | FlashWriteEnable(serialPort) 364 | rd_sws_wr_addr_usbcom(serialPort, 0x0d, bytearray([0x00])) # cns low 365 | rd_sws_wr_addr_usbcom(serialPort, 0x0c, bytearray([0x20])) # Flash cmd erase sector 366 | rd_sws_wr_addr_usbcom(serialPort, 0x0c, bytearray([(offset >> 16) & 0xff])) # Faddr hi 367 | rd_sws_wr_addr_usbcom(serialPort, 0x0c, bytearray([(offset >> 8) & 0xff])) # Faddr mi 368 | rd_sws_wr_addr_usbcom(serialPort, 0x0c, bytearray([offset & 0xff])) # Faddr lo 369 | rd_sws_wr_addr_usbcom(serialPort, 0x0d, bytearray([0x01])) # cns high 370 | offset += FLASH_SECTOR_SIZE 371 | size -= FLASH_SECTOR_SIZE 372 | time.sleep(0.08) 373 | if not FlashReady(serialPort): 374 | return False 375 | print('\r \r', end = '') 376 | return True 377 | def FlashWriteBlock(serialPort, stream, offset = 0, size = 0, erase = True): 378 | wrsize = 0x100 379 | if erase and (offset & (FLASH_SECTOR_SIZE-1)) != 0: 380 | erasec = offset & (0xffffff^(FLASH_SECTOR_SIZE-1)) 381 | else: 382 | erasec = 0xffffffff # = flag 383 | fa = 0 384 | while size > 0: 385 | offset &= 0xffffff 386 | if erase: 387 | wrsec = offset & (0xffffff^(FLASH_SECTOR_SIZE-1)) 388 | if erasec != wrsec: 389 | # send sector erase command + faddr 390 | if not FlashEraseSectors(serialPort, offset): 391 | print('\rError Erase sector at 0x%06x!' % offset) 392 | return False 393 | erasec = wrsec 394 | data = stream.read(wrsize) 395 | wrsize = len(data) 396 | if not data or wrsize == 0: # end of stream 397 | print('\rError Read file at 0x%06x! ' % (fa+wrsize)) 398 | return False 399 | for e in data: 400 | if e != 0xff: 401 | print('\rWrite to 0x%06x...' % offset, end = '') 402 | if not FlashWriteAddr(serialPort, offset, data): 403 | print('\rError write sector at 0x%06x!' % offset) 404 | return False 405 | break 406 | offset += wrsize 407 | size -= wrsize 408 | fa + wrsize 409 | print('\r \r', end = '') 410 | return True 411 | 412 | def main(): 413 | signal.signal(signal.SIGINT, signal_handler) 414 | t1 = time.time() 415 | #ports = serial.tools.list_ports.comports() #(win10) execution time more than 30 sec! 416 | #comport_def_name = ports[0].device 417 | comport_def_name='COM1' 418 | if sys.platform == 'linux' or sys.platform == 'linux2': 419 | comport_def_name = '/dev/ttyS0' 420 | elif sys.platform == 'win32': 421 | comport_def_name='COM1' 422 | #elif sys.platform == "darwin": 423 | #else: 424 | # print(sys.platform) 425 | parser = argparse.ArgumentParser(description='%s version %s' % (__progname__, __version__)) 426 | parser.add_argument( 427 | '-p', '--port', 428 | help='Serial port device (default: '+comport_def_name+')', 429 | default=comport_def_name) 430 | parser.add_argument( 431 | '-t', '--tact', 432 | help='Time Activation ms (0-off, default: 0 ms)', 433 | type=arg_auto_int, 434 | default=0) 435 | parser.add_argument( 436 | '-c', '--clk', 437 | help='SWire CLK (default: auto, 0 - auto)', 438 | type=arg_auto_int, 439 | default=0) 440 | parser.add_argument( 441 | '-b', '--baud', 442 | help='UART Baud Rate (default: '+str(COMPORT_DEF_BAUD_RATE)+', min: '+str(COMPORT_MIN_BAUD_RATE)+')', 443 | type=arg_auto_int, 444 | default=COMPORT_DEF_BAUD_RATE) 445 | parser.add_argument( 446 | '-r', '--run', 447 | help='CPU Run (post main processing)', 448 | action='store_true') 449 | parser.add_argument( 450 | '-d', '--debug', 451 | help='Debug info', 452 | action='store_true') 453 | subparsers = parser.add_subparsers( 454 | dest='operation', 455 | help=os.path.splitext(os.path.basename(__file__))[0]+' {command} -h for additional help') 456 | 457 | parser_read_flash = subparsers.add_parser( 458 | 'rf', 459 | help='Read Flash to binary file') 460 | parser_read_flash.add_argument('address', help='Start address', type=arg_auto_int) 461 | parser_read_flash.add_argument('size', help='Size of region', type=arg_auto_int) 462 | parser_read_flash.add_argument('filename', help='Name of binary file') 463 | 464 | parser_burn_flash = subparsers.add_parser( 465 | 'wf', 466 | help='Write file to Flash with sectors erases') 467 | parser_burn_flash.add_argument('address', help='Start address', type=arg_auto_int) 468 | parser_burn_flash.add_argument('filename', help='Name of binary file') 469 | 470 | parser_write_flash = subparsers.add_parser( 471 | 'we', 472 | help='Write file to Flash without sectors erases') 473 | parser_write_flash.add_argument('address', help='Start address', type=arg_auto_int) 474 | parser_write_flash.add_argument('filename', help='Name of binary file') 475 | 476 | parser_erase_sec_flash = subparsers.add_parser( 477 | 'es', 478 | help='Erase Region (sectors) of Flash') 479 | parser_erase_sec_flash.add_argument('address', help='Start address', type=arg_auto_int) 480 | parser_erase_sec_flash.add_argument('size', help='Size of region', type=arg_auto_int) 481 | 482 | parser_erase_all_flash = subparsers.add_parser( 483 | 'ea', 484 | help='Erase All Flash') 485 | 486 | args = parser.parse_args() 487 | print('=======================================================') 488 | print('%s version %s' % (__progname__, __version__)) 489 | print('-------------------------------------------------------') 490 | global debug 491 | debug = args.debug 492 | if(args.baud < COMPORT_MIN_BAUD_RATE): 493 | print ('The minimum speed of the COM port is %d baud!' % COMPORT_MIN_BAUD_RATE) 494 | sys.exit(1) 495 | print ('Open %s, %d baud...' % (args.port, args.baud)) 496 | try: 497 | serialPort = serial.Serial(args.port,args.baud) 498 | serialPort.reset_input_buffer() 499 | serialPort.timeout = 0.1 500 | except: 501 | print ('Error: Open %s, %d baud!' % (args.port, args.baud)) 502 | sys.exit(1) 503 | if args.tact != 0: 504 | # activate 505 | activate(serialPort, args.tact) 506 | if args.clk == 0: 507 | # auto speed 508 | if not set_sws_auto_speed(serialPort): 509 | print('Chip sleep? -> Use reset chip (RTS-RST): see option --tact') 510 | sys.exit(1) 511 | else: 512 | # Set SWS Speed = CLK/5/[0xb2] bits/s 513 | if not set_sws_speed(serialPort, args.clk * 1000000): 514 | if not set_sws_speed(serialPort, 16000000): 515 | if not set_sws_speed(serialPort, 24000000): 516 | if not set_sws_speed(serialPort, 32000000): 517 | if not set_sws_speed(serialPort, 48000000): 518 | print('Chip sleep? -> Use reset chip (RTS-RST): see option --tact') 519 | sys.exit(1) 520 | #serialPort.timeout = 0.01 # SerialPort.timeout must be set for the following operations! 521 | if args.operation == 'rf': 522 | offset = args.address & 0x00ffffff 523 | size = args.size & 0x00ffffff 524 | if size == 0: 525 | print('\rError: Read size = %d!' % size) 526 | sys.exit(1) 527 | print('Outfile: %s' % args.filename) 528 | try: 529 | stream = open(args.filename, 'wb') 530 | except: 531 | print('Error: Not open Outfile file <%s>!' % args.filename) 532 | sys.exit(1) 533 | print('Read Flash from 0x%06x to 0x%06x...' % (offset, offset + size)) 534 | if not FlashReadBlock(serialPort, stream, offset, size): 535 | sys.exit(1) 536 | elif args.operation == 'wf': 537 | offset = args.address & 0x00ffffff 538 | print('Inputfile: %s' % (args.filename)) 539 | try: 540 | stream = open(args.filename, 'rb') 541 | size = os.path.getsize(args.filename) 542 | except: 543 | print('Error: Not open input file <%s>!' % args.fldr) 544 | sys.exit(1) 545 | if size < 1: 546 | print('Error: File size = %d!'% size) 547 | else: 548 | print('Write Flash data 0x%08x to 0x%08x...' % (offset, offset + size)) 549 | if not FlashUnlock(serialPort): 550 | sys.exit(1) 551 | if not FlashWriteBlock(serialPort, stream, offset, size): 552 | sys.exit(1) 553 | elif args.operation == 'we': 554 | offset = args.address & 0x00ffffff 555 | print('Inputfile: %s' % (args.filename)) 556 | try: 557 | stream = open(args.filename, 'rb') 558 | size = os.path.getsize(args.filename) 559 | except: 560 | print('Error: Not open input file <%s>!' % args.fldr) 561 | sys.exit(1) 562 | if size < 1: 563 | print('Error: File size = %d!'% size) 564 | else: 565 | print('Write Flash data 0x%08x to 0x%08x...' % (offset, offset + size)) 566 | if not FlashUnlock(serialPort): 567 | sys.exit(1) 568 | if not FlashWriteBlock(serialPort, stream, offset, size, False): 569 | sys.exit(1) 570 | elif args.operation == 'es': 571 | count = int((args.size + FLASH_SECTOR_SIZE - 1) / FLASH_SECTOR_SIZE) 572 | size = (count * FLASH_SECTOR_SIZE) 573 | offset = args.address & (0xffffff^(FLASH_SECTOR_SIZE-1)) 574 | print('Erase Flash %d sectors,\r\ndata from 0x%06x to 0x%06x...' % (count, offset, offset + size)) 575 | if not FlashUnlock(serialPort): 576 | sys.exit(1) 577 | if not FlashEraseSectors(serialPort, offset, size): 578 | sys.exit(1) 579 | elif args.operation == 'ea': 580 | print('Erase All Flash ...') 581 | if not FlashUnlock(serialPort): 582 | sys.exit(1) 583 | if not FlashEraseAll(serialPort): 584 | print('Error Erase All Flash!') 585 | sys.exit(1) 586 | else: 587 | pc = sws_read_data(serialPort, 0x06bc, 4) 588 | if pc == None or len(pc) != 4: 589 | print('Error read PC!') 590 | sys.exit(1) 591 | x = pc[0] + (pc[1]<<8) + (pc[2]<<16) + (pc[3]<<24) 592 | print('PC = 0x%06x' % (x)) 593 | if args.run != 0: 594 | print('Reset CPU...') 595 | sws_wr_addr_usbcom(serialPort, 0x006f, bytearray([0x22])) # Reset CPU 596 | print('-------------------------------------------------------') 597 | # Second time slice 598 | t2 = time.time() 599 | print("Worked Time: %.3f sec" % (t2-t1)) 600 | print('Done!') 601 | #-------------------------------- 602 | # Set default register[0x00b2] 603 | # sws_wr_addr_usbcom(serialPort, 0x00b2, bytearray([5])) 604 | sys.exit(0) 605 | 606 | if __name__ == '__main__': 607 | main() 608 | --------------------------------------------------------------------------------