Mercurial > public > hwos_code
annotate src/external_flash.asm @ 646:5b7fe7777425
3.16 release
author | heinrichs weikamp |
---|---|
date | Thu, 14 Oct 2021 12:03:24 +0200 |
parents | 4050675965ea |
children | 75e90cd0c2c3 |
rev | line source |
---|---|
0 | 1 ;============================================================================= |
2 ; | |
634 | 3 ; File external_flash.asm * combined next generation V3.09.4e |
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 |
634 | 16 ;============================================================================= |
623 | 17 ext_flash CODE |
0 | 18 ;============================================================================= |
19 | |
634 | 20 ;----------------------------------------------------------------------------- |
21 ; increase Flash Address by one with wrap-around at 0x400000 to 0x000000 | |
22 ; | |
23 ext_flash_inc_address_0x40_p1: | |
24 movlw .1 ; increment by 1 | |
25 ;bra ext_flash_inc_address_0x40_exec ; execute incrementing | |
0 | 26 |
623 | 27 |
634 | 28 ;----------------------------------------------------------------------------- |
29 ; increase Flash Address by Value in WREG with wrap-around at 0x400000 to 0x000000 | |
30 ; | |
31 global ext_flash_inc_address_0x40_exec | |
32 ext_flash_inc_address_0x40_exec: | |
33 clrf ext_flash_address_limit ; | set wrap-around threshold to | |
34 bsf ext_flash_address_limit,6 ; | 0x40 without destroying WREG | |
631 | 35 bra incf_ext_flash_address0_common ; continue with common part |
0 | 36 |
582 | 37 |
634 | 38 ;----------------------------------------------------------------------------- |
39 ; increase Flash Address by one with wrap-around at 0x200000 to 0x000000 | |
40 ; | |
41 ext_flash_inc_address_0x20_p1: | |
42 movlw .1 ; increment by one | |
43 ;bra ext_flash_inc_address_0x20_exec ; execute incrementing | |
0 | 44 |
623 | 45 |
634 | 46 ;----------------------------------------------------------------------------- |
47 ; increase Flash Address by Value in WREG with wrap-around at 0x200000 to 0x000000 | |
48 ; | |
49 global ext_flash_inc_address_0x20_exec | |
50 ext_flash_inc_address_0x20_exec: | |
51 clrf ext_flash_address_limit ; | set wrap-around threshold to | |
52 bsf ext_flash_address_limit,5 ; | 0x20 without destroying WREG | |
631 | 53 ;bra incf_ext_flash_address0_common ; continue with common part |
0 | 54 |
55 | |
634 | 56 ;----------------------------------------------------------------------------- |
57 ; common Part for Flash Address Increasing | |
58 ; | |
631 | 59 incf_ext_flash_address0_common: |
634 | 60 bcf flash_wrap_around ; clear wrap-around flag |
631 | 61 addwf ext_flash_address+0,F ; add WREG to address:3 |
62 movlw d'0' ; ... | |
63 addwfc ext_flash_address+1,F ; ... | |
64 addwfc ext_flash_address+2,F ; ... | |
634 | 65 movf ext_flash_address_limit,W ; get wrap-around threshold |
631 | 66 cpfseq ext_flash_address+2 ; at wrap-around threshold ? |
67 bra incf_ext_flash_address1 ; NO - no wrap-around needed | |
68 ; clrf ext_flash_address+0 ; YES - wrap-around to 0x000000 | |
69 ; clrf ext_flash_address+1 ; - ... | |
70 clrf ext_flash_address+2 ; - ... | |
634 | 71 bsf flash_wrap_around ; - set wrap-around flag |
631 | 72 incf_ext_flash_address1: |
73 movf ext_flash_rw,W ; export current value of ext_flash_rw via WREG, too | |
74 return ; done | |
0 | 75 |
582 | 76 |
634 | 77 ;----------------------------------------------------------------------------- |
78 ; add 0x001000 to Flash Address, no Check for wrap-around | |
79 ; | |
80 global ext_flash_inc_address_4kB | |
81 ext_flash_inc_address_4kB: | |
82 movlw 0x10 ; add 0x10 to high byte | |
83 addwf ext_flash_address+1,F ; ... | |
84 movlw 0x00 ; propagate carry to upper byte | |
85 addwfc ext_flash_address+2,F ; ... | |
86 return ; done | |
87 | |
88 | |
89 ;----------------------------------------------------------------------------- | |
90 ; decrement Length Counter by 1 | |
91 ; | |
92 global ext_flash_dec_length_exec | |
93 ext_flash_dec_length_exec: | |
94 movlw .1 ; decrement by 1 | |
95 subwf ext_flash_length_counter+0,F ; ... | |
631 | 96 movlw d'0' ; ... |
97 subwfb ext_flash_length_counter+1,F ; ... | |
98 subwfb ext_flash_length_counter+2,F ; ... | |
99 return ; done | |
100 | |
0 | 101 |
634 | 102 ;----------------------------------------------------------------------------- |
103 ; read a Byte from Flash and increment Address with wrap-around at 0x20 / 0x40 | |
104 ; returns in ext_flash_rw and WREG | |
105 ; | |
106 global ext_flash_read_byte_0x40 | |
107 ext_flash_read_byte_0x40: | |
108 bsf flash_wrap_around ; wrap-around at 0x400000 | |
109 bra ext_flash_read_byte_common ; continue with common part | |
582 | 110 |
634 | 111 global ext_flash_read_byte_0x20 |
112 ext_flash_read_byte_0x20: | |
113 bcf flash_wrap_around ; wrap-around at 0x200000 | |
114 ;bra ext_flash_read_byte_common ; continue with common part | |
0 | 115 |
634 | 116 ext_flash_read_byte_common: |
117 movlw 0x03 ; prepare read command | |
118 rcall shift_spi ; execute read command | |
631 | 119 rcall ext_flash_set_address ; write 24 bit address ext_flash_address:3 via SPI |
120 rcall shift_spi ; shift the SPI to read data into WREG | |
121 bsf flash_ncs ; set CS=1 | |
634 | 122 movwf ext_flash_rw ; copy byte read from WREG to ext_flash_rw |
123 btfss flash_wrap_around ; shall wrap-around at 0x40000 ? | |
124 bra ext_flash_inc_address_0x20_p1 ; NO - increment address with wrap-around at 0x200000 and return | |
125 bra ext_flash_inc_address_0x40_p1 ; YES - increment address with wrap-around at 0x200000 and return | |
582 | 126 |
0 | 127 |
634 | 128 ;----------------------------------------------------------------------------- |
129 ; Read-Range Base Functions - start reading | |
130 ; | |
623 | 131 global ext_flash_read_block_start ; return data read in WREG |
0 | 132 ext_flash_read_block_start: |
631 | 133 movlw 0x03 ; set up read command |
134 rcall shift_spi ; execute read command | |
135 rcall ext_flash_set_address ; write 24 bit address ext_flash_address:3 via SPI | |
136 bra shift_spi ; shift the SPI to read data into WREG (and return) | |
0 | 137 |
582 | 138 |
634 | 139 ;----------------------------------------------------------------------------- |
140 ; Read-Range Base Functions - increment Address and read a Byte, wrap-around at 0x40 | |
141 ; | |
631 | 142 global ext_flash_read_block_0x40 ; return data read in WREG |
143 ext_flash_read_block_0x40: | |
634 | 144 rcall ext_flash_inc_address_0x40_p1 ; increase address with wrap-around at 0x400000 |
145 btfss flash_wrap_around ; did the address wrap-around? | |
631 | 146 bra shift_spi_loop_1 ; NO - shift the SPI to read data into WREG and return |
147 rcall ext_flash_read_block_stop ; YES - do a block-stop | |
148 bra ext_flash_read_block_start ; - do a block-start, read data into WREG and return | |
0 | 149 |
150 | |
634 | 151 ;----------------------------------------------------------------------------- |
152 ; Read-Range Base Functions - increment Address and read a Byte, wrap-around at 0x20 | |
153 ; | |
154 ; global ext_flash_read_block_0x20 ; return data read in WREG | |
155 ;ext_flash_read_block_0x20: | |
156 ; rcall ext_flash_inc_address_0x20_p1 ; increase address with wrap-around at 0x200000 | |
157 ; btfss flash_wrap_around ; did the address wrap-around? | |
158 ; bra shift_spi_loop_1 ; NO - shift the SPI to read data into WREG and return | |
159 ; rcall ext_flash_read_block_stop ; YES - do a block-stop | |
160 ; bra ext_flash_read_block_start ; - do a block-start, read data into WREG and return | |
161 | |
162 | |
163 ;----------------------------------------------------------------------------- | |
164 ; Read-Range Base Functions - terminate reading | |
165 ; | |
631 | 166 global ext_flash_read_block_stop ; end block operation |
167 ext_flash_read_block_stop: | |
168 bsf flash_ncs ; set CS=1 | |
169 return ; done | |
170 | |
634 | 171 |
631 | 172 ; ---------------------------------------------------------------------------- |
634 | 173 ; read a Range of Bytes, to be used via Macro |
631 | 174 ; |
175 global ext_flash_read_range | |
176 ext_flash_read_range: | |
177 movwf eeprom_loop ; load loop counter (eeprom variable used here) | |
634 | 178 rcall ext_flash_read_block_start ; read first byte from FLASH to WREG |
631 | 179 bra ext_flash_read_range_loop_start ; jump into loop |
180 ext_flash_read_range_loop: | |
634 | 181 rcall shift_spi_loop_1 ; read next byte from FLASH to WREG |
631 | 182 ext_flash_read_range_loop_start: |
634 | 183 movwf POSTINC1 ; write byte from WREG to memory |
631 | 184 decfsz eeprom_loop,F ; decrement loop counter, all done? |
185 bra ext_flash_read_range_loop ; NO - continue loop | |
186 bra ext_flash_read_block_stop ; YES - end reading from flash (and return) | |
582 | 187 |
279 | 188 |
631 | 189 ; ---------------------------------------------------------------------------- |
634 | 190 ; Write-Range Base Functions - for use with SST26VF Chip only! |
191 ; | |
631 | 192 ext_flash_write_block_start: |
634 | 193 movwf ext_flash_rw ; copy byte to write from WREG to ext_flash_rw |
631 | 194 bsf flash_ncs ; set CS=1 |
195 movlw 0x06 ; set up WREN command | |
196 rcall shift_spi ; execute WREN command | |
197 bsf flash_ncs ; set CS=1 | |
198 movlw 0x02 ; set up write (PP, Page-Program) command | |
199 rcall shift_spi ; execute write | |
200 rcall ext_flash_set_address ; write 24 bit address ext_flash_address:3 via SPI | |
634 | 201 movf ext_flash_rw,W ; get back byte to write |
631 | 202 bra shift_spi ; write the byte (and return) |
203 | |
204 ext_flash_write_block: | |
205 bra shift_spi_loop_1 ; shift the SPI to write data into FLASH (and return) | |
206 | |
207 ext_flash_write_block_stop: | |
208 bra ext_flash_wait_write ; wait for completion (and return) | |
0 | 209 |
634 | 210 |
631 | 211 ; ---------------------------------------------------------------------------- |
634 | 212 ; write a Range of Bytes, to be used via Macro |
631 | 213 ; |
214 global ext_flash_write_range | |
215 ext_flash_write_range: | |
216 movwf eeprom_loop ; load loop counter (eeprom variable used here) | |
633 | 217 |
634 | 218 btfsc flash_block_write ; does the FLASH support block-write? |
219 bra ext_flash_write_range_block ; YES - write data in block mode | |
220 ;bra ext_flash_write_range_seq ; NO - write data in sequential mode | |
633 | 221 |
634 | 222 ; sequential write |
223 ext_flash_write_range_seq: | |
224 bsf flash_wait ; wait for flash writes to complete | |
225 ext_flash_write_range_seq_loop: | |
226 movf POSTINC1,W ; copy byte from memory to WREG | |
227 rcall ext_flash_byte_write_common_W ; write byte from WREG to FLASH | |
228 rcall ext_flash_inc_address_0x40_p1 ; increase address with wrap-around at 0x400000 | |
633 | 229 decfsz eeprom_loop,F ; decrement loop counter, all done? |
634 | 230 bra ext_flash_write_range_seq_loop ; NO - loop |
633 | 231 return ; YES - done |
232 | |
634 | 233 ; block write |
234 ext_flash_write_range_block: | |
235 movf POSTINC1,W ; copy first byte from memory to WREG | |
236 rcall ext_flash_write_block_start ; copy first byte from WREG to FLASH | |
631 | 237 bra ext_flash_write_range_loop_start; jump into loop |
634 | 238 ext_flash_write_range_block_loop: |
239 movf POSTINC1,W ; copy next byte from memory to WREG | |
240 rcall ext_flash_write_block ; copy next byte from WREG to FLASH | |
631 | 241 ext_flash_write_range_loop_start: |
242 decfsz eeprom_loop,F ; decrement loop counter, all done? | |
634 | 243 bra ext_flash_write_range_block_loop; NO - loop |
244 rcall ext_flash_write_block_stop ; YES - initiate FLASH write | |
245 clrf ext_flash_address+0 ; - advance address to start of next block | |
246 infsnz ext_flash_address+1,F ; - ... | |
247 incf ext_flash_address+2,F ; - ... | |
248 return ; - done | |
0 | 249 |
250 | |
634 | 251 ;----------------------------------------------------------------------------- |
252 ; write a Byte with wrap-around at 0x200000, | |
253 ; erase on entering new 4kB Block, | |
254 ; increment Dive Length Counter | |
255 ; | |
256 global ext_flash_write_byte_0x20_incdc | |
257 ext_flash_write_byte_0x20_incdc: | |
631 | 258 movwf ext_flash_rw ; store byte to write |
259 incf ext_flash_length_counter+0,F ; increase dive length counter | |
260 movlw .0 ; ... | |
261 addwfc ext_flash_length_counter+1,F ; ... | |
262 addwfc ext_flash_length_counter+2,F ; ... | |
634 | 263 bra write_byte_ext_flash_plus_nocnt1; continue with checking for begin of new block |
631 | 264 |
265 | |
634 | 266 ;----------------------------------------------------------------------------- |
267 ; write a Byte with wrap-around at 0x200000, | |
268 ; erase on entering new 4kB Block | |
269 ; | |
270 global ext_flash_write_byte_0x20 | |
271 ext_flash_write_byte_0x20: | |
631 | 272 movwf ext_flash_rw ; store byte to write |
634 | 273 write_byte_ext_flash_plus_nocnt1: |
274 ; check if at 1st byte of a 4kB block, | |
275 ; if yes the block needs to be erased | |
276 ; before new data can be written to it | |
277 tstfsz ext_flash_address+0 ; is the low byte of the address = 0x00 ? | |
278 bra write_byte_ext_flash_plus_nodel1; NO - not at 1st byte, can execute write | |
279 movf ext_flash_address+1,W ; YES - get high byte of the address | |
280 andlw 0x0F ; - keep only the lower nibble | |
281 tstfsz WREG ; - is the lower nibble = 0x0 ? | |
282 bra write_byte_ext_flash_plus_nodel1; NO - not at 1st byte, can execute write | |
283 rcall ext_flash_erase_4kB ; YES - at 1st byte, erase 4kB block | |
631 | 284 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
|
285 |
582 | 286 |
634 | 287 ;----------------------------------------------------------------------------- |
288 ; write a Byte with wrap-around at 0x200000 | |
289 ; NO erase on entering new 4kB Block | |
290 ; | |
291 global ext_flash_write_byte_0x20_nodel | |
292 ext_flash_write_byte_0x20_nodel: | |
631 | 293 movwf ext_flash_rw ; store byte to write |
294 write_byte_ext_flash_plus_nodel1: | |
634 | 295 bsf flash_wait ; wait for flash write to complete |
296 rcall ext_flash_byte_write_common_F ; write the byte in ext_flash_rw | |
297 bra ext_flash_inc_address_0x20_p1 ; increase address with wrap-around at 0x200000 and return | |
631 | 298 |
299 | |
634 | 300 ;----------------------------------------------------------------------------- |
301 ; write a Byte without Wait (used by comm mode) | |
302 ; | |
303 ; time budget for flash to complete a write is ~86 us at 115200 Baud on serial | |
304 ; | |
305 global ext_flash_write_byte_0x40_nowait | |
306 ext_flash_write_byte_0x40_nowait: | |
631 | 307 bcf flash_wait ; do not wait on flash write to complete |
634 | 308 rcall ext_flash_byte_write_common_W ; write the byte in WREG |
309 bra ext_flash_inc_address_0x40_p1 ; increase address with wrap-around at 0x400000 and return | |
631 | 310 |
582 | 311 |
634 | 312 ;----------------------------------------------------------------------------- |
313 ; internal common Write Functions W: WREG -> FLASH(ext_flash_address) | |
314 ; F: ext_flash_rw -> FLASH(ext_flash_address) | |
315 ; | |
316 ext_flash_byte_write_common_W: | |
317 movwf ext_flash_rw ; copy byte to write from WREG to ext_flash_rw | |
318 ext_flash_byte_write_common_F: | |
631 | 319 bsf flash_ncs ; set CS=1 |
320 movlw 0x06 ; set up WREN command | |
321 rcall shift_spi ; execute WREN command | |
322 bsf flash_ncs ; set CS=1 | |
634 | 323 movlw 0x02 ; prepare write (PP, Page-Program) command |
631 | 324 rcall shift_spi ; execute write |
325 rcall ext_flash_set_address ; write 24 bit address ext_flash_address:3 via SPI | |
634 | 326 movf ext_flash_rw,W ; get back byte to write |
631 | 327 rcall shift_spi ; write the byte |
328 btfsc flash_wait ; shall wait on flash write to complete? | |
329 bra ext_flash_wait_write ; YES - wait for completion (and return) | |
330 bsf flash_ncs ; NO - set CS=1 | |
331 return ; - done | |
332 | |
0 | 333 |
634 | 334 ;----------------------------------------------------------------------------- |
335 ; switch off Write-Protection | |
336 ; | |
623 | 337 global ext_flash_disable_protection ; disable write protection |
582 | 338 ext_flash_disable_protection: |
339 ; unlock old memory | |
634 | 340 bsf flash_ncs ; set CS=1 |
341 movlw 0x50 ; prepare EWSR command | |
342 rcall shift_spi ; execute EWSR command | |
343 bsf flash_ncs ; set CS=1 | |
344 movlw 0x01 ; prepare WRSR command | |
345 rcall shift_spi ; execute WRSR command | |
346 movlw b'00000000' ; prepare new status | |
347 rcall shift_spi ; set new status | |
348 | |
582 | 349 ; unlock new memory |
634 | 350 bsf flash_ncs ; set CS=1 |
351 movlw 0x06 ; prepare WREN command | |
352 rcall shift_spi ; execute WREN command | |
353 bsf flash_ncs ; set CS=1 | |
354 movlw 0x98 ; prepare ULBPR command | |
355 rcall shift_spi ; execute ULBPR command | |
356 bsf flash_ncs ; set CS=1 | |
357 movlw 0x06 ; prepare WREN command | |
358 rcall shift_spi ; execute WREN command | |
359 bsf flash_ncs ; set CS=1 | |
360 movlw 0x42 ; prepare WBPR command | |
361 rcall shift_spi ; execute WBPR command | |
362 | |
631 | 363 movlw .18 ; 18 bytes to do |
364 movwf lo ; initialize loop counter | |
365 ext_flash_disable_prot_loop: | |
366 movlw 0x00 ; prepare writing a zero | |
634 | 367 rcall shift_spi ; write a zero |
631 | 368 decfsz lo,F ; all bytes done? |
369 bra ext_flash_disable_prot_loop ; NO - loop | |
370 bsf flash_ncs ; YES - set CS=1 | |
371 return ; - done | |
0 | 372 |
623 | 373 |
634 | 374 ;----------------------------------------------------------------------------- |
375 ; switch on Write-Protection | |
376 ; | |
0 | 377 global ext_flash_enable_protection |
378 ext_flash_enable_protection: | |
582 | 379 ; lock old memory |
631 | 380 bsf flash_ncs ; set CS=1 |
381 movlw 0x50 ; prepare EWSR command | |
382 rcall shift_spi ; execute EWSR command | |
383 bsf flash_ncs ; set CS=1 | |
384 movlw 0x01 ; prepare WRSR command | |
385 rcall shift_spi ; execute WRSR command | |
386 movlw b'00011100' ; prepare write protection on | |
387 rcall shift_spi ; execute write protection on | |
634 | 388 |
582 | 389 ; lock new memory |
634 | 390 bsf flash_ncs ; set CS=1 |
391 ; movlw 0x06 ; prepare WREN command | |
392 ; rcall shift_spi ; execute WREN command | |
393 ; bsf flash_ncs ; set CS=1 | |
394 ; movlw 0x8D ; prepare LBPR command | |
395 ; rcall shift_spi ; execute LBPR command | |
631 | 396 ; bsf flash_ncs ; set CS=1 |
397 movlw 0x06 ; prepare WREN command | |
398 rcall shift_spi ; execute WREN command | |
399 bsf flash_ncs ; set CS=1 | |
400 movlw 0x42 ; prepare WBPR command | |
401 rcall shift_spi ; execute WBPR command | |
634 | 402 |
631 | 403 movlw .18 ; 18 bytes to do |
404 movwf lo ; initialize loop counter | |
405 ext_flash_enable_prot_loop: | |
406 movlw 0xFF ; prepare writing 0xFF | |
634 | 407 rcall shift_spi ; write a zero |
631 | 408 decfsz lo,F ; all bytes done? |
409 bra ext_flash_enable_prot_loop ; NO - loop | |
410 bsf flash_ncs ; YES - set CS=1 | |
411 return ; - done | |
0 | 412 |
413 | |
634 | 414 ;----------------------------------------------------------------------------- |
415 ; erase complete Logbook | |
416 ; | |
631 | 417 global erase_complete_logbook |
418 erase_complete_logbook: | |
634 | 419 ; set address to 0x000000 / prepare a 3 byte zero integer |
420 CLRT ext_flash_address | |
421 | |
422 ; clear logbook data in EPROM by writing all zeros | |
423 EEPROM_II_WRITE ext_flash_address,eeprom_num_dives ; reset the total number of dives | |
424 EEPROM_TT_WRITE ext_flash_address,eeprom_log_pointer ; reset pointer to begin of profile data | |
425 | |
426 ; erase logbook data in FLASH from 0x000000 - 0x2FFFFF = 3 MByte = 3 * 256 blocks * 4 kB/block | |
427 | |
428 clrf WREG ; erase 256 blocks per call | |
429 rcall ext_flash_erase_range ; erase 1st bunch of 256 blocks | |
430 rcall ext_flash_erase_range_loop ; erase 2nd bunch of 256 blocks | |
431 rcall ext_flash_erase_range_loop ; erase 3rd bunch of 256 blocks | |
432 return ; done | |
0 | 433 |
631 | 434 |
634 | 435 ;----------------------------------------------------------------------------- |
436 ; erase a Number of 4kB Blocks | |
437 ; | |
438 global ext_flash_erase_range | |
439 ext_flash_erase_range: | |
440 movwf eeprom_loop ; initialize loop counter | |
441 ext_flash_erase_range_loop: | |
442 rcall ext_flash_erase_4kB ; erase one block | |
443 rcall ext_flash_inc_address_4kB ; increase start address by 0x1000 (4kB) | |
444 btfsc ext_flash_address+2,6 ; reached 0x400000 ? | |
445 return ; YES - reached end of address range, done anyhow | |
446 decfsz eeprom_loop,F ; NO - decrement number of blocks to do, all blocks done? | |
447 bra ext_flash_erase_range_loop ; NO - loop | |
448 return ; YES - done, back to command loop | |
449 | |
450 | |
451 ;----------------------------------------------------------------------------- | |
452 ; erase one 4kB Block | |
453 ; | |
454 global ext_flash_erase_4kB | |
631 | 455 ext_flash_erase_4kB: |
456 bsf flash_ncs ; set CS=1 | |
457 movlw 0x06 ; prepare WREN command | |
458 rcall shift_spi ; execute WREN command | |
459 bsf flash_ncs ; set CS=1 | |
634 | 460 movlw 0x20 ; prepare block erase command |
461 rcall shift_spi ; execute block erase command | |
631 | 462 rcall ext_flash_set_address ; write 24 bit address ext_flash_address:3 via SPI |
463 bra ext_flash_wait_write ; wait for write to complete and return | |
464 | |
465 | |
634 | 466 ;----------------------------------------------------------------------------- |
467 ; read JEDEC IDs | |
468 ; | |
469 global ext_flash_read_jedec | |
470 ext_flash_read_jedec: | |
471 movlw 0x9F ; prepare JEDEC read command | |
472 rcall shift_spi ; execute JEDEC read command | |
473 rcall shift_spi ; shift the SPI to read the manufacturer ID into WREG | |
474 movwf lo ; store the manufacturer ID in lo | |
475 rcall shift_spi ; shift the SPI to read the device type ID into WREG | |
476 movwf hi ; store the device type ID in hi | |
477 rcall shift_spi ; shift the SPI to read the device model ID into WREG | |
478 movwf up ; store the device model ID in up | |
479 bsf flash_ncs ; set CS=1 | |
480 return ; done | |
481 | |
482 | |
483 ;----------------------------------------------------------------------------- | |
484 ; low level Functions - send Address | |
485 ; | |
631 | 486 ext_flash_set_address: |
487 movf ext_flash_address+2,W ; write 24 bit address ext_flash_address:3 via SPI | |
488 rcall shift_spi ; ... | |
489 movf ext_flash_address+1,W ; ... | |
490 rcall shift_spi ; ... | |
491 movf ext_flash_address+0,W ; ... | |
492 bra shift_spi ; ... and return | |
493 | |
634 | 494 |
495 ;----------------------------------------------------------------------------- | |
496 ; low level Functions - wait for Completion of a Write Operation | |
497 ; | |
631 | 498 ext_flash_wait_write: |
499 bsf flash_ncs ; set CS=1 | |
500 ; WAITMS d'1' ; TBE/TSE=25ms... | |
501 movlw 0x05 ; prepare RDSR command | |
502 rcall shift_spi ; 1st cycle: execute command to read status | |
503 rcall shift_spi ; 2nd cycle: read status | |
504 bsf flash_ncs ; set CS=1 | |
505 btfsc SSP2BUF,0 ; write operation still in process? | |
506 bra ext_flash_wait_write ; YES - loop waiting | |
507 return ; NO - done | |
508 | |
414 | 509 |
634 | 510 ;----------------------------------------------------------------------------- |
511 ; low level functions - shift the SPI Bus for a combined Write/Read | |
512 ; | |
513 ; WREG --> write --->\ /---> read --> WREG | |
514 ; flash chip | |
515 ; | |
516 shift_spi: | |
631 | 517 bcf flash_ncs ; set CS=0 |
518 shift_spi_loop_1: | |
623 | 519 bcf SSP2STAT,WCOL ; clear flag |
520 movwf SSP2BUF ; write to buffer | |
521 btfsc SSP2STAT,WCOL ; was buffer full? | |
631 | 522 bra shift_spi_loop_1 ; YES - try again |
523 shift_spi_loop_2: | |
524 btfss SSP2STAT,BF ; buffer full? | |
525 bra shift_spi_loop_2 ; NO - loop waiting | |
526 movf SSP2BUF,W ; YES - copy received data to WREG | |
527 return ; - done | |
0 | 528 |
634 | 529 |
530 IFDEF _firmware_recovery | |
531 | |
532 ;----------------------------------------------------------------------------- | |
533 ; copy active Firmware to Backup Storage | |
534 ; | |
535 global copy_fw_active_to_backup | |
536 copy_fw_active_to_backup: | |
537 ; erase FLASH for recovery firmware (120 kByte = 30 * 4 kByte) | |
538 rcall ext_flash_to_recovery_fw ; set ext_flash_address to 0x3C0000 | |
539 movlw .30 ; 30 blocks to do | |
540 rcall ext_flash_erase_range ; erase #WREG 4kB blocks starting at ext_flash_address | |
541 | |
542 ; copy firmware (120 kByte = 2 x 240 x 256 byte) | |
543 rcall ext_flash_to_productive_fw ; set ext_flash_address to 0x3E0000 | |
544 clrf hi ; flag in 1st round | |
545 copy_fw_active_to_backup_loop1: | |
546 movlw .240 ; load loop counter | |
547 movwf lo ; ... | |
548 copy_fw_active_to_backup_loop2: | |
549 ; read active firmware | |
550 bsf ext_flash_address+2,1 ; switch to productive firmware | |
551 lfsr FSR1,buffer ; set start address in memory | |
552 movlw low(.256) ; set size of range to read | |
553 rcall ext_flash_read_range ; execute range-read (ext_flash_address NOT incremented) | |
554 ; write to backup storage | |
555 bcf ext_flash_address+2,1 ; switch to backup storage | |
556 lfsr FSR1,buffer ; set start address in memory | |
557 movlw low(.256) ; set size of range to write | |
558 rcall ext_flash_write_range ; execute range-write (ext_flash_address GETS incremented) | |
559 ; operate loop | |
560 decfsz lo,F ; decrement loop counter, done? | |
561 bra copy_fw_active_to_backup_loop2 ; NO - continue copying | |
562 tstfsz hi ; YES - 2nd round finished? | |
563 return ; YES - done | |
564 setf hi ; NO - flag in 2nd round now | |
565 bra copy_fw_active_to_backup_loop1 ; - start 2nd round | |
566 | |
567 | |
568 ;----------------------------------------------------------------------------- | |
569 ; copy Backup-Firmware to Update Storage | |
570 ; | |
571 global copy_fw_backup_to_active | |
572 copy_fw_backup_to_active: | |
573 ; erase FLASH for productive firmware (120 kByte = 30 * 4 kByte) | |
574 rcall ext_flash_to_productive_fw ; set ext_flash_address to 0x3E0000 | |
575 movlw .30 ; 30 blocks to do | |
576 rcall ext_flash_erase_range ; erase #WREG 4kB blocks starting at ext_flash_address | |
577 | |
578 ; copy firmware (120 kByte = 2 x 240 x 256 byte) | |
579 rcall ext_flash_to_recovery_fw ; set ext_flash_address to 0x3C0000 | |
580 clrf hi ; flag in 1st round | |
581 copy_fw_backup_to_active_loop1: | |
582 movlw .240 ; load loop counter | |
583 movwf lo ; ... | |
584 copy_fw_backup_to_active_loop2: | |
585 ; read backup firmware | |
586 bcf ext_flash_address+2,1 ; switch to backup firmware | |
587 lfsr FSR1,buffer ; set start address in memory | |
588 movlw low(.256) ; set size of range to read | |
589 rcall ext_flash_read_range ; execute range-read (ext_flash_address NOT incremented) | |
590 ; write to update storage | |
591 bsf ext_flash_address+2,1 ; switch to update storage | |
592 lfsr FSR1,buffer ; set start address in memory | |
593 movlw low(.256) ; set size of range to write | |
594 rcall ext_flash_write_range ; execute range-write (ext_flash_address GETS incremented) | |
595 ; operate loop | |
596 decfsz lo,F ; decrement loop counter, done? | |
597 bra copy_fw_backup_to_active_loop2 ; NO - continue copying | |
598 tstfsz hi ; YES - 2nd round finished? | |
599 return ; YES - done | |
600 setf hi ; NO - flag in 2nd round now | |
601 bra copy_fw_backup_to_active_loop1 ; - start 2nd round | |
602 | |
603 | |
604 ;----------------------------------------------------------------------------- | |
605 ; Helper Functions - point ext_flash_address to active / backup firmware storage | |
606 ; | |
607 ext_flash_to_recovery_fw | |
608 movlw 0x3C ; 0x3C| | |
609 bra ext_flash_common | |
610 | |
611 ext_flash_to_productive_fw: | |
612 movlw 0x3E ; 0x3E| | |
613 ;bra ext_flash_common | |
614 | |
615 ext_flash_common: | |
616 movwf ext_flash_address+2 ; ....| | |
617 clrf ext_flash_address+1 ; ....|00| | |
618 clrf ext_flash_address+0 ; .......|00 | |
619 return | |
620 | |
621 ENDIF | |
622 | |
623 ;----------------------------------------------------------------------------- | |
624 | |
582 | 625 END |