Mercurial > lcfOS
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): |