diff 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
line wrap: on
line diff
--- a/src/external_flash.asm	Fri Feb 21 10:51:36 2020 +0100
+++ b/src/external_flash.asm	Fri Feb 28 15:45:07 2020 +0100
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File external_flash.asm                    combined next generation V3.0.1
+;   File external_flash.asm                   combined next generation V3.08.8
 ;
 ;   External flash
 ;
@@ -11,352 +11,407 @@
 
 	#include "hwos.inc"
 	#include "wait.inc"
+	#include "eeprom_rs232.inc"
 
 ext_flash	CODE
 
 ;=============================================================================
 
-; increase flash address by one
-;
-	global	incf_ext_flash_address_p1
-incf_ext_flash_address_p1:
-	movlw	.1
-	;bra	incf_ext_flash_address0
+; increase flash address by one with wrap-around at 0x400000 to 0x000000
+incf_ext_flash_address_p1_0x40:
+	movlw	.1								; increase by 1
+	;bra	incf_ext_flash_address0_0x40	; continue
 
 
-; increase flash address by value in WREG
-;
-	global	incf_ext_flash_address0
-incf_ext_flash_address0:
-	addwf	ext_flash_address+0,F			; increase address
-	movlw	d'0'
-	addwfc	ext_flash_address+1,F
-	addwfc	ext_flash_address+2,F
-
-	movlw	0x40
-	cpfseq	ext_flash_address+2				; at address 40FFFF?
-	return									; NO -  return
-;	clrf	ext_flash_address+0
-;	clrf	ext_flash_address+1
-	clrf	ext_flash_address+2				; YES - rollover to 0x000000
-	return
+; increase flash address by value in WREG with wrap-around at 0x400000 to 0x000000
+	global	incf_ext_flash_address0_0x40
+incf_ext_flash_address0_0x40:
+	clrf	ext_flash_rollover_threshold	; set wrap-around threshold without destroying WREG to ...
+	bsf		ext_flash_rollover_threshold,6	; ... 0x40
+	bra		incf_ext_flash_address0_common	; continue with common part
 
 
-; increase flash address by one with roll-over at 0x200000 to 0x000000
-;
-	global	incf_ext_flash_address0_p1_0x20
-incf_ext_flash_address0_p1_0x20:			; increase by one
-	movlw	.1
-	;bra	incf_ext_flash_address0_0x20
+; increase flash address by one with wrap-around at 0x200000 to 0x000000
+incf_ext_flash_address_p1_0x20:
+	movlw	.1								; increase by one
+	;bra	incf_ext_flash_address0_0x20	; continue
 
 
-; increase flash address by value in WREG with roll-over at 0x200000 to 0x000000
-;
+; increase flash address by value in WREG with wrap-around at 0x200000 to 0x000000
 	global	incf_ext_flash_address0_0x20
 incf_ext_flash_address0_0x20:
-	addwf	ext_flash_address+0,F			; increase address
-	movlw	d'0'
-	addwfc	ext_flash_address+1,F
-	addwfc	ext_flash_address+2,F
-	movlw	0x20
-	cpfseq	ext_flash_address+2				; at address 0x200000?
-	return									; NO  - return
-;	clrf	ext_flash_address+0
-;	clrf	ext_flash_address+1
-	clrf	ext_flash_address+2				; YES - rollover to 0x000000
-	return
+	clrf	ext_flash_rollover_threshold	; set wrap-around threshold without destroying WREG to ...
+	bsf		ext_flash_rollover_threshold,5	; ... 0x20
+	;bra	incf_ext_flash_address0_common	; continue with common part
 
 
-; decrease flash address by value in WREG
-;
-	global	decf_ext_flash_address0
-decf_ext_flash_address0:
-	subwf	ext_flash_address+0,F			; decrease address: do a 16-8bits subtract
-	movlw	d'0'
-	subwfb	ext_flash_address+1,F
-	movlw	d'0'
-	subwfb	ext_flash_address+2,F
-	btfss	ext_flash_address+2,7			; under-run?
-	return									; NO  - return
-	clrf	ext_flash_address+2				; YES - set to 0x00FFFFF
-	setf	ext_flash_address+1
-	setf	ext_flash_address+0
-	return
-
-
-	global	ext_flash_byte_read_plus		; return data read in WREG and SSP2BUF and
-ext_flash_byte_read_plus:					; increase address after read
-	rcall	ext_flash_byte_read
-	movwf	ext_flash_rw					; store received data
-	bra		incf_ext_flash_address_p1		; +1 and return
+incf_ext_flash_address0_common:
+	bcf		address_wrap_around				; clear wrap-around flag
+	addwf	ext_flash_address+0,F			; add WREG to address:3
+	movlw	d'0'							; ...
+	addwfc	ext_flash_address+1,F			; ...
+	addwfc	ext_flash_address+2,F			; ...
+	movf	ext_flash_rollover_threshold,W	; get wrap-around threshold
+	cpfseq	ext_flash_address+2				; at  wrap-around threshold ?
+	bra		incf_ext_flash_address1			; NO  - no wrap-around needed
+;	clrf	ext_flash_address+0				; YES - wrap-around to 0x000000
+;	clrf	ext_flash_address+1				;     - ...
+	clrf	ext_flash_address+2				;     - ...
+	bsf		address_wrap_around				;     - set wrap-around flag
+incf_ext_flash_address1:
+	movf	ext_flash_rw,W					; export current value of ext_flash_rw via WREG, too
+	return									; done
 
 
-	global	ext_flash_byte_read_plus_0x20	; return data read in WREG and SSP2BUF and 
-ext_flash_byte_read_plus_0x20:				; increase address after read with banking at 0x200000
-	rcall	ext_flash_byte_read
-	movwf	ext_flash_rw					; store received data
-	bra		incf_ext_flash_address0_p1_0x20	; +1 and return
+; decrease flash length counter by value in WREG
+	global	decf_ext_flash_length0
+decf_ext_flash_length0:
+	subwf	ext_flash_length_counter+0,F	; decrease address by value in WREG
+	movlw	d'0'							; ...
+	subwfb	ext_flash_length_counter+1,F	; ...
+	subwfb	ext_flash_length_counter+2,F	; ...
+	return									; done
+
+; ----------------------------------------------------------------------------
+
+;	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
+;ext_flash_byte_read_plus_0x40:
+;	rcall	ext_flash_byte_read				; read byte into ext_flash_rw
+;	bra		incf_ext_flash_address_p1_0x40	; increase address with wrap-around at 0x400000 to 0x000000 (and return)
 
 
-	global	ext_flash_byte_read				; return data read in WREG
-ext_flash_byte_read:
-	movlw	0x03							; read command
-	rcall	write_spi
-	rcall	ext_flash_write_address			; write 24 bit address ext_flash_address:3 via SPI
-	rcall	write_spi						; dummy write to read data into WREG
-	bsf		flash_ncs						; CS=1
-	movwf	ext_flash_rw
-	return									; return data read in WREG and ext_flash_rw
+	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
+ext_flash_byte_read_plus_0x20:
+	rcall	ext_flash_byte_read				; read byte into ext_flash_rw
+	bra		incf_ext_flash_address_p1_0x20	; increase address with roll-over at 0x200000 to 0x000000 (and return)
 
 
-ext_flash_write_address:					; write 24 bit address ext_flash_address:3 via SPI
-	movf	ext_flash_address+2,W			; 24 bit address
-	rcall	write_spi
-	movf	ext_flash_address+1,W
-	rcall	write_spi
-	movf	ext_flash_address+0,W
-	bra 	write_spi						; and return....
+	global	ext_flash_byte_read				; return data read in WREG and ext_flash_rw, no address change
+ext_flash_byte_read:
+	movlw	0x03							; set up  read command
+	rcall	shift_spi						; prepare read command
+	rcall	ext_flash_set_address			; write 24 bit address ext_flash_address:3 via SPI
+	rcall	shift_spi						; shift the SPI to read data into WREG
+	bsf		flash_ncs						; set CS=1
+	movwf	ext_flash_rw					; return data read in WREG and ext_flash_rw
+	return									; done
 
+; ----------------------------------------------------------------------------
+; read-range base functions
 
 	global	ext_flash_read_block_start		; return data read in WREG
 ext_flash_read_block_start:
-	movlw	0x03							; read command
-	rcall	write_spi
-	rcall	ext_flash_write_address			; write 24 bit address ext_flash_address:3 via SPI
-	rcall	write_spi						; dummy write to read data into WREG
-	return									; return data read in WREG
+	movlw	0x03							; set up  read command
+	rcall	shift_spi						; execute read command
+	rcall	ext_flash_set_address			; write 24 bit address ext_flash_address:3 via SPI
+	bra		shift_spi						; shift the SPI to read data into WREG (and return)
 
 
-	global	ext_flash_read_block			; return data read in WREG
-ext_flash_read_block:
-	rcall	incf_ext_flash_address_p1		; increase address +1
-	bra		write_spi1						; dummy write to read data into WREG and return
-
-
-	global	ext_flash_read_block_stop		; return data read in WREG
-ext_flash_read_block_stop:
-	bsf		flash_ncs						; CS=1
-	return									; nO data in WREG
+	global	ext_flash_read_block_0x40		; return data read in WREG
+ext_flash_read_block_0x40:
+	rcall	incf_ext_flash_address_p1_0x40	; increase address with wrap-around at 0x400000
+	btfss	address_wrap_around				; did the address wrap-around?
+	bra		shift_spi_loop_1				; NO  - shift the SPI to  read data into WREG and return
+	rcall	ext_flash_read_block_stop		; YES - do a block-stop
+	bra		ext_flash_read_block_start		;     - do a block-start, read data into WREG and return
 
 
-	global	write_byte_ext_flash_plus_header
-write_byte_ext_flash_plus_header:			; write from WREG and increase address after write
-	movwf	ext_flash_rw					; store data
-	; test if write is done at first byte of 4kB block
-	; if yes -> delete 4kB block first
-	tstfsz	ext_flash_address+0				; at 0x00?
-	bra		write_byte_ext_flash_plus_h1	; NO - normal write
-	movf	ext_flash_address+1,W
-	andlw	0x0F							; mask lower nibble
-	tstfsz	WREG							; at 0x.0?
-	bra		write_byte_ext_flash_plus_h1	; NO  - normal write
-											; YES - at beginning of 4kB block -> erase first!
-	rcall	ext_flash_erase4kB				;     - erases 4kB sector @ext_flash_address:3
-write_byte_ext_flash_plus_h1:
-	movf	ext_flash_rw,W
-	rcall	ext_flash_byte_write			; write the byte
-	bra		incf_ext_flash_address_p1		; +1 and return
+	global	ext_flash_read_block_0x20		; return data read in WREG
+ext_flash_read_block_0x20:
+	rcall	incf_ext_flash_address_p1_0x20	; increase address with wrap-around at 0x200000
+	btfss	address_wrap_around				; did the address wrap-around?
+	bra		shift_spi_loop_1				; NO  - shift the SPI to  read data into WREG and return
+	rcall	ext_flash_read_block_stop		; YES - do a block-stop
+	bra		ext_flash_read_block_start		;     - do a block-start, read data into WREG and return
 
 
-	global	write_byte_ext_flash_plus_nocnt	; no increase of ext_flash_dive_counter:3
-write_byte_ext_flash_plus_nocnt:
-	movwf	ext_flash_rw					; store data
-	bra		write_byte_ext_flash_plus2
+	global	ext_flash_read_block_stop		; end block operation
+ext_flash_read_block_stop:
+	bsf		flash_ncs						; set CS=1
+	return									; done
+
+; ----------------------------------------------------------------------------
+; read-range function, to be used through macro
+;
+	global	ext_flash_read_range
+ext_flash_read_range:
+	movwf	eeprom_loop						; load loop counter (eeprom variable used here)
+	rcall	ext_flash_read_block_start		; read first byte from flash
+	bra		ext_flash_read_range_loop_start	; jump into loop
+ext_flash_read_range_loop:
+	rcall	ext_flash_read_block_0x40		; read next byte from flash
+ext_flash_read_range_loop_start:
+	movwf	POSTINC1						; write byte to memory
+	decfsz	eeprom_loop,F					; decrement loop counter, all done?
+	bra		ext_flash_read_range_loop		; NO  - continue loop
+	bra		ext_flash_read_block_stop		; YES - end reading from flash (and return)
 
 
-	global	write_byte_ext_flash_plus_nodel	; does NOT delete 4kB page when required
-write_byte_ext_flash_plus_nodel:			; write from WREG and increase address after write with banking at 0x200000
-	movwf	ext_flash_rw					; store data
-	bra		write_byte_ext_flash_plus1		; ignore possible begin of 4kB page, there have been written 0xFF already
+; ----------------------------------------------------------------------------
+; write-range base functions
 
-	global	write_byte_ext_flash_plus		; write from WREG and increase address after write with banking at 0x200000
-write_byte_ext_flash_plus:
-	movwf	ext_flash_rw					; store data
-	; First, increase dive length counter
-	incf	ext_flash_dive_counter+0,F
-	movlw	.0
-	addwfc	ext_flash_dive_counter+1,F
-	addwfc	ext_flash_dive_counter+2,F		; 24 bit ++
+ext_flash_write_block_start:
+	bsf		flash_ncs						; set CS=1
+	movlw	0x06							; set up  WREN command
+	rcall	shift_spi						; execute WREN command
+	bsf		flash_ncs						; set CS=1
+	movlw	0x02							; set up  write (PP, Page-Program) command
+	rcall	shift_spi						; execute write
+	rcall	ext_flash_set_address			; write 24 bit address ext_flash_address:3 via SPI
+	movf	ext_flash_rw,W					; get byte to write
+	bra		shift_spi						; write the byte (and return)
+
+ext_flash_write_block:
+	movf	ext_flash_rw,W					; get byte to write
+	bra		shift_spi_loop_1				; shift the SPI to write data into FLASH (and return)
+
+ext_flash_write_block_stop:
+	bra		ext_flash_wait_write			; wait for completion (and return)
 
-write_byte_ext_flash_plus2:
-	; Now test if write is done at first byte of 4kB block
-	; if yes -> delete 4kB block first
-	tstfsz	ext_flash_address+0				; at 0x00?
-	bra		write_byte_ext_flash_plus1		; NO - normal write
-	movf	ext_flash_address+1,W
-	andlw	0x0F							; mask lower nibble
-	tstfsz	WREG							; at 0x.0?
-	bra		write_byte_ext_flash_plus1		; NO  - normal write
-											; YES - at beginning of 4kB block -> erase first!
-	rcall	ext_flash_erase4kB				;     - erases 4kB sector @ext_flash_address:3
-write_byte_ext_flash_plus1:
-	movf	ext_flash_rw,W
-	rcall	ext_flash_byte_write			; write the byte
-	bra		incf_ext_flash_address0_p1_0x20	; +1 and roll over at 0x200000 to 0x000000	and return
+; ----------------------------------------------------------------------------
+; write-range function, to be used through macro
+;
+	global	ext_flash_write_range
+ext_flash_write_range:
+	movwf	eeprom_loop						; load loop counter (eeprom variable used here)
+	movff	POSTINC1,ext_flash_rw			; read  first byte from memory
+	rcall	ext_flash_write_block_start		; write first byte to FLASH
+	bra		ext_flash_write_range_loop_start; jump into loop
+ext_flash_write_range_loop:
+	movff	POSTINC1,ext_flash_rw			; read  next byte from memory
+	rcall	ext_flash_write_block			; write next byte to FLASH
+ext_flash_write_range_loop_start:
+	decfsz	eeprom_loop,F					; decrement loop counter, all done?
+	bra		ext_flash_write_range_loop		; NO  - continue loop
+	bra		ext_flash_write_block_stop		; YES - end writing to flash (and return)
+
+; ----------------------------------------------------------------------------
+
+;	global	write_byte_ext_flash_plus_header
+; write_byte_ext_flash_plus_header:
+;	movwf	ext_flash_rw					; store byte to write
+;											 ; test if write is done at first byte of 4kB block, if yes delete 4kB block first
+;	tstfsz	ext_flash_address+0				; at 0x....00 ?
+;	bra		write_byte_ext_flash_plus_h1	; NO - normal write
+;	movf	ext_flash_address+1,W			; YES - get high byte
+;	andlw	0x0F							;     - mask lower nibble
+;	tstfsz	WREG							;     - at 0x..0...?
+;	bra		write_byte_ext_flash_plus_h1	;       NO  - normal write
+;	rcall	ext_flash_erase_4kB				;       YES - at beginning of 4kB block -> erases 4kB sector @ext_flash_address:3
+;write_byte_ext_flash_plus_h1:
+;	rcall	ext_flash_byte_write			; write the byte in ext_flash_rw
+;	bra		incf_ext_flash_address_p1_0x40	; increase address with wrap-around at 0x400000 and return
 
 
-	global	ext_flash_byte_write			; write from WREG
-ext_flash_byte_write:
-	movwf	ext_flash_rw					; store data byte
-	bsf		flash_ncs						; CS=1
-	movlw	0x06							; WREN command
-	rcall	write_spi
-	bsf		flash_ncs						; CS=1
-	movlw	0x02							; write (PP, Page-Program) command
-	rcall	write_spi
-	rcall	ext_flash_write_address			; write 24 bit address ext_flash_address:3 via SPI
-	movf	ext_flash_rw,W					; load data byte
-	rcall	write_spi						; write one byte of data
-	bra		ext_flash_wait_write			; and return...
+	global	write_byte_ext_flash_plus_prof
+write_byte_ext_flash_plus_prof:
+	movwf	ext_flash_rw					; store byte to write
+	incf	ext_flash_length_counter+0,F	; increase dive length counter
+	movlw	.0								; ...
+	addwfc	ext_flash_length_counter+1,F	; ...
+	addwfc	ext_flash_length_counter+2,F	; ...
+	bra		write_byte_ext_flash_plus_nocnt1; continue with checking for begin of new page
+
+
+	global	write_byte_ext_flash_plus_nocnt
+write_byte_ext_flash_plus_nocnt:
+	movwf	ext_flash_rw					; store byte to write
+write_byte_ext_flash_plus_nocnt1:			; test if write is done at first byte of 4kB block, if yes delete 4kB block first
+	tstfsz	ext_flash_address+0				; at 0x....00?
+	bra		write_byte_ext_flash_plus_nodel1; NO  - execute write
+	movf	ext_flash_address+1,W			; YES - mask lower nibble
+	andlw	0x0F							;     - ...
+	tstfsz	WREG							;     - at 0x..0...?
+	bra		write_byte_ext_flash_plus_nodel1;       NO  - execute write
+											;       YES - at beginning of 4kB block -> erase first!
+	rcall	ext_flash_erase_4kB				;           - erases 4kB sector @ext_flash_address:3
+	bra		write_byte_ext_flash_plus_nodel1;           - execute write
 
 
-	global	ext_flash_byte_write_comms		; without wait, ~86us fixed delay due to 115200 Baud
-ext_flash_byte_write_comms:
-	movwf	ext_flash_rw					; store data byte
-	bsf		flash_ncs						; CS=1
-	movlw	0x06							; WREN command
-	rcall	write_spi
-	bsf		flash_ncs						; CS=1
-	movlw	0x02							; write PP (Page-Program) command
-	rcall	write_spi
-	rcall	ext_flash_write_address			; write 24 bit address ext_flash_address:3 via SPI
-	movf	ext_flash_rw,W					; load data byte
-	rcall	write_spi						; write one byte of data
-	bsf		flash_ncs						; CS=1
-	return
+	global	write_byte_ext_flash_plus_nodel
+write_byte_ext_flash_plus_nodel:
+	movwf	ext_flash_rw					; store byte to write
+write_byte_ext_flash_plus_nodel1:
+	rcall	ext_flash_byte_write			; write the byte in ext_flash_rw
+	bra		incf_ext_flash_address_p1_0x20	; increase address with wrap-around at 0x200000 and return
+
+
+	global	write_byte_ext_flash_plus_comms	; write from WREG without wait, ~86us fixed delay due to 115200 Baud, use with caution!
+write_byte_ext_flash_plus_comms:
+	movwf	ext_flash_rw					; store byte to write
+	bcf		flash_wait						; do not wait on flash write to complete
+	rcall	ext_flash_byte_write_common		; write the byte in ext_flash_rw
+	bra		incf_ext_flash_address_p1_0x40	; increase address with wrap-around at 0x400000 and return
+
 
+ext_flash_byte_write:
+	bsf		flash_wait						; wait for flash write to complete
+ext_flash_byte_write_common:
+	bsf		flash_ncs						; set CS=1
+	movlw	0x06							; set up  WREN command
+	rcall	shift_spi						; execute WREN command
+	bsf		flash_ncs						; set CS=1
+	movlw	0x02							; set up  write (PP, Page-Program) command
+	rcall	shift_spi						; execute write
+	rcall	ext_flash_set_address			; write 24 bit address ext_flash_address:3 via SPI
+	movf	ext_flash_rw,W					; get byte to write
+	rcall	shift_spi						; write the byte
+	btfsc	flash_wait						; shall wait on flash write to complete?
+	bra		ext_flash_wait_write			; YES - wait for completion (and return)
+	bsf		flash_ncs						; NO  - set CS=1
+	return									;     - done
+
+; ----------------------------------------------------------------------------
 
 	global	ext_flash_disable_protection	; disable write protection
 ext_flash_disable_protection:
 	; unlock old memory
 	bsf		flash_ncs						; CS=1
 	movlw	0x50							; EWSR command
-	rcall	write_spi
+	rcall	shift_spi
 	bsf		flash_ncs						; CS=1
 	movlw	0x01							; WRSR command
-	rcall	write_spi
+	rcall	shift_spi
 	movlw	b'00000000'						; new status
-	rcall	write_spi
+	rcall	shift_spi
 	bsf		flash_ncs						; CS=1
 	; unlock new memory
 	movlw	0x06							; WREN command
-	rcall	write_spi
+	rcall	shift_spi
 	bsf		flash_ncs						; CS=1
 	movlw	0x98							; ULBPR command
-	rcall	write_spi
+	rcall	shift_spi
 	bsf		flash_ncs						; CS=1
 	movlw	0x06							; WREN command
-	rcall	write_spi
+	rcall	shift_spi
 	bsf		flash_ncs						; CS=1
 	movlw	0x42							; WBPR command
-	rcall	write_spi
-	movlw	.18
-	movwf	lo
-ext_flash_disable_protection2:
-	movlw	0x00
-	rcall	write_spi
-	decfsz	lo,F							; 18 bytes with 0x00
-	bra		ext_flash_disable_protection2
-	bsf		flash_ncs						; CS=1
-	return
+	rcall	shift_spi
+	movlw	.18								; 18 bytes to do
+	movwf	lo								; initialize loop counter
+ext_flash_disable_prot_loop:
+	movlw	0x00							; prepare writing a zero
+	rcall	shift_spi						; execute write
+	decfsz	lo,F							; all bytes done?
+	bra		ext_flash_disable_prot_loop		; NO  - loop
+	bsf		flash_ncs						; YES - set CS=1
+	return									;     - done
 
 
 	global	ext_flash_enable_protection
 ext_flash_enable_protection:
 	; lock old memory
-	bsf		flash_ncs						; CS=1
-	movlw	0x50							; EWSR command
-	rcall	write_spi
-	bsf		flash_ncs						; CS=1
-	movlw	0x01							; WRSR command
-	rcall	write_spi
-	movlw	b'00011100'						; new status (write protection on)
-	rcall	write_spi
-	bsf		flash_ncs						; CS=1
+	bsf		flash_ncs						; set CS=1
+	movlw	0x50							; prepare EWSR command
+	rcall	shift_spi						; execute EWSR command
+	bsf		flash_ncs						; set CS=1
+	movlw	0x01							; prepare WRSR command
+	rcall	shift_spi						; execute WRSR command
+	movlw	b'00011100'						; prepare write protection on
+	rcall	shift_spi						; execute write protection on
+	bsf		flash_ncs						; set CS=1
 	; lock new memory
 ;	movlw	0x06							; WREN command
-;	rcall	write_spi
+;	rcall	shift_spi
 ;	bsf		flash_ncs						; CS=1
 ;	movlw	0x8D							; LBPR command
-;	rcall	write_spi
-;	bsf		flash_ncs						; CS=1
-	movlw	0x06							; WREN command
-	rcall	write_spi
-	bsf		flash_ncs						; CS=1
-	movlw	0x42							; WBPR command
-	rcall	write_spi
-	movlw	.18
-	movwf	lo
-ext_flash_enable_protection2:
-	movlw	0xFF
-	rcall	write_spi
-	decfsz	lo,F							; 18 bytes with 0xFF
-	bra		ext_flash_enable_protection2
-	bsf		flash_ncs						; CS=1
-	return
+;	rcall	shift_spi
+;	bsf		flash_ncs						; set CS=1
+	movlw	0x06							; prepare WREN command
+	rcall	shift_spi						; execute WREN command
+	bsf		flash_ncs						; set CS=1
+	movlw	0x42							; prepare WBPR command
+	rcall	shift_spi						; execute WBPR command
+	movlw	.18								; 18 bytes to do
+	movwf	lo								; initialize loop counter
+ext_flash_enable_prot_loop:
+	movlw	0xFF							; prepare writing 0xFF
+	rcall	shift_spi						; execute write
+	decfsz	lo,F							; all bytes done?
+	bra		ext_flash_enable_prot_loop		; NO  - loop
+	bsf		flash_ncs						; YES - set CS=1
+	return									;     - done
 
+; ----------------------------------------------------------------------------
 
-	global	ext_flash_erase4kB				; erases 4kB sector
-ext_flash_erase4kB:
-	bsf		flash_ncs						; CS=1
-	movlw	0x06							; WREN command
-	rcall	write_spi
+	global	erase_complete_logbook
+erase_complete_logbook:
+	; clear logbook data in EPROM
+	CLRT	mpr								; prepare a 3 byte zero integer
+	EEPROM_II_WRITE mpr,eeprom_num_dives	; reset total number of dives
+	EEPROM_TT_WRITE mpr,eeprom_log_pointer	; reset pointer to begin of log data
+	; erase logbook data in FLASH (0x000000 -> 0x2FFFFF -> 3 MByte -> 3145728 Bytes)
 	bsf		flash_ncs						; CS=1
-	movlw	0x20							; sector erase command
-	rcall	write_spi
-	rcall	ext_flash_write_address			; write 24 bit address ext_flash_address:3 via SPI
-;	bra		ext_flash_wait_write			; wait for write... and return
-ext_flash_wait_write:
-	bsf		flash_ncs						; CS=1
-;	WAITMS	d'1'							; TBE/TSE=25ms...
-	movlw	0x05							; RDSR command
-	rcall	write_spi						; read status
-	rcall	write_spi						; read status into WREG
-	bsf		flash_ncs						; CS=1
-	btfsc	SSP2BUF,0						; write operation in process?
-	bra		ext_flash_wait_write			; ES - loop waiting
-	return
-
-
-	global	ext_flash_erase_logbook			; erases logbook memory (000000h -> 2FFFFFh -> 3MByte -> 3145728 Bytes)
-ext_flash_erase_logbook:
-	bsf		flash_ncs						; CS=1
-	clrf	ext_flash_address+0
-	clrf	ext_flash_address+1
-	clrf	ext_flash_address+2
-
-	clrf	ext_flash_rw					; 256 * 12 kB = 3145728 bytes
-ext_flash_erase_logbook_loop:
-	rcall	ext_flash_erase4kB				; 4kB
+	clrf	ext_flash_address+0				; set address to 0x000000
+	clrf	ext_flash_address+1				; ...
+	clrf	ext_flash_address+2				; ...
+	clrf	ext_flash_rw					; write zeros
+ext_flash_erase_logbook_loop:				; 256 * 12 kB = 3.145.728 bytes to do
+	rcall	ext_flash_erase_4kB				; erase 4kB block
 	rcall	ext_flash_add_4kB				; increase ext_flash_address:3 by 4kB
-	rcall	ext_flash_erase4kB				; 4kB
+	rcall	ext_flash_erase_4kB				; erase 4kB block
 	rcall	ext_flash_add_4kB				; increase ext_flash_address:3 by 4kB
-	rcall	ext_flash_erase4kB				; 4kB
+	rcall	ext_flash_erase_4kB				; erase 4kB block
 	rcall	ext_flash_add_4kB				; increase ext_flash_address:3 by 4kB
 	decfsz	ext_flash_rw,F					; decrement loop counter, done?
 	bra		ext_flash_erase_logbook_loop	; NO  - loop
 	return									; YES - done
 
+
+	global	ext_flash_erase_4kB				; erase a 4kB sector
+ext_flash_erase_4kB:
+	bsf		flash_ncs						; set CS=1
+	movlw	0x06							; prepare WREN command
+	rcall	shift_spi						; execute WREN command
+	bsf		flash_ncs						; set CS=1
+	movlw	0x20							; prepare sector erase command
+	rcall	shift_spi						; execute sector erase command
+	rcall	ext_flash_set_address			; write 24 bit address ext_flash_address:3 via SPI
+	bra		ext_flash_wait_write			; wait for write to complete and return
+
+; ----------------------------------------------------------------------------
+
+; send address
+ext_flash_set_address:
+	movf	ext_flash_address+2,W			; write 24 bit address ext_flash_address:3 via SPI
+	rcall	shift_spi						; ...
+	movf	ext_flash_address+1,W			; ...
+	rcall	shift_spi						; ...
+	movf	ext_flash_address+0,W			; ...
+	bra 	shift_spi						; ... and return
+
+; wait on write operation to complete
+ext_flash_wait_write:
+	bsf		flash_ncs						; set CS=1
+;	WAITMS	d'1'							; TBE/TSE=25ms...
+	movlw	0x05							; prepare RDSR command
+	rcall	shift_spi						; 1st cycle: execute command to read status
+	rcall	shift_spi						; 2nd cycle: read status
+	bsf		flash_ncs						; set CS=1
+	btfsc	SSP2BUF,0						; write operation still in process?
+	bra		ext_flash_wait_write			; YES - loop waiting
+	return									; NO  - done
+
+; add 0x001000 to flash address
 ext_flash_add_4kB:
-	movlw	0x10
-	addwf	ext_flash_address+1,F
-	movlw	d'0'
-	addwfc	ext_flash_address+2,F
-	return
+	movlw	0x10							; add 0x10 to high byte
+	addwf	ext_flash_address+1,F			; ...
+	movlw	d'0'							; propagate carry to upper byte
+	addwfc	ext_flash_address+2,F			; ...
+	return									; done
 
-
-write_spi:									; with data in WREG...
-	bcf		flash_ncs						; CS
-	global	write_spi1
-write_spi1:									; with data in WREG...
+; shift the SPI bus for a combined write/read: WREG --->\      /---> WREG
+shift_spi:                                  ;          flash chip
+	bcf		flash_ncs						; set CS=0
+shift_spi_loop_1:
 	bcf		SSP2STAT,WCOL					; clear flag
 	movwf	SSP2BUF							; write to buffer
 	btfsc	SSP2STAT,WCOL					; was buffer full?
-	bra		write_spi1						; YES - try again
-write_spi2:									; wait for write command
-	btfss	SSP2STAT, BF					; buffer full?
-	bra		write_spi2						; NO  - loop waiting
-	movf	SSP2BUF,W						; YES - copy RX data to WREG
-	return									;     - return with RX data in WREG and SSP2BUF
+	bra		shift_spi_loop_1				; YES - try again
+shift_spi_loop_2:
+	btfss	SSP2STAT,BF						; buffer full?
+	bra		shift_spi_loop_2				; NO  - loop waiting
+	movf	SSP2BUF,W						; YES - copy received data to WREG
+	return									;     - done
 
 	END