comparison python/stm32.py @ 260:b2f94b4951f1

Nice-up
author Windel Bouwman
date Tue, 06 Aug 2013 18:29:53 +0200
parents 225f444019b1
children bd2593de3ff8
comparison
equal deleted inserted replaced
259:ac603eb66b63 260:b2f94b4951f1
21 FLASH_F4_CR_SNB = 3 21 FLASH_F4_CR_SNB = 3
22 FLASH_F4_CR_SNB_MASK = 0x38 22 FLASH_F4_CR_SNB_MASK = 0x38
23 FLASH_F4_SR_BSY = 16 23 FLASH_F4_SR_BSY = 16
24 24
25 class Stm32F4(Device): 25 class Stm32F4(Device):
26 """ 26 """
27 Implementation of the specifics of the STM32F4xx device series. 27 Implementation of the specifics of the STM32F4xx device series.
28 """ 28 """
29 def __init__(self, iface): 29 def __init__(self, iface):
30 super().__init__(iface) 30 super().__init__(iface)
31 self.logger = logging.getLogger('stm32') 31 self.logger = logging.getLogger('stm32')
32 32
33 def __str__(self): 33 def __str__(self):
34 return 'STM32F4 device size=0x{1:X} id=0x{0:X}'.format(\ 34 return 'STM32F4 device size=0x{1:X} id=0x{0:X}'.format(\
35 self.UID, self.FlashSize) 35 self.UID, self.FlashSize)
36 36
37 def calculate_F4_sector(self, address): 37 def calculate_F4_sector(self, address):
38 sectorstarts = [] 38 sectorstarts = []
39 a = STM32_FLASH_BASE 39 a = STM32_FLASH_BASE
40 for sectorsize in self.sectorsizes: 40 for sectorsize in self.sectorsizes:
41 sectorstarts.append(a) 41 sectorstarts.append(a)
42 a += sectorsize 42 a += sectorsize
45 while sec < len(self.sectorsizes) and address >= sectorstarts[sec]: 45 while sec < len(self.sectorsizes) and address >= sectorstarts[sec]:
46 sec += 1 46 sec += 1
47 sec -= 1 # one back. 47 sec -= 1 # one back.
48 return sec, self.sectorsizes[sec] 48 return sec, self.sectorsizes[sec]
49 49
50 def calcSectors(self, address, size): 50 def calcSectors(self, address, size):
51 off = 0 51 off = 0
52 sectors = [] 52 sectors = []
53 while off < size: 53 while off < size:
54 sectornum, sectorsize = self.calculate_F4_sector(address + off) 54 sectornum, sectorsize = self.calculate_F4_sector(address + off)
55 sectors.append((sectornum, sectorsize)) 55 sectors.append((sectornum, sectorsize))
56 off += sectorsize 56 off += sectorsize
57 return sectors 57 return sectors
58 # Device registers: 58
59 @property 59 # Device registers:
60 def UID(self): 60 @property
61 def UID(self):
61 uid_base = 0x1FFF7A10 62 uid_base = 0x1FFF7A10
62 uid1 = self.iface.read_debug32(uid_base) 63 uid1 = self.iface.read_debug32(uid_base)
63 uid2 = self.iface.read_debug32(uid_base + 0x4) 64 uid2 = self.iface.read_debug32(uid_base + 0x4)
64 uid3 = self.iface.read_debug32(uid_base + 0x8) 65 uid3 = self.iface.read_debug32(uid_base + 0x8)
65 return (uid3 << 64) | (uid2 << 32) | uid1 66 return (uid3 << 64) | (uid2 << 32) | uid1
66 67
67 @property 68 @property
68 def FlashSize(self): 69 def FlashSize(self):
69 f_id = self.iface.read_debug32(0x1FFF7A22) 70 f_id = self.iface.read_debug32(0x1FFF7A22)
70 f_id = f_id >> 16 71 f_id = f_id >> 16
71 return f_id * 1024 72 return f_id * 1024
72 73
73 @property 74 @property
74 def Running(self): 75 def Running(self):
75 return self.iface.Status == stlink.CORE_RUNNING 76 return self.iface.Status == stlink.CORE_RUNNING
76 77
77 # flashing commands: 78 # flashing commands:
78 def writeFlash(self, address, content): 79 def writeFlash(self, address, content):
79 flashsize = self.FlashSize 80 flashsize = self.FlashSize
80 pagesize = min(self.sectorsizes) 81 pagesize = min(self.sectorsizes)
81 82
82 # Check address range: 83 # Check address range:
83 if address < STM32_FLASH_BASE: 84 if address < STM32_FLASH_BASE:
112 while len(chunk) % 4 != 0: 113 while len(chunk) % 4 != 0:
113 chunk = chunk + bytes([0]) 114 chunk = chunk + bytes([0])
114 # Use simple mem32 writes: 115 # Use simple mem32 writes:
115 self.iface.write_mem32(address + offset, chunk) 116 self.iface.write_mem32(address + offset, chunk)
116 offset += size 117 offset += size
117 self.logger.info('.') 118 self.logger.info('{}%'.format(offset*100/len(content)))
118 t2 = time.time()
119 self.logger.info('Done!') 119 self.logger.info('Done!')
120 self.logger.info('Speed: {0} bytes/second'.format(len(content)/(t2-t1)))
121 self.lockFlash() 120 self.lockFlash()
122 # verfify program: 121 # verfify program:
123 self.verifyFlash(address, content) 122 self.verifyFlash(address, content)
124 def eraseFlashSector(self, sector): 123
125 self.waitFlashBusy() 124 def eraseFlashSector(self, sector):
126 self.unlockFlashIf() 125 self.waitFlashBusy()
127 self.writeFlashCrSnb(sector) 126 self.unlockFlashIf()
128 self.setFlashCrStart() 127 self.writeFlashCrSnb(sector)
129 self.waitFlashBusy() 128 self.setFlashCrStart()
130 self.lockFlash() 129 self.waitFlashBusy()
131 def eraseFlash(self): 130 self.lockFlash()
131
132 def eraseFlash(self):
132 self.waitFlashBusy() 133 self.waitFlashBusy()
133 self.unlockFlashIf() 134 self.unlockFlashIf()
134 self.setFlashCrMer() 135 self.setFlashCrMer()
135 self.setFlashCrStart() 136 self.setFlashCrStart()
136 self.waitFlashBusy() 137 self.waitFlashBusy()
137 self.clearFlashCrMer() 138 self.clearFlashCrMer()
138 self.lockFlash() 139 self.lockFlash()
139 140
140 def verifyFlash(self, address, content): 141 def verifyFlash(self, address, content):
141 device_content = self.readFlash(address, len(content)) 142 device_content = self.readFlash(address, len(content))
142 ok = content == device_content 143 ok = content == device_content
143 self.logger.info('Verify: {}'.format(ok)) 144 if ok:
144 145 self.logger.info('Verify: OK')
145 def readFlash(self, address, size): 146 else:
147 self.logger.warning('Verify: Mismatch')
148
149 def readFlash(self, address, size):
146 self.logger.info('Reading {1} bytes from 0x{0:X}'.format(address, size)) 150 self.logger.info('Reading {1} bytes from 0x{0:X}'.format(address, size))
147 offset = 0 151 offset = 0
148 tmp_size = 0x1800 152 tmp_size = 0x1800
149 t1 = time.time()
150 image = bytes() 153 image = bytes()
151 while offset < size: 154 while offset < size:
152 # Correct for last page: 155 # Correct for last page:
153 if offset + tmp_size > size: 156 if offset + tmp_size > size:
154 tmp_size = size - offset 157 tmp_size = size - offset
160 163
161 mem = self.iface.read_mem32(address + offset, aligned_size) 164 mem = self.iface.read_mem32(address + offset, aligned_size)
162 image += mem[:tmp_size] 165 image += mem[:tmp_size]
163 166
164 # indicate progress: 167 # indicate progress:
165 self.logger.info('.') 168 self.logger.info('{}%'.format(100*len(image) / size))
166 169
167 # increase for next piece: 170 # increase for next piece:
168 offset += tmp_size 171 offset += tmp_size
169 t2 = time.time()
170 assert size == len(image) 172 assert size == len(image)
171 self.logger.info('Done!') 173 self.logger.info('Done!')
172 self.logger.info('Speed: {0} bytes/second'.format(size/(t2-t1)))
173 return image 174 return image
174 175
175 def waitFlashBusy(self): 176 def waitFlashBusy(self):
176 """ block until flash operation completes. """ 177 """ block until flash operation completes. """
177 while self.isFlashBusy(): 178 while self.isFlashBusy():
178 time.sleep(0.01) 179 time.sleep(0.01)
179 def isFlashLocked(self): 180
180 cr = self.readFlashCr() 181 def isFlashLocked(self):
181 mask = 1 << FLASH_F4_CR_LOCK 182 mask = 1 << FLASH_F4_CR_LOCK
182 return cr & mask == mask 183 return self.Cr & mask == mask
183 def unlockFlashIf(self): 184
185 def unlockFlashIf(self):
184 FLASH_KEY1, FLASH_KEY2 = 0x45670123, 0xcdef89ab 186 FLASH_KEY1, FLASH_KEY2 = 0x45670123, 0xcdef89ab
185 if self.isFlashLocked(): 187 if self.isFlashLocked():
186 self.iface.write_debug32(FLASH_F4_KEYR, FLASH_KEY1) 188 self.iface.write_debug32(FLASH_F4_KEYR, FLASH_KEY1)
187 self.iface.write_debug32(FLASH_F4_KEYR, FLASH_KEY2) 189 self.iface.write_debug32(FLASH_F4_KEYR, FLASH_KEY2)
188 if self.isFlashLocked(): 190 if self.isFlashLocked():
189 raise STLinkException('Failed to unlock') 191 raise STLinkException('Failed to unlock')
190 def lockFlash(self): 192
191 x = self.readFlashCr() | (1 << FLASH_F4_CR_LOCK) 193 def lockFlash(self):
192 self.writeFlashCr(x) 194 self.Cr = self.Cr | (1 << FLASH_F4_CR_LOCK)
193 def readFlashSr(self): 195
194 return self.iface.read_debug32(FLASH_F4_SR) 196 def readFlashSr(self):
195 def readFlashCr(self): 197 return self.iface.read_debug32(FLASH_F4_SR)
196 return self.iface.read_debug32(FLASH_F4_CR) 198
197 def writeFlashCr(self, x): 199 def readFlashCr(self):
198 self.iface.write_debug32(FLASH_F4_CR, x) 200 return self.iface.read_debug32(FLASH_F4_CR)
199 def writeFlashCrSnb(self, sector): 201
200 x = self.readFlashCr() 202 def writeFlashCr(self, x):
203 self.iface.write_debug32(FLASH_F4_CR, x)
204
205 Cr = property(readFlashCr, writeFlashCr)
206
207 def writeFlashCrSnb(self, sector):
208 x = self.Cr
201 x &= ~FLASH_F4_CR_SNB_MASK 209 x &= ~FLASH_F4_CR_SNB_MASK
202 x |= sector << FLASH_F4_CR_SNB 210 x |= sector << FLASH_F4_CR_SNB
203 x |= 1 << FLASH_F4_CR_SER 211 x |= 1 << FLASH_F4_CR_SER
204 self.writeFlashCr(x) 212 self.Cr = x
205 def setFlashCrMer(self): 213
206 x = self.readFlashCr() 214 def setFlashCrMer(self):
207 x |= 1 << FLASH_CR_MER 215 self.Cr = self.Cr | (1 << FLASH_CR_MER)
208 self.writeFlashCr(x) 216
209 def setFlashCrPg(self): 217 def setFlashCrPg(self):
210 x = self.readFlashCr() 218 self.Cr = self.Cr | (1 << FLASH_CR_PG)
211 x |= 1 << FLASH_CR_PG 219
212 self.writeFlashCr(x) 220 def writeFlashCrPsiz(self, n):
213 def writeFlashCrPsiz(self, n): 221 x = self.Cr
214 x = self.readFlashCr() 222 x &= (0x3 << 8)
215 x &= (0x3 << 8) 223 x |= n << 8
216 x |= n << 8 224 self.Cr = x
217 self.writeFlashCr(x) 225
218 def clearFlashCrMer(self): 226 def clearFlashCrMer(self):
219 x = self.readFlashCr() 227 x = self.Cr
220 x &= ~(1 << FLASH_CR_MER) 228 x &= ~(1 << FLASH_CR_MER)
221 self.writeFlashCr(x) 229 self.Cr = x
222 def setFlashCrStart(self): 230
223 x = self.readFlashCr() 231 def setFlashCrStart(self):
224 x |= 1 << FLASH_F4_CR_START 232 self.Cr = self.Cr | (1 << FLASH_F4_CR_START)
225 self.writeFlashCr(x) 233
226 def isFlashBusy(self): 234 def isFlashBusy(self):
227 mask = 1 << FLASH_F4_SR_BSY 235 mask = 1 << FLASH_F4_SR_BSY
228 sr = self.readFlashSr() 236 sr = self.readFlashSr()
229 # Check for error bits: 237 # Check for error bits:
230 errorbits = {} 238 errorbits = {}
231 errorbits[7] = 'Programming sequence error' 239 errorbits[7] = 'Programming sequence error'