19e7ecf0e82976019ee412494e908433f591ed4d
[gnuk/gnuk.git] / tool / stlinkv2.py
1 #! /usr/bin/python
2
3 """
4 stlinkv2.py - a tool to control ST-Link/V2
5
6 Copyright (C) 2012, 2013 Free Software Initiative of Japan
7 Author: NIIBE Yutaka <gniibe@fsij.org>
8
9 This file is a part of Gnuk, a GnuPG USB Token implementation.
10
11 Gnuk is free software: you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by
13 the Free Software Foundation, either version 3 of the License, or
14 (at your option) any later version.
15
16 Gnuk is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
18 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
19 License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program.  If not, see <http://www.gnu.org/licenses/>.
23 """
24
25 from struct import *
26 import sys, time
27 import usb
28 from colorama import init as colorama_init, Fore, Back, Style
29
30 # INPUT: binary file
31
32 # Assumes only single ST-Link/V2 device is attached to computer.
33
34
35 GPIOA=0x40010800
36 GPIOB=0x40010C00
37 OPTION_BYTES_ADDR=0x1ffff800
38 RDP_KEY=0x00a5                  # Unlock readprotection
39 FLASH_BASE_ADDR=0x40022000
40
41 FLASH_KEYR=    FLASH_BASE_ADDR+0x04
42 FLASH_OPTKEYR= FLASH_BASE_ADDR+0x08
43 FLASH_SR=      FLASH_BASE_ADDR+0x0c
44 FLASH_CR=      FLASH_BASE_ADDR+0x10
45 FLASH_AR=      FLASH_BASE_ADDR+0x14
46 FLASH_OBR=     FLASH_BASE_ADDR+0x1c
47
48 FLASH_KEY1=0x45670123
49 FLASH_KEY2=0xcdef89ab
50
51 FLASH_SR_BSY=      0x0001
52 FLASH_SR_PGERR=    0x0004
53 FLASH_SR_WRPRTERR= 0x0010
54 FLASH_SR_EOP=      0x0020
55
56 FLASH_CR_PG=     0x0001
57 FLASH_CR_PER=    0x0002
58 FLASH_CR_MER=    0x0004
59 FLASH_CR_OPTPG=  0x0010
60 FLASH_CR_OPTER=  0x0020
61 FLASH_CR_STRT=   0x0040
62 FLASH_CR_LOCK=   0x0080
63 FLASH_CR_OPTWRE= 0x0200
64
65
66 SPI1= 0x40013000
67
68 def uint32(v):
69     return v[0] + (v[1]<<8) + (v[2]<<16) + (v[3]<<24)
70
71 ## HERE comes: "movw r2,#SIZE" instruction
72 prog_flash_write_body = "\x0A\x48" + "\x0B\x49" + \
73     "\x08\x4C" + "\x01\x25" + "\x14\x26" + "\x00\x27" + "\x25\x61" + \
74     "\xC3\x5B" + "\xCB\x53" + "\xE3\x68" + "\x2B\x42" + "\xFC\xD1" + \
75     "\x33\x42" + "\x02\xD1" + "\x02\x37" + "\x97\x42" + "\xF5\xD1" + \
76     "\x00\x27" + "\x27\x61" + "\x00\xBE" +  "\x00\x20\x02\x40" + \
77     "\x38\x00\x00\x20"
78 #   .SRC_ADDR: 0x20000038
79 ## HERE comes: target_addr in 4-byte
80 #   .TARGET_ADDR
81
82 def gen_prog_flash_write(addr,size):
83     return pack("<BBBB", (0x40 | (size&0xf000)>>12), (0xf2 | (size&0x0800)>>9),
84                 (size & 0x00ff), (0x02 | ((size&0x0700) >> 4))) + \
85                 prog_flash_write_body + pack("<I", addr)
86
87
88 ## HERE comes: "movw r0,#VAL" instruction
89 prog_option_bytes_write_body = "\x06\x49" + "\x05\x4A" + "\x10\x23" + \
90     "\x01\x24" + "\x13\x61" + "\x08\x80" + "\xD0\x68" + "\x20\x42" + \
91     "\xFC\xD1" + "\x00\x20" + "\x10\x61" + "\x00\xBE" + "\x00\x20\x02\x40"
92 ## HERE comes: target_addr in 4-byte
93 #   .TARGET_ADDR
94
95 def gen_prog_option_bytes_write(addr,val):
96     return pack("<BBBB", (0x40 | (val&0xf000)>>12), (0xf2 | (val&0x0800)>>9),
97                 (val & 0x00ff), (0x00 | ((val&0x0700) >> 4))) + \
98                 prog_option_bytes_write_body + pack("<I", addr)
99
100 prog_blank_check_body = "\x04\x49" + "\x05\x4A" + "\x08\x68" + "\x01\x30" + \
101     "\x02\xD1" + "\x04\x31" + "\x91\x42" + "\xF9\xD1" + "\x00\xBE" + \
102     "\x00\xBF" + "\x00\x00\x00\x08"
103 ## HERE comes: end_addr in 4-byte
104 # .END_ADDR
105
106 def gen_prog_blank_check(size):
107     return prog_blank_check_body + pack("<I", 0x08000000 + size)
108
109
110 SRAM_ADDRESS=0x20000000
111 BLOCK_SIZE=16384                # Should be less than (20KiB - 0x0038)
112 BLOCK_WRITE_TIMEOUT=80          # Increase this when you increase BLOCK_SIZE
113
114
115 class TimeOutError(Exception):
116      def __init__(self, msg):
117          self.msg = msg
118      def __str__(self):
119          return repr(self.msg)
120      def __repr__(self):
121          return "TimeoutError(" + self.msg + ")"
122
123 class OperationFailure(Exception):
124      def __init__(self, msg):
125          self.msg = msg
126      def __str__(self):
127          return repr(self.msg)
128      def __repr__(self):
129          return "OperationFailure(" + self.msg + ")"
130
131
132 class stlinkv2(object):
133     def __init__(self, dev):
134         self.__bulkout = 2
135         self.__bulkin  = 0x81
136
137         self.__timeout = 1000   # 1 second
138         conf = dev.configurations[0]
139         intf_alt = conf.interfaces[0]
140         intf = intf_alt[0]
141         if intf.interfaceClass != 0xff: # Vendor specific
142             raise ValueError("Wrong interface class.", intf.interfaceClass)
143         self.__devhandle = dev.open()
144         try:
145             self.__devhandle.setConfiguration(conf)
146         except:
147             pass
148         self.__devhandle.claimInterface(intf)
149         # self.__devhandle.setAltInterface(intf)  # This is not good for libusb-win32
150
151     def shutdown(self):
152         self.__devhandle.releaseInterface()
153
154     def execute_get(self, cmd, res_len):
155         self.__devhandle.bulkWrite(self.__bulkout, cmd, self.__timeout)
156         res = self.__devhandle.bulkRead(self.__bulkin, res_len, self.__timeout)
157         return res
158
159     def execute_put(self, cmd, data=None):
160         self.__devhandle.bulkWrite(self.__bulkout, cmd, self.__timeout)
161         if (data):
162             self.__devhandle.bulkWrite(self.__bulkout, data, self.__timeout)
163
164     def stl_mode(self):
165         v = self.execute_get("\xf5\x00", 2)
166         return (v[1] * 256 + v[0])
167
168     def exit_from_debug_swd(self):
169         self.execute_put("\xf2\x21\x00")
170         time.sleep(1)
171
172     def exit_from_dfu(self):
173         self.execute_put("\xf3\x07\x00")
174         time.sleep(1)
175
176     def exit_from_debug_swim(self):
177         self.execute_put("\xf4\x01\x00")
178         time.sleep(1)
179
180     def enter_swd(self):
181         self.execute_put("\xf2\x20\xa3")
182         time.sleep(1)
183
184     def get_status(self):
185         v = self.execute_get("\xf2\x01\x00", 2)
186         return (v[1] << 8) + v[0]
187     # RUN:128, HALT:129
188
189     def enter_debug(self):
190         v = self.execute_get("\xf2\x02\x00", 2)
191         return (v[1] << 8) + v[0]
192
193     def exit_debug(self):
194         self.execute_put("\xf2\x21\x00")
195
196     def reset_sys(self):
197         v = self.execute_get("\xf2\x03\x00", 2)
198         return (v[1] << 8) + v[0]
199
200     def read_memory(self, addr, length):
201         return self.execute_get("\xf2\x07" + pack('<IH', addr, length), length)
202
203     def read_memory_u32(self, addr):
204         return uint32(self.execute_get("\xf2\x07" + pack('<IH', addr, 4), 4))
205
206     def write_memory(self, addr, data):
207         return self.execute_put("\xf2\x08" + pack('<IH', addr, len(data)), data)
208
209     def write_memory_u32(self, addr, data):
210         return self.execute_put("\xf2\x08" + pack('<IH', addr, 4),
211                                 pack('<I', data))
212
213     def read_reg(self, regno):
214         return uint32(self.execute_get("\xf2\x05" + pack('<B', regno), 4))
215
216     def write_reg(self, regno, value):
217         return self.execute_get("\xf2\x06" + pack('<BI', regno, value), 2)
218
219     def run(self):
220         v = self.execute_get("\xf2\x09\x00", 2)
221         return (v[1] << 8) + v[0]
222
223     def core_id(self):
224         v = self.execute_get("\xf2\x22\x00", 4)
225         return v[0] + (v[1]<<8) + (v[2]<<16) + (v[3]<<24)
226
227     def version(self):
228         v = self.execute_get("\xf1", 6)
229         val = (v[0] << 8) + v[1]
230         return ((val >> 12) & 0x0f, (val >> 6) & 0x3f, val & 0x3f)
231
232     # For FST-01-00 and FST-01: LED on, USB connect
233     def setup_gpio(self):
234         apb2enr = self.read_memory_u32(0x40021018)
235         apb2enr = apb2enr | 4 | 8 | 0x1000 # Enable port A, port B, and SPI1
236         self.write_memory_u32(0x40021018, apb2enr)    # RCC->APB2ENR
237         self.write_memory_u32(0x4002100c, 4|8|0x1000) # RCC->APB2RSTR
238         self.write_memory_u32(0x4002100c, 0)
239         self.write_memory_u32(GPIOA+0x0c, 0xffffffff) # ODR
240         self.write_memory_u32(GPIOA+0x04, 0x88888383) # CRH
241         self.write_memory_u32(GPIOA+0x00, 0xBBB38888) # CRL
242         self.write_memory_u32(GPIOB+0x0c, 0xffffffff) # ODR
243         self.write_memory_u32(GPIOB+0x04, 0x88888888) # CRH
244         self.write_memory_u32(GPIOB+0x00, 0x88888883) # CRL
245
246     # For FST-01-00 and FST-01: LED on, USB disconnect
247     def usb_disconnect(self):
248         self.write_memory_u32(GPIOA+0x0c, 0xfffffbff) # ODR
249
250     # For FST-01-00 and FST-01: LED off, USB connect
251     def finish_gpio(self):
252         self.write_memory_u32(GPIOA+0x0c, 0xfffffeff) # ODR
253         self.write_memory_u32(GPIOB+0x0c, 0xfffffffe) # ODR
254         apb2enr = self.read_memory_u32(0x40021018)
255         apb2enr = apb2enr &  ~(4 | 8 | 0x1000)
256         self.write_memory_u32(0x40021018, apb2enr)    # RCC->APB2ENR
257
258     def spi_flash_init(self):
259         self.write_memory_u32(SPI1+0x00, 0x0004); # CR1 <= MSTR
260         i2scfgr = self.read_memory_u32(SPI1+0x1c) # I2SCFGR
261         i2scfgr = i2scfgr & 0xf7ff                # 
262         self.write_memory_u32(SPI1+0x1c, i2scfgr); # I2SCFGR <= SPI mode
263         self.write_memory_u32(SPI1+0x10, 7);       # CRCPR <= 7
264         self.write_memory_u32(SPI1+0x04, 0x04);    # CR2 <= SSOE
265         self.write_memory_u32(SPI1+0x00, 0x0044);  # CR1 <= MSTR | SPE
266
267     def spi_flash_select(self, enable):
268         if enable:
269             self.write_memory_u32(GPIOA+0x0c, 0xffffffef) # ODR
270         else:
271             self.write_memory_u32(GPIOA+0x0c, 0xffffffff) # ODR
272
273     def spi_flash_sendbyte(self, v):
274         i = 0
275         while True:
276             status = self.read_memory_u32(SPI1+0x08) # SR
277             if status & 0x02 != 0:                   # TXE (Data Empty)
278                 break
279             time.sleep(0.01)
280             i = i + 1
281             if i > 10:
282                 raise TimeOutError('spi_flash_sendbyte')
283         self.write_memory_u32(SPI1+0x0c, v) # DR
284         i = 0
285         while True:
286             status = self.read_memory_u32(SPI1+0x08) # SR
287             if status & 0x01 != 0:                   # RXNE (Data Not Empty)
288                 break
289             time.sleep(0.01)
290             i = i + 1
291             if i > 10:
292                 raise TimeOutError('spi_flash_sendbyte')
293         v = self.read_memory_u32(SPI1+0x0c) # DR
294         return v
295
296     def spi_flash_read_id(self):
297         self.spi_flash_select(True)
298         self.spi_flash_sendbyte(0x9f)
299         t0 = self.spi_flash_sendbyte(0xa5)
300         t1 = self.spi_flash_sendbyte(0xa5)
301         t2 = self.spi_flash_sendbyte(0xa5)
302         self.spi_flash_select(False)
303         return (t0 << 16) | (t1 << 8) | t2
304
305     def protection(self):
306         return (self.read_memory_u32(FLASH_OBR) & 0x0002) != 0
307
308     def blank_check(self):
309         prog = gen_prog_blank_check(0x20000) # 128KiB  XXX: table lookup???
310         self.write_memory(SRAM_ADDRESS, prog)
311         self.write_reg(15, SRAM_ADDRESS)
312         self.run()
313         i = 0
314         while self.get_status() == 0x80:
315             time.sleep(0.050)
316             i = i + 1
317             if i >= 10:
318                 raise TimeOutError("blank check")
319
320         r0_value = self.read_reg(0)
321         return r0_value == 0
322
323     def option_bytes_read(self):
324         return self.read_memory_u32(OPTION_BYTES_ADDR)
325
326     def option_bytes_write(self,addr,val):
327         self.write_memory_u32(FLASH_KEYR, FLASH_KEY1)
328         self.write_memory_u32(FLASH_KEYR, FLASH_KEY2)
329         self.write_memory_u32(FLASH_SR, FLASH_SR_EOP | FLASH_SR_WRPRTERR | FLASH_SR_PGERR)
330
331         self.write_memory_u32(FLASH_OPTKEYR, FLASH_KEY1)
332         self.write_memory_u32(FLASH_OPTKEYR, FLASH_KEY2)
333
334         prog = gen_prog_option_bytes_write(addr,val)
335         self.write_memory(SRAM_ADDRESS, prog)
336         self.write_reg(15, SRAM_ADDRESS)
337         self.run()
338         i = 0
339         while self.get_status() == 0x80:
340             time.sleep(0.050)
341             i = i + 1
342             if i >= 10:
343                 raise TimeOutError("option bytes write")
344
345         status = self.read_memory_u32(FLASH_SR)
346         self.write_memory_u32(FLASH_CR, FLASH_CR_LOCK)
347         if (status & FLASH_SR_EOP) == 0:
348             raise OperationFailure("option bytes write")
349
350     def option_bytes_erase(self):
351         self.write_memory_u32(FLASH_KEYR, FLASH_KEY1)
352         self.write_memory_u32(FLASH_KEYR, FLASH_KEY2)
353         self.write_memory_u32(FLASH_SR, FLASH_SR_EOP | FLASH_SR_WRPRTERR | FLASH_SR_PGERR)
354
355         self.write_memory_u32(FLASH_OPTKEYR, FLASH_KEY1)
356         self.write_memory_u32(FLASH_OPTKEYR, FLASH_KEY2)
357
358         self.write_memory_u32(FLASH_CR, FLASH_CR_OPTER)
359         self.write_memory_u32(FLASH_CR, FLASH_CR_STRT | FLASH_CR_OPTER)
360
361         i = 0
362         while True:
363             status = self.read_memory_u32(FLASH_SR)
364             if (status & FLASH_SR_BSY) == 0:
365                 break
366             i = i + 1
367             if i >= 1000:
368                 break
369
370         self.write_memory_u32(FLASH_CR, FLASH_CR_LOCK)
371         if (status & FLASH_SR_EOP) == 0:
372             raise OperationFailure("option bytes erase")
373
374     def flash_write_internal(self, addr, data, off, size):
375         prog = gen_prog_flash_write(addr,size)
376         self.write_memory(SRAM_ADDRESS, prog+data[off:off+size])
377         self.write_reg(15, SRAM_ADDRESS)
378         self.run()
379         i = 0
380         while self.get_status() == 0x80:
381             time.sleep(0.050)
382             i = i + 1
383             if i >= BLOCK_WRITE_TIMEOUT:
384                 raise TimeOutError("flash write")
385         status = self.read_memory_u32(FLASH_SR)
386         if (status & FLASH_SR_PGERR) != 0:
387             raise OperationFailure("flash write: write to not erased part")
388         if (status & FLASH_SR_WRPRTERR) != 0:
389             raise OperationFailure("flash write: write to protected part")
390
391     def flash_write(self, addr, data):
392         self.write_memory_u32(FLASH_KEYR, FLASH_KEY1)
393         self.write_memory_u32(FLASH_KEYR, FLASH_KEY2)
394         self.write_memory_u32(FLASH_SR, FLASH_SR_EOP | FLASH_SR_WRPRTERR | FLASH_SR_PGERR)
395
396         off = 0
397         while True:
398             if len(data[off:]) > BLOCK_SIZE:
399                 size = BLOCK_SIZE
400                 self.flash_write_internal(addr, data, off, size)
401                 off = off + size
402                 addr = addr + size
403             else:
404                 size = len(data[off:])
405                 self.flash_write_internal(addr, data, off, size)
406                 break
407
408         self.write_memory_u32(FLASH_CR, FLASH_CR_LOCK)
409
410     def flash_erase_all(self):
411         self.write_memory_u32(FLASH_KEYR, FLASH_KEY1)
412         self.write_memory_u32(FLASH_KEYR, FLASH_KEY2)
413         self.write_memory_u32(FLASH_SR, FLASH_SR_EOP | FLASH_SR_WRPRTERR | FLASH_SR_PGERR)
414
415         self.write_memory_u32(FLASH_CR, FLASH_CR_MER)
416         self.write_memory_u32(FLASH_CR, FLASH_CR_STRT | FLASH_CR_MER)
417
418         i = 0
419         while True:
420             status = self.read_memory_u32(FLASH_SR)
421             if (status & FLASH_SR_BSY) == 0:
422                 break
423             i = i + 1
424             time.sleep(0.050)
425             if i >= 100:
426                 break
427
428         self.write_memory_u32(FLASH_CR, FLASH_CR_LOCK)
429
430         if (status & FLASH_SR_EOP) == 0:
431             raise OperationFailure("flash erase all")
432
433     def flash_erase_page(self, addr):
434         self.write_memory_u32(FLASH_KEYR, FLASH_KEY1)
435         self.write_memory_u32(FLASH_KEYR, FLASH_KEY2)
436
437         self.write_memory_u32(FLASH_SR, FLASH_SR_EOP | FLASH_SR_WRPRTERR | FLASH_SR_PGERR)
438
439         self.write_memory_u32(FLASH_CR, FLASH_CR_PER)
440         self.write_memory_u32(FLASH_AR, addr)
441         self.write_memory_u32(FLASH_CR, FLASH_CR_STRT | FLASH_CR_PER)
442
443         i = 0
444         while True:
445             status = self.read_memory_u32(FLASH_SR)
446             if (status & FLASH_SR_BSY) == 0:
447                 break
448             i = i + 1
449             if i >= 1000:
450                 break
451
452         self.write_memory_u32(FLASH_CR, FLASH_CR_LOCK)
453
454         if (status & FLASH_SR_EOP) == 0:
455             raise OperationFailure("flash page erase")
456
457     def start(self):
458         mode = self.stl_mode()
459         if mode == 2:
460             self.exit_from_debug_swd()
461         elif mode == 5:
462             self.exit_from_debug_swim()
463         elif mode != 1 and mode != 4:
464             self.exit_from_dfu()
465         new_mode = self.stl_mode()
466         print "Change ST-Link/V2 mode %04x -> %04x" % (mode, new_mode)
467         self.enter_swd()
468         s = self.get_status()
469         if s != 0x0080:
470             print "Status is %04x" % s
471             self.run()
472             s = self.get_status()
473             if s != 0x0080:
474                 raise ValueError("Status of core is not running.", s)
475         mode = self.stl_mode()
476         if mode != 2:
477             raise ValueError("Failed to switch debug mode.", mode)
478
479
480 USB_VENDOR_ST=0x0483            # 0x0483 SGS Thomson Microelectronics
481 USB_VENDOR_STLINKV2=0x3748      # 0x3748 ST-LINK/V2
482
483 def stlinkv2_devices():
484     busses = usb.busses()
485     for bus in busses:
486         devices = bus.devices
487         for dev in devices:
488             if dev.idVendor != USB_VENDOR_ST:
489                 continue
490             if dev.idProduct != USB_VENDOR_STLINKV2:
491                 continue
492             yield dev
493
494 def compare(data_original, data_in_device):
495     i = 0 
496     for d in data_original:
497         if ord(d) != data_in_device[i]:
498             raise ValueError("Verify failed at:", i)
499         i += 1
500
501 def open_stlinkv2():
502     for d in stlinkv2_devices():
503         try:
504             stl = stlinkv2(d)
505             return stl
506         except:
507             pass
508     return None
509
510 def help():
511     print "stlinkv2.py [-h]: Show this help message"
512     print "stlinkv2.py [-e]: Erase flash ROM"
513     print "stlinkv2.py [-u]: Unlock flash ROM"
514     print "stlinkv2.py [-s]: Show status"
515     print "stlinkv2.py [-b] [-n] [-r] [-i] FILE: Write content of FILE to flash ROM"
516     print "    -b: Blank check before write (auto erase when not blank)"
517     print "    -n: Don't enable read protection after write"
518     print "    -r: Don't reset after write"
519     print "    -i: Don't test SPI flash"
520
521
522 def main(show_help, erase_only, no_protect, spi_flash_check,
523          reset_after_successful_write,
524          skip_blank_check, status_only, unlock, data):
525     if show_help or len(sys.argv) != 1:
526         help()
527         return 1
528
529     stl = open_stlinkv2()
530     if not stl:
531         raise ValueError("No ST-Link/V2 device found.", None)
532
533     print "ST-Link/V2 version info: %d %d %d" % stl.version()
534     stl.start()
535     core_id = stl.core_id()
536     chip_id = stl.read_memory_u32(0xE0042000)
537
538     # FST-01 chip id: 0x20036410
539     print "CORE: %08x, CHIP_ID: %08x" % (core_id, chip_id)
540     print "Flash ROM read protection:",
541     protection = stl.protection()
542     if protection:
543         print "ON"
544     else:
545         print "off"
546
547     option_bytes = stl.option_bytes_read()
548     print "Option bytes: %08x" % option_bytes
549     if (option_bytes & 0xff) == RDP_KEY:
550         ob_protection_enable = False
551     else:
552         ob_protection_enable = True
553
554     stl.enter_debug()
555     status = stl.get_status()
556     if status != 0x0081:
557         raise ValueError("Status of core is not halt.", status)
558
559     if protection:
560         if status_only:
561             print "The MCU is now stopped."
562             return 0
563         elif not unlock:
564             raise OperationFailure("Flash ROM is protected")
565     else:
566         if not skip_blank_check:
567             stl.reset_sys()
568             blank = stl.blank_check()
569             print "Flash ROM blank check: %s" % blank
570         else:
571             blank = True
572         if status_only:
573             stl.reset_sys()
574             stl.run()
575             stl.exit_debug()
576             return 0
577         elif unlock and not ob_protection_enable:
578             print "No need to unlock.  Protection is not enabled."
579             return 1
580
581     if erase_only:
582         if blank:
583             print "No need to erase"
584             return 0
585
586     stl.setup_gpio()
587
588     if unlock:
589         if option_bytes != 0xff:
590             stl.reset_sys()
591             stl.option_bytes_erase()
592         stl.reset_sys()
593         stl.option_bytes_write(OPTION_BYTES_ADDR,RDP_KEY)
594         stl.usb_disconnect()
595         time.sleep(0.100)
596         stl.finish_gpio()
597         print "Flash ROM read protection disabled.  Reset the board, now."
598         return 0
599
600     if spi_flash_check:
601         stl.spi_flash_init()
602         id = stl.spi_flash_read_id()
603         print "SPI Flash ROM ID: %06x" % id
604         if id != 0xbf254a:
605             raise ValueError("bad spi flash ROM ID")
606
607     if not blank:
608         print "ERASE ALL"
609         stl.reset_sys()
610         stl.flash_erase_all()
611
612     if erase_only:
613         stl.usb_disconnect()
614         time.sleep(0.100)
615         stl.finish_gpio()
616         return 0
617
618     time.sleep(0.100)
619
620     print "WRITE"
621     stl.flash_write(0x08000000, data)
622
623     print "VERIFY"
624     data_received = ()
625     size = len(data)
626     off = 0
627     while size > 0:
628         if size > 1024:
629             blk_size = 1024
630         else:
631             blk_size = size
632         data_received = data_received + stl.read_memory(0x08000000+off, 1024)
633         size = size - blk_size
634         off = off + blk_size
635     compare(data, data_received)
636
637     if not no_protect:
638         print "PROTECT"
639         stl.option_bytes_erase()
640         print "Flash ROM read protection enabled.  Reset the board to enable protection."
641
642     if reset_after_successful_write:
643         stl.usb_disconnect()
644         stl.reset_sys()
645         stl.run()
646         stl.exit_debug()
647     else:
648         stl.finish_gpio()
649
650     stl.shutdown()
651     return 0
652
653 if __name__ == '__main__':
654     show_help = False
655     erase_only = False
656     no_protect = False
657     reset_after_successful_write = True
658     skip_blank_check=True
659     status_only = False
660     unlock = False
661     data = None
662     spi_flash_check = True
663
664     while len(sys.argv) > 1:
665         if sys.argv[1] == '-h':
666             sys.argv.pop(1)
667             show_help = True
668             break
669         elif sys.argv[1] == '-e':
670             sys.argv.pop(1)
671             erase_only = True
672             skip_blank_check=False
673             break
674         elif sys.argv[1] == '-u':
675             sys.argv.pop(1)
676             unlock = True
677             break
678         elif sys.argv[1] == '-s':
679             sys.argv.pop(1)
680             status_only = True
681             skip_blank_check=False
682             break
683         elif sys.argv[1] == '-b':
684             skip_blank_check=False
685         elif sys.argv[1] == '-n':
686             no_protect = True
687         elif sys.argv[1] == '-r':
688             reset_after_successful_write = False
689         elif sys.argv[1] == '-i':
690             spi_flash_check = False
691         else:
692             filename = sys.argv[1]
693             f = open(filename,'rb')
694             data = f.read()
695             f.close()
696         sys.argv.pop(1)
697
698     colorama_init()
699
700     try:
701         r = main(show_help, erase_only, no_protect, spi_flash_check,
702                  reset_after_successful_write,
703                  skip_blank_check, status_only, unlock, data)
704         if r == 0:
705             print Fore.WHITE + Back.BLUE + Style.BRIGHT + "SUCCESS" + Style.RESET_ALL
706         sys.exit(r)
707     except Exception as e:
708         print Back.RED + Style.BRIGHT + repr(e) + Style.RESET_ALL