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)
525 BLOCK_SIZE = 4 * BLOCK_DWORDS
526 def at91x40_cli_handler(client, argv):
528 if(argv[1]=="chipRegStr"):
531 print client.getChipSelectRegstr(int(argv[2]))
535 if(argv[1]=="chipRegList"):
538 print client.getChipSelectReglist(int(argv[2]))
542 if(argv[1]=="chipRegValue"):
545 print "Chip Register Value:",hex(client.getChipSelectReg(int(argv[2])))
548 if(argv[1]=="ecdump"):
553 start=int(argv[3],16)
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:
569 # Chip IDCODE: 0x1f0f0f0f
574 # Debug Status: Interrupts Enabled (or not?)
577 # Chip Register Value: 0x10000000
579 ##############################
581 special_addr=0x010000000
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)
588 print "Dumping from %04x to %04x as %s." % (start,stop,f)
589 # FIXME: get mcu state and return it to that state
601 data=client.ARMreadChunk(i, BLOCK_DWORDS, verbose=0)
602 print "Dumped %06x."%i
604 if i<=stop:# and dword != 0xdeadbeef:
605 h.puts( i, struct.pack("<I", dword) )
611 # FIXME: get mcu state and return it to that state
613 # Handle exceptions by counting errors after pausing to let ARM settle
619 print "Unknown error occurred at least 100 times. Resync did not work. Writing incomplete data to file."
624 print "Unknown error during read. Resync and retry."
625 err_list.append("0x%06x"%i)
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):
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):
640 print " Resetting Target"
641 client.ARMresettarget(1000)
646 #Resync ARM and Watch Dog
657 # we've confirmed the write on this block... move on.
661 print "Addresses that required resync:"
671 print "error resuming... resetting"
673 client.ARMresettarget()
675 print "error resetting! just exiting"
679 if(argv[1]=="memorymap"):
681 print "=============================================="
682 print client.getEBIMCRstr()
684 print client.getEBIMemoryMapstr()
687 if(argv[1]=="memorycontrolreg"):
689 print client.getEBIMCRstr()
694 if(argv[1]=="stat_watchdog"):
696 print "Watch Dog Status:"
698 client.statWatchDog()
701 if(argv[1]=="test_disable_watchdog"):
703 print "Status Watch Dog:"
704 client.statWatchDog()
706 print "Disabling Watchdog Timer:"
707 client.disableWatchDog()
708 time.sleep(2) # pause to settle
710 client.statWatchDog()
712 print "Done. Resume may re-enable Watch Dog."
715 # anything we didn't provide from arm7:
716 arm7_cli_handler(client, argv)
718 #client.ARMreleasecpu()
722 if __name__ == "__main__":
723 if(len(sys.argv)==1):