comparison python/stlink.py @ 119:f51791638cae

Simplified flashing
author Windel Bouwman
date Sat, 12 Jan 2013 10:23:33 +0100
parents f2b37d78082d
children 347d7d8b96c0
comparison
equal deleted inserted replaced
118:db8aafe00d27 119:f51791638cae
114 sectors.append((sectornum, sectorsize)) 114 sectors.append((sectornum, sectorsize))
115 off += sectorsize 115 off += sectorsize
116 return sectors 116 return sectors
117 117
118 class STLink: 118 class STLink:
119 def __init__(self): 119 """ ST link interface code """
120 self.context = UsbContext() 120 def __init__(self, stlink2=None):
121 if not stlink2:
122 context = UsbContext()
123 stlink2s = list(filter(checkDevice, context.DeviceList))
124 if not stlink2s:
125 raise STLinkException('Could not find an ST link')
126 if len(stlink2s) > 1:
127 print('More then one stlink2 found, picking first one')
128 stlink2 = stlink2s[0]
129 self.stlink2 = stlink2
121 def open(self): 130 def open(self):
122 context = UsbContext() 131 self.devHandle = self.stlink2.open()
123 stlink2s = list(filter(checkDevice, context.DeviceList))
124 if not stlink2s:
125 raise STLinkException('Could not find an ST link')
126 if len(stlink2s) > 1:
127 print('More then one stlink2 found, picking first one')
128 stlink2 = stlink2s[0]
129 self.devHandle = stlink2.open()
130 if self.devHandle.Configuration != 1: 132 if self.devHandle.Configuration != 1:
131 self.devHandle.Configuration = 1 133 self.devHandle.Configuration = 1
132 self.devHandle.claimInterface(0) 134 self.devHandle.claimInterface(0)
133 135
134 # First initialization: 136 # First initialization:
243 245
244 # erase required space 246 # erase required space
245 sectors = calcSectors(address, len(content)) 247 sectors = calcSectors(address, len(content))
246 print('erasing {0} sectors'.format(len(sectors))) 248 print('erasing {0} sectors'.format(len(sectors)))
247 for sector, secsize in sectors: 249 for sector, secsize in sectors:
248 print('erasing sector {0} of size {1}'.format(sector, secsize)) 250 print('erasing sector {0} of {1} bytes'.format(sector, secsize))
249 self.eraseFlashSector(sector) 251 self.eraseFlashSector(sector)
250 252
251 # program pages: 253 # program pages:
252 self.initFlashLoader()
253 self.unlockFlashIf() 254 self.unlockFlashIf()
254 self.writeFlashCrPsiz(2) 255 self.writeFlashCrPsiz(2) # writes are 32 bits aligned
255 self.setFlashCrPg() 256 self.setFlashCrPg()
256 257
258 print('writing {0} bytes'.format(len(content)), end='')
257 offset = 0 259 offset = 0
260 t1 = time.time()
258 while offset < len(content): 261 while offset < len(content):
259 size = len(content) - offset 262 size = len(content) - offset
260 if size > 0x8000: 263 if size > 0x8000:
261 size = 0x8000 264 size = 0x8000
262 265
263 self.runFlashLoader(address + offset, content[offset:offset + size]) 266 chunk = content[offset:offset + size]
267 while len(chunk) % 4 != 0:
268 print('padding chunk')
269 chunk = chunk + bytes([0])
270
271 # Use simple mem32 writes:
272 self.write_mem32(address + offset, chunk)
273
264 offset += size 274 offset += size
275 print('.', end='', flush=True)
276 t2 = time.time()
277 print('Done!')
278 print('Speed: {0} bytes/second'.format(len(content)/(t2-t1)))
265 279
266 self.lockFlash() 280 self.lockFlash()
267 281
268 # verfify program: 282 # verfify program:
269 self.verifyFlash(address, content) 283 self.verifyFlash(address, content)
285 def verifyFlash(self, address, content): 299 def verifyFlash(self, address, content):
286 device_content = self.readFlash(address, len(content)) 300 device_content = self.readFlash(address, len(content))
287 ok = content == device_content 301 ok = content == device_content
288 print('Verify:', ok) 302 print('Verify:', ok)
289 def readFlash(self, address, size): 303 def readFlash(self, address, size):
290 print('reading', address, size) 304 print('Reading {1} bytes from 0x{0:X}'.format(address, size), end='')
291 offset = 0 305 offset = 0
292 tmp_size = 0x1800 306 tmp_size = 0x1800
293 t1 = time.time() 307 t1 = time.time()
294 image = bytes() 308 image = bytes()
295 while offset < size: 309 while offset < size:
310 324
311 # increase for next piece: 325 # increase for next piece:
312 offset += tmp_size 326 offset += tmp_size
313 t2 = time.time() 327 t2 = time.time()
314 assert size == len(image) 328 assert size == len(image)
315 print('done! {0} bytes/second'.format(size/(t2-t1))) 329 print('Done!')
330 print('Speed: {0} bytes/second'.format(size/(t2-t1)))
316 return image 331 return image
317 def initFlashLoader(self):
318 # TODO: support other loader code.
319 self.write_mem32(STM32_SRAM_BASE, loader_code_stm32f4)
320 def runFlashLoader(self, targetaddress, buf):
321 bufAddress = STM32_SRAM_BASE + len(loader_code_stm32f4)
322 print('running flash loader for {0} bytes'.format(len(buf)))
323 self.write_buffer_to_sram(buf)
324 count = int(len(buf) / 4)
325 if len(buf) % 4 != 0: count += 1
326 self.write_reg(0, bufAddress)
327 self.write_reg(1, targetaddress)
328 self.write_reg(2, count)
329 self.write_reg(15, STM32_SRAM_BASE) # pc
330
331 self.run() # Let loose cpu!
332
333 while self.Status == CORE_RUNNING:
334 pass
335
336 r2 = self.read_reg(2)
337 if r2 != 0:
338 raise STLinkException("write error! {0}".format(r2))
339 def write_buffer_to_sram(self, buf):
340 bufAddress = STM32_SRAM_BASE + len(loader_code_stm32f4)
341 chunk = len(buf) >> 2
342 rem = len(buf) & 0x3
343 if chunk > 0:
344 self.write_mem32(bufAddress, buf[:chunk])
345 if rem > 0:
346 self.write_mem8(bufAddress + chunk, buf[chunk:chunk+rem])
347
348 def readFlashSr(self): 332 def readFlashSr(self):
349 return self.read_debug32(FLASH_F4_SR) 333 return self.read_debug32(FLASH_F4_SR)
350 def readFlashCr(self): 334 def readFlashCr(self):
351 return self.read_debug32(FLASH_F4_CR) 335 return self.read_debug32(FLASH_F4_CR)
336 def writeFlashCr(self, x):
337 self.write_debug32(FLASH_F4_CR, x)
352 def writeFlashCrSnb(self, sector): 338 def writeFlashCrSnb(self, sector):
353 x = self.readFlashCr() 339 x = self.readFlashCr()
354 x &= ~FLASH_F4_CR_SNB_MASK 340 x &= ~FLASH_F4_CR_SNB_MASK
355 x |= sector << FLASH_F4_CR_SNB 341 x |= sector << FLASH_F4_CR_SNB
356 x |= 1 << FLASH_F4_CR_SER 342 x |= 1 << FLASH_F4_CR_SER
357 self.write_debug32(FLASH_F4_CR, x) 343 self.writeFlashCr(x)
358 def setFlashCrMer(self): 344 def setFlashCrMer(self):
359 x = self.readFlashCr() 345 x = self.readFlashCr()
360 x |= 1 << FLASH_CR_MER 346 x |= 1 << FLASH_CR_MER
361 self.write_debug32(FLASH_F4_CR, x) 347 self.writeFlashCr(x)
362 def setFlashCrPg(self): 348 def setFlashCrPg(self):
363 x = self.readFlashCr() 349 x = self.readFlashCr()
364 x |= 1 << FLASH_CR_PG 350 x |= 1 << FLASH_CR_PG
365 self.write_debug32(FLASH_F4_CR, x) 351 self.writeFlashCr(x)
366 def writeFlashCrPsiz(self, n): 352 def writeFlashCrPsiz(self, n):
367 x = self.readFlashCr() 353 x = self.readFlashCr()
368 x &= (0x3 << 8) 354 x &= (0x3 << 8)
369 x |= n << 8 355 x |= n << 8
370 print('psiz', n) 356 self.writeFlashCr(x)
371 self.write_debug32(FLASH_F4_CR, x)
372 def clearFlashCrMer(self): 357 def clearFlashCrMer(self):
373 x = self.readFlashCr() 358 x = self.readFlashCr()
374 x &= ~(1 << FLASH_CR_MER) 359 x &= ~(1 << FLASH_CR_MER)
375 self.write_debug32(FLASH_F4_CR, x) 360 self.writeFlashCr(x)
376 def setFlashCrStart(self): 361 def setFlashCrStart(self):
377 x = self.readFlashCr() 362 x = self.readFlashCr()
378 x |= 1 << FLASH_F4_CR_START 363 x |= 1 << FLASH_F4_CR_START
379 self.write_debug32(FLASH_F4_CR, x) 364 self.writeFlashCr(x)
380 def isFlashBusy(self): 365 def isFlashBusy(self):
381 mask = 1 << FLASH_F4_SR_BSY 366 mask = 1 << FLASH_F4_SR_BSY
382 sr = self.readFlashSr() 367 sr = self.readFlashSr()
368 # Check for error bits:
369 errorbits = {}
370 errorbits[7] = 'Programming sequence error'
371 errorbits[6] = 'Programming parallelism error'
372 errorbits[5] = 'Programming alignment error'
373 errorbits[4] = 'Write protection error'
374 errorbits[1] = 'Operation error'
375 #errorbits[0] = 'End of operation'
376 for bit, msg in errorbits.items():
377 if sr & (1 << bit) == (1 << bit):
378 raise STLinkException(msg)
379
383 return sr & mask == mask 380 return sr & mask == mask
384 def waitFlashBusy(self): 381 def waitFlashBusy(self):
385 """ block until flash operation completes. """ 382 """ block until flash operation completes. """
386 while self.isFlashBusy(): 383 while self.isFlashBusy():
387 pass 384 pass
389 cr = self.readFlashCr() 386 cr = self.readFlashCr()
390 mask = 1 << FLASH_F4_CR_LOCK 387 mask = 1 << FLASH_F4_CR_LOCK
391 return cr & mask == mask 388 return cr & mask == mask
392 def unlockFlashIf(self): 389 def unlockFlashIf(self):
393 if self.isFlashLocked(): 390 if self.isFlashLocked():
394 print('unlocking')
395 self.write_debug32(FLASH_F4_KEYR, FLASH_KEY1) 391 self.write_debug32(FLASH_F4_KEYR, FLASH_KEY1)
396 self.write_debug32(FLASH_F4_KEYR, FLASH_KEY2) 392 self.write_debug32(FLASH_F4_KEYR, FLASH_KEY2)
397 if self.isFlashLocked(): 393 if self.isFlashLocked():
398 raise STLinkException('Failed to unlock') 394 raise STLinkException('Failed to unlock')
399 def lockFlash(self): 395 def lockFlash(self):
400 print('locking')
401 x = self.readFlashCr() | (1 << FLASH_F4_CR_LOCK) 396 x = self.readFlashCr() | (1 << FLASH_F4_CR_LOCK)
402 self.write_debug32(FLASH_F4_CR, x) 397 self.write_debug32(FLASH_F4_CR, x)
403 398
404 # Helper 1 functions: 399 # Helper 1 functions:
405 def write_debug32(self, address, value): 400 def write_debug32(self, address, value):
406 cmd = bytearray(16) 401 cmd = bytearray(16)
407 cmd[0:2] = DEBUG_COMMAND, JTAG_WRITEDEBUG_32BIT 402 cmd[0:2] = DEBUG_COMMAND, JTAG_WRITEDEBUG_32BIT
408 cmd[2:6] = struct.pack('<I', address) 403 cmd[2:10] = struct.pack('<II', address, value)
409 cmd[6:10] = struct.pack('<I', value)
410 self.send_recv(cmd, 2) 404 self.send_recv(cmd, 2)
411 def read_debug32(self, address): 405 def read_debug32(self, address):
412 cmd = bytearray(16) 406 cmd = bytearray(16)
413 cmd[0:2] = DEBUG_COMMAND, JTAG_READDEBUG_32BIT 407 cmd[0:2] = DEBUG_COMMAND, JTAG_READDEBUG_32BIT
414 cmd[2:6] = struct.pack('<I', address) # pack into u32 little endian 408 cmd[2:6] = struct.pack('<I', address) # pack into u32 little endian
426 return struct.unpack('<I', reply)[0] 420 return struct.unpack('<I', reply)[0]
427 def write_mem32(self, address, content): 421 def write_mem32(self, address, content):
428 assert len(content) % 4 == 0 422 assert len(content) % 4 == 0
429 cmd = bytearray(16) 423 cmd = bytearray(16)
430 cmd[0:2] = DEBUG_COMMAND, DEBUG_WRITEMEM_32BIT 424 cmd[0:2] = DEBUG_COMMAND, DEBUG_WRITEMEM_32BIT
431 cmd[2:6] = struct.pack('<I', address) 425 cmd[2:8] = struct.pack('<IH', address, len(content))
432 cmd[6:8] = struct.pack('<H', len(content))
433 self.send_recv(cmd) 426 self.send_recv(cmd)
434 self.send_recv(content) 427 self.send_recv(content)
435 def read_mem32(self, address, length): 428 def read_mem32(self, address, length):
436 assert length % 4 == 0 429 assert length % 4 == 0
437 cmd = bytearray(16) 430 cmd = bytearray(16)
438 cmd[0:2] = DEBUG_COMMAND, DEBUG_READMEM_32BIT 431 cmd[0:2] = DEBUG_COMMAND, DEBUG_READMEM_32BIT
439 cmd[2:6] = struct.pack('<I', address) 432 cmd[2:8] = struct.pack('<IH', address, length)
440 cmd[6:8] = struct.pack('<H', length) # uint16
441 reply = self.send_recv(cmd, length) # expect memory back! 433 reply = self.send_recv(cmd, length) # expect memory back!
442 return reply 434 return reply
443 435
444 # Helper 2 functions: 436 # Helper 2 functions:
445 def send_recv(self, tx, rxsize=0): 437 def send_recv(self, tx, rxsize=0):
485 477
486 sl.exitDebugMode() 478 sl.exitDebugMode()
487 print('mode at end:', sl.CurrentModeString) 479 print('mode at end:', sl.CurrentModeString)
488 480
489 sl.close() 481 sl.close()
490 482 print('Test succes!')
483