1 from GoodFETARM7 import *
2 import ATMEL_USART as usart
4 This is the ARM7 series of microcontrollers from Atmel, including:
11 ##### FLASH UPLOADER CODE
21 EBI_CSR0_MASK = 0xFFFF0000
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
35 REMAP_CMD = 0x00000001
36 MEM_CTRL_VAL = 0x00000006
39 SF_CHIP_ID = 0xFFF00000 # AT91R40 series, not sure on others
40 SF_CIDR_MASK = 0x0FFFFF00
44 PS_PCER = PS_BASE + 0x4
45 PS_PCDR = PS_BASE + 0x8
46 PS_PCSR = PS_BASE + 0xC
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"),
71 ("IRQ0","External Interrupt 0"),
72 ("IRQ1","External Interrupt 0"),
73 ("IRQ0","External Interrupt 0"),
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)],
93 return "\n".join(output)
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
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
129 WD_OMR = WD_BASE + 0x0
130 WD_CMR = WD_BASE + 0x4
131 WD_CR = WD_BASE + 0x8
132 WD_SR = WD_BASE + 0xc
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
142 FLASH_BASE_ADDR = 0x1000000
144 FLASH_CODE_MASK = 0x000000FF
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
155 FLASH_AT29LV1024 = 0X26
156 FLASH_AT29C020 = 0XDA
158 #* Flash Program information
159 FLASH_PRG_SIZE = 0x800 #* 2Kbytes
160 FLASH_PRG_DEST = 0x20 #* Address on the target
163 #* Parameter for Flash_XV_Send_Data functions
172 #* Load program parameters
176 #* Flash LV Send Data parameters
177 SIZE_256_BYTES = 0x100
194 NB_TARGET_SUPPORTED = 6
200 #* Flash Program Address
201 FLASH_LV_PRG = 0x01018000
202 FLASH_BV_PRG = 0x0101A000
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),
219 def ebi_csr_decode(reg):
228 return [ addr, csen, bat, tdf, pages, wse, nws, dbw]
230 def ebi_csr_decode_str(reg):
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],
249 return "\n".join(output)
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"),
263 validAddrBits,maxAddrSpace,validCS,codeLabel = mcr_ale[mcr&7]
268 return (validAddrBits, maxAddrSpace, validCS, codeLabel, drp)
270 def mcr_decode_str(mcr):
271 ( validAddrBits, maxAddrSpace, validCS, codeLabel, drp) = mcr_decode(mcr)
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]
280 return "\n".join(output)
282 def wd_omr_decode(omr):
283 return (omr>>4, (omr>>3)&1, (omr>>2)&1, (omr>>1)&1, omr&1)
285 def wd_omr_decode_str(omr):
286 ( okey, esig, int, rst, wdog ) = wd_omr_decode(omr)
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],
295 def wd_cmr_decode(cmr):
296 return "MCK/%d"%(8,32,128,1024)[(cmr>>2)&0xf]
302 class GoodFETAT91X40(GoodFETARM7):
304 GoodFETARM7.__init__(self)
305 self.usart0 = usart.USART(usart.USART0_BASE)
306 self.usart1 = usart.USART(usart.USART1_BASE)
308 def halt(self, disableWD=True):
309 GoodFETARM7.halt(self)
310 if not disableWD: return
313 self.disableWatchDog()
315 def resume(self, enableWD=False):
316 GoodFETARM7.resume(self)
317 if not enableWD: return
319 self.enableWatchDog()
321 def getChipSelectReg(self, chipnum):
322 addr = EBI_BASE + (chipnum*4)
323 reg, = self.ARMreadChunk(addr,1)
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])
333 def getEBIMemoryMapstr(self):
334 keys = ebi_memory_map_items.keys()
336 output = [ "===EBI Memory Map==="]
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)
342 self.ARMwriteChunk(EBI_BASE + EBI_OFF_RCR,[REMAP_CMD])
343 def getMemoryControlRegister(self):
344 mcr, = self.ARMreadMem(EBI_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()
351 def getInterruptSourceModeReg(self, regnum):
352 regval = self.ARMreadMem(AIC_SMR[regnum][0])
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)
359 def getInterruptSourceVectorReg(self, regnum):
360 regval = self.ARMreadMem(AIC_SVR[regnum][0])
362 def setInterruptSourceModeReg(self, regnum, val):
363 self.ARMwriteMem(AIC_SVR[regnum][0], val)
365 def getIRQVectorReg(self):
366 return self.ARMreadMem(AIC_IVR)
367 def getFIQVectorReg(self):
368 return self.ARMreadMem(AIC_FVR)
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)
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)
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)
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)
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()
459 chipid = self.ARMreadMem(SF_CIDR,1)
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)
478 def ARMwriteFirmware(self, firmware):
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)
487 # get manufacturer crap through DCC (really?? screw this...)
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)
494 # FIXME: use DCC to upload the new firmware
496 def clearFlash(self):
499 def readPages(self, addr, pagecount, pagesz=(1024*1024)):
502 for page in xrange(pagecount):
503 pages.append(self.ARMreadChunk(addr+(pagesz*page), pagesz))
507 ######### command line stuff #########
509 from GoodFETARM7 import *
512 ''' this function should be called from command line app '''
513 #Initialize FET and set baud rate
514 client=GoodFETAT91X40()
520 at91x40_cli_handler(client, sys.argv)
522 def at91x40_cli_handler(client, argv):
524 if(argv[1]=="chipRegStr"):
527 print client.getChipSelectRegstr(int(argv[2]))
531 if(argv[1]=="chipRegList"):
534 print client.getChipSelectReglist(int(argv[2]))
538 if(argv[1]=="chipRegValue"):
541 print "Chip Register Value:",hex(client.getChipSelectReg(int(argv[2])))
544 if(argv[1]=="ecdump"):
549 start=int(argv[3],16)
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:
565 # Chip IDCODE: 0x1f0f0f0f
570 # Debug Status: Interrupts Enabled (or not?)
573 # Chip Register Value: 0x10000000
575 ##############################
577 special_addr=0x010000000
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)
584 print "Dumping from %04x to %04x as %s." % (start,stop,f)
585 # FIXME: get mcu state and return it to that state
594 data=client.ARMreadChunk(i, 48, verbose=0)
595 print "Dumped %06x."%i
597 if i<=stop and dword != 0xdeadbeef:
598 h.puts( i, struct.pack("<I", dword) )
601 # FIXME: get mcu state and return it to that state
603 # Handle exceptions by counting errors after pausing to let ARM settle
609 print "Unknown error occurred at least 100 times. Resync did not work. Writing incomplete data to file."
614 print "Unknown error during read. Resync and retry."
615 err_list.append("0x%06x"%i)
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):
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):
630 print " Resetting Target"
631 client.ARMresettarget(1000)
636 #Resync ARM and Watch Dog
649 print "Addresses that required resync:"
658 if(argv[1]=="memorymap"):
660 print "=============================================="
661 print client.getEBIMCRstr()
663 print client.getEBIMemoryMapstr()
666 if(argv[1]=="memorycontrolreg"):
668 print client.getEBIMCRstr()
673 if(argv[1]=="stat_watchdog"):
675 print "Watch Dog Status:"
677 client.statWatchDog()
680 if(argv[1]=="test_disable_watchdog"):
682 print "Status Watch Dog:"
683 client.statWatchDog()
685 print "Disabling Watchdog Timer:"
686 client.disableWatchDog()
687 time.sleep(2) # pause to settle
689 client.statWatchDog()
691 print "Done. Resume may re-enable Watch Dog."
694 # anything we didn't provide from arm7:
695 arm7_cli_handler(client, argv)
697 #client.ARMreleasecpu()
701 if __name__ == "__main__":
702 if(len(sys.argv)==1):