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 | 
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 |
--------------------------------------------------------------------------------