added packet fuzzing
[goodfet] / client / GoodFETAT91X40.py
1 from GoodFETARM7 import *
2 import ATMEL_USART as usart
3 """
4 This is the ARM7 series of microcontrollers from Atmel, including:
5 * AT91M40800
6 * AT91R40807
7 * AT91M40807
8 * AT91R40008
9
10 """
11 ##### FLASH UPLOADER CODE
12 EBI_BASE =       0xFFE00000
13 EBI_OFF_CSR0 =   0x0
14 EBI_OFF_CSR1 =   0x4
15 EBI_OFF_CSR2 =   0x8
16 EBI_OFF_CSR3 =   0xc
17 EBI_OFF_CSR4 =   0x10
18 EBI_OFF_CSR5 =   0x14
19 EBI_OFF_CSR6 =   0x18
20 EBI_OFF_CSR7 =   0x1c
21 EBI_CSR0_MASK =  0xFFFF0000
22 EBI_OFF_RCR =    0x20
23 EBI_OFF_MCR =    0x24
24
25 EBI_CSR0 =      EBI_BASE + EBI_OFF_CSR0
26 EBI_CSR1 =      EBI_BASE + EBI_OFF_CSR1
27 EBI_CSR2 =      EBI_BASE + EBI_OFF_CSR2
28 EBI_CSR3 =      EBI_BASE + EBI_OFF_CSR3
29 EBI_CSR4 =      EBI_BASE + EBI_OFF_CSR4
30 EBI_CSR5 =      EBI_BASE + EBI_OFF_CSR5
31 EBI_CSR6 =      EBI_BASE + EBI_OFF_CSR6
32 EBI_CSR7 =      EBI_BASE + EBI_OFF_CSR7
33 EBI_MCR =       EBI_BASE + EBI_OFF_MCR
34
35 REMAP_CMD =      0x00000001
36 MEM_CTRL_VAL =   0x00000006
37
38
39 SF_CHIP_ID =     0xFFF00000         # AT91R40 series, not sure on others
40 SF_CIDR_MASK =   0x0FFFFF00
41
42 PS_BASE =        0xFFFF4000
43 PS_CR =          PS_BASE
44 PS_PCER =        PS_BASE + 0x4
45 PS_PCDR =        PS_BASE + 0x8
46 PS_PCSR =        PS_BASE + 0xC
47 PS_US0 =         1<<2
48 PS_US1 =         1<<3
49 PS_TC0 =         1<<4
50 PS_TC1 =         1<<5
51 PS_TC2 =         1<<6
52 PS_PIO =         1<<8
53
54 AIC_INT_SOURCES = (
55         ("FIQ","Fast Interrupt"),
56         ("SWIRQ","Software Interrupt"),
57         ("US0IRQ","USART Channel 0 Interrupt"),
58         ("US1IRQ","USART Channel 1 Interrupt"),
59         ("TC0IRQ","Timer Channel 0 Interrupt"),
60         ("TC1IRQ","Timer Channel 1 Interrupt"),
61         ("TC2IRQ","Timer Channel 2 Interrupt"),
62         ("WDIRQ", "Watchdog Interrupt"),
63         ("PIOIRQ","Parallel I/O Controller Interrupt"),
64         (None,None),
65         (None,None),
66         (None,None),
67         (None,None),
68         (None,None),
69         (None,None),
70         (None,None),
71         ("IRQ0","External Interrupt 0"),
72         ("IRQ1","External Interrupt 0"),
73         ("IRQ0","External Interrupt 0"),
74         (None,None),
75         (None,None),
76         (None,None),
77         (None,None),
78         (None,None),
79         (None,None),
80         (None,None),
81         (None,None),
82         (None,None),
83         (None,None),
84         (None,None),
85         (None,None),
86         (None,None),
87         )
88
89 def aic_smr_decode(smr):
90     output = ["Interrupt Priority: %s"%(smr&7),
91             "Interrupt Source Type: %s"%("Low Level Sensitive","Negative Edge Triggered","High Level Sensitive","Positive Edge Triggered")[(smr>>5)],
92             ]
93     return "\n".join(output)
94
95 AIC_BASE = 0xFFFFF000
96 AIC_SMR = [(AIC_BASE+(x*4), "Source Mode Register %d"%x)  for x in xrange(32)]
97 AIC_SVR = [(AIC_BASE+0x80+(x*4), "Source Vector Register %d"%x)  for x in xrange(32)]
98 AIC_IVR = AIC_BASE + 0x100
99 AIC_FVR = AIC_BASE + 0x104
100 AIC_ISR = AIC_BASE + 0x108
101 AIC_IPR = AIC_BASE + 0x10c
102 AIC_IMR = AIC_BASE + 0x110
103 AIC_CISR = AIC_BASE + 0x114
104 AIC_IECR = AIC_BASE + 0x120
105 AIC_IDCR = AIC_BASE + 0x124
106 AIC_ICCR = AIC_BASE + 0x128
107 AIC_ISCR = AIC_BASE + 0x12c
108 AIC_EOICR = AIC_BASE + 0x130
109 AIC_SPU = AIC_BASE + 0x134
110
111
112 PIO_BASE = 0xFFFF0000
113 PIO_PER =   PIO_BASE + 0x0
114 PIO_PDR =   PIO_BASE + 0x4
115 PIO_PSR =   PIO_BASE + 0x8
116 PIO_OER =   PIO_BASE + 0x10
117 PIO_ODR =   PIO_BASE + 0x14
118 PIO_OSR =   PIO_BASE + 0x18
119 PIO_SODR =  PIO_BASE + 0x30
120 PIO_CODR =  PIO_BASE + 0x34
121 PIO_ODSR =  PIO_BASE + 0x38
122 PIO_CDSR =  PIO_BASE + 0x3c
123 PIO_IER =   PIO_BASE + 0x40
124 PIO_IDR =   PIO_BASE + 0x44
125 PIO_IMR =   PIO_BASE + 0x48
126 PIO_ISR =   PIO_BASE + 0x4c
127
128 WD_BASE = 0xFFFF8000
129 WD_OMR  =   WD_BASE + 0x0
130 WD_CMR  =   WD_BASE + 0x4
131 WD_CR   =   WD_BASE + 0x8
132 WD_SR   =   WD_BASE + 0xc
133
134 SF_BASE = 0xFFF00000
135 SF_CIDR =   SF_BASE + 0x0
136 SF_EXID =   SF_BASE + 0x4
137 SF_RSR =    SF_BASE + 0x8
138 SF_MMR =    SF_BASE + 0xC
139 SF_PMR =    SF_BASE + 0x18
140
141 #* Flash
142 FLASH_BASE_ADDR =    0x1000000
143 WAIT =               300000
144 FLASH_CODE_MASK =    0x000000FF
145
146 #*Flash AT49 codes
147 ATMEL_MANUFACTURED =         0x001F
148 FLASH_AT49BV_UNKNOW =        0xFFFF
149 FLASH_AT49BV8011 =           0x00CB
150 FLASH_AT49BV8011T =          0x004A
151 FLASH_AT49BV16x4 =           0x00C0
152 FLASH_AT49BV16x4T =          0x00C2
153
154 #*Flash AT29 codes
155 FLASH_AT29LV1024 =               0X26
156 FLASH_AT29C020 =                 0XDA
157
158 #* Flash Program information
159 FLASH_PRG_SIZE =     0x800   #* 2Kbytes
160 FLASH_PRG_DEST =     0x20    #* Address on the target
161 START_PRG =          0x20
162
163 #* Parameter for Flash_XV_Send_Data functions
164 ERASE =  1
165 PROGRAM =0
166
167 MIRROR =     1
168 NO_MIRROR =  0
169
170 ERASE_DATA = 0
171
172 #* Load program parameters
173 NB_REG =     13
174 SIZE_DATA =  4
175
176 #* Flash LV Send Data parameters
177 SIZE_256_BYTES = 0x100
178 PACKET_SIZE =64
179
180 NB_PRG =     3
181
182 #* Periph
183 EBI =    0
184 PLL =    1
185
186 #* Targets
187 EB40 =   0x04080700
188 EB40A =  0x04000800
189 EB42 =   0x04280000
190 EB55 =   0x05580000
191 EB63 =   0x06320000
192 EBMASK = 0x0fffff00
193
194 NB_TARGET_SUPPORTED =    6
195
196 #* Flash type
197 FLASH_LV =   0
198 FLASH_BV =   1
199
200 #* Flash Program Address 
201 FLASH_LV_PRG =   0x01018000
202 FLASH_BV_PRG =   0x0101A000
203
204 EBI_READ    = 4
205 EBI_WRITE   = 2
206
207 ebi_memory_map_items = {
208         EBI_OFF_CSR0:("Chip Select Register 0", "EBI_CSR0", EBI_READ|EBI_WRITE,0x0000203e),
209         EBI_OFF_CSR1:("Chip Select Register 1", "EBI_CSR1", EBI_READ|EBI_WRITE,0x10000000),
210         EBI_OFF_CSR2:("Chip Select Register 2", "EBI_CSR2", EBI_READ|EBI_WRITE,0x20000000),
211         EBI_OFF_CSR3:("Chip Select Register 3", "EBI_CSR3", EBI_READ|EBI_WRITE,0x30000000),
212         EBI_OFF_CSR4:("Chip Select Register 4", "EBI_CSR4", EBI_READ|EBI_WRITE,0x40000000),
213         EBI_OFF_CSR5:("Chip Select Register 5", "EBI_CSR5", EBI_READ|EBI_WRITE,0x50000000),
214         EBI_OFF_CSR6:("Chip Select Register 6", "EBI_CSR6", EBI_READ|EBI_WRITE,0x60000000),
215         EBI_OFF_CSR7:("Chip Select Register 7", "EBI_CSR7", EBI_READ|EBI_WRITE,0x70000000),
216         EBI_OFF_MCR: ("Memory Control Register","EBI_MCR",  EBI_READ|EBI_WRITE,0),
217         }
218
219 def ebi_csr_decode(reg):
220     addr = reg>>20
221     csen = (reg>>13)&1
222     bat =  (reg>>12)&1
223     tdf =  (reg>>9)&7
224     pages =(reg>>7)&3
225     wse =  (reg>>5)&1
226     nws =  (reg>>2)&7
227     dbw =  (reg&3)
228     return [ addr, csen, bat, tdf, pages, wse, nws, dbw]
229
230 def ebi_csr_decode_str(reg):
231     (addr,
232     csen,
233     bat,
234     tdf,
235     pages,
236     wse,
237     nws,
238     dbw) = ebi_csr_decode(reg)
239     output = ["(register: %x)"%reg,
240             "Base Address: %s"%hex(addr<<20),
241             "Chip Select: %s"%("False","True")[csen],
242             "Byte Access Type: %s"%("Byte-Write","Byte-Access")[bat],
243             "Data Float Output Time: %d cycles added"%tdf,
244             "Page Size: %d MB"%(1,4,16,64)[pages],
245             "Wait State: %s"%("disabled","enabled")[wse],
246             "Wait States: %d"%nws,
247             "Data Bus Size: %d bits"%(0,16,8,0)[dbw],
248             ]
249     return "\n".join(output)
250
251 mcr_ale = {
252         0: ("A20,A21,A22,A23", 16, "None", "EBI_ALE_16M"),
253         1: ("A20,A21,A22,A23", 16, "None", "EBI_ALE_16M"),
254         2: ("A20,A21,A22,A23", 16, "None", "EBI_ALE_16M"),
255         3: ("A20,A21,A22,A23", 16, "None", "EBI_ALE_16M"),
256         4: ("A20,A21,A22", 8, "CS4", "EBI_ALE_8M"),
257         5: ("A20,A21", 4, "CS4,CS5", "EBI_ALE_4M"),
258         6: ("A20", 2, "CS4,CS5,CS6", "EBI_ALE_2M"),
259         7: ("None", 1, "CS4,CS5,CS6,CS7", "EBI_ALE_1M"),
260         }
261
262 def mcr_decode(mcr):
263     validAddrBits,maxAddrSpace,validCS,codeLabel = mcr_ale[mcr&7]
264     drp = mcr>>4
265     #print hex(drp)
266     if drp and drp != 1:
267         drp = 2
268     return (validAddrBits, maxAddrSpace, validCS, codeLabel, drp)
269
270 def mcr_decode_str(mcr):
271     ( validAddrBits, maxAddrSpace, validCS, codeLabel, drp) = mcr_decode(mcr)
272     output = [ 
273             "(register: %x)"%mcr,
274             "Valid Address Bits: %s"%validAddrBits,
275             "Maximum Address Space: 0x%x MB"%maxAddrSpace,
276             "Valid Chip Select: %s"%validCS,
277             "Code Label:  %s"%codeLabel,
278             ("Standard Read Protocol for all external memory devices enabled (EBI_DRP_STANDARD)","Early Read Protocol for all external memory devices enabled (EBI_DRP_EARLY)","Invalid mcr")[drp]
279             ]
280     return "\n".join(output)
281
282 def wd_omr_decode(omr):
283         return (omr>>4, (omr>>3)&1, (omr>>2)&1, (omr>>1)&1, omr&1)
284
285 def wd_omr_decode_str(omr):
286     ( okey, esig, int, rst, wdog ) = wd_omr_decode(omr)
287     return "\n".join([
288             "Overflow Access Key (OKEY): %x"%(okey),
289             "External Signal (EXTEN): %s"%("disabled","enabled")[esig],
290             "Interrupt (IRQEN): %s"%("disabled","enabled")[int],
291             "Reset (RSTEN): %s"%("disabled","enabled")[rst],
292             "Watch Dog (WDEN): %s"%("disabled","enabled")[wdog],
293             ])
294
295 def wd_cmr_decode(cmr):
296     return "MCK/%d"%(8,32,128,1024)[(cmr>>2)&0xf]
297
298
299
300
301
302 class GoodFETAT91X40(GoodFETARM7):
303     def __init__(self):
304         GoodFETARM7.__init__(self)
305         self.usart0 = usart.USART(usart.USART0_BASE)
306         self.usart1 = usart.USART(usart.USART1_BASE)
307
308     def halt(self, disableWD=True):
309         GoodFETARM7.halt(self)
310         if not disableWD: return
311
312         #Disable Watch Dog
313         self.disableWatchDog()
314
315     def resume(self, enableWD=False):
316         GoodFETARM7.resume(self)
317         if not enableWD: return
318
319         self.enableWatchDog()
320
321     def getChipSelectReg(self, chipnum):
322         addr = EBI_BASE + (chipnum*4)
323         reg, = self.ARMreadChunk(addr,1)
324         return reg
325     def getChipSelectRegstr(self, chipnum):
326         return ebi_csr_decode_str(self.getChipSelectReg(chipnum))
327     def getChipSelectReglist(self, chipnum):
328         return ebi_csr_decode(self.getChipSelectReg(chipnum))
329     def setChipSelectReg(self, chipnum, value):
330         addr = EBI_BASE + (chipnum*4)
331         self.ARMwriteChunk(addr,[value])
332
333     def getEBIMemoryMapstr(self):
334         keys = ebi_memory_map_items.keys()
335         keys.sort()
336         output = [ "===EBI Memory Map==="]
337         for x in xrange(8):
338             desc,name,rw,default = ebi_memory_map_items[x*4]
339             output.append("\nMAP: %s (%s) - default: %x\n%s"%(name,desc,default,self.getChipSelectRegstr(x)))
340         return "\n".join(output)
341     def setRemap(self):
342         self.ARMwriteChunk(EBI_BASE + EBI_OFF_RCR,[REMAP_CMD])
343     def getMemoryControlRegister(self):
344         mcr, = self.ARMreadMem(EBI_MCR)
345         return mcr
346     def getMemoryControlRegisterstr(self):
347         return mcr_decode_str(self.getMemoryControlRegister())
348     def getEBIMCRstr(self):
349         return  "EBI Memory Control Register\n" + self.getMemoryControlRegisterstr()
350
351     def getInterruptSourceModeReg(self, regnum):
352         regval = self.ARMreadMem(AIC_SMR[regnum][0])
353         return retval
354     def getInterruptSourceModeRegstr(self, regnum):
355         return aic_smr_decode(self.getInterruptSourceModeReg(regnum))
356     def setInterruptSourceModeReg(self, regnum, val):
357         self.ARMwriteMem(AIC_SMR[regnum][0], val)
358
359     def getInterruptSourceVectorReg(self, regnum):
360         regval = self.ARMreadMem(AIC_SVR[regnum][0])
361         return retval
362     def setInterruptSourceModeReg(self, regnum, val):
363         self.ARMwriteMem(AIC_SVR[regnum][0], val)
364
365     def getIRQVectorReg(self):
366         return self.ARMreadMem(AIC_IVR)
367     def getFIQVectorReg(self):
368         return self.ARMreadMem(AIC_FVR)
369
370     def getInterruptStatusReg(self):
371         return self.ARMreadMem(AIC_ISR)
372     def getInterruptPendingReg(self):
373         return self.ARMreadMem(AIC_FSR)
374     def getInterruptMaskReg(self):
375         return self.ARMreadMem(AIC_IMR)
376     def getCoreInterruptStatusReg(self):
377         return self.ARMreadMem(AIC_CISR)
378     def enableInterrupt(self, interrupt):
379         self.ARMwriteMem(AIC_IECR, 1<<interrupt)
380     def disableInterrupt(self, interrupt):
381         self.ARMwriteMem(AIC_IDCR, 1<<interrupt)
382     def setInterruptCommandReg(self, interrupt):
383         self.ARMwriteMem(AIC_ISCR, 1<<interrupt)
384     def clearInterruptCommandReg(self, interrupt):
385         self.ARMwriteMem(AIC_ICCR, 1<<interrupt)
386     def clearCurrentInterrupt(self):
387         self.ARMwriteMem(AIC_EOICR, 1<<interrupt)
388     def getSpuriousVectorReg(self):
389         return self.ARMreadMem(AIC_SPU)
390     def setSpuriousVectorReg(self, val):
391         return self.ARMreadMem(AIC_SPU)
392
393     def enablePIOpin(self, mask):
394         self.ARMwriteMem(PIO_PER, mask)
395     def disablePIOpin(self, mask):
396         self.ARMwriteMem(PIO_PDR, mask)
397     def getPIOstatus(self):
398         return self.ARMreadMem(PIO_PSR)
399     def enablePIOoutput(self,mask):
400         self.ARMwriteMem(PIO_OER, mask)
401     def disablePIOoutput(self,mask):
402         self.ARMwriteMem(PIO_ODR, mask)
403     def getPIOoutputStatus(self):
404         return self.ARMreadMem(PIO_OSR)
405
406     def setOutputPin(self,mask):
407         self.ARMwriteMem(PIO_SODR, mask)
408     def clearOutputPin(self,mask):
409         self.ARMwriteMem(PIO_CODR, mask)
410     def getOutputDataStatusReg(self):
411         return self.ARMreadMem(PIO_ODSR)
412     def getPinDataStatusReg(self):
413         return self.ARMreadMem(PIO_PDSR)
414     def enablePIOinterrupt(self, mask):
415         self.ARMwriteMem(PIO_IER, mask)
416     def disablePIOinterrupt(self, mask):
417         self.ARMwriteMem(PIO_IDR, mask)
418     def getPIOinterruptMaskReg(self):
419         return self.ARMreadMem(PIO_IMR)
420     def getPIOinteruptStatusReg(self):
421         return self.ARMreadMem(PIO_ODSR)
422
423
424     def getWatchDogOverflowModeReg(self):
425         return self.ARMreadMem(WD_OMR)
426     def getWatchDogOverflowModeStr(self):
427         return wd_omr_decode_str(self.getWatchDogOverflowModeReg()[0])
428     def setWatchDogOverflowModeReg(self, mode=0x00002340):
429         self.ARMwriteMem(WD_OMR, [mode])
430     def getWatchDogClockModeReg(self):
431         return self.ARMreadMem(WD_CMR)[0]
432     def setWatchDogClockModeReg(self, mode=0x06e):
433         self.ARMwriteMem(WD_CMR, [mode])
434     def setWatchDogControlReg(self, mode=0xC071):
435         self.ARMwriteMem(WD_CR, [mode])
436     def getWatchDogStatusReg(self):
437         return self.ARMreadMem(WD_SR)[0]
438     def disableWatchDog(self):
439         # 0x234 in OKEY enables writing and 0 in lowest nibble disables
440         self.setWatchDogOverflowModeReg()
441     def enableWatchDog(self):
442         # Initialize the WD Clock Mode Register
443         self.setWatchDogClockModeReg(mode=0x0000373c)
444         # Restart the timer
445         self.setWatchDogControlReg(mode=0x0000c071)
446         # Enable the watchdog
447         self.setWatchDogOverflowModeReg(mode=0x00002340)
448     def statWatchDog(self):
449         print "Status Watch Dog:"
450         print "Register Value: 0b%s" % '{0:032b}'.format(self.getWatchDogOverflowModeReg()[0])
451         print self.getWatchDogOverflowModeStr()
452         print "Clock Mode Reg: %x" % self.getWatchDogClockModeReg()
453         print "Status Reg: %x" % self.getWatchDogStatusReg()
454     def checkWatchDog(self):
455         return self.getWatchDogOverflowModeStr()
456         
457
458     def getChipID(self):
459         chipid = self.ARMreadMem(SF_CIDR,1)
460         return chipid[0]
461     def getResetStatusReg(self):
462         return self.ARMreadMem(SF_RSR)
463     def getMemoryModeReg(self):
464         return self.ARMreadMem(SF_MMR)
465     def setMemoryModeReg(self, val=0):
466         self.ARMwriteMem(SF_MMR, val)
467     def getProtectModeReg(self):
468         return self.ARMreadMem(SF_PMR)
469     def setProtectModeReg(self, val=0x27a80000):
470         self.ARMwriteMem(SF_PMR, val)
471
472
473
474
475
476
477
478     def ARMwriteFirmware(self, firmware):
479         self.halt()
480         chipid = self.ARMgetChipID()
481         # FIXME: initialize PLL or EBI
482         self.ARMmassErase(chipid)
483         self.ARMset_regCPSR(PM_svc)   # set supervisor mode
484         # FIXME: download the "flash identifier" program into target RAM
485         self.ARMsetPC(PROGGYBASE)
486         self.release()
487         # get manufacturer crap through DCC (really??  screw this...)
488         self.halt()
489         if (self.ARMget_regCPSR() & PM_svc != PM_svc):
490             raise Exception("No longer in Supervisor mode after firmware upload")
491         # FIXME: download the downloader program into target RAM
492         self.ARMsetPC(PROGGYBASE)
493         self.release()
494         # FIXME: use DCC to upload the new firmware
495
496     def clearFlash(self):
497         pass
498
499     def readPages(self, addr, pagecount, pagesz=(1024*1024)):
500         global pages;
501         pages = []
502         for page in xrange(pagecount):
503             pages.append(self.ARMreadChunk(addr+(pagesz*page), pagesz))
504         return pages
505
506
507 ######### command line stuff #########
508
509 from GoodFETARM7 import *
510
511 def at91x40_main():
512     ''' this function should be called from command line app '''
513     #Initialize FET and set baud rate
514     client=GoodFETAT91X40()
515     client.serInit()
516
517     client.setup()
518     client.start()
519
520     at91x40_cli_handler(client, sys.argv)
521
522
523
524 BLOCK_DWORDS = 48
525 BLOCK_SIZE   = 4 * BLOCK_DWORDS
526 def at91x40_cli_handler(client, argv):
527
528     if(argv[1]=="chipRegStr"):
529         client.halt()
530         print "#####"
531         print client.getChipSelectRegstr(int(argv[2]))
532         print "#####"
533         client.resume()
534
535     if(argv[1]=="chipRegList"):
536         client.halt()
537         print "#####"
538         print client.getChipSelectReglist(int(argv[2]))
539         print "#####"
540         client.resume()
541
542     if(argv[1]=="chipRegValue"):
543         client.halt()
544         print "#####"
545         print "Chip Register Value:",hex(client.getChipSelectReg(int(argv[2])))
546         print "#####"
547
548     if(argv[1]=="ecdump"):
549         f = argv[2]
550         start=0x00000000
551         stop=0xFFFFFFFF
552         if(len(argv)>3):
553             start=int(argv[3],16)
554         if(len(argv)>4):
555             stop=int(argv[4],16)
556
557         ##############################3
558         # Error checking requires a special register
559         # Should an error occur while reading from the chip's memory
560         # These values will help to test if the chip is working and 
561         # the memory is mapped properly before continuing
562         # Use the chipRegStr verb to determine the value of the 
563         # Special Register when the chip is operating normally
564         # Example: ./goodfet.at91x40 chipRegValue 1
565         ##############################3
566         # user$ ./goodfet.at91x40 chipRegValue 1
567         # Identifying Target:
568         # # DEBUG 0x120
569         # Chip IDCODE: 0x1f0f0f0f
570         #     ver: 1
571         #     partno: f0f0
572         #     mfgid: 787
573         #
574         # Debug Status:   Interrupts Enabled (or not?) 
575         #
576         # #####
577         # Chip Register Value: 0x10000000
578         # #####
579         ##############################
580         special_reg_num=1
581         special_addr=0x010000000
582         if(len(argv)>5):
583             # Yes, this requires that you set the start and stop addresses
584             special_reg_num=int(argv[5])
585             special_addr=int(argv[6],16)
586         err_list = []
587         
588         print "Dumping from %04x to %04x as %s." % (start,stop,f)
589         # FIXME: get mcu state and return it to that state
590         client.halt()
591
592         h = IntelHex(None)
593         base = start
594         err_cnt = 0
595         reset_cnt = 0
596         while base<=stop:
597             confirmed = False
598             while not confirmed: 
599                 i = base
600                 try:
601                     data=client.ARMreadChunk(i, BLOCK_DWORDS, verbose=0)
602                     print "Dumped %06x."%i
603                     for dword in data:
604                         if i<=stop:# and dword != 0xdeadbeef:
605                             h.puts( i, struct.pack("<I", dword) )
606                             err_cnt = 0
607                         i += 4
608
609                     confirmed=True
610
611                 # FIXME: get mcu state and return it to that state
612                 except:
613                     # Handle exceptions by counting errors after pausing to let ARM settle
614                     err_cnt = 1
615                     fail = 0
616                     while err_cnt:
617                         time.sleep(.25)
618                         if err_cnt == 100:
619                             print "Unknown error occurred at least 100 times. Resync did not work. Writing incomplete data to file."
620                             fail = 1
621                             break
622                         else:
623                             try:
624                                 print "Unknown error during read. Resync and retry."
625                                 err_list.append("0x%06x"%i)
626
627                                 # If we error out several times then reset the chip and restart
628                                 # This uses a special register value from a Chip Select Register
629                                 # to test that the chip is in the operation state we expect
630                                 if not ((err_cnt+1) % 2):
631                                     while True:
632                                         print "    Reset:",reset_cnt
633                                         check_addr = client.getChipSelectReg(special_reg_num)
634                                         print "    Special Addr:",hex(special_addr)
635                                         print "    Check Addr:",hex(check_addr)
636                                         if (special_addr == check_addr):
637                                             break
638                                         if reset_cnt == 10:
639                                             reset_cnt = 0
640                                             print "    Resetting Target"
641                                             client.ARMresettarget(1000)
642                                             client.halt()
643                                         reset_cnt += 1
644                                         time.sleep(.25)
645                                 else:
646                                     #Resync ARM and Watch Dog
647                                     client.resume()
648                                     client.halt()
649
650                                 err_cnt = 0
651                             except:
652                                 err_cnt += 1
653                                 pass
654                     if fail:
655                         break
656
657             # we've confirmed the write on this block... move on.
658             base += BLOCK_SIZE
659
660         h.write_hex_file(f)
661         print "Addresses that required resync:"
662         if err_list:
663             for e in err_list:
664                 print "   ",e
665         else:
666             print "   None"
667
668         try:
669             client.resume()
670         except:
671             print "error resuming...  resetting"
672             try:
673                 client.ARMresettarget()
674             except:
675                 print "error resetting!  just exiting"
676
677
678
679     if(argv[1]=="memorymap"):
680         client.halt()
681         print "=============================================="
682         print client.getEBIMCRstr()
683         print ""
684         print client.getEBIMemoryMapstr()
685         client.resume()
686
687     if(argv[1]=="memorycontrolreg"):
688         client.halt()
689         print client.getEBIMCRstr()
690         client.resume()
691
692
693
694     if(argv[1]=="stat_watchdog"):
695         client.halt()
696         print "Watch Dog Status:"
697         print "--"
698         client.statWatchDog()
699         client.resume()
700
701     if(argv[1]=="test_disable_watchdog"):
702         client.halt()
703         print "Status Watch Dog:"
704         client.statWatchDog()
705         print "--"
706         print "Disabling Watchdog Timer:"
707         client.disableWatchDog()
708         time.sleep(2) # pause to settle
709         print "\nChecking:"
710         client.statWatchDog()
711         print "--"
712         print "Done. Resume may re-enable Watch Dog."
713         client.resume()
714
715     # anything we didn't provide from arm7:        
716     arm7_cli_handler(client, argv)
717
718     #client.ARMreleasecpu()
719     #client.ARMstop()
720
721
722 if __name__ == "__main__":
723     if(len(sys.argv)==1):
724         at91x40_syntax()
725
726     else: 
727         at91x40_main()
728
729