Mercurial > public > hwos_code
annotate src/external_flash.asm @ 631:185ba2f91f59
3.09 beta 1 release
author | heinrichsweikamp |
---|---|
date | Fri, 28 Feb 2020 15:45:07 +0100 |
parents | cd58f7fc86db |
children | 690c48db7b5b |
rev | line source |
---|---|
0 | 1 ;============================================================================= |
2 ; | |
631 | 3 ; File external_flash.asm combined next generation V3.08.8 |
0 | 4 ; |
5 ; External flash | |
6 ; | |
7 ; Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved. | |
8 ;============================================================================= | |
9 ; HISTORY | |
10 ; 2011-08-12 : [mH] creation | |
11 | |
275 | 12 #include "hwos.inc" |
0 | 13 #include "wait.inc" |
631 | 14 #include "eeprom_rs232.inc" |
0 | 15 |
623 | 16 ext_flash CODE |
604 | 17 |
0 | 18 ;============================================================================= |
19 | |
631 | 20 ; increase flash address by one with wrap-around at 0x400000 to 0x000000 |
21 incf_ext_flash_address_p1_0x40: | |
22 movlw .1 ; increase by 1 | |
23 ;bra incf_ext_flash_address0_0x40 ; continue | |
0 | 24 |
623 | 25 |
631 | 26 ; increase flash address by value in WREG with wrap-around at 0x400000 to 0x000000 |
27 global incf_ext_flash_address0_0x40 | |
28 incf_ext_flash_address0_0x40: | |
29 clrf ext_flash_rollover_threshold ; set wrap-around threshold without destroying WREG to ... | |
30 bsf ext_flash_rollover_threshold,6 ; ... 0x40 | |
31 bra incf_ext_flash_address0_common ; continue with common part | |
0 | 32 |
582 | 33 |
631 | 34 ; increase flash address by one with wrap-around at 0x200000 to 0x000000 |
35 incf_ext_flash_address_p1_0x20: | |
36 movlw .1 ; increase by one | |
37 ;bra incf_ext_flash_address0_0x20 ; continue | |
0 | 38 |
623 | 39 |
631 | 40 ; increase flash address by value in WREG with wrap-around at 0x200000 to 0x000000 |
582 | 41 global incf_ext_flash_address0_0x20 |
623 | 42 incf_ext_flash_address0_0x20: |
631 | 43 clrf ext_flash_rollover_threshold ; set wrap-around threshold without destroying WREG to ... |
44 bsf ext_flash_rollover_threshold,5 ; ... 0x20 | |
45 ;bra incf_ext_flash_address0_common ; continue with common part | |
0 | 46 |
47 | |
631 | 48 incf_ext_flash_address0_common: |
49 bcf address_wrap_around ; clear wrap-around flag | |
50 addwf ext_flash_address+0,F ; add WREG to address:3 | |
51 movlw d'0' ; ... | |
52 addwfc ext_flash_address+1,F ; ... | |
53 addwfc ext_flash_address+2,F ; ... | |
54 movf ext_flash_rollover_threshold,W ; get wrap-around threshold | |
55 cpfseq ext_flash_address+2 ; at wrap-around threshold ? | |
56 bra incf_ext_flash_address1 ; NO - no wrap-around needed | |
57 ; clrf ext_flash_address+0 ; YES - wrap-around to 0x000000 | |
58 ; clrf ext_flash_address+1 ; - ... | |
59 clrf ext_flash_address+2 ; - ... | |
60 bsf address_wrap_around ; - set wrap-around flag | |
61 incf_ext_flash_address1: | |
62 movf ext_flash_rw,W ; export current value of ext_flash_rw via WREG, too | |
63 return ; done | |
0 | 64 |
582 | 65 |
631 | 66 ; decrease flash length counter by value in WREG |
67 global decf_ext_flash_length0 | |
68 decf_ext_flash_length0: | |
69 subwf ext_flash_length_counter+0,F ; decrease address by value in WREG | |
70 movlw d'0' ; ... | |
71 subwfb ext_flash_length_counter+1,F ; ... | |
72 subwfb ext_flash_length_counter+2,F ; ... | |
73 return ; done | |
74 | |
75 ; ---------------------------------------------------------------------------- | |
76 | |
77 ; global ext_flash_byte_read_plus_0x40 ; return data read in ext_flash_rw and WREG, increase address after read with wrap-around at 0x400000 | |
78 ;ext_flash_byte_read_plus_0x40: | |
79 ; rcall ext_flash_byte_read ; read byte into ext_flash_rw | |
80 ; bra incf_ext_flash_address_p1_0x40 ; increase address with wrap-around at 0x400000 to 0x000000 (and return) | |
0 | 81 |
82 | |
631 | 83 global ext_flash_byte_read_plus_0x20 ; return data read in ext_flash_rw and WREG, increase address after read with wrap-around at 0x200000 |
84 ext_flash_byte_read_plus_0x20: | |
85 rcall ext_flash_byte_read ; read byte into ext_flash_rw | |
86 bra incf_ext_flash_address_p1_0x20 ; increase address with roll-over at 0x200000 to 0x000000 (and return) | |
582 | 87 |
0 | 88 |
631 | 89 global ext_flash_byte_read ; return data read in WREG and ext_flash_rw, no address change |
90 ext_flash_byte_read: | |
91 movlw 0x03 ; set up read command | |
92 rcall shift_spi ; prepare read command | |
93 rcall ext_flash_set_address ; write 24 bit address ext_flash_address:3 via SPI | |
94 rcall shift_spi ; shift the SPI to read data into WREG | |
95 bsf flash_ncs ; set CS=1 | |
96 movwf ext_flash_rw ; return data read in WREG and ext_flash_rw | |
97 return ; done | |
582 | 98 |
631 | 99 ; ---------------------------------------------------------------------------- |
100 ; read-range base functions | |
0 | 101 |
623 | 102 global ext_flash_read_block_start ; return data read in WREG |
0 | 103 ext_flash_read_block_start: |
631 | 104 movlw 0x03 ; set up read command |
105 rcall shift_spi ; execute read command | |
106 rcall ext_flash_set_address ; write 24 bit address ext_flash_address:3 via SPI | |
107 bra shift_spi ; shift the SPI to read data into WREG (and return) | |
0 | 108 |
582 | 109 |
631 | 110 global ext_flash_read_block_0x40 ; return data read in WREG |
111 ext_flash_read_block_0x40: | |
112 rcall incf_ext_flash_address_p1_0x40 ; increase address with wrap-around at 0x400000 | |
113 btfss address_wrap_around ; did the address wrap-around? | |
114 bra shift_spi_loop_1 ; NO - shift the SPI to read data into WREG and return | |
115 rcall ext_flash_read_block_stop ; YES - do a block-stop | |
116 bra ext_flash_read_block_start ; - do a block-start, read data into WREG and return | |
582 | 117 |
0 | 118 |
631 | 119 global ext_flash_read_block_0x20 ; return data read in WREG |
120 ext_flash_read_block_0x20: | |
121 rcall incf_ext_flash_address_p1_0x20 ; increase address with wrap-around at 0x200000 | |
122 btfss address_wrap_around ; did the address wrap-around? | |
123 bra shift_spi_loop_1 ; NO - shift the SPI to read data into WREG and return | |
124 rcall ext_flash_read_block_stop ; YES - do a block-stop | |
125 bra ext_flash_read_block_start ; - do a block-start, read data into WREG and return | |
0 | 126 |
127 | |
631 | 128 global ext_flash_read_block_stop ; end block operation |
129 ext_flash_read_block_stop: | |
130 bsf flash_ncs ; set CS=1 | |
131 return ; done | |
132 | |
133 ; ---------------------------------------------------------------------------- | |
134 ; read-range function, to be used through macro | |
135 ; | |
136 global ext_flash_read_range | |
137 ext_flash_read_range: | |
138 movwf eeprom_loop ; load loop counter (eeprom variable used here) | |
139 rcall ext_flash_read_block_start ; read first byte from flash | |
140 bra ext_flash_read_range_loop_start ; jump into loop | |
141 ext_flash_read_range_loop: | |
142 rcall ext_flash_read_block_0x40 ; read next byte from flash | |
143 ext_flash_read_range_loop_start: | |
144 movwf POSTINC1 ; write byte to memory | |
145 decfsz eeprom_loop,F ; decrement loop counter, all done? | |
146 bra ext_flash_read_range_loop ; NO - continue loop | |
147 bra ext_flash_read_block_stop ; YES - end reading from flash (and return) | |
582 | 148 |
279 | 149 |
631 | 150 ; ---------------------------------------------------------------------------- |
151 ; write-range base functions | |
6 | 152 |
631 | 153 ext_flash_write_block_start: |
154 bsf flash_ncs ; set CS=1 | |
155 movlw 0x06 ; set up WREN command | |
156 rcall shift_spi ; execute WREN command | |
157 bsf flash_ncs ; set CS=1 | |
158 movlw 0x02 ; set up write (PP, Page-Program) command | |
159 rcall shift_spi ; execute write | |
160 rcall ext_flash_set_address ; write 24 bit address ext_flash_address:3 via SPI | |
161 movf ext_flash_rw,W ; get byte to write | |
162 bra shift_spi ; write the byte (and return) | |
163 | |
164 ext_flash_write_block: | |
165 movf ext_flash_rw,W ; get byte to write | |
166 bra shift_spi_loop_1 ; shift the SPI to write data into FLASH (and return) | |
167 | |
168 ext_flash_write_block_stop: | |
169 bra ext_flash_wait_write ; wait for completion (and return) | |
0 | 170 |
631 | 171 ; ---------------------------------------------------------------------------- |
172 ; write-range function, to be used through macro | |
173 ; | |
174 global ext_flash_write_range | |
175 ext_flash_write_range: | |
176 movwf eeprom_loop ; load loop counter (eeprom variable used here) | |
177 movff POSTINC1,ext_flash_rw ; read first byte from memory | |
178 rcall ext_flash_write_block_start ; write first byte to FLASH | |
179 bra ext_flash_write_range_loop_start; jump into loop | |
180 ext_flash_write_range_loop: | |
181 movff POSTINC1,ext_flash_rw ; read next byte from memory | |
182 rcall ext_flash_write_block ; write next byte to FLASH | |
183 ext_flash_write_range_loop_start: | |
184 decfsz eeprom_loop,F ; decrement loop counter, all done? | |
185 bra ext_flash_write_range_loop ; NO - continue loop | |
186 bra ext_flash_write_block_stop ; YES - end writing to flash (and return) | |
187 | |
188 ; ---------------------------------------------------------------------------- | |
189 | |
190 ; global write_byte_ext_flash_plus_header | |
191 ; write_byte_ext_flash_plus_header: | |
192 ; movwf ext_flash_rw ; store byte to write | |
193 ; ; test if write is done at first byte of 4kB block, if yes delete 4kB block first | |
194 ; tstfsz ext_flash_address+0 ; at 0x....00 ? | |
195 ; bra write_byte_ext_flash_plus_h1 ; NO - normal write | |
196 ; movf ext_flash_address+1,W ; YES - get high byte | |
197 ; andlw 0x0F ; - mask lower nibble | |
198 ; tstfsz WREG ; - at 0x..0...? | |
199 ; bra write_byte_ext_flash_plus_h1 ; NO - normal write | |
200 ; rcall ext_flash_erase_4kB ; YES - at beginning of 4kB block -> erases 4kB sector @ext_flash_address:3 | |
201 ;write_byte_ext_flash_plus_h1: | |
202 ; rcall ext_flash_byte_write ; write the byte in ext_flash_rw | |
203 ; bra incf_ext_flash_address_p1_0x40 ; increase address with wrap-around at 0x400000 and return | |
0 | 204 |
205 | |
631 | 206 global write_byte_ext_flash_plus_prof |
207 write_byte_ext_flash_plus_prof: | |
208 movwf ext_flash_rw ; store byte to write | |
209 incf ext_flash_length_counter+0,F ; increase dive length counter | |
210 movlw .0 ; ... | |
211 addwfc ext_flash_length_counter+1,F ; ... | |
212 addwfc ext_flash_length_counter+2,F ; ... | |
213 bra write_byte_ext_flash_plus_nocnt1; continue with checking for begin of new page | |
214 | |
215 | |
216 global write_byte_ext_flash_plus_nocnt | |
217 write_byte_ext_flash_plus_nocnt: | |
218 movwf ext_flash_rw ; store byte to write | |
219 write_byte_ext_flash_plus_nocnt1: ; test if write is done at first byte of 4kB block, if yes delete 4kB block first | |
220 tstfsz ext_flash_address+0 ; at 0x....00? | |
221 bra write_byte_ext_flash_plus_nodel1; NO - execute write | |
222 movf ext_flash_address+1,W ; YES - mask lower nibble | |
223 andlw 0x0F ; - ... | |
224 tstfsz WREG ; - at 0x..0...? | |
225 bra write_byte_ext_flash_plus_nodel1; NO - execute write | |
226 ; YES - at beginning of 4kB block -> erase first! | |
227 rcall ext_flash_erase_4kB ; - erases 4kB sector @ext_flash_address:3 | |
228 bra write_byte_ext_flash_plus_nodel1; - execute write | |
423
ccaaac45b61a
_another_ timing fix for firmware updates (2.07 was not published yet anyway)
heinrichsweikamp
parents:
421
diff
changeset
|
229 |
582 | 230 |
631 | 231 global write_byte_ext_flash_plus_nodel |
232 write_byte_ext_flash_plus_nodel: | |
233 movwf ext_flash_rw ; store byte to write | |
234 write_byte_ext_flash_plus_nodel1: | |
235 rcall ext_flash_byte_write ; write the byte in ext_flash_rw | |
236 bra incf_ext_flash_address_p1_0x20 ; increase address with wrap-around at 0x200000 and return | |
237 | |
238 | |
239 global write_byte_ext_flash_plus_comms ; write from WREG without wait, ~86us fixed delay due to 115200 Baud, use with caution! | |
240 write_byte_ext_flash_plus_comms: | |
241 movwf ext_flash_rw ; store byte to write | |
242 bcf flash_wait ; do not wait on flash write to complete | |
243 rcall ext_flash_byte_write_common ; write the byte in ext_flash_rw | |
244 bra incf_ext_flash_address_p1_0x40 ; increase address with wrap-around at 0x400000 and return | |
245 | |
582 | 246 |
631 | 247 ext_flash_byte_write: |
248 bsf flash_wait ; wait for flash write to complete | |
249 ext_flash_byte_write_common: | |
250 bsf flash_ncs ; set CS=1 | |
251 movlw 0x06 ; set up WREN command | |
252 rcall shift_spi ; execute WREN command | |
253 bsf flash_ncs ; set CS=1 | |
254 movlw 0x02 ; set up write (PP, Page-Program) command | |
255 rcall shift_spi ; execute write | |
256 rcall ext_flash_set_address ; write 24 bit address ext_flash_address:3 via SPI | |
257 movf ext_flash_rw,W ; get byte to write | |
258 rcall shift_spi ; write the byte | |
259 btfsc flash_wait ; shall wait on flash write to complete? | |
260 bra ext_flash_wait_write ; YES - wait for completion (and return) | |
261 bsf flash_ncs ; NO - set CS=1 | |
262 return ; - done | |
263 | |
264 ; ---------------------------------------------------------------------------- | |
0 | 265 |
623 | 266 global ext_flash_disable_protection ; disable write protection |
582 | 267 ext_flash_disable_protection: |
268 ; unlock old memory | |
269 bsf flash_ncs ; CS=1 | |
270 movlw 0x50 ; EWSR command | |
631 | 271 rcall shift_spi |
582 | 272 bsf flash_ncs ; CS=1 |
273 movlw 0x01 ; WRSR command | |
631 | 274 rcall shift_spi |
623 | 275 movlw b'00000000' ; new status |
631 | 276 rcall shift_spi |
582 | 277 bsf flash_ncs ; CS=1 |
278 ; unlock new memory | |
279 movlw 0x06 ; WREN command | |
631 | 280 rcall shift_spi |
582 | 281 bsf flash_ncs ; CS=1 |
282 movlw 0x98 ; ULBPR command | |
631 | 283 rcall shift_spi |
582 | 284 bsf flash_ncs ; CS=1 |
285 movlw 0x06 ; WREN command | |
631 | 286 rcall shift_spi |
582 | 287 bsf flash_ncs ; CS=1 |
288 movlw 0x42 ; WBPR command | |
631 | 289 rcall shift_spi |
290 movlw .18 ; 18 bytes to do | |
291 movwf lo ; initialize loop counter | |
292 ext_flash_disable_prot_loop: | |
293 movlw 0x00 ; prepare writing a zero | |
294 rcall shift_spi ; execute write | |
295 decfsz lo,F ; all bytes done? | |
296 bra ext_flash_disable_prot_loop ; NO - loop | |
297 bsf flash_ncs ; YES - set CS=1 | |
298 return ; - done | |
0 | 299 |
623 | 300 |
0 | 301 global ext_flash_enable_protection |
302 ext_flash_enable_protection: | |
582 | 303 ; lock old memory |
631 | 304 bsf flash_ncs ; set CS=1 |
305 movlw 0x50 ; prepare EWSR command | |
306 rcall shift_spi ; execute EWSR command | |
307 bsf flash_ncs ; set CS=1 | |
308 movlw 0x01 ; prepare WRSR command | |
309 rcall shift_spi ; execute WRSR command | |
310 movlw b'00011100' ; prepare write protection on | |
311 rcall shift_spi ; execute write protection on | |
312 bsf flash_ncs ; set CS=1 | |
582 | 313 ; lock new memory |
623 | 314 ; movlw 0x06 ; WREN command |
631 | 315 ; rcall shift_spi |
623 | 316 ; bsf flash_ncs ; CS=1 |
317 ; movlw 0x8D ; LBPR command | |
631 | 318 ; rcall shift_spi |
319 ; bsf flash_ncs ; set CS=1 | |
320 movlw 0x06 ; prepare WREN command | |
321 rcall shift_spi ; execute WREN command | |
322 bsf flash_ncs ; set CS=1 | |
323 movlw 0x42 ; prepare WBPR command | |
324 rcall shift_spi ; execute WBPR command | |
325 movlw .18 ; 18 bytes to do | |
326 movwf lo ; initialize loop counter | |
327 ext_flash_enable_prot_loop: | |
328 movlw 0xFF ; prepare writing 0xFF | |
329 rcall shift_spi ; execute write | |
330 decfsz lo,F ; all bytes done? | |
331 bra ext_flash_enable_prot_loop ; NO - loop | |
332 bsf flash_ncs ; YES - set CS=1 | |
333 return ; - done | |
0 | 334 |
631 | 335 ; ---------------------------------------------------------------------------- |
0 | 336 |
631 | 337 global erase_complete_logbook |
338 erase_complete_logbook: | |
339 ; clear logbook data in EPROM | |
340 CLRT mpr ; prepare a 3 byte zero integer | |
341 EEPROM_II_WRITE mpr,eeprom_num_dives ; reset total number of dives | |
342 EEPROM_TT_WRITE mpr,eeprom_log_pointer ; reset pointer to begin of log data | |
343 ; erase logbook data in FLASH (0x000000 -> 0x2FFFFF -> 3 MByte -> 3145728 Bytes) | |
623 | 344 bsf flash_ncs ; CS=1 |
631 | 345 clrf ext_flash_address+0 ; set address to 0x000000 |
346 clrf ext_flash_address+1 ; ... | |
347 clrf ext_flash_address+2 ; ... | |
348 clrf ext_flash_rw ; write zeros | |
349 ext_flash_erase_logbook_loop: ; 256 * 12 kB = 3.145.728 bytes to do | |
350 rcall ext_flash_erase_4kB ; erase 4kB block | |
623 | 351 rcall ext_flash_add_4kB ; increase ext_flash_address:3 by 4kB |
631 | 352 rcall ext_flash_erase_4kB ; erase 4kB block |
623 | 353 rcall ext_flash_add_4kB ; increase ext_flash_address:3 by 4kB |
631 | 354 rcall ext_flash_erase_4kB ; erase 4kB block |
623 | 355 rcall ext_flash_add_4kB ; increase ext_flash_address:3 by 4kB |
356 decfsz ext_flash_rw,F ; decrement loop counter, done? | |
357 bra ext_flash_erase_logbook_loop ; NO - loop | |
358 return ; YES - done | |
0 | 359 |
631 | 360 |
361 global ext_flash_erase_4kB ; erase a 4kB sector | |
362 ext_flash_erase_4kB: | |
363 bsf flash_ncs ; set CS=1 | |
364 movlw 0x06 ; prepare WREN command | |
365 rcall shift_spi ; execute WREN command | |
366 bsf flash_ncs ; set CS=1 | |
367 movlw 0x20 ; prepare sector erase command | |
368 rcall shift_spi ; execute sector erase command | |
369 rcall ext_flash_set_address ; write 24 bit address ext_flash_address:3 via SPI | |
370 bra ext_flash_wait_write ; wait for write to complete and return | |
371 | |
372 ; ---------------------------------------------------------------------------- | |
373 | |
374 ; send address | |
375 ext_flash_set_address: | |
376 movf ext_flash_address+2,W ; write 24 bit address ext_flash_address:3 via SPI | |
377 rcall shift_spi ; ... | |
378 movf ext_flash_address+1,W ; ... | |
379 rcall shift_spi ; ... | |
380 movf ext_flash_address+0,W ; ... | |
381 bra shift_spi ; ... and return | |
382 | |
383 ; wait on write operation to complete | |
384 ext_flash_wait_write: | |
385 bsf flash_ncs ; set CS=1 | |
386 ; WAITMS d'1' ; TBE/TSE=25ms... | |
387 movlw 0x05 ; prepare RDSR command | |
388 rcall shift_spi ; 1st cycle: execute command to read status | |
389 rcall shift_spi ; 2nd cycle: read status | |
390 bsf flash_ncs ; set CS=1 | |
391 btfsc SSP2BUF,0 ; write operation still in process? | |
392 bra ext_flash_wait_write ; YES - loop waiting | |
393 return ; NO - done | |
394 | |
395 ; add 0x001000 to flash address | |
414 | 396 ext_flash_add_4kB: |
631 | 397 movlw 0x10 ; add 0x10 to high byte |
398 addwf ext_flash_address+1,F ; ... | |
399 movlw d'0' ; propagate carry to upper byte | |
400 addwfc ext_flash_address+2,F ; ... | |
401 return ; done | |
414 | 402 |
631 | 403 ; shift the SPI bus for a combined write/read: WREG --->\ /---> WREG |
404 shift_spi: ; flash chip | |
405 bcf flash_ncs ; set CS=0 | |
406 shift_spi_loop_1: | |
623 | 407 bcf SSP2STAT,WCOL ; clear flag |
408 movwf SSP2BUF ; write to buffer | |
409 btfsc SSP2STAT,WCOL ; was buffer full? | |
631 | 410 bra shift_spi_loop_1 ; YES - try again |
411 shift_spi_loop_2: | |
412 btfss SSP2STAT,BF ; buffer full? | |
413 bra shift_spi_loop_2 ; NO - loop waiting | |
414 movf SSP2BUF,W ; YES - copy received data to WREG | |
415 return ; - done | |
0 | 416 |
582 | 417 END |