Mercurial > lcfOS
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' |