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