Mercurial > public > hwos_code
annotate src/external_flash.asm @ 633:690c48db7b5b
3.09 beta 2 release
author | heinrichsweikamp |
---|---|
date | Thu, 05 Mar 2020 15:06:14 +0100 |
parents | 185ba2f91f59 |
children | 4050675965ea |
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) | |
633 | 177 |
178 ; btfsc flash_block_write ; does the FLASH support block-write? | |
179 ; bra ext_flash_write_range_block ; YES - write date via block operation | |
180 ; ;bra ext_flash_write_range_seq ; NO - write data via sequential single writes | |
181 | |
182 ext_flash_write_range_seq: ; sequential write | |
183 ext_flash_write_range_loop_s: | |
184 movff POSTINC1,ext_flash_rw ; read byte from memory to ext_flash_rw | |
185 rcall ext_flash_byte_write ; write byte from ext_flash_rw to FLASH | |
186 rcall incf_ext_flash_address_p1_0x40 ; increase address with wrap-around at 0x400000 | |
187 decfsz eeprom_loop,F ; decrement loop counter, all done? | |
188 bra ext_flash_write_range_loop_s ; NO - continue loop | |
189 return ; YES - done | |
190 | |
191 ext_flash_write_range_block: ; block write | |
631 | 192 movff POSTINC1,ext_flash_rw ; read first byte from memory |
193 rcall ext_flash_write_block_start ; write first byte to FLASH | |
194 bra ext_flash_write_range_loop_start; jump into loop | |
633 | 195 ext_flash_write_range_loop_b: |
631 | 196 movff POSTINC1,ext_flash_rw ; read next byte from memory |
197 rcall ext_flash_write_block ; write next byte to FLASH | |
198 ext_flash_write_range_loop_start: | |
199 decfsz eeprom_loop,F ; decrement loop counter, all done? | |
633 | 200 bra ext_flash_write_range_loop_b ; NO - continue loop |
631 | 201 bra ext_flash_write_block_stop ; YES - end writing to flash (and return) |
202 | |
203 ; ---------------------------------------------------------------------------- | |
633 | 204 |
631 | 205 ; global write_byte_ext_flash_plus_header |
206 ; write_byte_ext_flash_plus_header: | |
207 ; movwf ext_flash_rw ; store byte to write | |
208 ; ; test if write is done at first byte of 4kB block, if yes delete 4kB block first | |
209 ; tstfsz ext_flash_address+0 ; at 0x....00 ? | |
210 ; bra write_byte_ext_flash_plus_h1 ; NO - normal write | |
211 ; movf ext_flash_address+1,W ; YES - get high byte | |
212 ; andlw 0x0F ; - mask lower nibble | |
213 ; tstfsz WREG ; - at 0x..0...? | |
214 ; bra write_byte_ext_flash_plus_h1 ; NO - normal write | |
215 ; rcall ext_flash_erase_4kB ; YES - at beginning of 4kB block -> erases 4kB sector @ext_flash_address:3 | |
216 ;write_byte_ext_flash_plus_h1: | |
217 ; rcall ext_flash_byte_write ; write the byte in ext_flash_rw | |
218 ; bra incf_ext_flash_address_p1_0x40 ; increase address with wrap-around at 0x400000 and return | |
0 | 219 |
220 | |
631 | 221 global write_byte_ext_flash_plus_prof |
222 write_byte_ext_flash_plus_prof: | |
223 movwf ext_flash_rw ; store byte to write | |
224 incf ext_flash_length_counter+0,F ; increase dive length counter | |
225 movlw .0 ; ... | |
226 addwfc ext_flash_length_counter+1,F ; ... | |
227 addwfc ext_flash_length_counter+2,F ; ... | |
228 bra write_byte_ext_flash_plus_nocnt1; continue with checking for begin of new page | |
229 | |
230 | |
231 global write_byte_ext_flash_plus_nocnt | |
232 write_byte_ext_flash_plus_nocnt: | |
233 movwf ext_flash_rw ; store byte to write | |
234 write_byte_ext_flash_plus_nocnt1: ; test if write is done at first byte of 4kB block, if yes delete 4kB block first | |
235 tstfsz ext_flash_address+0 ; at 0x....00? | |
236 bra write_byte_ext_flash_plus_nodel1; NO - execute write | |
237 movf ext_flash_address+1,W ; YES - mask lower nibble | |
238 andlw 0x0F ; - ... | |
239 tstfsz WREG ; - at 0x..0...? | |
240 bra write_byte_ext_flash_plus_nodel1; NO - execute write | |
241 ; YES - at beginning of 4kB block -> erase first! | |
242 rcall ext_flash_erase_4kB ; - erases 4kB sector @ext_flash_address:3 | |
243 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
|
244 |
582 | 245 |
631 | 246 global write_byte_ext_flash_plus_nodel |
247 write_byte_ext_flash_plus_nodel: | |
248 movwf ext_flash_rw ; store byte to write | |
249 write_byte_ext_flash_plus_nodel1: | |
250 rcall ext_flash_byte_write ; write the byte in ext_flash_rw | |
251 bra incf_ext_flash_address_p1_0x20 ; increase address with wrap-around at 0x200000 and return | |
252 | |
253 | |
254 global write_byte_ext_flash_plus_comms ; write from WREG without wait, ~86us fixed delay due to 115200 Baud, use with caution! | |
255 write_byte_ext_flash_plus_comms: | |
256 movwf ext_flash_rw ; store byte to write | |
257 bcf flash_wait ; do not wait on flash write to complete | |
258 rcall ext_flash_byte_write_common ; write the byte in ext_flash_rw | |
259 bra incf_ext_flash_address_p1_0x40 ; increase address with wrap-around at 0x400000 and return | |
260 | |
582 | 261 |
631 | 262 ext_flash_byte_write: |
263 bsf flash_wait ; wait for flash write to complete | |
264 ext_flash_byte_write_common: | |
265 bsf flash_ncs ; set CS=1 | |
266 movlw 0x06 ; set up WREN command | |
267 rcall shift_spi ; execute WREN command | |
268 bsf flash_ncs ; set CS=1 | |
269 movlw 0x02 ; set up write (PP, Page-Program) command | |
270 rcall shift_spi ; execute write | |
271 rcall ext_flash_set_address ; write 24 bit address ext_flash_address:3 via SPI | |
272 movf ext_flash_rw,W ; get byte to write | |
273 rcall shift_spi ; write the byte | |
274 btfsc flash_wait ; shall wait on flash write to complete? | |
275 bra ext_flash_wait_write ; YES - wait for completion (and return) | |
276 bsf flash_ncs ; NO - set CS=1 | |
277 return ; - done | |
278 | |
279 ; ---------------------------------------------------------------------------- | |
0 | 280 |
623 | 281 global ext_flash_disable_protection ; disable write protection |
582 | 282 ext_flash_disable_protection: |
283 ; unlock old memory | |
284 bsf flash_ncs ; CS=1 | |
285 movlw 0x50 ; EWSR command | |
631 | 286 rcall shift_spi |
582 | 287 bsf flash_ncs ; CS=1 |
288 movlw 0x01 ; WRSR command | |
631 | 289 rcall shift_spi |
623 | 290 movlw b'00000000' ; new status |
631 | 291 rcall shift_spi |
582 | 292 bsf flash_ncs ; CS=1 |
293 ; unlock new memory | |
294 movlw 0x06 ; WREN command | |
631 | 295 rcall shift_spi |
582 | 296 bsf flash_ncs ; CS=1 |
297 movlw 0x98 ; ULBPR command | |
631 | 298 rcall shift_spi |
582 | 299 bsf flash_ncs ; CS=1 |
300 movlw 0x06 ; WREN command | |
631 | 301 rcall shift_spi |
582 | 302 bsf flash_ncs ; CS=1 |
303 movlw 0x42 ; WBPR command | |
631 | 304 rcall shift_spi |
305 movlw .18 ; 18 bytes to do | |
306 movwf lo ; initialize loop counter | |
307 ext_flash_disable_prot_loop: | |
308 movlw 0x00 ; prepare writing a zero | |
309 rcall shift_spi ; execute write | |
310 decfsz lo,F ; all bytes done? | |
311 bra ext_flash_disable_prot_loop ; NO - loop | |
312 bsf flash_ncs ; YES - set CS=1 | |
313 return ; - done | |
0 | 314 |
623 | 315 |
0 | 316 global ext_flash_enable_protection |
317 ext_flash_enable_protection: | |
582 | 318 ; lock old memory |
631 | 319 bsf flash_ncs ; set CS=1 |
320 movlw 0x50 ; prepare EWSR command | |
321 rcall shift_spi ; execute EWSR command | |
322 bsf flash_ncs ; set CS=1 | |
323 movlw 0x01 ; prepare WRSR command | |
324 rcall shift_spi ; execute WRSR command | |
325 movlw b'00011100' ; prepare write protection on | |
326 rcall shift_spi ; execute write protection on | |
327 bsf flash_ncs ; set CS=1 | |
582 | 328 ; lock new memory |
623 | 329 ; movlw 0x06 ; WREN command |
631 | 330 ; rcall shift_spi |
623 | 331 ; bsf flash_ncs ; CS=1 |
332 ; movlw 0x8D ; LBPR command | |
631 | 333 ; rcall shift_spi |
334 ; bsf flash_ncs ; set CS=1 | |
335 movlw 0x06 ; prepare WREN command | |
336 rcall shift_spi ; execute WREN command | |
337 bsf flash_ncs ; set CS=1 | |
338 movlw 0x42 ; prepare WBPR command | |
339 rcall shift_spi ; execute WBPR command | |
340 movlw .18 ; 18 bytes to do | |
341 movwf lo ; initialize loop counter | |
342 ext_flash_enable_prot_loop: | |
343 movlw 0xFF ; prepare writing 0xFF | |
344 rcall shift_spi ; execute write | |
345 decfsz lo,F ; all bytes done? | |
346 bra ext_flash_enable_prot_loop ; NO - loop | |
347 bsf flash_ncs ; YES - set CS=1 | |
348 return ; - done | |
0 | 349 |
631 | 350 ; ---------------------------------------------------------------------------- |
0 | 351 |
631 | 352 global erase_complete_logbook |
353 erase_complete_logbook: | |
354 ; clear logbook data in EPROM | |
355 CLRT mpr ; prepare a 3 byte zero integer | |
356 EEPROM_II_WRITE mpr,eeprom_num_dives ; reset total number of dives | |
357 EEPROM_TT_WRITE mpr,eeprom_log_pointer ; reset pointer to begin of log data | |
358 ; erase logbook data in FLASH (0x000000 -> 0x2FFFFF -> 3 MByte -> 3145728 Bytes) | |
623 | 359 bsf flash_ncs ; CS=1 |
631 | 360 clrf ext_flash_address+0 ; set address to 0x000000 |
361 clrf ext_flash_address+1 ; ... | |
362 clrf ext_flash_address+2 ; ... | |
363 clrf ext_flash_rw ; write zeros | |
364 ext_flash_erase_logbook_loop: ; 256 * 12 kB = 3.145.728 bytes to do | |
365 rcall ext_flash_erase_4kB ; erase 4kB block | |
623 | 366 rcall ext_flash_add_4kB ; increase ext_flash_address:3 by 4kB |
631 | 367 rcall ext_flash_erase_4kB ; erase 4kB block |
623 | 368 rcall ext_flash_add_4kB ; increase ext_flash_address:3 by 4kB |
631 | 369 rcall ext_flash_erase_4kB ; erase 4kB block |
623 | 370 rcall ext_flash_add_4kB ; increase ext_flash_address:3 by 4kB |
371 decfsz ext_flash_rw,F ; decrement loop counter, done? | |
372 bra ext_flash_erase_logbook_loop ; NO - loop | |
373 return ; YES - done | |
0 | 374 |
631 | 375 |
376 global ext_flash_erase_4kB ; erase a 4kB sector | |
377 ext_flash_erase_4kB: | |
378 bsf flash_ncs ; set CS=1 | |
379 movlw 0x06 ; prepare WREN command | |
380 rcall shift_spi ; execute WREN command | |
381 bsf flash_ncs ; set CS=1 | |
382 movlw 0x20 ; prepare sector erase command | |
383 rcall shift_spi ; execute sector erase command | |
384 rcall ext_flash_set_address ; write 24 bit address ext_flash_address:3 via SPI | |
385 bra ext_flash_wait_write ; wait for write to complete and return | |
386 | |
387 ; ---------------------------------------------------------------------------- | |
388 | |
389 ; send address | |
390 ext_flash_set_address: | |
391 movf ext_flash_address+2,W ; write 24 bit address ext_flash_address:3 via SPI | |
392 rcall shift_spi ; ... | |
393 movf ext_flash_address+1,W ; ... | |
394 rcall shift_spi ; ... | |
395 movf ext_flash_address+0,W ; ... | |
396 bra shift_spi ; ... and return | |
397 | |
398 ; wait on write operation to complete | |
399 ext_flash_wait_write: | |
400 bsf flash_ncs ; set CS=1 | |
401 ; WAITMS d'1' ; TBE/TSE=25ms... | |
402 movlw 0x05 ; prepare RDSR command | |
403 rcall shift_spi ; 1st cycle: execute command to read status | |
404 rcall shift_spi ; 2nd cycle: read status | |
405 bsf flash_ncs ; set CS=1 | |
406 btfsc SSP2BUF,0 ; write operation still in process? | |
407 bra ext_flash_wait_write ; YES - loop waiting | |
408 return ; NO - done | |
409 | |
410 ; add 0x001000 to flash address | |
414 | 411 ext_flash_add_4kB: |
631 | 412 movlw 0x10 ; add 0x10 to high byte |
413 addwf ext_flash_address+1,F ; ... | |
414 movlw d'0' ; propagate carry to upper byte | |
415 addwfc ext_flash_address+2,F ; ... | |
416 return ; done | |
414 | 417 |
631 | 418 ; shift the SPI bus for a combined write/read: WREG --->\ /---> WREG |
419 shift_spi: ; flash chip | |
420 bcf flash_ncs ; set CS=0 | |
421 shift_spi_loop_1: | |
623 | 422 bcf SSP2STAT,WCOL ; clear flag |
423 movwf SSP2BUF ; write to buffer | |
424 btfsc SSP2STAT,WCOL ; was buffer full? | |
631 | 425 bra shift_spi_loop_1 ; YES - try again |
426 shift_spi_loop_2: | |
427 btfss SSP2STAT,BF ; buffer full? | |
428 bra shift_spi_loop_2 ; NO - loop waiting | |
429 movf SSP2BUF,W ; YES - copy received data to WREG | |
430 return ; - done | |
0 | 431 |
582 | 432 END |