0
|
1 ;=============================================================================
|
|
2 ;
|
|
3 ; File external_flash.asm
|
|
4 ;
|
|
5 ; External flash
|
|
6 ;
|
|
7 ; Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved.
|
|
8 ;=============================================================================
|
|
9 ; HISTORY
|
|
10 ; 2011-08-12 : [mH] creation
|
|
11
|
275
|
12 #include "hwos.inc"
|
0
|
13 #include "wait.inc"
|
|
14
|
|
15 basic CODE
|
|
16 ;=============================================================================
|
|
17
|
|
18 global incf_ext_flash_address_p1
|
|
19 incf_ext_flash_address_p1: ; Increase by one
|
|
20 movlw .1
|
|
21
|
|
22 global incf_ext_flash_address0
|
|
23 incf_ext_flash_address0:
|
|
24 addwf ext_flash_address+0,F ; increase address
|
|
25 movlw d'0'
|
|
26 addwfc ext_flash_address+1,F
|
|
27 addwfc ext_flash_address+2,F
|
|
28
|
|
29 movlw 0x40
|
|
30 cpfseq ext_flash_address+2 ; at address 40FFFF?
|
|
31 return ; No, return
|
167
|
32 ; clrf ext_flash_address+0
|
|
33 ; clrf ext_flash_address+1
|
|
34 clrf ext_flash_address+2 ; Yes, rollover to 0x000000
|
0
|
35 return
|
|
36
|
|
37 global incf_ext_flash_address0_p1_0x20
|
|
38 incf_ext_flash_address0_p1_0x20: ; Increase by one
|
|
39 movlw .1
|
|
40
|
|
41 global incf_ext_flash_address0_0x20
|
|
42 incf_ext_flash_address0_0x20: ; with roll-over at 0x200000 to 0x000000
|
|
43 addwf ext_flash_address+0,F ; increase address
|
|
44 movlw d'0'
|
|
45 addwfc ext_flash_address+1,F
|
|
46 addwfc ext_flash_address+2,F
|
|
47
|
|
48 movlw 0x20
|
|
49 cpfseq ext_flash_address+2 ; at address 0x200000?
|
|
50 return ; No, return
|
167
|
51 ; clrf ext_flash_address+0
|
|
52 ; clrf ext_flash_address+1
|
|
53 clrf ext_flash_address+2 ; Yes, rollover to 0x000000
|
0
|
54 return
|
|
55
|
|
56 global decf_ext_flash_address0
|
|
57 decf_ext_flash_address0:
|
|
58 subwf ext_flash_address+0,F ; decrease address: do a 16-8bits substract.
|
|
59 movlw d'0'
|
|
60 subwfb ext_flash_address+1,F
|
|
61 movlw d'0'
|
|
62 subwfb ext_flash_address+2,F
|
|
63
|
|
64 btfss ext_flash_address+2,7 ; Rollover to 0xFFFFFF?
|
|
65 return ; No, return
|
|
66 clrf ext_flash_address+2 ; Set to 0x00FFFFF
|
|
67 setf ext_flash_address+1
|
|
68 setf ext_flash_address+0
|
|
69 return
|
|
70
|
|
71 global ext_flash_byte_read_plus ; Return data read in WREG and SSP2BUF and
|
|
72 ext_flash_byte_read_plus: ; increase address after read
|
|
73 rcall ext_flash_byte_read
|
|
74 movwf temp1 ; store received data
|
|
75 bra incf_ext_flash_address_p1 ; +1 and return
|
|
76
|
|
77 global ext_flash_byte_read_plus_0x20; Return data read in WREG and SSP2BUF and
|
|
78 ext_flash_byte_read_plus_0x20: ; increase address after read with banking at 0x200000
|
|
79 rcall ext_flash_byte_read
|
|
80 movwf temp1 ; store received data
|
|
81 bra incf_ext_flash_address0_p1_0x20 ;+1 and return
|
|
82
|
|
83
|
|
84 global ext_flash_byte_read ; Return data read in WREG
|
|
85 ext_flash_byte_read:
|
|
86 movlw 0x03 ; Read command
|
|
87 rcall write_spi
|
|
88 rcall ext_flash_write_address ; Write 24bit address ext_flash_address:3 via SPI
|
|
89 rcall write_spi ; Dummy write to read data into WREG
|
|
90 bsf flash_ncs ; CS=1
|
|
91 movwf temp1
|
|
92 return ; Return data read in WREG and temp1
|
|
93
|
|
94 ext_flash_write_address: ; Write 24bit address ext_flash_address:3 via SPI
|
|
95 movf ext_flash_address+2,W ; 24Bit Address
|
|
96 rcall write_spi
|
|
97 movf ext_flash_address+1,W
|
|
98 rcall write_spi
|
|
99 movf ext_flash_address+0,W
|
|
100 bra write_spi ; And return....
|
|
101
|
|
102 global ext_flash_read_block_start ; Return data read in WREG
|
|
103 ext_flash_read_block_start:
|
|
104 movlw 0x03 ; Read command
|
|
105 rcall write_spi
|
|
106 rcall ext_flash_write_address ; Write 24bit address ext_flash_address:3 via SPI
|
|
107 rcall write_spi ; Dummy write to read data into WREG
|
|
108 return ; Return data read in WREG
|
|
109
|
|
110 global ext_flash_read_block ; Return data read in WREG
|
|
111 ext_flash_read_block:
|
|
112 rcall incf_ext_flash_address_p1 ; Increase address +1
|
|
113 bra write_spi1 ; Dummy write to read data into WREG and return
|
|
114
|
|
115 global ext_flash_read_block_stop ; Return data read in WREG
|
|
116 ext_flash_read_block_stop:
|
|
117 bsf flash_ncs ; CS=1
|
|
118 return ; NO data in WREG
|
|
119
|
|
120 global write_byte_ext_flash_plus_header
|
|
121 write_byte_ext_flash_plus_header: ; Write from WREG and increase address after write
|
|
122 movwf temp1 ; store data
|
|
123 ; test if write is done at first byte of 4kB block
|
|
124 ; if yes -> delete 4kB block first
|
|
125 tstfsz ext_flash_address+0 ; at 0x00?
|
|
126 bra write_byte_ext_flash_plus_h1 ; No, normal Write
|
|
127
|
|
128 movf ext_flash_address+1,W
|
|
129 andlw 0x0F ; Mask lower nibble
|
|
130 tstfsz WREG ; at 0x.0?
|
|
131 bra write_byte_ext_flash_plus_h1; No, normal Write
|
|
132
|
|
133 ; At beginning of 4kB block -> rease first!
|
|
134 rcall ext_flash_erase4kB ; Erases 4kB sector @ext_flash_address:3
|
|
135 write_byte_ext_flash_plus_h1:
|
|
136 movf temp1,W
|
|
137 rcall ext_flash_byte_write ; Write the byte
|
|
138 bra incf_ext_flash_address_p1 ; +1 and return
|
|
139
|
279
|
140 global write_byte_ext_flash_plus_nocnt ; No increase of ext_flash_dive_counter:3
|
|
141 write_byte_ext_flash_plus_nocnt:
|
|
142 movwf temp1 ; store data
|
|
143 bra write_byte_ext_flash_plus2
|
|
144
|
278
dfac47ac2e1d
BUGFIX: There was a 1:4096 chance that a portion of a dive was not stored correctly resulting in download issues
heinrichsweikamp
diff
changeset
|
145 global write_byte_ext_flash_plus_nodel ; Does NOT delete 4kB Page when required
|
279
|
146 write_byte_ext_flash_plus_nodel: ; Write from WREG and increase address after write with banking at 0x200000
|
|
147 movwf temp1 ; store data
|
278
dfac47ac2e1d
BUGFIX: There was a 1:4096 chance that a portion of a dive was not stored correctly resulting in download issues
heinrichsweikamp
diff
changeset
|
148 bra write_byte_ext_flash_plus1 ; Ignore possible begin of 4kB page, there have been written 0xFF already
|
6
|
149
|
0
|
150 global write_byte_ext_flash_plus ; Write from WREG and increase address after write with banking at 0x200000
|
|
151 write_byte_ext_flash_plus:
|
|
152 movwf temp1 ; store data
|
|
153
|
|
154 ; First, increase dive length counter
|
|
155 incf ext_flash_dive_counter+0,F
|
|
156 movlw .0
|
|
157 addwfc ext_flash_dive_counter+1,F
|
|
158 addwfc ext_flash_dive_counter+2,F ; 24bit++
|
|
159
|
6
|
160 write_byte_ext_flash_plus2:
|
0
|
161 ; Now test if write is done at first byte of 4kB block
|
|
162 ; if yes -> delete 4kB block first
|
|
163 tstfsz ext_flash_address+0 ; at 0x00?
|
|
164 bra write_byte_ext_flash_plus1 ; No, normal Write
|
|
165
|
|
166 movf ext_flash_address+1,W
|
|
167 andlw 0x0F ; Mask lower nibble
|
|
168 tstfsz WREG ; at 0x.0?
|
|
169 bra write_byte_ext_flash_plus1 ; No, normal Write
|
|
170
|
|
171 ; At beginning of 4kB block -> erase first!
|
|
172 rcall ext_flash_erase4kB ; Erases 4kB sector @ext_flash_address:3
|
|
173 write_byte_ext_flash_plus1:
|
|
174 movf temp1,W
|
|
175 rcall ext_flash_byte_write ; Write the byte
|
|
176 bra incf_ext_flash_address0_p1_0x20 ; +1 and roll over at 0x200000 to 0x000000 and return
|
|
177
|
|
178 global ext_flash_byte_write ; Write from WREG
|
|
179 ext_flash_byte_write:
|
|
180 movwf temp1 ; store data byte
|
|
181 bsf flash_ncs ; CS=1
|
|
182 movlw 0x06 ; WREN command
|
|
183 rcall write_spi
|
|
184 bsf flash_ncs ; CS=1
|
421
|
185 movlw 0x02 ; Write (PP, Page-Program) command
|
0
|
186 rcall write_spi
|
420
|
187 rcall ext_flash_write_address ; Write 24bit address ext_flash_address:3 via SPI
|
0
|
188 movf temp1,W ; load data byte
|
|
189 rcall write_spi ; write one byte of data!
|
423
|
190 bra ext_flash_wait_write ; And return...
|
|
191
|
|
192 global ext_flash_byte_write_comms ; without wait, ~86us fixed delay due to 115200 Bauds
|
|
193 ext_flash_byte_write_comms:
|
|
194 movwf temp1 ; store data byte
|
0
|
195 bsf flash_ncs ; CS=1
|
423
|
196 movlw 0x06 ; WREN command
|
|
197 rcall write_spi
|
|
198 bsf flash_ncs ; CS=1
|
|
199 movlw 0x02 ; Write (PP, Page-Program) command
|
|
200 rcall write_spi
|
|
201 rcall ext_flash_write_address ; Write 24bit address ext_flash_address:3 via SPI
|
|
202 movf temp1,W ; load data byte
|
|
203 rcall write_spi ; write one byte of data!
|
|
204 bsf flash_ncs ; CS=1
|
|
205 return
|
0
|
206
|
|
207 global ext_flash_disable_protection ; Disable write protection
|
|
208 ext_flash_disable_protection:
|
414
|
209 ; unlock old memory
|
0
|
210 bsf flash_ncs ; CS=1
|
|
211 movlw 0x50 ; EWSR command
|
|
212 rcall write_spi
|
|
213 bsf flash_ncs ; CS=1
|
|
214
|
|
215 movlw 0x01 ; WRSR command
|
|
216 rcall write_spi
|
|
217 movlw b'00000000' ; New status
|
|
218 rcall write_spi
|
|
219 bsf flash_ncs ; CS=1
|
414
|
220
|
|
221 ; unlock new memory
|
423
|
222 movlw 0x06 ; WREN command
|
|
223 rcall write_spi
|
|
224 bsf flash_ncs ; CS=1
|
|
225 movlw 0x98 ; ULBPR command
|
|
226 rcall write_spi
|
|
227 bsf flash_ncs ; CS=1
|
|
228
|
414
|
229 movlw 0x06 ; WREN command
|
|
230 rcall write_spi
|
|
231 bsf flash_ncs ; CS=1
|
420
|
232 movlw 0x42 ; WBPR command
|
414
|
233 rcall write_spi
|
420
|
234 movlw .18
|
423
|
235 movwf temp2
|
420
|
236 ext_flash_disable_protection2:
|
|
237 movlw 0x00
|
|
238 rcall write_spi
|
423
|
239 decfsz temp2,F ; 18 bytes with 0x00
|
420
|
240 bra ext_flash_disable_protection2
|
|
241 bsf flash_ncs ; CS=1
|
0
|
242 return
|
|
243
|
|
244 global ext_flash_enable_protection
|
|
245 ext_flash_enable_protection:
|
414
|
246 ; lock old memory
|
0
|
247 bsf flash_ncs ; CS=1
|
|
248 movlw 0x50 ; EWSR command
|
|
249 rcall write_spi
|
|
250 bsf flash_ncs ; CS=1
|
|
251
|
|
252 movlw 0x01 ; WRSR command
|
|
253 rcall write_spi
|
|
254 movlw b'00011100' ; New status (Write protect on)
|
|
255 rcall write_spi
|
423
|
256 bsf flash_ncs ; CS=1
|
414
|
257
|
|
258 ; lock new memory
|
423
|
259 ; movlw 0x06 ; WREN command
|
|
260 ; rcall write_spi
|
|
261 ; bsf flash_ncs ; CS=1
|
|
262 ; movlw 0x8D ; LBPR command
|
|
263 ; rcall write_spi
|
|
264 ; bsf flash_ncs ; CS=1
|
414
|
265 movlw 0x06 ; WREN command
|
|
266 rcall write_spi
|
|
267 bsf flash_ncs ; CS=1
|
|
268 movlw 0x42 ; WBPR command
|
|
269 rcall write_spi
|
|
270 movlw .18
|
423
|
271 movwf temp2
|
414
|
272 ext_flash_enable_protection2:
|
|
273 movlw 0xFF
|
|
274 rcall write_spi
|
423
|
275 decfsz temp2,F ; 18 bytes with 0xFF
|
414
|
276 bra ext_flash_enable_protection2
|
|
277 bsf flash_ncs ; CS=1
|
0
|
278 return
|
|
279
|
|
280
|
|
281 global ext_flash_erase4kB ; Erases 4kB sector
|
|
282 ext_flash_erase4kB:
|
|
283 bsf flash_ncs ; CS=1
|
|
284 movlw 0x06 ; WREN command
|
|
285 rcall write_spi
|
|
286 bsf flash_ncs ; CS=1
|
|
287 movlw 0x20 ; Sector erase command
|
|
288 rcall write_spi
|
|
289 rcall ext_flash_write_address ; Write 24bit address ext_flash_address:3 via SPI
|
|
290 ; bra ext_flash_wait_write ; Wait for write... and return
|
|
291 ext_flash_wait_write:
|
423
|
292 bsf flash_ncs ; CS=1
|
|
293 ; WAITMS d'1' ; TBE/TSE=25ms...
|
0
|
294 movlw 0x05 ; RDSR command
|
|
295 rcall write_spi ; Read status
|
|
296 rcall write_spi ; Read status into WREG
|
|
297 bsf flash_ncs ; CS=1
|
|
298 btfsc SSP2BUF,0 ; Write operation in process?
|
|
299 bra ext_flash_wait_write ; Yes, wait more..
|
|
300 return
|
|
301
|
414
|
302 global ext_flash_erase_logbook ; erases logbook memory (000000h -> 2FFFFFh -> 3MByte -> 3145728 Bytes)
|
0
|
303 ext_flash_erase_logbook:
|
|
304 bsf flash_ncs ; CS=1
|
|
305 clrf ext_flash_address+0
|
|
306 clrf ext_flash_address+1
|
|
307 clrf ext_flash_address+2
|
|
308
|
414
|
309 setf temp1 ; 256*12kB=3145728 Bytes
|
0
|
310 ext_flash_erase_logbook_loop:
|
414
|
311 rcall ext_flash_erase4kB ; 4kB
|
|
312 rcall ext_flash_add_4kB ; Increase ext_flash_address:3 by 4kB
|
|
313 rcall ext_flash_erase4kB ; 4kB
|
|
314 rcall ext_flash_add_4kB ; Increase ext_flash_address:3 by 4kB
|
|
315 rcall ext_flash_erase4kB ; 4kB
|
|
316 rcall ext_flash_add_4kB ; Increase ext_flash_address:3 by 4kB
|
0
|
317 decfsz temp1,F
|
|
318 bra ext_flash_erase_logbook_loop
|
|
319 return
|
|
320
|
414
|
321 ext_flash_add_4kB:
|
|
322 movlw 0x10
|
|
323 addwf ext_flash_address+1,F
|
|
324 movlw d'0'
|
|
325 addwfc ext_flash_address+2,F
|
|
326 return
|
|
327
|
0
|
328
|
|
329 write_spi: ; With data in WREG...
|
|
330 bcf flash_ncs ; CS
|
|
331 global write_spi1
|
|
332 write_spi1: ; With data in WREG...
|
|
333 bcf SSP2STAT,WCOL ; Clear flag
|
|
334 movwf SSP2BUF ; Write to buffer
|
|
335 btfsc SSP2STAT,WCOL ; Was buffer full?
|
|
336 bra write_spi1 ; Yes, try again
|
|
337
|
|
338 write_spi2: ; Wait for write command
|
|
339 btfss SSP2STAT, BF ; Buffer full?
|
|
340 bra write_spi2 ; No, wait.
|
|
341 movf SSP2BUF,W
|
|
342 return ; Returns RX data in WREG and SSP2BUF
|
|
343
|
281
|
344 global fix_180_dives
|
|
345 fix_180_dives: ; fix dives made with the 1.80
|
|
346 clrf divesecs ; Here: # of dive (0-255) in TOC
|
|
347 fix_180_dives2:
|
|
348 rcall fix_load_dive_into_buffer ; Load header #divesecs into buffer:256
|
|
349 rcall fix_check_buffer ; Check the buffered dive
|
|
350 tstfsz WREG ; Dive needs fix?
|
|
351 rcall fix_buffered_dive ; Yes, fix and save it
|
|
352 decfsz divesecs,F ; All done?
|
|
353 bra fix_180_dives2 ; No, continue
|
|
354 return ; All done.
|
|
355
|
|
356 fix_buffered_dive: ; Yes, fix and save it
|
|
357 rcall ext_flash_disable_protection ; Disable write protection for external flash
|
|
358 banksel buffer
|
|
359 ; Set to 1.81
|
|
360 movlw .81
|
|
361 movwf buffer+.49
|
|
362 ; Fix wrong profile length
|
|
363 movlw .3
|
|
364 subwf buffer+.9,F
|
|
365 movlw d'0'
|
|
366 subwfb buffer+.10,F
|
|
367 subwfb buffer+.11,F
|
|
368 banksel common
|
|
369 ; save result into external flash again
|
|
370 rcall fix_set_to_toc_start
|
|
371 clrf lo
|
|
372 lfsr FSR0,buffer+0
|
|
373 fix_buffered_dive2:
|
|
374 movf POSTINC0,W
|
|
375 rcall write_byte_ext_flash_plus_header; Write from WREG and increase address after write
|
|
376 decfsz lo,F ; All done?
|
|
377 bra fix_buffered_dive2 ; No, continue
|
|
378 return
|
|
379
|
|
380 fix_check_buffer: ; Check the buffered dive
|
|
381 movff buffer+.48,temp1
|
|
382 movlw .1
|
|
383 cpfseq temp1 ; buffer+.48 = .1 ?
|
|
384 retlw .0 ; No, abort
|
|
385 movff buffer+.49,temp1
|
|
386 movlw .80
|
|
387 cpfseq temp1 ; buffer+.49 = .80 ?
|
|
388 retlw .0 ; No, abort
|
|
389 retlw .1 ; Yes, fix this dive
|
|
390
|
|
391 fix_load_dive_into_buffer: ; Load header #divesecs into buffer:256
|
|
392 rcall fix_set_to_toc_start
|
|
393 clrf lo
|
|
394 lfsr FSR0,buffer+0
|
|
395 fix_load_dive_into_buffer2:
|
|
396 rcall ext_flash_byte_read_plus ; increase address after read
|
|
397 movff temp1,POSTINC0 ; copy into buffer
|
|
398 decfsz lo,F ; All done?
|
|
399 bra fix_load_dive_into_buffer2 ; No, continue
|
|
400
|
|
401 fix_set_to_toc_start:
|
|
402 clrf ext_flash_address+0
|
|
403 clrf ext_flash_address+1
|
|
404 movlw 0x20
|
|
405 movwf ext_flash_address+2
|
|
406 movlw .16
|
|
407 mulwf divesecs; divesecs*16 = offset to 0x2000 (up:hi)
|
|
408 movf PRODL,W
|
|
409 addwf ext_flash_address+1,F
|
|
410 movf PRODH,W
|
|
411 addwfc ext_flash_address+2,F
|
|
412 ; pointer at the first 0xFA of header
|
|
413 return
|
|
414
|
|
415
|
0
|
416 END |