Mercurial > public > hwos_code
comparison src/external_flash.asm @ 634:4050675965ea
3.10 stable release
author | heinrichsweikamp |
---|---|
date | Tue, 28 Apr 2020 17:34:31 +0200 |
parents | 690c48db7b5b |
children | 75e90cd0c2c3 |
comparison
equal
deleted
inserted
replaced
633:690c48db7b5b | 634:4050675965ea |
---|---|
1 ;============================================================================= | 1 ;============================================================================= |
2 ; | 2 ; |
3 ; File external_flash.asm combined next generation V3.08.8 | 3 ; File external_flash.asm * combined next generation V3.09.4e |
4 ; | 4 ; |
5 ; External flash | 5 ; External flash |
6 ; | 6 ; |
7 ; Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved. | 7 ; Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved. |
8 ;============================================================================= | 8 ;============================================================================= |
11 | 11 |
12 #include "hwos.inc" | 12 #include "hwos.inc" |
13 #include "wait.inc" | 13 #include "wait.inc" |
14 #include "eeprom_rs232.inc" | 14 #include "eeprom_rs232.inc" |
15 | 15 |
16 ;============================================================================= | |
16 ext_flash CODE | 17 ext_flash CODE |
17 | |
18 ;============================================================================= | 18 ;============================================================================= |
19 | 19 |
20 ; increase flash address by one with wrap-around at 0x400000 to 0x000000 | 20 ;----------------------------------------------------------------------------- |
21 incf_ext_flash_address_p1_0x40: | 21 ; increase Flash Address by one with wrap-around at 0x400000 to 0x000000 |
22 movlw .1 ; increase by 1 | 22 ; |
23 ;bra incf_ext_flash_address0_0x40 ; continue | 23 ext_flash_inc_address_0x40_p1: |
24 | 24 movlw .1 ; increment by 1 |
25 | 25 ;bra ext_flash_inc_address_0x40_exec ; execute incrementing |
26 ; increase flash address by value in WREG with wrap-around at 0x400000 to 0x000000 | 26 |
27 global incf_ext_flash_address0_0x40 | 27 |
28 incf_ext_flash_address0_0x40: | 28 ;----------------------------------------------------------------------------- |
29 clrf ext_flash_rollover_threshold ; set wrap-around threshold without destroying WREG to ... | 29 ; increase Flash Address by Value in WREG with wrap-around at 0x400000 to 0x000000 |
30 bsf ext_flash_rollover_threshold,6 ; ... 0x40 | 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 | |
31 bra incf_ext_flash_address0_common ; continue with common part | 35 bra incf_ext_flash_address0_common ; continue with common part |
32 | 36 |
33 | 37 |
34 ; increase flash address by one with wrap-around at 0x200000 to 0x000000 | 38 ;----------------------------------------------------------------------------- |
35 incf_ext_flash_address_p1_0x20: | 39 ; increase Flash Address by one with wrap-around at 0x200000 to 0x000000 |
36 movlw .1 ; increase by one | 40 ; |
37 ;bra incf_ext_flash_address0_0x20 ; continue | 41 ext_flash_inc_address_0x20_p1: |
38 | 42 movlw .1 ; increment by one |
39 | 43 ;bra ext_flash_inc_address_0x20_exec ; execute incrementing |
40 ; increase flash address by value in WREG with wrap-around at 0x200000 to 0x000000 | 44 |
41 global incf_ext_flash_address0_0x20 | 45 |
42 incf_ext_flash_address0_0x20: | 46 ;----------------------------------------------------------------------------- |
43 clrf ext_flash_rollover_threshold ; set wrap-around threshold without destroying WREG to ... | 47 ; increase Flash Address by Value in WREG with wrap-around at 0x200000 to 0x000000 |
44 bsf ext_flash_rollover_threshold,5 ; ... 0x20 | 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 | |
45 ;bra incf_ext_flash_address0_common ; continue with common part | 53 ;bra incf_ext_flash_address0_common ; continue with common part |
46 | 54 |
47 | 55 |
56 ;----------------------------------------------------------------------------- | |
57 ; common Part for Flash Address Increasing | |
58 ; | |
48 incf_ext_flash_address0_common: | 59 incf_ext_flash_address0_common: |
49 bcf address_wrap_around ; clear wrap-around flag | 60 bcf flash_wrap_around ; clear wrap-around flag |
50 addwf ext_flash_address+0,F ; add WREG to address:3 | 61 addwf ext_flash_address+0,F ; add WREG to address:3 |
51 movlw d'0' ; ... | 62 movlw d'0' ; ... |
52 addwfc ext_flash_address+1,F ; ... | 63 addwfc ext_flash_address+1,F ; ... |
53 addwfc ext_flash_address+2,F ; ... | 64 addwfc ext_flash_address+2,F ; ... |
54 movf ext_flash_rollover_threshold,W ; get wrap-around threshold | 65 movf ext_flash_address_limit,W ; get wrap-around threshold |
55 cpfseq ext_flash_address+2 ; at wrap-around threshold ? | 66 cpfseq ext_flash_address+2 ; at wrap-around threshold ? |
56 bra incf_ext_flash_address1 ; NO - no wrap-around needed | 67 bra incf_ext_flash_address1 ; NO - no wrap-around needed |
57 ; clrf ext_flash_address+0 ; YES - wrap-around to 0x000000 | 68 ; clrf ext_flash_address+0 ; YES - wrap-around to 0x000000 |
58 ; clrf ext_flash_address+1 ; - ... | 69 ; clrf ext_flash_address+1 ; - ... |
59 clrf ext_flash_address+2 ; - ... | 70 clrf ext_flash_address+2 ; - ... |
60 bsf address_wrap_around ; - set wrap-around flag | 71 bsf flash_wrap_around ; - set wrap-around flag |
61 incf_ext_flash_address1: | 72 incf_ext_flash_address1: |
62 movf ext_flash_rw,W ; export current value of ext_flash_rw via WREG, too | 73 movf ext_flash_rw,W ; export current value of ext_flash_rw via WREG, too |
63 return ; done | 74 return ; done |
64 | 75 |
65 | 76 |
66 ; decrease flash length counter by value in WREG | 77 ;----------------------------------------------------------------------------- |
67 global decf_ext_flash_length0 | 78 ; add 0x001000 to Flash Address, no Check for wrap-around |
68 decf_ext_flash_length0: | 79 ; |
69 subwf ext_flash_length_counter+0,F ; decrease address by value in WREG | 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 ; ... | |
70 movlw d'0' ; ... | 96 movlw d'0' ; ... |
71 subwfb ext_flash_length_counter+1,F ; ... | 97 subwfb ext_flash_length_counter+1,F ; ... |
72 subwfb ext_flash_length_counter+2,F ; ... | 98 subwfb ext_flash_length_counter+2,F ; ... |
73 return ; done | 99 return ; done |
74 | 100 |
75 ; ---------------------------------------------------------------------------- | 101 |
76 | 102 ;----------------------------------------------------------------------------- |
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 | 103 ; read a Byte from Flash and increment Address with wrap-around at 0x20 / 0x40 |
78 ;ext_flash_byte_read_plus_0x40: | 104 ; returns in ext_flash_rw and WREG |
79 ; rcall ext_flash_byte_read ; read byte into ext_flash_rw | 105 ; |
80 ; bra incf_ext_flash_address_p1_0x40 ; increase address with wrap-around at 0x400000 to 0x000000 (and return) | 106 global ext_flash_read_byte_0x40 |
81 | 107 ext_flash_read_byte_0x40: |
82 | 108 bsf flash_wrap_around ; wrap-around at 0x400000 |
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 | 109 bra ext_flash_read_byte_common ; continue with common part |
84 ext_flash_byte_read_plus_0x20: | 110 |
85 rcall ext_flash_byte_read ; read byte into ext_flash_rw | 111 global ext_flash_read_byte_0x20 |
86 bra incf_ext_flash_address_p1_0x20 ; increase address with roll-over at 0x200000 to 0x000000 (and return) | 112 ext_flash_read_byte_0x20: |
87 | 113 bcf flash_wrap_around ; wrap-around at 0x200000 |
88 | 114 ;bra ext_flash_read_byte_common ; continue with common part |
89 global ext_flash_byte_read ; return data read in WREG and ext_flash_rw, no address change | 115 |
90 ext_flash_byte_read: | 116 ext_flash_read_byte_common: |
91 movlw 0x03 ; set up read command | 117 movlw 0x03 ; prepare read command |
92 rcall shift_spi ; prepare read command | 118 rcall shift_spi ; execute read command |
93 rcall ext_flash_set_address ; write 24 bit address ext_flash_address:3 via SPI | 119 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 | 120 rcall shift_spi ; shift the SPI to read data into WREG |
95 bsf flash_ncs ; set CS=1 | 121 bsf flash_ncs ; set CS=1 |
96 movwf ext_flash_rw ; return data read in WREG and ext_flash_rw | 122 movwf ext_flash_rw ; copy byte read from WREG to ext_flash_rw |
97 return ; done | 123 btfss flash_wrap_around ; shall wrap-around at 0x40000 ? |
98 | 124 bra ext_flash_inc_address_0x20_p1 ; NO - increment address with wrap-around at 0x200000 and return |
99 ; ---------------------------------------------------------------------------- | 125 bra ext_flash_inc_address_0x40_p1 ; YES - increment address with wrap-around at 0x200000 and return |
100 ; read-range base functions | 126 |
101 | 127 |
128 ;----------------------------------------------------------------------------- | |
129 ; Read-Range Base Functions - start reading | |
130 ; | |
102 global ext_flash_read_block_start ; return data read in WREG | 131 global ext_flash_read_block_start ; return data read in WREG |
103 ext_flash_read_block_start: | 132 ext_flash_read_block_start: |
104 movlw 0x03 ; set up read command | 133 movlw 0x03 ; set up read command |
105 rcall shift_spi ; execute read command | 134 rcall shift_spi ; execute read command |
106 rcall ext_flash_set_address ; write 24 bit address ext_flash_address:3 via SPI | 135 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) | 136 bra shift_spi ; shift the SPI to read data into WREG (and return) |
108 | 137 |
109 | 138 |
139 ;----------------------------------------------------------------------------- | |
140 ; Read-Range Base Functions - increment Address and read a Byte, wrap-around at 0x40 | |
141 ; | |
110 global ext_flash_read_block_0x40 ; return data read in WREG | 142 global ext_flash_read_block_0x40 ; return data read in WREG |
111 ext_flash_read_block_0x40: | 143 ext_flash_read_block_0x40: |
112 rcall incf_ext_flash_address_p1_0x40 ; increase address with wrap-around at 0x400000 | 144 rcall ext_flash_inc_address_0x40_p1 ; increase address with wrap-around at 0x400000 |
113 btfss address_wrap_around ; did the address wrap-around? | 145 btfss flash_wrap_around ; did the address wrap-around? |
114 bra shift_spi_loop_1 ; NO - shift the SPI to read data into WREG and return | 146 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 | 147 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 | 148 bra ext_flash_read_block_start ; - do a block-start, read data into WREG and return |
117 | 149 |
118 | 150 |
119 global ext_flash_read_block_0x20 ; return data read in WREG | 151 ;----------------------------------------------------------------------------- |
120 ext_flash_read_block_0x20: | 152 ; Read-Range Base Functions - increment Address and read a Byte, wrap-around at 0x20 |
121 rcall incf_ext_flash_address_p1_0x20 ; increase address with wrap-around at 0x200000 | 153 ; |
122 btfss address_wrap_around ; did the address wrap-around? | 154 ; global ext_flash_read_block_0x20 ; return data read in WREG |
123 bra shift_spi_loop_1 ; NO - shift the SPI to read data into WREG and return | 155 ;ext_flash_read_block_0x20: |
124 rcall ext_flash_read_block_stop ; YES - do a block-stop | 156 ; rcall ext_flash_inc_address_0x20_p1 ; increase address with wrap-around at 0x200000 |
125 bra ext_flash_read_block_start ; - do a block-start, read data into WREG and return | 157 ; btfss flash_wrap_around ; did the address wrap-around? |
126 | 158 ; bra shift_spi_loop_1 ; NO - shift the SPI to read data into WREG and return |
127 | 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 ; | |
128 global ext_flash_read_block_stop ; end block operation | 166 global ext_flash_read_block_stop ; end block operation |
129 ext_flash_read_block_stop: | 167 ext_flash_read_block_stop: |
130 bsf flash_ncs ; set CS=1 | 168 bsf flash_ncs ; set CS=1 |
131 return ; done | 169 return ; done |
132 | 170 |
171 | |
133 ; ---------------------------------------------------------------------------- | 172 ; ---------------------------------------------------------------------------- |
134 ; read-range function, to be used through macro | 173 ; read a Range of Bytes, to be used via Macro |
135 ; | 174 ; |
136 global ext_flash_read_range | 175 global ext_flash_read_range |
137 ext_flash_read_range: | 176 ext_flash_read_range: |
138 movwf eeprom_loop ; load loop counter (eeprom variable used here) | 177 movwf eeprom_loop ; load loop counter (eeprom variable used here) |
139 rcall ext_flash_read_block_start ; read first byte from flash | 178 rcall ext_flash_read_block_start ; read first byte from FLASH to WREG |
140 bra ext_flash_read_range_loop_start ; jump into loop | 179 bra ext_flash_read_range_loop_start ; jump into loop |
141 ext_flash_read_range_loop: | 180 ext_flash_read_range_loop: |
142 rcall ext_flash_read_block_0x40 ; read next byte from flash | 181 rcall shift_spi_loop_1 ; read next byte from FLASH to WREG |
143 ext_flash_read_range_loop_start: | 182 ext_flash_read_range_loop_start: |
144 movwf POSTINC1 ; write byte to memory | 183 movwf POSTINC1 ; write byte from WREG to memory |
145 decfsz eeprom_loop,F ; decrement loop counter, all done? | 184 decfsz eeprom_loop,F ; decrement loop counter, all done? |
146 bra ext_flash_read_range_loop ; NO - continue loop | 185 bra ext_flash_read_range_loop ; NO - continue loop |
147 bra ext_flash_read_block_stop ; YES - end reading from flash (and return) | 186 bra ext_flash_read_block_stop ; YES - end reading from flash (and return) |
148 | 187 |
149 | 188 |
150 ; ---------------------------------------------------------------------------- | 189 ; ---------------------------------------------------------------------------- |
151 ; write-range base functions | 190 ; Write-Range Base Functions - for use with SST26VF Chip only! |
152 | 191 ; |
153 ext_flash_write_block_start: | 192 ext_flash_write_block_start: |
193 movwf ext_flash_rw ; copy byte to write from WREG to ext_flash_rw | |
154 bsf flash_ncs ; set CS=1 | 194 bsf flash_ncs ; set CS=1 |
155 movlw 0x06 ; set up WREN command | 195 movlw 0x06 ; set up WREN command |
156 rcall shift_spi ; execute WREN command | 196 rcall shift_spi ; execute WREN command |
157 bsf flash_ncs ; set CS=1 | 197 bsf flash_ncs ; set CS=1 |
158 movlw 0x02 ; set up write (PP, Page-Program) command | 198 movlw 0x02 ; set up write (PP, Page-Program) command |
159 rcall shift_spi ; execute write | 199 rcall shift_spi ; execute write |
160 rcall ext_flash_set_address ; write 24 bit address ext_flash_address:3 via SPI | 200 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 | 201 movf ext_flash_rw,W ; get back byte to write |
162 bra shift_spi ; write the byte (and return) | 202 bra shift_spi ; write the byte (and return) |
163 | 203 |
164 ext_flash_write_block: | 204 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) | 205 bra shift_spi_loop_1 ; shift the SPI to write data into FLASH (and return) |
167 | 206 |
168 ext_flash_write_block_stop: | 207 ext_flash_write_block_stop: |
169 bra ext_flash_wait_write ; wait for completion (and return) | 208 bra ext_flash_wait_write ; wait for completion (and return) |
170 | 209 |
210 | |
171 ; ---------------------------------------------------------------------------- | 211 ; ---------------------------------------------------------------------------- |
172 ; write-range function, to be used through macro | 212 ; write a Range of Bytes, to be used via Macro |
173 ; | 213 ; |
174 global ext_flash_write_range | 214 global ext_flash_write_range |
175 ext_flash_write_range: | 215 ext_flash_write_range: |
176 movwf eeprom_loop ; load loop counter (eeprom variable used here) | 216 movwf eeprom_loop ; load loop counter (eeprom variable used here) |
177 | 217 |
178 ; btfsc flash_block_write ; does the FLASH support block-write? | 218 btfsc flash_block_write ; does the FLASH support block-write? |
179 ; bra ext_flash_write_range_block ; YES - write date via block operation | 219 bra ext_flash_write_range_block ; YES - write data in block mode |
180 ; ;bra ext_flash_write_range_seq ; NO - write data via sequential single writes | 220 ;bra ext_flash_write_range_seq ; NO - write data in sequential mode |
181 | 221 |
182 ext_flash_write_range_seq: ; sequential write | 222 ; sequential write |
183 ext_flash_write_range_loop_s: | 223 ext_flash_write_range_seq: |
184 movff POSTINC1,ext_flash_rw ; read byte from memory to ext_flash_rw | 224 bsf flash_wait ; wait for flash writes to complete |
185 rcall ext_flash_byte_write ; write byte from ext_flash_rw to FLASH | 225 ext_flash_write_range_seq_loop: |
186 rcall incf_ext_flash_address_p1_0x40 ; increase address with wrap-around at 0x400000 | 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 | |
187 decfsz eeprom_loop,F ; decrement loop counter, all done? | 229 decfsz eeprom_loop,F ; decrement loop counter, all done? |
188 bra ext_flash_write_range_loop_s ; NO - continue loop | 230 bra ext_flash_write_range_seq_loop ; NO - loop |
189 return ; YES - done | 231 return ; YES - done |
190 | 232 |
191 ext_flash_write_range_block: ; block write | 233 ; block write |
192 movff POSTINC1,ext_flash_rw ; read first byte from memory | 234 ext_flash_write_range_block: |
193 rcall ext_flash_write_block_start ; write first byte to FLASH | 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 | |
194 bra ext_flash_write_range_loop_start; jump into loop | 237 bra ext_flash_write_range_loop_start; jump into loop |
195 ext_flash_write_range_loop_b: | 238 ext_flash_write_range_block_loop: |
196 movff POSTINC1,ext_flash_rw ; read next byte from memory | 239 movf POSTINC1,W ; copy next byte from memory to WREG |
197 rcall ext_flash_write_block ; write next byte to FLASH | 240 rcall ext_flash_write_block ; copy next byte from WREG to FLASH |
198 ext_flash_write_range_loop_start: | 241 ext_flash_write_range_loop_start: |
199 decfsz eeprom_loop,F ; decrement loop counter, all done? | 242 decfsz eeprom_loop,F ; decrement loop counter, all done? |
200 bra ext_flash_write_range_loop_b ; NO - continue loop | 243 bra ext_flash_write_range_block_loop; NO - loop |
201 bra ext_flash_write_block_stop ; YES - end writing to flash (and return) | 244 rcall ext_flash_write_block_stop ; YES - initiate FLASH write |
202 | 245 clrf ext_flash_address+0 ; - advance address to start of next block |
203 ; ---------------------------------------------------------------------------- | 246 infsnz ext_flash_address+1,F ; - ... |
204 | 247 incf ext_flash_address+2,F ; - ... |
205 ; global write_byte_ext_flash_plus_header | 248 return ; - done |
206 ; write_byte_ext_flash_plus_header: | 249 |
207 ; movwf ext_flash_rw ; store byte to write | 250 |
208 ; ; test if write is done at first byte of 4kB block, if yes delete 4kB block first | 251 ;----------------------------------------------------------------------------- |
209 ; tstfsz ext_flash_address+0 ; at 0x....00 ? | 252 ; write a Byte with wrap-around at 0x200000, |
210 ; bra write_byte_ext_flash_plus_h1 ; NO - normal write | 253 ; erase on entering new 4kB Block, |
211 ; movf ext_flash_address+1,W ; YES - get high byte | 254 ; increment Dive Length Counter |
212 ; andlw 0x0F ; - mask lower nibble | 255 ; |
213 ; tstfsz WREG ; - at 0x..0...? | 256 global ext_flash_write_byte_0x20_incdc |
214 ; bra write_byte_ext_flash_plus_h1 ; NO - normal write | 257 ext_flash_write_byte_0x20_incdc: |
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 | |
219 | |
220 | |
221 global write_byte_ext_flash_plus_prof | |
222 write_byte_ext_flash_plus_prof: | |
223 movwf ext_flash_rw ; store byte to write | 258 movwf ext_flash_rw ; store byte to write |
224 incf ext_flash_length_counter+0,F ; increase dive length counter | 259 incf ext_flash_length_counter+0,F ; increase dive length counter |
225 movlw .0 ; ... | 260 movlw .0 ; ... |
226 addwfc ext_flash_length_counter+1,F ; ... | 261 addwfc ext_flash_length_counter+1,F ; ... |
227 addwfc ext_flash_length_counter+2,F ; ... | 262 addwfc ext_flash_length_counter+2,F ; ... |
228 bra write_byte_ext_flash_plus_nocnt1; continue with checking for begin of new page | 263 bra write_byte_ext_flash_plus_nocnt1; continue with checking for begin of new block |
229 | 264 |
230 | 265 |
231 global write_byte_ext_flash_plus_nocnt | 266 ;----------------------------------------------------------------------------- |
232 write_byte_ext_flash_plus_nocnt: | 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: | |
233 movwf ext_flash_rw ; store byte to write | 272 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 | 273 write_byte_ext_flash_plus_nocnt1: |
235 tstfsz ext_flash_address+0 ; at 0x....00? | 274 ; check if at 1st byte of a 4kB block, |
236 bra write_byte_ext_flash_plus_nodel1; NO - execute write | 275 ; if yes the block needs to be erased |
237 movf ext_flash_address+1,W ; YES - mask lower nibble | 276 ; before new data can be written to it |
238 andlw 0x0F ; - ... | 277 tstfsz ext_flash_address+0 ; is the low byte of the address = 0x00 ? |
239 tstfsz WREG ; - at 0x..0...? | 278 bra write_byte_ext_flash_plus_nodel1; NO - not at 1st byte, can execute write |
240 bra write_byte_ext_flash_plus_nodel1; NO - execute write | 279 movf ext_flash_address+1,W ; YES - get high byte of the address |
241 ; YES - at beginning of 4kB block -> erase first! | 280 andlw 0x0F ; - keep only the lower nibble |
242 rcall ext_flash_erase_4kB ; - erases 4kB sector @ext_flash_address:3 | 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 | |
243 bra write_byte_ext_flash_plus_nodel1; - execute write | 284 bra write_byte_ext_flash_plus_nodel1; - execute write |
244 | 285 |
245 | 286 |
246 global write_byte_ext_flash_plus_nodel | 287 ;----------------------------------------------------------------------------- |
247 write_byte_ext_flash_plus_nodel: | 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: | |
248 movwf ext_flash_rw ; store byte to write | 293 movwf ext_flash_rw ; store byte to write |
249 write_byte_ext_flash_plus_nodel1: | 294 write_byte_ext_flash_plus_nodel1: |
250 rcall ext_flash_byte_write ; write the byte in ext_flash_rw | 295 bsf flash_wait ; wait for flash write to complete |
251 bra incf_ext_flash_address_p1_0x20 ; increase address with wrap-around at 0x200000 and return | 296 rcall ext_flash_byte_write_common_F ; write the byte in ext_flash_rw |
252 | 297 bra ext_flash_inc_address_0x20_p1 ; increase address with wrap-around at 0x200000 and return |
253 | 298 |
254 global write_byte_ext_flash_plus_comms ; write from WREG without wait, ~86us fixed delay due to 115200 Baud, use with caution! | 299 |
255 write_byte_ext_flash_plus_comms: | 300 ;----------------------------------------------------------------------------- |
256 movwf ext_flash_rw ; store byte to write | 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: | |
257 bcf flash_wait ; do not wait on flash write to complete | 307 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 | 308 rcall ext_flash_byte_write_common_W ; write the byte in WREG |
259 bra incf_ext_flash_address_p1_0x40 ; increase address with wrap-around at 0x400000 and return | 309 bra ext_flash_inc_address_0x40_p1 ; increase address with wrap-around at 0x400000 and return |
260 | 310 |
261 | 311 |
262 ext_flash_byte_write: | 312 ;----------------------------------------------------------------------------- |
263 bsf flash_wait ; wait for flash write to complete | 313 ; internal common Write Functions W: WREG -> FLASH(ext_flash_address) |
264 ext_flash_byte_write_common: | 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: | |
265 bsf flash_ncs ; set CS=1 | 319 bsf flash_ncs ; set CS=1 |
266 movlw 0x06 ; set up WREN command | 320 movlw 0x06 ; set up WREN command |
267 rcall shift_spi ; execute WREN command | 321 rcall shift_spi ; execute WREN command |
268 bsf flash_ncs ; set CS=1 | 322 bsf flash_ncs ; set CS=1 |
269 movlw 0x02 ; set up write (PP, Page-Program) command | 323 movlw 0x02 ; prepare write (PP, Page-Program) command |
270 rcall shift_spi ; execute write | 324 rcall shift_spi ; execute write |
271 rcall ext_flash_set_address ; write 24 bit address ext_flash_address:3 via SPI | 325 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 | 326 movf ext_flash_rw,W ; get back byte to write |
273 rcall shift_spi ; write the byte | 327 rcall shift_spi ; write the byte |
274 btfsc flash_wait ; shall wait on flash write to complete? | 328 btfsc flash_wait ; shall wait on flash write to complete? |
275 bra ext_flash_wait_write ; YES - wait for completion (and return) | 329 bra ext_flash_wait_write ; YES - wait for completion (and return) |
276 bsf flash_ncs ; NO - set CS=1 | 330 bsf flash_ncs ; NO - set CS=1 |
277 return ; - done | 331 return ; - done |
278 | 332 |
279 ; ---------------------------------------------------------------------------- | 333 |
280 | 334 ;----------------------------------------------------------------------------- |
335 ; switch off Write-Protection | |
336 ; | |
281 global ext_flash_disable_protection ; disable write protection | 337 global ext_flash_disable_protection ; disable write protection |
282 ext_flash_disable_protection: | 338 ext_flash_disable_protection: |
283 ; unlock old memory | 339 ; unlock old memory |
284 bsf flash_ncs ; CS=1 | 340 bsf flash_ncs ; set CS=1 |
285 movlw 0x50 ; EWSR command | 341 movlw 0x50 ; prepare EWSR command |
286 rcall shift_spi | 342 rcall shift_spi ; execute EWSR command |
287 bsf flash_ncs ; CS=1 | 343 bsf flash_ncs ; set CS=1 |
288 movlw 0x01 ; WRSR command | 344 movlw 0x01 ; prepare WRSR command |
289 rcall shift_spi | 345 rcall shift_spi ; execute WRSR command |
290 movlw b'00000000' ; new status | 346 movlw b'00000000' ; prepare new status |
291 rcall shift_spi | 347 rcall shift_spi ; set new status |
292 bsf flash_ncs ; CS=1 | 348 |
293 ; unlock new memory | 349 ; unlock new memory |
294 movlw 0x06 ; WREN command | 350 bsf flash_ncs ; set CS=1 |
295 rcall shift_spi | 351 movlw 0x06 ; prepare WREN command |
296 bsf flash_ncs ; CS=1 | 352 rcall shift_spi ; execute WREN command |
297 movlw 0x98 ; ULBPR command | 353 bsf flash_ncs ; set CS=1 |
298 rcall shift_spi | 354 movlw 0x98 ; prepare ULBPR command |
299 bsf flash_ncs ; CS=1 | 355 rcall shift_spi ; execute ULBPR command |
300 movlw 0x06 ; WREN command | 356 bsf flash_ncs ; set CS=1 |
301 rcall shift_spi | 357 movlw 0x06 ; prepare WREN command |
302 bsf flash_ncs ; CS=1 | 358 rcall shift_spi ; execute WREN command |
303 movlw 0x42 ; WBPR command | 359 bsf flash_ncs ; set CS=1 |
304 rcall shift_spi | 360 movlw 0x42 ; prepare WBPR command |
361 rcall shift_spi ; execute WBPR command | |
362 | |
305 movlw .18 ; 18 bytes to do | 363 movlw .18 ; 18 bytes to do |
306 movwf lo ; initialize loop counter | 364 movwf lo ; initialize loop counter |
307 ext_flash_disable_prot_loop: | 365 ext_flash_disable_prot_loop: |
308 movlw 0x00 ; prepare writing a zero | 366 movlw 0x00 ; prepare writing a zero |
309 rcall shift_spi ; execute write | 367 rcall shift_spi ; write a zero |
310 decfsz lo,F ; all bytes done? | 368 decfsz lo,F ; all bytes done? |
311 bra ext_flash_disable_prot_loop ; NO - loop | 369 bra ext_flash_disable_prot_loop ; NO - loop |
312 bsf flash_ncs ; YES - set CS=1 | 370 bsf flash_ncs ; YES - set CS=1 |
313 return ; - done | 371 return ; - done |
314 | 372 |
315 | 373 |
374 ;----------------------------------------------------------------------------- | |
375 ; switch on Write-Protection | |
376 ; | |
316 global ext_flash_enable_protection | 377 global ext_flash_enable_protection |
317 ext_flash_enable_protection: | 378 ext_flash_enable_protection: |
318 ; lock old memory | 379 ; lock old memory |
319 bsf flash_ncs ; set CS=1 | 380 bsf flash_ncs ; set CS=1 |
320 movlw 0x50 ; prepare EWSR command | 381 movlw 0x50 ; prepare EWSR command |
322 bsf flash_ncs ; set CS=1 | 383 bsf flash_ncs ; set CS=1 |
323 movlw 0x01 ; prepare WRSR command | 384 movlw 0x01 ; prepare WRSR command |
324 rcall shift_spi ; execute WRSR command | 385 rcall shift_spi ; execute WRSR command |
325 movlw b'00011100' ; prepare write protection on | 386 movlw b'00011100' ; prepare write protection on |
326 rcall shift_spi ; execute write protection on | 387 rcall shift_spi ; execute write protection on |
327 bsf flash_ncs ; set CS=1 | 388 |
328 ; lock new memory | 389 ; lock new memory |
329 ; movlw 0x06 ; WREN command | 390 bsf flash_ncs ; set CS=1 |
330 ; rcall shift_spi | 391 ; movlw 0x06 ; prepare WREN command |
331 ; bsf flash_ncs ; CS=1 | 392 ; rcall shift_spi ; execute WREN command |
332 ; movlw 0x8D ; LBPR command | 393 ; bsf flash_ncs ; set CS=1 |
333 ; rcall shift_spi | 394 ; movlw 0x8D ; prepare LBPR command |
395 ; rcall shift_spi ; execute LBPR command | |
334 ; bsf flash_ncs ; set CS=1 | 396 ; bsf flash_ncs ; set CS=1 |
335 movlw 0x06 ; prepare WREN command | 397 movlw 0x06 ; prepare WREN command |
336 rcall shift_spi ; execute WREN command | 398 rcall shift_spi ; execute WREN command |
337 bsf flash_ncs ; set CS=1 | 399 bsf flash_ncs ; set CS=1 |
338 movlw 0x42 ; prepare WBPR command | 400 movlw 0x42 ; prepare WBPR command |
339 rcall shift_spi ; execute WBPR command | 401 rcall shift_spi ; execute WBPR command |
402 | |
340 movlw .18 ; 18 bytes to do | 403 movlw .18 ; 18 bytes to do |
341 movwf lo ; initialize loop counter | 404 movwf lo ; initialize loop counter |
342 ext_flash_enable_prot_loop: | 405 ext_flash_enable_prot_loop: |
343 movlw 0xFF ; prepare writing 0xFF | 406 movlw 0xFF ; prepare writing 0xFF |
344 rcall shift_spi ; execute write | 407 rcall shift_spi ; write a zero |
345 decfsz lo,F ; all bytes done? | 408 decfsz lo,F ; all bytes done? |
346 bra ext_flash_enable_prot_loop ; NO - loop | 409 bra ext_flash_enable_prot_loop ; NO - loop |
347 bsf flash_ncs ; YES - set CS=1 | 410 bsf flash_ncs ; YES - set CS=1 |
348 return ; - done | 411 return ; - done |
349 | 412 |
350 ; ---------------------------------------------------------------------------- | 413 |
351 | 414 ;----------------------------------------------------------------------------- |
415 ; erase complete Logbook | |
416 ; | |
352 global erase_complete_logbook | 417 global erase_complete_logbook |
353 erase_complete_logbook: | 418 erase_complete_logbook: |
354 ; clear logbook data in EPROM | 419 ; set address to 0x000000 / prepare a 3 byte zero integer |
355 CLRT mpr ; prepare a 3 byte zero integer | 420 CLRT ext_flash_address |
356 EEPROM_II_WRITE mpr,eeprom_num_dives ; reset total number of dives | 421 |
357 EEPROM_TT_WRITE mpr,eeprom_log_pointer ; reset pointer to begin of log data | 422 ; clear logbook data in EPROM by writing all zeros |
358 ; erase logbook data in FLASH (0x000000 -> 0x2FFFFF -> 3 MByte -> 3145728 Bytes) | 423 EEPROM_II_WRITE ext_flash_address,eeprom_num_dives ; reset the total number of dives |
359 bsf flash_ncs ; CS=1 | 424 EEPROM_TT_WRITE ext_flash_address,eeprom_log_pointer ; reset pointer to begin of profile data |
360 clrf ext_flash_address+0 ; set address to 0x000000 | 425 |
361 clrf ext_flash_address+1 ; ... | 426 ; erase logbook data in FLASH from 0x000000 - 0x2FFFFF = 3 MByte = 3 * 256 blocks * 4 kB/block |
362 clrf ext_flash_address+2 ; ... | 427 |
363 clrf ext_flash_rw ; write zeros | 428 clrf WREG ; erase 256 blocks per call |
364 ext_flash_erase_logbook_loop: ; 256 * 12 kB = 3.145.728 bytes to do | 429 rcall ext_flash_erase_range ; erase 1st bunch of 256 blocks |
365 rcall ext_flash_erase_4kB ; erase 4kB block | 430 rcall ext_flash_erase_range_loop ; erase 2nd bunch of 256 blocks |
366 rcall ext_flash_add_4kB ; increase ext_flash_address:3 by 4kB | 431 rcall ext_flash_erase_range_loop ; erase 3rd bunch of 256 blocks |
367 rcall ext_flash_erase_4kB ; erase 4kB block | 432 return ; done |
368 rcall ext_flash_add_4kB ; increase ext_flash_address:3 by 4kB | 433 |
369 rcall ext_flash_erase_4kB ; erase 4kB block | 434 |
370 rcall ext_flash_add_4kB ; increase ext_flash_address:3 by 4kB | 435 ;----------------------------------------------------------------------------- |
371 decfsz ext_flash_rw,F ; decrement loop counter, done? | 436 ; erase a Number of 4kB Blocks |
372 bra ext_flash_erase_logbook_loop ; NO - loop | 437 ; |
373 return ; YES - done | 438 global ext_flash_erase_range |
374 | 439 ext_flash_erase_range: |
375 | 440 movwf eeprom_loop ; initialize loop counter |
376 global ext_flash_erase_4kB ; erase a 4kB sector | 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 | |
377 ext_flash_erase_4kB: | 455 ext_flash_erase_4kB: |
378 bsf flash_ncs ; set CS=1 | 456 bsf flash_ncs ; set CS=1 |
379 movlw 0x06 ; prepare WREN command | 457 movlw 0x06 ; prepare WREN command |
380 rcall shift_spi ; execute WREN command | 458 rcall shift_spi ; execute WREN command |
381 bsf flash_ncs ; set CS=1 | 459 bsf flash_ncs ; set CS=1 |
382 movlw 0x20 ; prepare sector erase command | 460 movlw 0x20 ; prepare block erase command |
383 rcall shift_spi ; execute sector erase command | 461 rcall shift_spi ; execute block erase command |
384 rcall ext_flash_set_address ; write 24 bit address ext_flash_address:3 via SPI | 462 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 | 463 bra ext_flash_wait_write ; wait for write to complete and return |
386 | 464 |
387 ; ---------------------------------------------------------------------------- | 465 |
388 | 466 ;----------------------------------------------------------------------------- |
389 ; send address | 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 ; | |
390 ext_flash_set_address: | 486 ext_flash_set_address: |
391 movf ext_flash_address+2,W ; write 24 bit address ext_flash_address:3 via SPI | 487 movf ext_flash_address+2,W ; write 24 bit address ext_flash_address:3 via SPI |
392 rcall shift_spi ; ... | 488 rcall shift_spi ; ... |
393 movf ext_flash_address+1,W ; ... | 489 movf ext_flash_address+1,W ; ... |
394 rcall shift_spi ; ... | 490 rcall shift_spi ; ... |
395 movf ext_flash_address+0,W ; ... | 491 movf ext_flash_address+0,W ; ... |
396 bra shift_spi ; ... and return | 492 bra shift_spi ; ... and return |
397 | 493 |
398 ; wait on write operation to complete | 494 |
495 ;----------------------------------------------------------------------------- | |
496 ; low level Functions - wait for Completion of a Write Operation | |
497 ; | |
399 ext_flash_wait_write: | 498 ext_flash_wait_write: |
400 bsf flash_ncs ; set CS=1 | 499 bsf flash_ncs ; set CS=1 |
401 ; WAITMS d'1' ; TBE/TSE=25ms... | 500 ; WAITMS d'1' ; TBE/TSE=25ms... |
402 movlw 0x05 ; prepare RDSR command | 501 movlw 0x05 ; prepare RDSR command |
403 rcall shift_spi ; 1st cycle: execute command to read status | 502 rcall shift_spi ; 1st cycle: execute command to read status |
405 bsf flash_ncs ; set CS=1 | 504 bsf flash_ncs ; set CS=1 |
406 btfsc SSP2BUF,0 ; write operation still in process? | 505 btfsc SSP2BUF,0 ; write operation still in process? |
407 bra ext_flash_wait_write ; YES - loop waiting | 506 bra ext_flash_wait_write ; YES - loop waiting |
408 return ; NO - done | 507 return ; NO - done |
409 | 508 |
410 ; add 0x001000 to flash address | 509 |
411 ext_flash_add_4kB: | 510 ;----------------------------------------------------------------------------- |
412 movlw 0x10 ; add 0x10 to high byte | 511 ; low level functions - shift the SPI Bus for a combined Write/Read |
413 addwf ext_flash_address+1,F ; ... | 512 ; |
414 movlw d'0' ; propagate carry to upper byte | 513 ; WREG --> write --->\ /---> read --> WREG |
415 addwfc ext_flash_address+2,F ; ... | 514 ; flash chip |
416 return ; done | 515 ; |
417 | 516 shift_spi: |
418 ; shift the SPI bus for a combined write/read: WREG --->\ /---> WREG | |
419 shift_spi: ; flash chip | |
420 bcf flash_ncs ; set CS=0 | 517 bcf flash_ncs ; set CS=0 |
421 shift_spi_loop_1: | 518 shift_spi_loop_1: |
422 bcf SSP2STAT,WCOL ; clear flag | 519 bcf SSP2STAT,WCOL ; clear flag |
423 movwf SSP2BUF ; write to buffer | 520 movwf SSP2BUF ; write to buffer |
424 btfsc SSP2STAT,WCOL ; was buffer full? | 521 btfsc SSP2STAT,WCOL ; was buffer full? |
427 btfss SSP2STAT,BF ; buffer full? | 524 btfss SSP2STAT,BF ; buffer full? |
428 bra shift_spi_loop_2 ; NO - loop waiting | 525 bra shift_spi_loop_2 ; NO - loop waiting |
429 movf SSP2BUF,W ; YES - copy received data to WREG | 526 movf SSP2BUF,W ; YES - copy received data to WREG |
430 return ; - done | 527 return ; - done |
431 | 528 |
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 | |
432 END | 625 END |