comparison python/stm32.py @ 130:654093a9a1e3

Added icons, improved device explorer
author Windel Bouwman
date Sat, 19 Jan 2013 18:16:04 +0100
parents 9e350a7dde98
children 04e45faafd1d
comparison
equal deleted inserted replaced
129:9e350a7dde98 130:654093a9a1e3
2 from devices import Device, registerDevice, STLinkException, Interface 2 from devices import Device, registerDevice, STLinkException, Interface
3 3
4 # F4 specifics: 4 # F4 specifics:
5 STM32_FLASH_BASE = 0x08000000 5 STM32_FLASH_BASE = 0x08000000
6 STM32_SRAM_BASE = 0x20000000 6 STM32_SRAM_BASE = 0x20000000
7
8 FLASH_KEY1 = 0x45670123
9 FLASH_KEY2 = 0xcdef89ab
10 7
11 # flash registers: 8 # flash registers:
12 FLASH_F4_REGS_ADDR = 0x40023c00 9 FLASH_F4_REGS_ADDR = 0x40023c00
13 FLASH_F4_KEYR = FLASH_F4_REGS_ADDR + 0x04 10 FLASH_F4_KEYR = FLASH_F4_REGS_ADDR + 0x04
14 FLASH_F4_SR = FLASH_F4_REGS_ADDR + 0x0c 11 FLASH_F4_SR = FLASH_F4_REGS_ADDR + 0x0c
21 FLASH_CR_MER = 2 18 FLASH_CR_MER = 2
22 FLASH_F4_CR_SNB = 3 19 FLASH_F4_CR_SNB = 3
23 FLASH_F4_CR_SNB_MASK = 0x38 20 FLASH_F4_CR_SNB_MASK = 0x38
24 FLASH_F4_SR_BSY = 16 21 FLASH_F4_SR_BSY = 16
25 22
26 def calculate_F4_sector(address):
27 """
28 from 0x8000000 to 0x80FFFFF
29 4 sectors of 0x4000 (16 kB)
30 1 sector of 0x10000 (64 kB)
31 7 of 0x20000 (128 kB)
32 """
33 sectorsizes = [0x4000] * 4 + [0x10000] + [0x20000] * 7
34 sectorstarts = []
35 a = STM32_FLASH_BASE
36 for sectorsize in sectorsizes:
37 sectorstarts.append(a)
38 a += sectorsize
39 # linear search:
40 sec = 0
41 while sec < len(sectorsizes) and address >= sectorstarts[sec]:
42 sec += 1
43 sec -= 1 # one back.
44 return sec, sectorsizes[sec]
45
46 def calcSectors(address, size):
47 off = 0
48 sectors = []
49 while off < size:
50 sectornum, sectorsize = calculate_F4_sector(address + off)
51 sectors.append((sectornum, sectorsize))
52 off += sectorsize
53 return sectors
54
55 @registerDevice(0x10016413) 23 @registerDevice(0x10016413)
56 class Stm32F4(Device): 24 class Stm32F4(Device):
25 """
26 Implementation of the specifics of the STM32F4xx device series.
27 """
57 def __init__(self, iface): 28 def __init__(self, iface):
58 super().__init__(iface) 29 super().__init__(iface)
30 # Assert the proper size for this device:
31 assert self.FlashSize == 0x100000
32 """
33 from 0x8000000 to 0x80FFFFF
34 4 sectors of 0x4000 (16 kB)
35 1 sector of 0x10000 (64 kB)
36 7 of 0x20000 (128 kB)
37 """
38 self.sectorsizes = [0x4000] * 4 + [0x10000] + [0x20000] * 7
59 def __str__(self): 39 def __str__(self):
60 return 'STM32F4 device' 40 return 'STM32F4 device size=0x{1:X} id=0x{0:X}'.format(\
41 self.UID, self.FlashSize)
42 def calculate_F4_sector(self, address):
43 sectorstarts = []
44 a = STM32_FLASH_BASE
45 for sectorsize in self.sectorsizes:
46 sectorstarts.append(a)
47 a += sectorsize
48 # linear search:
49 sec = 0
50 while sec < len(self.sectorsizes) and address >= sectorstarts[sec]:
51 sec += 1
52 sec -= 1 # one back.
53 return sec, self.sectorsizes[sec]
54
55 def calcSectors(self, address, size):
56 off = 0
57 sectors = []
58 while off < size:
59 sectornum, sectorsize = self.calculate_F4_sector(address + off)
60 sectors.append((sectornum, sectorsize))
61 off += sectorsize
62 return sectors
63 # Device registers:
64 @property
65 def UID(self):
66 uid_base = 0x1FFF7A10
67 uid1 = self.iface.read_debug32(uid_base)
68 uid2 = self.iface.read_debug32(uid_base + 0x4)
69 uid3 = self.iface.read_debug32(uid_base + 0x8)
70 return (uid3 << 64) | (uid2 << 32) | uid1
71 @property
72 def FlashSize(self):
73 f_id = self.iface.read_debug32(0x1FFF7A22)
74 f_id = f_id >> 16
75 return f_id * 1024
61 # flashing commands: 76 # flashing commands:
62 def writeFlash(self, address, content): 77 def writeFlash(self, address, content):
63 # TODO: 78 flashsize = self.FlashSize
64 flashsize = 0x100000 # fixed 1 MB for now.. 79 pagesize = min(self.sectorsizes)
65 print('WARNING: using 1 MB as flash size')
66 pagesize = 0x4000 # fixed for now!
67 print('warning: page size hardcoded')
68 80
69 # Check address range: 81 # Check address range:
70 if address < STM32_FLASH_BASE: 82 if address < STM32_FLASH_BASE:
71 raise STLinkException('Flashing below flash start') 83 raise STLinkException('Flashing below flash start')
72 if address + len(content) > STM32_FLASH_BASE + flashsize: 84 if address + len(content) > STM32_FLASH_BASE + flashsize:
76 if len(content) & 1 == 1: 88 if len(content) & 1 == 1:
77 print('unaligned length, padding with zero') 89 print('unaligned length, padding with zero')
78 content += bytes([0]) 90 content += bytes([0])
79 if address & (pagesize - 1) != 0: 91 if address & (pagesize - 1) != 0:
80 raise STLinkException('Address not aligned with pagesize') 92 raise STLinkException('Address not aligned with pagesize')
81
82 # erase required space 93 # erase required space
83 sectors = calcSectors(address, len(content)) 94 sectors = self.calcSectors(address, len(content))
84 print('erasing {0} sectors'.format(len(sectors))) 95 print('erasing {0} sectors'.format(len(sectors)))
85 for sector, secsize in sectors: 96 for sector, secsize in sectors:
86 print('erasing sector {0} of {1} bytes'.format(sector, secsize)) 97 print('erasing sector {0} of {1} bytes'.format(sector, secsize))
87 self.eraseFlashSector(sector) 98 self.eraseFlashSector(sector)
88
89 # program pages: 99 # program pages:
90 self.unlockFlashIf() 100 self.unlockFlashIf()
91 self.writeFlashCrPsiz(2) # writes are 32 bits aligned 101 self.writeFlashCrPsiz(2) # writes are 32 bits aligned
92 self.setFlashCrPg() 102 self.setFlashCrPg()
93
94 print('writing {0} bytes'.format(len(content)), end='') 103 print('writing {0} bytes'.format(len(content)), end='')
95 offset = 0 104 offset = 0
96 t1 = time.time() 105 t1 = time.time()
97 while offset < len(content): 106 while offset < len(content):
98 size = len(content) - offset 107 size = len(content) - offset
99 if size > 0x8000: 108 if size > 0x8000:
100 size = 0x8000 109 size = 0x8000
101
102 chunk = content[offset:offset + size] 110 chunk = content[offset:offset + size]
103 while len(chunk) % 4 != 0: 111 while len(chunk) % 4 != 0:
104 print('padding chunk')
105 chunk = chunk + bytes([0]) 112 chunk = chunk + bytes([0])
106
107 # Use simple mem32 writes: 113 # Use simple mem32 writes:
108 self.iface.write_mem32(address + offset, chunk) 114 self.iface.write_mem32(address + offset, chunk)
109
110 offset += size 115 offset += size
111 print('.', end='', flush=True) 116 print('.', end='', flush=True)
112 t2 = time.time() 117 t2 = time.time()
113 print('Done!') 118 print('Done!')
114 print('Speed: {0} bytes/second'.format(len(content)/(t2-t1))) 119 print('Speed: {0} bytes/second'.format(len(content)/(t2-t1)))
115
116 self.lockFlash() 120 self.lockFlash()
117
118 # verfify program: 121 # verfify program:
119 self.verifyFlash(address, content) 122 self.verifyFlash(address, content)
120 def eraseFlashSector(self, sector): 123 def eraseFlashSector(self, sector):
121 self.waitFlashBusy() 124 self.waitFlashBusy()
122 self.unlockFlashIf() 125 self.unlockFlashIf()
173 def isFlashLocked(self): 176 def isFlashLocked(self):
174 cr = self.readFlashCr() 177 cr = self.readFlashCr()
175 mask = 1 << FLASH_F4_CR_LOCK 178 mask = 1 << FLASH_F4_CR_LOCK
176 return cr & mask == mask 179 return cr & mask == mask
177 def unlockFlashIf(self): 180 def unlockFlashIf(self):
181 FLASH_KEY1, FLASH_KEY2 = 0x45670123, 0xcdef89ab
178 if self.isFlashLocked(): 182 if self.isFlashLocked():
179 self.iface.write_debug32(FLASH_F4_KEYR, FLASH_KEY1) 183 self.iface.write_debug32(FLASH_F4_KEYR, FLASH_KEY1)
180 self.iface.write_debug32(FLASH_F4_KEYR, FLASH_KEY2) 184 self.iface.write_debug32(FLASH_F4_KEYR, FLASH_KEY2)
181 if self.isFlashLocked(): 185 if self.isFlashLocked():
182 raise STLinkException('Failed to unlock') 186 raise STLinkException('Failed to unlock')
183 def lockFlash(self): 187 def lockFlash(self):
184 x = self.readFlashCr() | (1 << FLASH_F4_CR_LOCK) 188 x = self.readFlashCr() | (1 << FLASH_F4_CR_LOCK)
185 self.writeFlashCr(x) 189 self.writeFlashCr(x)
186
187 def readFlashSr(self): 190 def readFlashSr(self):
188 return self.iface.read_debug32(FLASH_F4_SR) 191 return self.iface.read_debug32(FLASH_F4_SR)
189 def readFlashCr(self): 192 def readFlashCr(self):
190 return self.iface.read_debug32(FLASH_F4_CR) 193 return self.iface.read_debug32(FLASH_F4_CR)
191 def writeFlashCr(self, x): 194 def writeFlashCr(self, x):