comparison src/external_flash.asm @ 631:185ba2f91f59

3.09 beta 1 release
author heinrichsweikamp
date Fri, 28 Feb 2020 15:45:07 +0100
parents cd58f7fc86db
children 690c48db7b5b
comparison
equal deleted inserted replaced
630:4cd81bdbf15c 631:185ba2f91f59
1 ;============================================================================= 1 ;=============================================================================
2 ; 2 ;
3 ; File external_flash.asm combined next generation V3.0.1 3 ; File external_flash.asm combined next generation V3.08.8
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 ;=============================================================================
9 ; HISTORY 9 ; HISTORY
10 ; 2011-08-12 : [mH] creation 10 ; 2011-08-12 : [mH] creation
11 11
12 #include "hwos.inc" 12 #include "hwos.inc"
13 #include "wait.inc" 13 #include "wait.inc"
14 #include "eeprom_rs232.inc"
14 15
15 ext_flash CODE 16 ext_flash CODE
16 17
17 ;============================================================================= 18 ;=============================================================================
18 19
19 ; increase flash address by one 20 ; increase flash address by one with wrap-around at 0x400000 to 0x000000
20 ; 21 incf_ext_flash_address_p1_0x40:
21 global incf_ext_flash_address_p1 22 movlw .1 ; increase by 1
22 incf_ext_flash_address_p1: 23 ;bra incf_ext_flash_address0_0x40 ; continue
23 movlw .1 24
24 ;bra incf_ext_flash_address0 25
25 26 ; increase flash address by value in WREG with wrap-around at 0x400000 to 0x000000
26 27 global incf_ext_flash_address0_0x40
27 ; increase flash address by value in WREG 28 incf_ext_flash_address0_0x40:
28 ; 29 clrf ext_flash_rollover_threshold ; set wrap-around threshold without destroying WREG to ...
29 global incf_ext_flash_address0 30 bsf ext_flash_rollover_threshold,6 ; ... 0x40
30 incf_ext_flash_address0: 31 bra incf_ext_flash_address0_common ; continue with common part
31 addwf ext_flash_address+0,F ; increase address 32
32 movlw d'0' 33
33 addwfc ext_flash_address+1,F 34 ; increase flash address by one with wrap-around at 0x200000 to 0x000000
34 addwfc ext_flash_address+2,F 35 incf_ext_flash_address_p1_0x20:
35 36 movlw .1 ; increase by one
36 movlw 0x40 37 ;bra incf_ext_flash_address0_0x20 ; continue
37 cpfseq ext_flash_address+2 ; at address 40FFFF? 38
38 return ; NO - return 39
39 ; clrf ext_flash_address+0 40 ; increase flash address by value in WREG with wrap-around at 0x200000 to 0x000000
40 ; clrf ext_flash_address+1
41 clrf ext_flash_address+2 ; YES - rollover to 0x000000
42 return
43
44
45 ; increase flash address by one with roll-over at 0x200000 to 0x000000
46 ;
47 global incf_ext_flash_address0_p1_0x20
48 incf_ext_flash_address0_p1_0x20: ; increase by one
49 movlw .1
50 ;bra incf_ext_flash_address0_0x20
51
52
53 ; increase flash address by value in WREG with roll-over at 0x200000 to 0x000000
54 ;
55 global incf_ext_flash_address0_0x20 41 global incf_ext_flash_address0_0x20
56 incf_ext_flash_address0_0x20: 42 incf_ext_flash_address0_0x20:
57 addwf ext_flash_address+0,F ; increase address 43 clrf ext_flash_rollover_threshold ; set wrap-around threshold without destroying WREG to ...
58 movlw d'0' 44 bsf ext_flash_rollover_threshold,5 ; ... 0x20
59 addwfc ext_flash_address+1,F 45 ;bra incf_ext_flash_address0_common ; continue with common part
60 addwfc ext_flash_address+2,F 46
61 movlw 0x20 47
62 cpfseq ext_flash_address+2 ; at address 0x200000? 48 incf_ext_flash_address0_common:
63 return ; NO - return 49 bcf address_wrap_around ; clear wrap-around flag
64 ; clrf ext_flash_address+0 50 addwf ext_flash_address+0,F ; add WREG to address:3
65 ; clrf ext_flash_address+1 51 movlw d'0' ; ...
66 clrf ext_flash_address+2 ; YES - rollover to 0x000000 52 addwfc ext_flash_address+1,F ; ...
67 return 53 addwfc ext_flash_address+2,F ; ...
68 54 movf ext_flash_rollover_threshold,W ; get wrap-around threshold
69 55 cpfseq ext_flash_address+2 ; at wrap-around threshold ?
70 ; decrease flash address by value in WREG 56 bra incf_ext_flash_address1 ; NO - no wrap-around needed
71 ; 57 ; clrf ext_flash_address+0 ; YES - wrap-around to 0x000000
72 global decf_ext_flash_address0 58 ; clrf ext_flash_address+1 ; - ...
73 decf_ext_flash_address0: 59 clrf ext_flash_address+2 ; - ...
74 subwf ext_flash_address+0,F ; decrease address: do a 16-8bits subtract 60 bsf address_wrap_around ; - set wrap-around flag
75 movlw d'0' 61 incf_ext_flash_address1:
76 subwfb ext_flash_address+1,F 62 movf ext_flash_rw,W ; export current value of ext_flash_rw via WREG, too
77 movlw d'0' 63 return ; done
78 subwfb ext_flash_address+2,F 64
79 btfss ext_flash_address+2,7 ; under-run? 65
80 return ; NO - return 66 ; decrease flash length counter by value in WREG
81 clrf ext_flash_address+2 ; YES - set to 0x00FFFFF 67 global decf_ext_flash_length0
82 setf ext_flash_address+1 68 decf_ext_flash_length0:
83 setf ext_flash_address+0 69 subwf ext_flash_length_counter+0,F ; decrease address by value in WREG
84 return 70 movlw d'0' ; ...
85 71 subwfb ext_flash_length_counter+1,F ; ...
86 72 subwfb ext_flash_length_counter+2,F ; ...
87 global ext_flash_byte_read_plus ; return data read in WREG and SSP2BUF and 73 return ; done
88 ext_flash_byte_read_plus: ; increase address after read 74
89 rcall ext_flash_byte_read 75 ; ----------------------------------------------------------------------------
90 movwf ext_flash_rw ; store received data 76
91 bra incf_ext_flash_address_p1 ; +1 and return 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
92 78 ;ext_flash_byte_read_plus_0x40:
93 79 ; rcall ext_flash_byte_read ; read byte into ext_flash_rw
94 global ext_flash_byte_read_plus_0x20 ; return data read in WREG and SSP2BUF and 80 ; bra incf_ext_flash_address_p1_0x40 ; increase address with wrap-around at 0x400000 to 0x000000 (and return)
95 ext_flash_byte_read_plus_0x20: ; increase address after read with banking at 0x200000 81
96 rcall ext_flash_byte_read 82
97 movwf ext_flash_rw ; store received data 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
98 bra incf_ext_flash_address0_p1_0x20 ; +1 and return 84 ext_flash_byte_read_plus_0x20:
99 85 rcall ext_flash_byte_read ; read byte into ext_flash_rw
100 86 bra incf_ext_flash_address_p1_0x20 ; increase address with roll-over at 0x200000 to 0x000000 (and return)
101 global ext_flash_byte_read ; return data read in WREG 87
88
89 global ext_flash_byte_read ; return data read in WREG and ext_flash_rw, no address change
102 ext_flash_byte_read: 90 ext_flash_byte_read:
103 movlw 0x03 ; read command 91 movlw 0x03 ; set up read command
104 rcall write_spi 92 rcall shift_spi ; prepare read command
105 rcall ext_flash_write_address ; write 24 bit address ext_flash_address:3 via SPI 93 rcall ext_flash_set_address ; write 24 bit address ext_flash_address:3 via SPI
106 rcall write_spi ; dummy write to read data into WREG 94 rcall shift_spi ; shift the SPI to read data into WREG
107 bsf flash_ncs ; CS=1 95 bsf flash_ncs ; set CS=1
108 movwf ext_flash_rw 96 movwf ext_flash_rw ; return data read in WREG and ext_flash_rw
109 return ; return data read in WREG and ext_flash_rw 97 return ; done
110 98
111 99 ; ----------------------------------------------------------------------------
112 ext_flash_write_address: ; write 24 bit address ext_flash_address:3 via SPI 100 ; read-range base functions
113 movf ext_flash_address+2,W ; 24 bit address
114 rcall write_spi
115 movf ext_flash_address+1,W
116 rcall write_spi
117 movf ext_flash_address+0,W
118 bra write_spi ; and return....
119
120 101
121 global ext_flash_read_block_start ; return data read in WREG 102 global ext_flash_read_block_start ; return data read in WREG
122 ext_flash_read_block_start: 103 ext_flash_read_block_start:
123 movlw 0x03 ; read command 104 movlw 0x03 ; set up read command
124 rcall write_spi 105 rcall shift_spi ; execute read command
125 rcall ext_flash_write_address ; write 24 bit address ext_flash_address:3 via SPI 106 rcall ext_flash_set_address ; write 24 bit address ext_flash_address:3 via SPI
126 rcall write_spi ; dummy write to read data into WREG 107 bra shift_spi ; shift the SPI to read data into WREG (and return)
127 return ; return data read in WREG 108
128 109
129 110 global ext_flash_read_block_0x40 ; return data read in WREG
130 global ext_flash_read_block ; return data read in WREG 111 ext_flash_read_block_0x40:
131 ext_flash_read_block: 112 rcall incf_ext_flash_address_p1_0x40 ; increase address with wrap-around at 0x400000
132 rcall incf_ext_flash_address_p1 ; increase address +1 113 btfss address_wrap_around ; did the address wrap-around?
133 bra write_spi1 ; dummy write to read data into WREG and return 114 bra shift_spi_loop_1 ; NO - shift the SPI to read data into WREG and return
134 115 rcall ext_flash_read_block_stop ; YES - do a block-stop
135 116 bra ext_flash_read_block_start ; - do a block-start, read data into WREG and return
136 global ext_flash_read_block_stop ; return data read in WREG 117
118
119 global ext_flash_read_block_0x20 ; return data read in WREG
120 ext_flash_read_block_0x20:
121 rcall incf_ext_flash_address_p1_0x20 ; increase address with wrap-around at 0x200000
122 btfss address_wrap_around ; did the address wrap-around?
123 bra shift_spi_loop_1 ; NO - shift the SPI to read data into WREG and return
124 rcall ext_flash_read_block_stop ; YES - do a block-stop
125 bra ext_flash_read_block_start ; - do a block-start, read data into WREG and return
126
127
128 global ext_flash_read_block_stop ; end block operation
137 ext_flash_read_block_stop: 129 ext_flash_read_block_stop:
138 bsf flash_ncs ; CS=1 130 bsf flash_ncs ; set CS=1
139 return ; nO data in WREG 131 return ; done
140 132
141 133 ; ----------------------------------------------------------------------------
142 global write_byte_ext_flash_plus_header 134 ; read-range function, to be used through macro
143 write_byte_ext_flash_plus_header: ; write from WREG and increase address after write 135 ;
144 movwf ext_flash_rw ; store data 136 global ext_flash_read_range
145 ; test if write is done at first byte of 4kB block 137 ext_flash_read_range:
146 ; if yes -> delete 4kB block first 138 movwf eeprom_loop ; load loop counter (eeprom variable used here)
147 tstfsz ext_flash_address+0 ; at 0x00? 139 rcall ext_flash_read_block_start ; read first byte from flash
148 bra write_byte_ext_flash_plus_h1 ; NO - normal write 140 bra ext_flash_read_range_loop_start ; jump into loop
149 movf ext_flash_address+1,W 141 ext_flash_read_range_loop:
150 andlw 0x0F ; mask lower nibble 142 rcall ext_flash_read_block_0x40 ; read next byte from flash
151 tstfsz WREG ; at 0x.0? 143 ext_flash_read_range_loop_start:
152 bra write_byte_ext_flash_plus_h1 ; NO - normal write 144 movwf POSTINC1 ; write byte to memory
153 ; YES - at beginning of 4kB block -> erase first! 145 decfsz eeprom_loop,F ; decrement loop counter, all done?
154 rcall ext_flash_erase4kB ; - erases 4kB sector @ext_flash_address:3 146 bra ext_flash_read_range_loop ; NO - continue loop
155 write_byte_ext_flash_plus_h1: 147 bra ext_flash_read_block_stop ; YES - end reading from flash (and return)
156 movf ext_flash_rw,W 148
157 rcall ext_flash_byte_write ; write the byte 149
158 bra incf_ext_flash_address_p1 ; +1 and return 150 ; ----------------------------------------------------------------------------
159 151 ; write-range base functions
160 152
161 global write_byte_ext_flash_plus_nocnt ; no increase of ext_flash_dive_counter:3 153 ext_flash_write_block_start:
154 bsf flash_ncs ; set CS=1
155 movlw 0x06 ; set up WREN command
156 rcall shift_spi ; execute WREN command
157 bsf flash_ncs ; set CS=1
158 movlw 0x02 ; set up write (PP, Page-Program) command
159 rcall shift_spi ; execute write
160 rcall ext_flash_set_address ; write 24 bit address ext_flash_address:3 via SPI
161 movf ext_flash_rw,W ; get byte to write
162 bra shift_spi ; write the byte (and return)
163
164 ext_flash_write_block:
165 movf ext_flash_rw,W ; get byte to write
166 bra shift_spi_loop_1 ; shift the SPI to write data into FLASH (and return)
167
168 ext_flash_write_block_stop:
169 bra ext_flash_wait_write ; wait for completion (and return)
170
171 ; ----------------------------------------------------------------------------
172 ; write-range function, to be used through macro
173 ;
174 global ext_flash_write_range
175 ext_flash_write_range:
176 movwf eeprom_loop ; load loop counter (eeprom variable used here)
177 movff POSTINC1,ext_flash_rw ; read first byte from memory
178 rcall ext_flash_write_block_start ; write first byte to FLASH
179 bra ext_flash_write_range_loop_start; jump into loop
180 ext_flash_write_range_loop:
181 movff POSTINC1,ext_flash_rw ; read next byte from memory
182 rcall ext_flash_write_block ; write next byte to FLASH
183 ext_flash_write_range_loop_start:
184 decfsz eeprom_loop,F ; decrement loop counter, all done?
185 bra ext_flash_write_range_loop ; NO - continue loop
186 bra ext_flash_write_block_stop ; YES - end writing to flash (and return)
187
188 ; ----------------------------------------------------------------------------
189
190 ; global write_byte_ext_flash_plus_header
191 ; write_byte_ext_flash_plus_header:
192 ; movwf ext_flash_rw ; store byte to write
193 ; ; test if write is done at first byte of 4kB block, if yes delete 4kB block first
194 ; tstfsz ext_flash_address+0 ; at 0x....00 ?
195 ; bra write_byte_ext_flash_plus_h1 ; NO - normal write
196 ; movf ext_flash_address+1,W ; YES - get high byte
197 ; andlw 0x0F ; - mask lower nibble
198 ; tstfsz WREG ; - at 0x..0...?
199 ; bra write_byte_ext_flash_plus_h1 ; NO - normal write
200 ; rcall ext_flash_erase_4kB ; YES - at beginning of 4kB block -> erases 4kB sector @ext_flash_address:3
201 ;write_byte_ext_flash_plus_h1:
202 ; rcall ext_flash_byte_write ; write the byte in ext_flash_rw
203 ; bra incf_ext_flash_address_p1_0x40 ; increase address with wrap-around at 0x400000 and return
204
205
206 global write_byte_ext_flash_plus_prof
207 write_byte_ext_flash_plus_prof:
208 movwf ext_flash_rw ; store byte to write
209 incf ext_flash_length_counter+0,F ; increase dive length counter
210 movlw .0 ; ...
211 addwfc ext_flash_length_counter+1,F ; ...
212 addwfc ext_flash_length_counter+2,F ; ...
213 bra write_byte_ext_flash_plus_nocnt1; continue with checking for begin of new page
214
215
216 global write_byte_ext_flash_plus_nocnt
162 write_byte_ext_flash_plus_nocnt: 217 write_byte_ext_flash_plus_nocnt:
163 movwf ext_flash_rw ; store data 218 movwf ext_flash_rw ; store byte to write
164 bra write_byte_ext_flash_plus2 219 write_byte_ext_flash_plus_nocnt1: ; test if write is done at first byte of 4kB block, if yes delete 4kB block first
165 220 tstfsz ext_flash_address+0 ; at 0x....00?
166 221 bra write_byte_ext_flash_plus_nodel1; NO - execute write
167 global write_byte_ext_flash_plus_nodel ; does NOT delete 4kB page when required 222 movf ext_flash_address+1,W ; YES - mask lower nibble
168 write_byte_ext_flash_plus_nodel: ; write from WREG and increase address after write with banking at 0x200000 223 andlw 0x0F ; - ...
169 movwf ext_flash_rw ; store data 224 tstfsz WREG ; - at 0x..0...?
170 bra write_byte_ext_flash_plus1 ; ignore possible begin of 4kB page, there have been written 0xFF already 225 bra write_byte_ext_flash_plus_nodel1; NO - execute write
171 226 ; YES - at beginning of 4kB block -> erase first!
172 global write_byte_ext_flash_plus ; write from WREG and increase address after write with banking at 0x200000 227 rcall ext_flash_erase_4kB ; - erases 4kB sector @ext_flash_address:3
173 write_byte_ext_flash_plus: 228 bra write_byte_ext_flash_plus_nodel1; - execute write
174 movwf ext_flash_rw ; store data 229
175 ; First, increase dive length counter 230
176 incf ext_flash_dive_counter+0,F 231 global write_byte_ext_flash_plus_nodel
177 movlw .0 232 write_byte_ext_flash_plus_nodel:
178 addwfc ext_flash_dive_counter+1,F 233 movwf ext_flash_rw ; store byte to write
179 addwfc ext_flash_dive_counter+2,F ; 24 bit ++ 234 write_byte_ext_flash_plus_nodel1:
180 235 rcall ext_flash_byte_write ; write the byte in ext_flash_rw
181 write_byte_ext_flash_plus2: 236 bra incf_ext_flash_address_p1_0x20 ; increase address with wrap-around at 0x200000 and return
182 ; Now test if write is done at first byte of 4kB block 237
183 ; if yes -> delete 4kB block first 238
184 tstfsz ext_flash_address+0 ; at 0x00? 239 global write_byte_ext_flash_plus_comms ; write from WREG without wait, ~86us fixed delay due to 115200 Baud, use with caution!
185 bra write_byte_ext_flash_plus1 ; NO - normal write 240 write_byte_ext_flash_plus_comms:
186 movf ext_flash_address+1,W 241 movwf ext_flash_rw ; store byte to write
187 andlw 0x0F ; mask lower nibble 242 bcf flash_wait ; do not wait on flash write to complete
188 tstfsz WREG ; at 0x.0? 243 rcall ext_flash_byte_write_common ; write the byte in ext_flash_rw
189 bra write_byte_ext_flash_plus1 ; NO - normal write 244 bra incf_ext_flash_address_p1_0x40 ; increase address with wrap-around at 0x400000 and return
190 ; YES - at beginning of 4kB block -> erase first! 245
191 rcall ext_flash_erase4kB ; - erases 4kB sector @ext_flash_address:3 246
192 write_byte_ext_flash_plus1:
193 movf ext_flash_rw,W
194 rcall ext_flash_byte_write ; write the byte
195 bra incf_ext_flash_address0_p1_0x20 ; +1 and roll over at 0x200000 to 0x000000 and return
196
197
198 global ext_flash_byte_write ; write from WREG
199 ext_flash_byte_write: 247 ext_flash_byte_write:
200 movwf ext_flash_rw ; store data byte 248 bsf flash_wait ; wait for flash write to complete
201 bsf flash_ncs ; CS=1 249 ext_flash_byte_write_common:
202 movlw 0x06 ; WREN command 250 bsf flash_ncs ; set CS=1
203 rcall write_spi 251 movlw 0x06 ; set up WREN command
204 bsf flash_ncs ; CS=1 252 rcall shift_spi ; execute WREN command
205 movlw 0x02 ; write (PP, Page-Program) command 253 bsf flash_ncs ; set CS=1
206 rcall write_spi 254 movlw 0x02 ; set up write (PP, Page-Program) command
207 rcall ext_flash_write_address ; write 24 bit address ext_flash_address:3 via SPI 255 rcall shift_spi ; execute write
208 movf ext_flash_rw,W ; load data byte 256 rcall ext_flash_set_address ; write 24 bit address ext_flash_address:3 via SPI
209 rcall write_spi ; write one byte of data 257 movf ext_flash_rw,W ; get byte to write
210 bra ext_flash_wait_write ; and return... 258 rcall shift_spi ; write the byte
211 259 btfsc flash_wait ; shall wait on flash write to complete?
212 260 bra ext_flash_wait_write ; YES - wait for completion (and return)
213 global ext_flash_byte_write_comms ; without wait, ~86us fixed delay due to 115200 Baud 261 bsf flash_ncs ; NO - set CS=1
214 ext_flash_byte_write_comms: 262 return ; - done
215 movwf ext_flash_rw ; store data byte 263
216 bsf flash_ncs ; CS=1 264 ; ----------------------------------------------------------------------------
217 movlw 0x06 ; WREN command
218 rcall write_spi
219 bsf flash_ncs ; CS=1
220 movlw 0x02 ; write PP (Page-Program) command
221 rcall write_spi
222 rcall ext_flash_write_address ; write 24 bit address ext_flash_address:3 via SPI
223 movf ext_flash_rw,W ; load data byte
224 rcall write_spi ; write one byte of data
225 bsf flash_ncs ; CS=1
226 return
227
228 265
229 global ext_flash_disable_protection ; disable write protection 266 global ext_flash_disable_protection ; disable write protection
230 ext_flash_disable_protection: 267 ext_flash_disable_protection:
231 ; unlock old memory 268 ; unlock old memory
232 bsf flash_ncs ; CS=1 269 bsf flash_ncs ; CS=1
233 movlw 0x50 ; EWSR command 270 movlw 0x50 ; EWSR command
234 rcall write_spi 271 rcall shift_spi
235 bsf flash_ncs ; CS=1 272 bsf flash_ncs ; CS=1
236 movlw 0x01 ; WRSR command 273 movlw 0x01 ; WRSR command
237 rcall write_spi 274 rcall shift_spi
238 movlw b'00000000' ; new status 275 movlw b'00000000' ; new status
239 rcall write_spi 276 rcall shift_spi
240 bsf flash_ncs ; CS=1 277 bsf flash_ncs ; CS=1
241 ; unlock new memory 278 ; unlock new memory
242 movlw 0x06 ; WREN command 279 movlw 0x06 ; WREN command
243 rcall write_spi 280 rcall shift_spi
244 bsf flash_ncs ; CS=1 281 bsf flash_ncs ; CS=1
245 movlw 0x98 ; ULBPR command 282 movlw 0x98 ; ULBPR command
246 rcall write_spi 283 rcall shift_spi
247 bsf flash_ncs ; CS=1 284 bsf flash_ncs ; CS=1
248 movlw 0x06 ; WREN command 285 movlw 0x06 ; WREN command
249 rcall write_spi 286 rcall shift_spi
250 bsf flash_ncs ; CS=1 287 bsf flash_ncs ; CS=1
251 movlw 0x42 ; WBPR command 288 movlw 0x42 ; WBPR command
252 rcall write_spi 289 rcall shift_spi
253 movlw .18 290 movlw .18 ; 18 bytes to do
254 movwf lo 291 movwf lo ; initialize loop counter
255 ext_flash_disable_protection2: 292 ext_flash_disable_prot_loop:
256 movlw 0x00 293 movlw 0x00 ; prepare writing a zero
257 rcall write_spi 294 rcall shift_spi ; execute write
258 decfsz lo,F ; 18 bytes with 0x00 295 decfsz lo,F ; all bytes done?
259 bra ext_flash_disable_protection2 296 bra ext_flash_disable_prot_loop ; NO - loop
260 bsf flash_ncs ; CS=1 297 bsf flash_ncs ; YES - set CS=1
261 return 298 return ; - done
262 299
263 300
264 global ext_flash_enable_protection 301 global ext_flash_enable_protection
265 ext_flash_enable_protection: 302 ext_flash_enable_protection:
266 ; lock old memory 303 ; lock old memory
267 bsf flash_ncs ; CS=1 304 bsf flash_ncs ; set CS=1
268 movlw 0x50 ; EWSR command 305 movlw 0x50 ; prepare EWSR command
269 rcall write_spi 306 rcall shift_spi ; execute EWSR command
270 bsf flash_ncs ; CS=1 307 bsf flash_ncs ; set CS=1
271 movlw 0x01 ; WRSR command 308 movlw 0x01 ; prepare WRSR command
272 rcall write_spi 309 rcall shift_spi ; execute WRSR command
273 movlw b'00011100' ; new status (write protection on) 310 movlw b'00011100' ; prepare write protection on
274 rcall write_spi 311 rcall shift_spi ; execute write protection on
275 bsf flash_ncs ; CS=1 312 bsf flash_ncs ; set CS=1
276 ; lock new memory 313 ; lock new memory
277 ; movlw 0x06 ; WREN command 314 ; movlw 0x06 ; WREN command
278 ; rcall write_spi 315 ; rcall shift_spi
279 ; bsf flash_ncs ; CS=1 316 ; bsf flash_ncs ; CS=1
280 ; movlw 0x8D ; LBPR command 317 ; movlw 0x8D ; LBPR command
281 ; rcall write_spi 318 ; rcall shift_spi
282 ; bsf flash_ncs ; CS=1 319 ; bsf flash_ncs ; set CS=1
283 movlw 0x06 ; WREN command 320 movlw 0x06 ; prepare WREN command
284 rcall write_spi 321 rcall shift_spi ; execute WREN command
285 bsf flash_ncs ; CS=1 322 bsf flash_ncs ; set CS=1
286 movlw 0x42 ; WBPR command 323 movlw 0x42 ; prepare WBPR command
287 rcall write_spi 324 rcall shift_spi ; execute WBPR command
288 movlw .18 325 movlw .18 ; 18 bytes to do
289 movwf lo 326 movwf lo ; initialize loop counter
290 ext_flash_enable_protection2: 327 ext_flash_enable_prot_loop:
291 movlw 0xFF 328 movlw 0xFF ; prepare writing 0xFF
292 rcall write_spi 329 rcall shift_spi ; execute write
293 decfsz lo,F ; 18 bytes with 0xFF 330 decfsz lo,F ; all bytes done?
294 bra ext_flash_enable_protection2 331 bra ext_flash_enable_prot_loop ; NO - loop
295 bsf flash_ncs ; CS=1 332 bsf flash_ncs ; YES - set CS=1
296 return 333 return ; - done
297 334
298 335 ; ----------------------------------------------------------------------------
299 global ext_flash_erase4kB ; erases 4kB sector 336
300 ext_flash_erase4kB: 337 global erase_complete_logbook
301 bsf flash_ncs ; CS=1 338 erase_complete_logbook:
302 movlw 0x06 ; WREN command 339 ; clear logbook data in EPROM
303 rcall write_spi 340 CLRT mpr ; prepare a 3 byte zero integer
304 bsf flash_ncs ; CS=1 341 EEPROM_II_WRITE mpr,eeprom_num_dives ; reset total number of dives
305 movlw 0x20 ; sector erase command 342 EEPROM_TT_WRITE mpr,eeprom_log_pointer ; reset pointer to begin of log data
306 rcall write_spi 343 ; erase logbook data in FLASH (0x000000 -> 0x2FFFFF -> 3 MByte -> 3145728 Bytes)
307 rcall ext_flash_write_address ; write 24 bit address ext_flash_address:3 via SPI 344 bsf flash_ncs ; CS=1
308 ; bra ext_flash_wait_write ; wait for write... and return 345 clrf ext_flash_address+0 ; set address to 0x000000
309 ext_flash_wait_write: 346 clrf ext_flash_address+1 ; ...
310 bsf flash_ncs ; CS=1 347 clrf ext_flash_address+2 ; ...
311 ; WAITMS d'1' ; TBE/TSE=25ms... 348 clrf ext_flash_rw ; write zeros
312 movlw 0x05 ; RDSR command 349 ext_flash_erase_logbook_loop: ; 256 * 12 kB = 3.145.728 bytes to do
313 rcall write_spi ; read status 350 rcall ext_flash_erase_4kB ; erase 4kB block
314 rcall write_spi ; read status into WREG
315 bsf flash_ncs ; CS=1
316 btfsc SSP2BUF,0 ; write operation in process?
317 bra ext_flash_wait_write ; ES - loop waiting
318 return
319
320
321 global ext_flash_erase_logbook ; erases logbook memory (000000h -> 2FFFFFh -> 3MByte -> 3145728 Bytes)
322 ext_flash_erase_logbook:
323 bsf flash_ncs ; CS=1
324 clrf ext_flash_address+0
325 clrf ext_flash_address+1
326 clrf ext_flash_address+2
327
328 clrf ext_flash_rw ; 256 * 12 kB = 3145728 bytes
329 ext_flash_erase_logbook_loop:
330 rcall ext_flash_erase4kB ; 4kB
331 rcall ext_flash_add_4kB ; increase ext_flash_address:3 by 4kB 351 rcall ext_flash_add_4kB ; increase ext_flash_address:3 by 4kB
332 rcall ext_flash_erase4kB ; 4kB 352 rcall ext_flash_erase_4kB ; erase 4kB block
333 rcall ext_flash_add_4kB ; increase ext_flash_address:3 by 4kB 353 rcall ext_flash_add_4kB ; increase ext_flash_address:3 by 4kB
334 rcall ext_flash_erase4kB ; 4kB 354 rcall ext_flash_erase_4kB ; erase 4kB block
335 rcall ext_flash_add_4kB ; increase ext_flash_address:3 by 4kB 355 rcall ext_flash_add_4kB ; increase ext_flash_address:3 by 4kB
336 decfsz ext_flash_rw,F ; decrement loop counter, done? 356 decfsz ext_flash_rw,F ; decrement loop counter, done?
337 bra ext_flash_erase_logbook_loop ; NO - loop 357 bra ext_flash_erase_logbook_loop ; NO - loop
338 return ; YES - done 358 return ; YES - done
339 359
360
361 global ext_flash_erase_4kB ; erase a 4kB sector
362 ext_flash_erase_4kB:
363 bsf flash_ncs ; set CS=1
364 movlw 0x06 ; prepare WREN command
365 rcall shift_spi ; execute WREN command
366 bsf flash_ncs ; set CS=1
367 movlw 0x20 ; prepare sector erase command
368 rcall shift_spi ; execute sector erase command
369 rcall ext_flash_set_address ; write 24 bit address ext_flash_address:3 via SPI
370 bra ext_flash_wait_write ; wait for write to complete and return
371
372 ; ----------------------------------------------------------------------------
373
374 ; send address
375 ext_flash_set_address:
376 movf ext_flash_address+2,W ; write 24 bit address ext_flash_address:3 via SPI
377 rcall shift_spi ; ...
378 movf ext_flash_address+1,W ; ...
379 rcall shift_spi ; ...
380 movf ext_flash_address+0,W ; ...
381 bra shift_spi ; ... and return
382
383 ; wait on write operation to complete
384 ext_flash_wait_write:
385 bsf flash_ncs ; set CS=1
386 ; WAITMS d'1' ; TBE/TSE=25ms...
387 movlw 0x05 ; prepare RDSR command
388 rcall shift_spi ; 1st cycle: execute command to read status
389 rcall shift_spi ; 2nd cycle: read status
390 bsf flash_ncs ; set CS=1
391 btfsc SSP2BUF,0 ; write operation still in process?
392 bra ext_flash_wait_write ; YES - loop waiting
393 return ; NO - done
394
395 ; add 0x001000 to flash address
340 ext_flash_add_4kB: 396 ext_flash_add_4kB:
341 movlw 0x10 397 movlw 0x10 ; add 0x10 to high byte
342 addwf ext_flash_address+1,F 398 addwf ext_flash_address+1,F ; ...
343 movlw d'0' 399 movlw d'0' ; propagate carry to upper byte
344 addwfc ext_flash_address+2,F 400 addwfc ext_flash_address+2,F ; ...
345 return 401 return ; done
346 402
347 403 ; shift the SPI bus for a combined write/read: WREG --->\ /---> WREG
348 write_spi: ; with data in WREG... 404 shift_spi: ; flash chip
349 bcf flash_ncs ; CS 405 bcf flash_ncs ; set CS=0
350 global write_spi1 406 shift_spi_loop_1:
351 write_spi1: ; with data in WREG...
352 bcf SSP2STAT,WCOL ; clear flag 407 bcf SSP2STAT,WCOL ; clear flag
353 movwf SSP2BUF ; write to buffer 408 movwf SSP2BUF ; write to buffer
354 btfsc SSP2STAT,WCOL ; was buffer full? 409 btfsc SSP2STAT,WCOL ; was buffer full?
355 bra write_spi1 ; YES - try again 410 bra shift_spi_loop_1 ; YES - try again
356 write_spi2: ; wait for write command 411 shift_spi_loop_2:
357 btfss SSP2STAT, BF ; buffer full? 412 btfss SSP2STAT,BF ; buffer full?
358 bra write_spi2 ; NO - loop waiting 413 bra shift_spi_loop_2 ; NO - loop waiting
359 movf SSP2BUF,W ; YES - copy RX data to WREG 414 movf SSP2BUF,W ; YES - copy received data to WREG
360 return ; - return with RX data in WREG and SSP2BUF 415 return ; - done
361 416
362 END 417 END