added parsing abilities to sniff as well as improvements to the simpleGUI
[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 def at91x40_cli_handler(client, argv):
523
524     if(argv[1]=="chipRegStr"):
525         client.halt()
526         print "#####"
527         print client.getChipSelectRegstr(int(argv[2]))
528         print "#####"
529         client.resume()
530
531     if(argv[1]=="chipRegList"):
532         client.halt()
533         print "#####"
534         print client.getChipSelectReglist(int(argv[2]))
535         print "#####"
536         client.resume()
537
538     if(argv[1]=="chipRegValue"):
539         client.halt()
540         print "#####"
541         print "Chip Register Value:",hex(client.getChipSelectReg(int(argv[2])))
542         print "#####"
543
544     if(argv[1]=="ecdump"):
545         f = argv[2]
546         start=0x00000000
547         stop=0xFFFFFFFF
548         if(len(argv)>3):
549             start=int(argv[3],16)
550         if(len(argv)>4):
551             stop=int(argv[4],16)
552
553         ##############################3
554         # Error checking requires a special register
555         # Should an error occur while reading from the chip's memory
556         # These values will help to test if the chip is working and 
557         # the memory is mapped properly before continuing
558         # Use the chipRegStr verb to determine the value of the 
559         # Special Register when the chip is operating normally
560         # Example: ./goodfet.at91x40 chipRegValue 1
561         ##############################3
562         # user$ ./goodfet.at91x40 chipRegValue 1
563         # Identifying Target:
564         # # DEBUG 0x120
565         # Chip IDCODE: 0x1f0f0f0f
566         #     ver: 1
567         #     partno: f0f0
568         #     mfgid: 787
569         #
570         # Debug Status:   Interrupts Enabled (or not?) 
571         #
572         # #####
573         # Chip Register Value: 0x10000000
574         # #####
575         ##############################
576         special_reg_num=1
577         special_addr=0x010000000
578         if(len(argv)>5):
579             # Yes, this requires that you set the start and stop addresses
580             special_reg_num=int(argv[5])
581             special_addr=int(argv[6],16)
582         err_list = []
583         
584         print "Dumping from %04x to %04x as %s." % (start,stop,f)
585         # FIXME: get mcu state and return it to that state
586         client.halt()
587
588         h = IntelHex(None)
589         i=start
590         err_cnt = 0
591         reset_cnt = 0
592         while i<=stop:
593             try:
594                 data=client.ARMreadChunk(i, 48, verbose=0)
595                 print "Dumped %06x."%i
596                 for dword in data:
597                     if i<=stop and dword != 0xdeadbeef:
598                         h.puts( i, struct.pack("<I", dword) )
599                         err_cnt = 0
600                     i+=4
601             # FIXME: get mcu state and return it to that state
602             except:
603                 # Handle exceptions by counting errors after pausing to let ARM settle
604                 err_cnt = 1
605                 fail = 0
606                 while err_cnt:
607                     time.sleep(.25)
608                     if err_cnt == 100:
609                         print "Unknown error occurred at least 100 times. Resync did not work. Writing incomplete data to file."
610                         fail = 1
611                         break
612                     else:
613                         try:
614                             print "Unknown error during read. Resync and retry."
615                             err_list.append("0x%06x"%i)
616
617                             # If we error out several times then reset the chip and restart
618                             # This uses a special register value from a Chip Select Register
619                             # to test that the chip is in the operation state we expect
620                             if not ((err_cnt+1) % 2):
621                                 while True:
622                                     print "    Reset:",reset_cnt
623                                     check_addr = client.getChipSelectReg(special_reg_num)
624                                     print "    Special Addr:",hex(special_addr)
625                                     print "    Check Addr:",hex(check_addr)
626                                     if (special_addr == check_addr):
627                                         break
628                                     if reset_cnt == 10:
629                                         reset_cnt = 0
630                                         print "    Resetting Target"
631                                         client.ARMresettarget(1000)
632                                         client.halt()
633                                     reset_cnt += 1
634                                     time.sleep(.25)
635                             else:
636                                 #Resync ARM and Watch Dog
637                                 client.resume()
638                                 client.halt()
639
640                             err_cnt = 0
641                         except:
642                             err_cnt += 1
643                             pass
644                 if fail:
645                     break
646
647         client.resume()
648         h.write_hex_file(f)
649         print "Addresses that required resync:"
650         if err_list:
651             for e in err_list:
652                 print "   ",e
653         else:
654             print "   None"
655
656
657
658     if(argv[1]=="memorymap"):
659         client.halt()
660         print "=============================================="
661         print client.getEBIMCRstr()
662         print ""
663         print client.getEBIMemoryMapstr()
664         client.resume()
665
666     if(argv[1]=="memorycontrolreg"):
667         client.halt()
668         print client.getEBIMCRstr()
669         client.resume()
670
671
672
673     if(argv[1]=="stat_watchdog"):
674         client.halt()
675         print "Watch Dog Status:"
676         print "--"
677         client.statWatchDog()
678         client.resume()
679
680     if(argv[1]=="test_disable_watchdog"):
681         client.halt()
682         print "Status Watch Dog:"
683         client.statWatchDog()
684         print "--"
685         print "Disabling Watchdog Timer:"
686         client.disableWatchDog()
687         time.sleep(2) # pause to settle
688         print "\nChecking:"
689         client.statWatchDog()
690         print "--"
691         print "Done. Resume may re-enable Watch Dog."
692         client.resume()
693
694     # anything we didn't provide from arm7:        
695     arm7_cli_handler(client, argv)
696
697     #client.ARMreleasecpu()
698     #client.ARMstop()
699
700
701 if __name__ == "__main__":
702     if(len(sys.argv)==1):
703         at91x40_syntax()
704
705     else: 
706         at91x40_main()
707
708