Mercurial > public > hwos_code
annotate src/external_flash.asm @ 656:8af5aefbcdaf default tip
Update to 3.31 beta
| author | heinrichsweikamp |
|---|---|
| date | Thu, 27 Nov 2025 18:32:58 +0100 |
| parents | 75e90cd0c2c3 |
| children |
| rev | line source |
|---|---|
| 0 | 1 ;============================================================================= |
| 2 ; | |
| 634 | 3 ; File external_flash.asm * combined next generation V3.09.4e |
| 0 | 4 ; |
| 5 ; External flash | |
| 6 ; | |
| 654 | 7 ; Copyright (c) 2011, JD Gascuel, heinrichs weikamp gmbh, all right reserved. |
| 0 | 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 |
