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