diff 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
line wrap: on
line diff
--- a/python/stm32.py	Fri Jan 18 12:52:11 2013 +0100
+++ b/python/stm32.py	Sat Jan 19 18:16:04 2013 +0100
@@ -5,9 +5,6 @@
 STM32_FLASH_BASE = 0x08000000
 STM32_SRAM_BASE  = 0x20000000
 
-FLASH_KEY1 = 0x45670123
-FLASH_KEY2 = 0xcdef89ab
-
 # flash registers:
 FLASH_F4_REGS_ADDR = 0x40023c00
 FLASH_F4_KEYR = FLASH_F4_REGS_ADDR + 0x04
@@ -23,48 +20,63 @@
 FLASH_F4_CR_SNB_MASK = 0x38
 FLASH_F4_SR_BSY = 16
 
-def calculate_F4_sector(address):
-   """
-      from 0x8000000 to 0x80FFFFF
-      4 sectors of 0x4000 (16 kB)
-      1 sector of 0x10000 (64 kB)
-      7 of 0x20000 (128 kB)
-   """
-   sectorsizes = [0x4000] * 4 + [0x10000] + [0x20000] * 7
-   sectorstarts = []
-   a = STM32_FLASH_BASE
-   for sectorsize in sectorsizes:
-      sectorstarts.append(a)
-      a += sectorsize
-   # linear search:
-   sec = 0
-   while sec < len(sectorsizes) and address >= sectorstarts[sec]:
-      sec += 1
-   sec -= 1 # one back.
-   return sec, sectorsizes[sec]
-
-def calcSectors(address, size):
-   off = 0
-   sectors = []
-   while off < size:
-      sectornum, sectorsize = calculate_F4_sector(address + off)
-      sectors.append((sectornum, sectorsize))
-      off += sectorsize
-   return sectors
-
 @registerDevice(0x10016413)
 class Stm32F4(Device):
+   """
+      Implementation of the specifics of the STM32F4xx device series.
+   """
    def __init__(self, iface):
       super().__init__(iface)
+      # Assert the proper size for this device:
+      assert self.FlashSize == 0x100000
+      """
+         from 0x8000000 to 0x80FFFFF
+         4 sectors of 0x4000 (16 kB)
+         1 sector of 0x10000 (64 kB)
+         7 of 0x20000 (128 kB)
+      """
+      self.sectorsizes = [0x4000] * 4 + [0x10000] + [0x20000] * 7
    def __str__(self):
-      return 'STM32F4 device'
+      return 'STM32F4 device size=0x{1:X} id=0x{0:X}'.format(\
+         self.UID, self.FlashSize)
+   def calculate_F4_sector(self, address):
+      sectorstarts = []
+      a = STM32_FLASH_BASE
+      for sectorsize in self.sectorsizes:
+         sectorstarts.append(a)
+         a += sectorsize
+      # linear search:
+      sec = 0
+      while sec < len(self.sectorsizes) and address >= sectorstarts[sec]:
+         sec += 1
+      sec -= 1 # one back.
+      return sec, self.sectorsizes[sec]
+
+   def calcSectors(self, address, size):
+      off = 0
+      sectors = []
+      while off < size:
+         sectornum, sectorsize = self.calculate_F4_sector(address + off)
+         sectors.append((sectornum, sectorsize))
+         off += sectorsize
+      return sectors
+   # Device registers:
+   @property
+   def UID(self):
+      uid_base = 0x1FFF7A10
+      uid1 = self.iface.read_debug32(uid_base)
+      uid2 = self.iface.read_debug32(uid_base + 0x4)
+      uid3 = self.iface.read_debug32(uid_base + 0x8)
+      return (uid3 << 64) | (uid2 << 32) | uid1
+   @property
+   def FlashSize(self):
+      f_id = self.iface.read_debug32(0x1FFF7A22)
+      f_id = f_id >> 16
+      return f_id * 1024
    # flashing commands:
    def writeFlash(self, address, content):
-      # TODO:
-      flashsize = 0x100000 # fixed 1 MB for now..
-      print('WARNING: using 1 MB as flash size')
-      pagesize = 0x4000 # fixed for now!
-      print('warning: page size hardcoded')
+      flashsize = self.FlashSize
+      pagesize = min(self.sectorsizes)
 
       # Check address range:
       if address < STM32_FLASH_BASE:
@@ -78,19 +90,16 @@
          content += bytes([0])
       if address & (pagesize - 1) != 0:
          raise STLinkException('Address not aligned with pagesize')
-      
       # erase required space
-      sectors = calcSectors(address, len(content))
+      sectors = self.calcSectors(address, len(content))
       print('erasing {0} sectors'.format(len(sectors)))
       for sector, secsize in sectors:
          print('erasing sector {0} of {1} bytes'.format(sector, secsize))
          self.eraseFlashSector(sector)
-
       # program pages:
       self.unlockFlashIf()
       self.writeFlashCrPsiz(2) # writes are 32 bits aligned
       self.setFlashCrPg()
-
       print('writing {0} bytes'.format(len(content)), end='')
       offset = 0
       t1 = time.time()
@@ -98,23 +107,17 @@
          size = len(content) - offset
          if size > 0x8000:
             size = 0x8000
-
          chunk = content[offset:offset + size]
          while len(chunk) % 4 != 0:
-            print('padding chunk')
             chunk = chunk + bytes([0])
-
          # Use simple mem32 writes:
          self.iface.write_mem32(address + offset, chunk)
-
          offset += size
          print('.', end='', flush=True)
       t2 = time.time()
       print('Done!')
       print('Speed: {0} bytes/second'.format(len(content)/(t2-t1)))
-
       self.lockFlash()
-
       # verfify program:
       self.verifyFlash(address, content)
    def eraseFlashSector(self, sector):
@@ -175,6 +178,7 @@
       mask = 1 << FLASH_F4_CR_LOCK
       return cr & mask == mask
    def unlockFlashIf(self):
+      FLASH_KEY1, FLASH_KEY2 = 0x45670123, 0xcdef89ab
       if self.isFlashLocked():
          self.iface.write_debug32(FLASH_F4_KEYR, FLASH_KEY1)
          self.iface.write_debug32(FLASH_F4_KEYR, FLASH_KEY2)
@@ -183,7 +187,6 @@
    def lockFlash(self):
       x = self.readFlashCr() | (1 << FLASH_F4_CR_LOCK)
       self.writeFlashCr(x)
-
    def readFlashSr(self):
       return self.iface.read_debug32(FLASH_F4_SR)
    def readFlashCr(self):