flushmagic.py


1
#!/usr/bin/python
2
3
################################################################################
4
#
5
# A script to program a LPC800 devices via ISP serial interface
6
#
7
# Author: Axel Heider, axelheider(_at_)gmx.de
8
# Created:     2014-Mar-20
9
# Last Change: 2014-Jan-01
10
#
11
# License: Creative Commons, CC-BY-NC-SA 3.0/de
12
#          German:  http://creativecommons.org/licenses/by-nc-sa/3.0/de/
13
#          General: http://creativecommons.org/licenses/by-nc-sa/3.0/
14
#
15
#
16
# This script is based on the work of Lars Ole Belhage (belhage@midibel.com),
17
# who published it together with a minimal development enviroment for the
18
# LPC800.
19
#
20
################################################################################
21
22
import sys
23
import argparse
24
import serial
25
26
#
27
# http://www.nxp.com/documents/user_manual/UM10601.pdf
28
#
29
# Memory map:
30
#   0x00000000   
31
#       Flash (4 Kb)
32
#   0x00001000
33
#       Flash (on devices with 8 Kb)
34
#   0x00002000
35
#       Flash (on devices with 16 Kb)
36
#   0x00004000
37
#       ...
38
#   0x10000000
39
#       SRAM (1 Kb)
40
#   0x10000400
41
#       SRAM (on devices with 2 Kb)
42
#   0x10000800
43
#       SRAM (on devices with 4 Kb)
44
#   0x10001000
45
#       ...
46
#   0x14000000
47
#       Micro Trace Buffer (1 Kb)
48
#   0x14000400
49
#       ...
50
#   0x1FFF0000
51
#       Boot ROM (8 Kb)
52
#   0x1FFF2000
53
#       ....
54
#
55
# Flash:
56
#   page size:    64 Byte
57
#   sector size:  1 kB (16 pages)
58
#
59
# Sector   Page      Address                  4 KB   8 KB  16 Kb
60
#    0     0 -  15   0x00000000 - 0x000003FF    x      x     x
61
#    1    16 -  31   0x00000400 - 0x000007FF    x      x     x
62
#    2    32 -  47   0x00000800 - 0x00000BFF    x      x     x
63
#    3    48 -  63   0x00000C00 - 0x00000FFF    x      x     x
64
#    4    64 -  79   0x00001000 - 0x000013FF    -      x     x
65
#    5    80 -  95   0x00001400 - 0x000017FF    -      x     x
66
#    6    96 - 111   0x00001800 - 0x00001BFF    -      x     x
67
#    7   112 - 127   0x00001C00 - 0x00001FFF    -      x     x
68
#    8   128 - 143   0x00002000 - 0x000023FF    -      -     x
69
#    9   144 - 159   0x00002400 - 0x000027FF    -      -     x
70
#   10   160 - 175   0x00002800 - 0x00002BFF    -      -     x
71
#   11   176 - 191   0x00002C00 - 0x00002FFF    -      -     x
72
#   12   192 - 207   0x00003000 - 0x000033FF    -      -     x
73
#   13   208 - 223   0x00003400 - 0x000037FF    -      -     x
74
#   14   224 - 239   0x00003800 - 0x00003BFF    -      -     x
75
#   15   240 - 255   0x00003C00 - 0x00003FFF    -      -     x
76
#
77
# 80 byte of SRAM from 0x10000000 to 0x10000050 are not used by the bootloader,
78
# thus content in this area is retained during reset. SRAM memory is not 
79
# retained for deep power-down mode for full power.
80
#
81
82
ADDR_CHECKSUM = 0x001C
83
84
ADDR_CRP      = 0x02fc
85
NO_ISP = 0x4E697370
86
CRP1   = 0x12345678
87
CRP2   = 0x87654321
88
CRP3   = 0x43218765
89
90
91
92
#-------------------------------------------------------------------------------
93
def printVerbose(level,string):
94
    if (args.verbose >= level):
95
        print(string)
96
97
#-------------------------------------------------------------------------------
98
def hexdump(data, indentStr="", printOffs=0, length=16, sep='.'):
99
  FILTER = ''.join([(len(repr(chr(x))) == 3) and chr(x) or sep for x in range(256)])
100
  lines = []
101
  for c in xrange(0, len(data), length):
102
    chars = data[c:c+length]
103
    hexStr = ' '.join(["%02x"%x for x in chars])
104
    if len(hexStr) > 24:
105
      hexStr = "%s %s"%(hexStr[:24], hexStr[24:])
106
    printable = ''.join(["%s"%((x<=127 and FILTER[x]) or sep) for x in chars])
107
    lines.append("%s%08x:  %-*s  | %s"%(indentStr,printOffs+c, length*3, hexStr, printable))
108
  print "\n".join(lines)
109
110
#-------------------------------------------------------------------------------
111
def get_uint32_le(data, offset):
112
    return data[offset] \
113
           | (data[offset+1] <<  8) \
114
           | (data[offset+2] << 16) \
115
           | (data[offset+3] << 24)
116
117
118
#-------------------------------------------------------------------------------
119
def set_uint32_le(data,offset,val):
120
    data[offset]   = (val >>  0) & 0xff
121
    data[offset+1] = (val >>  8) & 0xff
122
    data[offset+2] = (val >> 16) & 0xff
123
    data[offset+3] = (val >> 24) & 0xff
124
125
#-------------------------------------------------------------------------------
126
def get_uint16_le(data, offset):
127
    return data[offset] \
128
           | (data[offset+1] <<  8)
129
130
#-------------------------------------------------------------------------------
131
def set_uint16_le(data,offset,val):
132
    data[offset]   = (val >>  0) & 0xff
133
    data[offset+1] = (val >>  8) & 0xff
134
135
#-------------------------------------------------------------------------------
136
def append_uint16_le(data,val):
137
    data.append( (val >>  0) & 0xff );
138
    data.append( (val >>  8) & 0xff );
139
140
#-------------------------------------------------------------------------------
141
def append_uint32_le(data,val):
142
    data.append( (val >>  0) & 0xff );
143
    data.append( (val >>  8) & 0xff );
144
    data.append( (val >> 16) & 0xff );
145
    data.append( (val >> 24) & 0xff );
146
147
148
#-------------------------------------------------------------------------------
149
def sendSer(data):
150
    printVerbose(2,"sendRaw: <"+data+">")
151
    ser.write(data)
152
    ser.flush()
153
154
#-------------------------------------------------------------------------------
155
def sendSerCrLf(data):
156
    printVerbose(2,"sendCrLf: <"+data+"> CR LF")
157
    ser.write(data+"\r\n")
158
    ser.flush()
159
160
#-------------------------------------------------------------------------------
161
def readSer():
162
    ret = ser.readline().rstrip()
163
    printVerbose(2,"read: <"+ret+">")
164
    return ret
165
166
#-------------------------------------------------------------------------------
167
CMD_SUCCESS              =  0 
168
ERR_INVALID_CMD          =  1
169
ERR_SRC_ADDR             =  2 # not on word boundary.
170
ERR_DST_ADDR             =  3 # not on a correct boundary.
171
ERR_SRC_ADDR_NOT_MAPPED  =  4 # not mapped in memory map. Count value is taken in to consideration where applicable.
172
ERR_DST_ADDR_NOT_MAPPED  =  5 # not mapped in memory map. Count value is taken in to consideration where applicable.
173
ERR_COUNT                =  6 # Byte count is not multiple of 4 or is not a permitted value.
174
ERR_INVALID_SECTOR       =  7 # Sector number is invalid or end sector number is greater than start sector number.
175
ERR_SECTOR_NOT_BLANK     =  8
176
ERR_SECTOR_NOT_PREPARED  =  9 # Command to prepare sector for write operation was not executed.
177
ERR_COMPARE              = 10
178
ERR_BUSY                 = 11 # Flash programming hardware interface is busy.
179
ERR_PARAM                = 12
180
ERR_ADDR                 = 13 # not on word boundary
181
ERR_ADDR_NOT_MAPPED      = 14 # Address is not mapped in the memory map. Count value is taken in to consideration where applicable.
182
ERR_CMD_LOCKED           = 15
183
ERR_INVALID_CODE         = 16
184
ERR_INVALID_BAUD_RATE    = 17
185
ERR_INVALID_STOP_BIT     = 18
186
ERR_CRP_ENABLED          = 19
187
188
189
#-------------------------------------------------------------------------------
190
def cmdErr2Str(cmdErr):
191
    return { CMD_SUCCESS: "SUCCESS",
192
             ERR_INVALID_CMD: "ERR_INVALID_CMD",
193
             ERR_SRC_ADDR: "ERR_SRC_ADDR",
194
             ERR_DST_ADDR: "ERR_DST_ADDR",
195
             ERR_SRC_ADDR_NOT_MAPPED: "ERR_SRC_ADDR_NOT_MAPPED",
196
             ERR_DST_ADDR_NOT_MAPPED: "ERR_DST_ADDR_NOT_MAPPED",
197
             ERR_COUNT: "ERR_COUNT",
198
             ERR_INVALID_SECTOR: "ERR_INVALID_SECTOR",
199
             ERR_SECTOR_NOT_BLANK: "ERR_SECTOR_NOT_BLANK",
200
             ERR_SECTOR_NOT_PREPARED: "ERR_SECTOR_NOT_PREPARED",
201
             ERR_COMPARE: "ERR_COMPARE",
202
             ERR_BUSY: "ERR_BUSY",
203
             ERR_PARAM: "ERR_PARAM",
204
             ERR_ADDR: "ERR_ADDR",
205
             ERR_ADDR_NOT_MAPPED: "ERR_ADDR_NOT_MAPPED",
206
             ERR_CMD_LOCKED: "ERR_CMD_LOCKED",
207
             ERR_INVALID_CODE: "ERR_INVALID_CODE",
208
             ERR_INVALID_BAUD_RATE: "ERR_INVALID_BAUD_RATE",
209
             ERR_INVALID_STOP_BIT: "ERR_INVALID_STOP_BIT",
210
             ERR_CRP_ENABLED: "ERR_CRP_ENABLED",
211
            }.get(cmdErr, "ERR_%d_ ???"%(cmdErr))
212
213
#-------------------------------------------------------------------------------
214
def sendCmd(cmd, dataResp=0):
215
216
    sendSerCrLf(cmd)
217
    if (echo != 0):
218
        cmdEcho = readSer()
219
        printVerbose(2,"ECHO: <"+cmdEcho+">")
220
221
    respCode = 0
222
    if cmd.startswith("G "):
223
         while (1):
224
             c = ser.read()
225
             if (c >= '0') and (c <= '9'):
226
                respCode = 10*respCode + (ord(c)-ord('0'))
227
             else:
228
                print("ERROR: response for G command broken")
229
                quit()
230
    else: 
231
        respStr = readSer()
232
        respCode = int(respStr)
233
234
    if (respCode != 0):
235
        print("ERROR: command <%s> failed, ret=%s (%s)"%(cmd,respCode,cmdErr2Str(respCode)))
236
237
    return respCode
238
239
#-------------------------------------------------------------------------------
240
def Cmd_A(val):
241
    printVerbose(1,"Set Echo to %d"%(val))
242
    cmdStr = "A %d"%(val)
243
    cmdRet = sendCmd(cmdStr)
244
    if (cmdRet != CMD_SUCCESS):
245
        quit()
246
247
    global echo
248
    echo = val
249
250
#-------------------------------------------------------------------------------
251
def Cmd_C(addrFlash, addrRam, numBytes):
252
    printVerbose(1,"Copy %d byte from 0x%08x in RAM to 0x%08x in flash"%(numBytes,addrRam,addrFlash))
253
    cmdStr = "C %d %d %d"%(addrFlash,addrRam,numBytes)
254
    cmdRet = sendCmd(cmdStr)
255
    if (cmdRet != CMD_SUCCESS):
256
        quit()
257
258
#-------------------------------------------------------------------------------
259
def Cmd_E(startSector,endSector):
260
    printVerbose(1,"Erasing sector %d - %d"%(startSector,endSector))
261
    cmdStr = "E %d %d"%(startSector,endSector)
262
    cmdRet = sendCmd(cmdStr)
263
    if (cmdRet != CMD_SUCCESS):
264
        quit()
265
266
#-------------------------------------------------------------------------------
267
def Cmd_G(addr):
268
    # execute a program residing in RAM or flash memory. Sddress must 
269
    # 0x00000200 or  greater. "T" is thumb mode
270
    printVerbose(1,"Executing code at 0x%08x"%(addr))
271
    cmdStr = "G %d T"%(addr)
272
    cmdRet = sendCmd(cmdStr)
273
274
#-------------------------------------------------------------------------------
275
def Cmd_J():
276
    cmdRet = sendCmd("J")
277
    if (cmdRet != CMD_SUCCESS):
278
        quit()
279
    partID = int(readSer())
280
    return partID 
281
282
283
#-------------------------------------------------------------------------------
284
def Cmd_K():
285
    cmdRet = sendCmd("K")
286
    if (cmdRet != CMD_SUCCESS):
287
        quit()
288
    bootRomMinor = int(readSer())
289
    bootRomMajor = int(readSer())
290
291
    return (bootRomMajor, bootRomMinor)
292
293
#-------------------------------------------------------------------------------
294
def Cmd_M(addr1,addr2,numBytes):
295
    printVerbose(1,"Compare %d bytes at 0x%08x and 0x%08x"%(numBytes,addr1,addr2))
296
    cmdStr = "M %d %d %d"%(addr1,addr2,numBytes)
297
    cmdRet = sendCmd(cmdStr)
298
    return cmdRet
299
 
300
#-------------------------------------------------------------------------------
301
def Cmd_N():
302
    cmdRet = sendCmd("N")
303
    if (cmdRet != CMD_SUCCESS):
304
        quit()
305
    uid1 = int(readSer())
306
    uid2 = int(readSer())
307
    uid3 = int(readSer())
308
    uid4 = int(readSer())
309
    return (uid1,uid2,uid3,uid4)
310
311
#-------------------------------------------------------------------------------
312
def Cmd_P(startSector,endSector):
313
    printVerbose(1,"Prepare sector %d - %d for write operation"%(startSector,endSector))
314
    cmdStr = "P %d %d"%(startSector,endSector)
315
    cmdRet = sendCmd(cmdStr)
316
    if (cmdRet != CMD_SUCCESS):
317
        quit()
318
319
#-------------------------------------------------------------------------------
320
def Cmd_R(addr,numBytes):
321
    printVerbose(1,"Read %d bytes from 0x%08x"%(numBytes,addr))
322
    cmdStr = "R %d %d"%(addr,numBytes)
323
    cmdRet = sendCmd(cmdStr,numBytes)
324
    if (cmdRet != CMD_SUCCESS):
325
        quit()
326
327
    data = []
328
    while (numBytes != 0):
329
        c = ord(ser.read())
330
        data.append(c)
331
        numBytes -= 1
332
    
333
    if (args.verbose >= 2):
334
        hexdump(data)
335
336
    return data
337
338
#-------------------------------------------------------------------------------
339
def Cmd_S(ramAddr,numBytes):
340
    printVerbose(1,"Read CRC checksum of block at 0x%08x len &d"%(ramAddr,numBytes))
341
    cmdStr = "S %d %d"%(ramAddr,numBytes)
342
    cmdRet = sendCmd(cmdStr)
343
    if (cmdRet != CMD_SUCCESS):
344
        quit()
345
    crc = int(readSer())
346
    return crc
347
348
#-------------------------------------------------------------------------------
349
def Cmd_U(val):
350
    printVerbose(1,"unlocking with code %d"%(val))
351
    cmdStr = "U %d"%(val)
352
    cmdRet = sendCmd(cmdStr)
353
    if (cmdRet != CMD_SUCCESS):
354
        quit()
355
356
#-------------------------------------------------------------------------------
357
def Cmd_W(addr,data):
358
    numBytes = len(data)
359
    printVerbose(1,"Write %d byte to RAM at 0x%08x"%(numBytes,addr))
360
361
    if (args.verbose >= 2):
362
        hexdump(data)
363
364
    cmdStr = "W %d %d"%(addr,numBytes)
365
    cmdRet = sendCmd(cmdStr)
366
    if (cmdRet != CMD_SUCCESS):
367
        quit()
368
369
    ser.write(data)
370
371
#-------------------------------------------------------------------------------
372
def getPartName(partID):
373
    return { 0x00008100: "LPC810M021FN8",
374
    #          0x00008110: "LPC811M001JDH16",
375
    #          0x00008120: "LPC812M101JDH16",
376
    #          0x00008121: "LPC812M101JD20",
377
    #          0x00008122: "LPC812M101JDH20"
378
            }.get(partID, "")
379
380
#-------------------------------------------------------------------------------
381
def unlock():
382
    UNLOCK_MAGIC = 23130 # magic value
383
    Cmd_U(UNLOCK_MAGIC) 
384
385
386
#-------------------------------------------------------------------------------
387
def printInfo():
388
389
    partID = Cmd_J()
390
    (uid1,uid2,uid3,uid4) = Cmd_N()
391
    (bootRomMajor, bootRomMinor) = Cmd_K()
392
393
    partName = getPartName(partID);
394
    partNameStr = partName 
395
    if (partNameStr == ""):
396
        partNameStr = "unknown"
397
398
    print("Device:")
399
    print("  PartID: 0x%08x (%s)"%(partID,partNameStr))
400
    print("  UID: %08x-%08x-%08x-%08x"%(uid1,uid2,uid3,uid4))
401
    print("  Boot Loder: V%d.%d"%(bootRomMajor,bootRomMinor))
402
403
404
#-------------------------------------------------------------------------------
405
def checkIfSupportedCotroller():
406
    partID = Cmd_J()
407
    partName = getPartName(partID);
408
    if (partName == ""):
409
        printInfo()
410
        quit()
411
412
413
414
#-------------------------------------------------------------------------------
415
def init():
416
    # serial setting: 8 data bits, 1 stop bit, no parity.
417
    # Device detects baud rate automatically when host sends "?" (0x3F) as the
418
    # first character. ASCII string "Synchronized"+CR+LF is send back then with
419
    # the detected baud rate. Host must send the same "Synchronized"+CR+LF 
420
    # back, so device can verify the baud rate. If synchronization is verified
421
    # then device sends "OK"+CR+LF. 
422
    # Then host must send the crystal frequency (in kHz) at which the part is
423
    # running. The response is required for backward compatibility of the boot
424
    # loader code. On the LPC800 it is ignored, boot loader configures 12 MHz 
425
    # IRC frequency. 
426
    # Now ISP command handler is invoked. For safety reasons an "Unlock" 
427
    # command is required before executing the commands resulting in flash
428
    # erase/write operations and the "Go" command.  The rest of the commands
429
    # can be executed without the unlock command. The Unlock command is 
430
    # required to be executed once per ISP session.
431
432
    isEcho = 1
433
    syncStr = "Synchronized"
434
435
    ser.flushInput()
436
    ser.flushOutput()
437
438
    ser.timeout = 2
439
    sendSer("?")
440
    j = readSer()
441
    ser.timeout = 1
442
    if j == syncStr:
443
        print("LPC8xx ISP setup")
444
        sendSerCrLf(syncStr)
445
        readSer() # cmd echo
446
        readSer() # "OK"
447
        sendSerCrLf("12") # backwards compatibility dummy 
448
        readSer() #  cmd echo
449
        readSer() # "OK"
450
    else:
451
        sendSerCrLf("")
452
        c = readSer()
453
        if (j != "?"):
454
            # already in ISP more with echo off?
455
            isEcho = 0
456
        else:
457
            # already in ISP more with echo on?
458
            if (c != ""):
459
                print("LPC8xx ISP mode error 1, read: <"+c+">")
460
                quit()
461
            c = readSer()
462
463
        if (c != "1"):
464
            print("LPC8xx ISP mode error 2, read: <"+c+">")
465
            quit()
466
        
467
    global echo
468
    echo = isEcho
469
470
    # try echo off command 
471
    Cmd_A(0) 
472
473
    print("LPC8xx ISP ready")
474
475
476
#-------------------------------------------------------------------------------
477
def calcChecksum(data):
478
479
    # The reserved Cortex-M0+ exception vector (offset 0x1C) contains the 
480
    # 2-complement of the check-sum of vector table entries 0 through 6. This 
481
    # causes the checksum of the first 8 table entries to be 0. The bootloader
482
    # code checksums the first 8 locations in sector 0 of the flash. If the
483
    # result is 0, then execution control is transferred to the user code.
484
485
    dlen = len(data)
486
    if (dlen < ADDR_CHECKSUM+4):
487
        print("Error: not enough data to insert the checksum")
488
        quit()
489
490
    sig = 0
491
    for v in range(0, 7):
492
      sig += get_uint32_le(data, 4*v)
493
494
    sig ^= 0xffffffff
495
    sig += 1
496
497
    print("setting checksum: 0x%08x"%(sig))
498
499
    set_uint32_le(data,ADDR_CHECKSUM,sig)
500
501
502
#-------------------------------------------------------------------------------
503
def checkCrp(data):
504
505
    # Code Read Protection (CRP)
506
    # any CRP change becomes effective in the next power cycle.
507
    #
508
    # CRP   User    ISP entry    SWD      Enters     partial flash 
509
    #       Code    pin at       enabled  ISP mode   update in 
510
    #       Valid   reset                            ISP mode
511
    # 
512
    # None  No      x            Yes      Yes        Yes
513
    # None  Yes     High         Yes      No         NA
514
    # None  Yes     Low          Yes      Yes        Yes
515
    # CRP1  Yes     High         No       No         NA
516
    # CRP1  Yes     Low          No       Yes        Yes
517
    # CRP2  Yes     High         No       No         NA
518
    # CRP2  Yes     Low          No       Yes        No
519
    # CRP3  Yes     x            No       No         NA
520
    # CRP1  No      x            No       Yes        Yes
521
    # CRP2  No      x            No       Yes        No
522
    # CRP3  No      x            No       Yes        No
523
524
525
    dlen = len(data)
526
    if (dlen >= ADDR_CRP+4):
527
        crp = get_uint32_le(data,ADDR_CRP)
528
        if (crp in [NO_ISP, CRP1, CRP2, CRP3]):
529
            print("Error: found CRP-Magic word 0x%08x"%(magic))
530
            quit()
531
532
533
#-------------------------------------------------------------------------------
534
def flash(image):
535
536
    data = bytearray(image.read())
537
    image.close()
538
539
    dlen = len(data)
540
    if (0 == dlen):
541
        print("no data found")
542
        quit()
543
544
    sectEnd = (dlen-1)/1024
545
    pageCnt = (dlen + 63) / 64
546
    rlen = pageCnt * 64
547
548
    data += bytearray(rlen-dlen)  # add padding 
549
550
    checkCrp(data)
551
    calcChecksum(data) 
552
553
    print("flashing %d byte (%d pages)"%(dlen, pageCnt))
554
555
    unlock()
556
    Cmd_P(0,sectEnd)
557
    Cmd_E(0,sectEnd)
558
559
    tmpRamAddr = 0x10000000
560
    dataOffset = 0
561
    flashAddr = 0
562
    blockLen = 64
563
564
    while (dataOffset < dlen):
565
        if (args.verbose == 0):
566
           sys.stdout.write(".")
567
           sys.stdout.flush()
568
        else:
569
          printVerbose(1,"Write block: 0x%08x"%(flashAddr))
570
571
        Cmd_P(0,sectEnd)
572
573
        Cmd_W(tmpRamAddr,data[dataOffset:dataOffset+blockLen])
574
        Cmd_R(tmpRamAddr,blockLen)
575
576
        Cmd_C(flashAddr,tmpRamAddr,blockLen)
577
        Cmd_R(flashAddr,blockLen)
578
579
        flashAddr += blockLen
580
        dataOffset += blockLen
581
582
    if (args.verbose == 0):
583
       print("done")
584
585
    print("%d bytes were written"%(dlen))
586
587
#-------------------------------------------------------------------------------
588
def systemReset():
589
590
    print("resetting device...")
591
592
    # issue system reset as described in in LPC800 user manual section 22.5.1.8
593
    #   AIRCR_VECTKEY     = (0x05FA << 8)  // magic number
594
    #   AIRCR_SYSRESETREQ = (1U << 2)      // request reset
595
    #   LPC8xx_SCS->AIRCR = (AIRCR_VECTKEY << 8) | AIRCR_SYSRESETREQ;
596
597
    data = []
598
    append_uint16_le(data,0x4a01)     # 00: ldr r0, [pc, #4]   ; r0 = [08]
599
    append_uint16_le(data,0x4b02)     # 02: ldr r1, [pc, #8]   ; r0 = [0c]
600
    append_uint16_le(data,0x601a)     # 04: str r0, [r1]       ; write
601
    append_uint16_le(data,0xe7fe)     # 06: b   .              ; dummy failsafe loop
602
    append_uint32_le(data,0xe000ed0c) # 08: .word  0x05fa0004 ; (VECTKEY << 8) | SYSRESETREQ
603
    append_uint32_le(data,0x05fa0004) # 0c: .word  0xe000ed0c ; &(LPC8xx_SCS->AIRCR)
604
605
    Cmd_W(0x10000000, bytearray(data))
606
    unlock();
607
    Cmd_G(0x10000000)
608
609
#-------------------------------------------------------------------------------
610
if __name__ == '__main__':
611
    parser = argparse.ArgumentParser()
612
    parser.add_argument("-p", dest="port", default="/dev/ttyUSB0", help="serial/USB port, default is /dev/ttyUSB0")
613
    parser.add_argument('--verbose', '-v', default=0, action='count', help="verbosity level, -v or -vv or -vvv ...")
614
    parser.add_argument("--reset", '-r',  action='store_true', help="reset target")
615
    parser.add_argument("--dump",  action='store_true', help="dump Flash and RAM")
616
    parser.add_argument("image", nargs="?", type=argparse.FileType('rt'), help="image to flash")
617
618
    args = parser.parse_args()
619
    if (args.verbose > 0):
620
        print(args)
621
    
622
    try:
623
        ser = serial.Serial(args.port, 
624
                            baudrate=115200, bytesize=8, parity='N', stopbits=1, 
625
                            timeout=10, xonxoff=0, rtscts=0)
626
    except serial.serialutil.SerialException as e:
627
        print("Error: %s"%e)
628
        quit()
629
    except:
630
        print("Error: %s"%sys.exc_info()[0])
631
        quit()
632
633
    init()
634
    checkIfSupportedCotroller()
635
    printInfo()
636
637
    if (args.dump):
638
        print("RAM dump (first 0x80 survive reset):")
639
        data = Cmd_R(0x10000000, 0x400)
640
        hexdump(data,"  ")
641
        print("Flash dump:")
642
        data = Cmd_R(0x00000000, 0x1000)
643
        print("  Image checksum at 0x%08x: 0x%08x"%(ADDR_CHECKSUM,get_uint32_le(data,ADDR_CHECKSUM)))
644
        print("  CRP            at 0x%08x: 0x%08x"%(ADDR_CRP,get_uint32_le(data,ADDR_CRP)))
645
        hexdump(data,"  ")
646
    #else:
647
    #    print("RAM dump of contents surviving a reset:")
648
    #    data = Cmd_R(0x10000000, 80)
649
    #    hexdump(data,"  ")
650
651
    if (args.image):
652
        flash(args.image)
653
654
    if (args.reset):
655
        systemReset()