diff src/comm.asm @ 634:4050675965ea

3.10 stable release
author heinrichsweikamp
date Tue, 28 Apr 2020 17:34:31 +0200
parents 185ba2f91f59
children 2737ddc643bb
line wrap: on
line diff
--- a/src/comm.asm	Thu Mar 05 15:06:14 2020 +0100
+++ b/src/comm.asm	Tue Apr 28 17:34:31 2020 +0200
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File comm.asm                             combined next generation V3.08.8
+;   File comm.asm                           * combined next generation V3.09.5
 ;
 ;   RS232 via USB
 ;
@@ -25,6 +25,7 @@
 #include "math.inc"
 #include "i2c.inc"
 #include "logbook.inc"
+#include "colorschemes.inc"
 
 
 	extern	restart
@@ -34,6 +35,7 @@
 	extern	option_write_serial
 	extern	gaslist_cleanup_list
 	extern	eeprom_deco_data_write
+	extern	eeprom_memorize_fw_checksum
 
 
 ; timeouts
@@ -58,6 +60,9 @@
 #DEFINE comm_status3_column		comm_status1_column
 #DEFINE	comm_status4_row		.160
 #DEFINE	comm_status4_column		comm_status1_column
+#DEFINE	comm_status5_row		.190
+#DEFINE	comm_status5_column		comm_status1_column
+
 
 ; positioning of COMM mode warning icon
 #DEFINE comm_warning_row		.160
@@ -66,11 +71,13 @@
 
 ;#DEFINE	testloop_avail				; uncomment if testloop code is available
 
-
+;=============================================================================
 comm	CODE
-
 ;=============================================================================
 
+;-----------------------------------------------------------------------------
+; Entry Point for Comm Mode / USB
+;
 	global	comm_mode_usb
 comm_mode_usb:										; entry point for comm mode via USB
 	WAITMS	d'1'									; wait 1 ms
@@ -82,46 +89,60 @@
 	bsf		aux_flag								;       YES - remember to show USB title
 	bra		comm_mode_common						;           - continue with common part
 
-	global	comm_mode_ble
-comm_mode_ble:										; entry point for comm mode via BLE
+
+;-----------------------------------------------------------------------------
+; Entry Point for Comm Mode / BT
+;
+	global	comm_mode_bt
+comm_mode_bt:										; entry point for comm mode via BT
 	bcf		aux_flag								; remember to show BLE title
 	;bra	comm_mode_common						; continue with common part
 
+
+;-----------------------------------------------------------------------------
+; Common Part of Comm Mode Entry
+;
 comm_mode_common:
 	clrf	STKPTR									; reset addresses stack
 	call	TFT_ClearScreen							; clear screen
-	WIN_COLOR color_greenish						; set color
+	FONT_COLOR color_greenish						; set color
 
 	btfss	aux_flag								; shall show USB title?
-	bra		comm_mode_common_1						; NO  - show BLE title
-	WIN_SMALL comm_title_column_usb, comm_title_row	; YES - set   USB title position
-	STRCPY_TEXT_PRINT tUsbTitle						;     - print USB title text
-	bra		comm_mode_common_2						;     - continue with common part
+	bra		comm_mode_common_bt						; NO  - show BT  title
+	;bra	comm_mode_common_usb					; YES - show USB title
 
-comm_mode_common_1:
-	WIN_SMALL comm_title_column_ble, comm_title_row	; set   BLE title position
-	STRCPY_TEXT_PRINT tBleTitle						; print BLE title text
-	;bra	comm_mode_common_2						; continue with common part
+comm_mode_common_usb:
+	WIN_SMALL comm_title_column_usb, comm_title_row	; set   USB title position
+	STRCPY_TEXT_PRINT tUsbTitle						; print USB title text
+	bra		comm_mode_common_logo					; continue with logo
 
-comm_mode_common_2:
-	call	TFT_standard_color						; set standard color
+comm_mode_common_bt:
+	WIN_SMALL comm_title_column_ble, comm_title_row	; set   BT title position
+	STRCPY_TEXT_PRINT tBleTitle						; print BT title text
+	;bra	comm_mode_common_logo					; continue with logo
+
+comm_mode_common_logo:
 	WIN_TOP  .10									; set position of USB/BLE logo, row
 	WIN_LEFT .1										; set position of USB/BLE logo, column
-	btfsc	battery_gauge_available					; "+" bootloader ?
-	bra		comm_mode_common_3						; NO  - show logo type 1
-	TFT_WRITE_PROM_IMAGE_BY_ADDR usb_ble_logo_2		; YES - show USB/BLE logo 2
-	bra		comm_mode_common_4						;     - continue with common part
+	btfss	battery_gauge_available					; "+" bootloader ?
+	bra		comm_mode_common_logo2					; YES - show logo type 2
+	;bra	comm_mode_common_logo1					; NO  - show logo type 1
+
+comm_mode_common_logo1:
+	TFT_WRITE_PROM_IMAGE_BY_ADDR comm_logo_1		; show USB/BT logo
+	bra		comm_mode_common_start					; continue with starting message
 
-comm_mode_common_3:
-	TFT_WRITE_PROM_IMAGE_BY_ADDR usb_ble_logo_1		; show logo type 1
-	;bra	comm_mode_common_4						; continue with common part
+comm_mode_common_logo2:
+	TFT_WRITE_PROM_IMAGE_BY_ADDR comm_logo_2		; show BT logo / OSTC+
+	;bra	comm_mode_common_start					; continue with starting message
 
-comm_mode_common_4:
-	WIN_SMALL comm_status1_column,comm_status1_row	; print status message "starting..."
-	STRCPY_TEXT_PRINT tUsbStarting					; ...
+comm_mode_common_start:
+	WIN_SMALL comm_status1_column,comm_status1_row	; set position
+	FONT_COLOR_MEMO									; set standard color
+	STRCPY_TEXT_PRINT tUsbStarting					; print status message "starting..."
 
 	WIN_TINY .40,.240-.16							; set output position to bottom line
-	call	TFT_show_serial_and_firmware			; show serial number and firmware version
+	call	TFT_print_serial_and_firmware			; show serial number and firmware version
 
  IFDEF _screendump
 	bcf		screen_dump_avail						; disable screen dump function
@@ -130,12 +151,18 @@
 	bcf		switch_right							; clear potential left-over right button event
 	call	enable_rs232							; enable serial comm, also sets CPU to normal speed
 
-	WIN_SMALL comm_status1_column+.80,comm_status1_row	; print (adding to status message) "done..."
-	STRCPY_TEXT_PRINT tUsbStartDone						; ...
+	WIN_SMALL comm_status1_column+.80,comm_status1_row	; set position after starting message
+	FONT_COLOR_MEMO										; set standard color
+	STRCPY_TEXT_PRINT tUsbStartDone						; print (adding to status message) "done..."
 
 	movlw	timeout_comm_pre_mode					; get timeout for phase without communication established yet
 	movwf	comm_timeout_timer						; initialize timeout counter
+	;bra	comm_mode_selection_loop				; continue with mode selection loop
 
+
+;-----------------------------------------------------------------------------
+; Mode Selection Loop: Download Mode or Service Mode
+;
 comm_mode_selection_loop:
 	bcf		trigger_full_second						; clear 'one second elapsed' flag
 	bcf		LEDr									; switch off red LED / power down TR co-processor
@@ -151,10 +178,10 @@
 	bz		comm_service_mode_check					;       YES - check if correct key will be send
 	movf	lo,W									;       NO  - copy received byte to lo again
 	xorlw	0xBB									;           - download mode start byte received?
-	bz		comm_download_mode						;              YES - enter command loop
-	;bra	comm_mode_selection_loop_2				;              NO  - check for comm mode termination
+	bz		comm_download_mode						;             YES - enter command loop
+	;bra	comm_mode_selection_loop_2				;             NO  - check for comm mode termination
 comm_mode_selection_loop_2:
-	btfsc	ble_available							; BLE available?
+	btfsc	ble_available							; BT available?
 	bra		comm_mode_selection_loop_3				; YES - skip USB check check (required for very old OSTC sport)
 	btfss	vusb_in									; NO  - USB plugged in?
 	bra		comm_service_exit_nousb_delay			;       NO  - disconnected, check for vusb_in glitch
@@ -168,10 +195,9 @@
 
 
 ;-----------------------------------------------------------------------------
-; Received start byte for service mode, await service key
+; Check Service Mode Pass-Key and notify Service Mode on Success
 ;
 comm_service_mode_check:
-
 	SERIAL_LC_SEND 0x4B								; request peer to send service key
 
 	; receive a 3 byte service key transmitted in big-endian, echo each byte
@@ -197,53 +223,82 @@
 	tstfsz	WREG									; received expected service key?
 	bra		comm_mode_selection_loop				; NO  - back to mode selection loop
 	WIN_SMALL comm_status2_column, comm_status2_row	; YES - print service mode enabled message
+	FONT_COLOR_MEMO									;     - set standard color
 	STRCPY_TEXT_PRINT tUsbServiceMode				;     - ...
 	bsf		comm_service_mode						;     - enable service mode commands
 	bra		comm_command_loop						;     - enter command loop
 
 
 ;-----------------------------------------------------------------------------
-; Received start byte for download mode
+; Notify RX Timeout occurred
+;
+comm_command_timeout:
+	WIN_SMALL comm_status4_column, comm_status4_row	; select font and output position
+	FONT_COLOR_WARNING								; set warning color
+	STRCPY_PRINT "Data Rx Timeout"					; print failure message
+	FONT_COLOR_MEMO									; back to standard color
+	bra		comm_drain_rx_queue						; continue with draining the RX queue
+
+
+;-----------------------------------------------------------------------------
+; Notify Error in Parameters
+;
+comm_command_error:
+	WIN_SMALL comm_status4_column, comm_status4_row	; select font and output position
+	FONT_COLOR_WARNING								; set warning color
+	STRCPY_PRINT "Parameter Error"					; print failure message
+	FONT_COLOR_MEMO									; back to standard color
+	;bra	comm_drain_rx_queue						; continue with draining the RX queue
+
+
+;-----------------------------------------------------------------------------
+; Drain the RX Queue until next Timeout
+;
+comm_drain_rx_queue:
+	bsf		INTCON,GIE								; re-enable all interrupts
+comm_drain_rx_queue_loop:
+	btfsc	switch_right							; right button (abort) pressed?
+	bra		comm_service_exit						; YES - exit comm mode
+	SERIAL_CC_RECEIVE WREG							; NO  - (try to) receive one byte
+	btfss	rs232_rx_timeout						;     - got a byte?
+	bra		comm_drain_rx_queue_loop				;       YES - try to drain more bytes
+	bra		comm_command_loop						;       NO  - re-enter command loop
+
+
+;-----------------------------------------------------------------------------
+; Debug Code - show Number of Bytes received
+;
+ IFDEF _comm_debug
+comm_command_debug:
+	WIN_SMALL comm_status5_column, comm_status5_row	; select font and output position
+	FONT_COLOR_MEMO									; set standard color
+	STRCPY	"last RX: "								; print label
+	output_9999										; print number of bytes received (0-9999)
+	STRCAT_PRINT " Byte"							; finalize output
+	bra		comm_command_loop						; re-enter command loop
+ ENDIF
+
+
+;-----------------------------------------------------------------------------
+; Notify Download Mode selected
 ;
 comm_download_mode:
 	SERIAL_LC_SEND 0xBB								; inform peer download mode will be started
 
-	WIN_SMALL comm_status2_column, comm_status2_row	; print download mode enabled message
-	STRCPY_TEXT_PRINT tUsbDownloadMode				; ... 
+	WIN_SMALL comm_status2_column, comm_status2_row	; set position
+	FONT_COLOR_MEMO									; set standard color
+	STRCPY_TEXT_PRINT tUsbDownloadMode				; print download mode enabled message
 	bcf		comm_service_mode						; disable service mode commands
-	bra		comm_command_loop						; enter command loop
+	;bra	comm_command_loop						; enter command loop
 
 
 ;-----------------------------------------------------------------------------
-; Notify RX timeout occurred
-;
-comm_command_timeout:
-	; select font and output position
-	WIN_SMALL comm_string_column, comm_string_row
-	call	TFT_warning_color			; select color
-	STRCPY_PRINT "Data Rx Timeout"		; print failure message (fill to 15 chars)
-	call	TFT_standard_color			; back to standard color
-	bra		comm_command_loop			; re-enter command loop
-
-
-;-----------------------------------------------------------------------------
-; Notify error in parameters
-;
-comm_command_error:
-	; select font and output position
-	WIN_SMALL comm_string_column, comm_string_row
-	call	TFT_warning_color			; switch to waring color
-	STRCPY_PRINT "Parameter Error"		; print failure message (fill to 15 chars)
-	call	TFT_standard_color			; back to standard color
-	;bra	comm_command_loop			; re-enter command loop
-
-
-;-----------------------------------------------------------------------------
-; Command loop: wait for a command
+; Command Loop: await, decode and execute Commands
 ;
 comm_command_loop:
-	; (re-)initialize
 	bsf		INTCON,GIE								; re-enable all interrupts
+
+	; restart command timeout
 	movlw	timeout_service_mode					; get    timeout value
 	movwf	comm_timeout_timer						; reload timeout timer
 
@@ -260,10 +315,12 @@
 	bra		comm_command_decode						; NO  - decode and execute the command
 	btfsc	comm_service_mode						; YES - service mode enabled?
 	btg		LEDr									;       YES - blink in service mode
-	btfsc	ble_available							;     - BLE available?
+	btfsc	ble_available							;     - BT available?
 	bra		comm_command_loop_wait_1				;       YES - skip USB check (required for very old OSTC sport)
 	btfss	vusb_in									;       NO  - USB still plugged in?
 	bra		comm_service_exit_nousb					;             NO  - disconnected -> exit comm mode
+	;bra	comm_command_loop_wait_1				;             YES - proceed
+
 comm_command_loop_wait_1:
 	btfsc	switch_right							; right button (abort) pressed?
 	bra		comm_service_exit						; YES - exit comm mode
@@ -276,17 +333,18 @@
 
 
 ;-----------------------------------------------------------------------------
-; Macro for easier writing of command decoding rules
+; Macro for easier writing of Command Decoding Rules
 ;
 command_decode  macro  command_id,command_function
-	movf	lo,W				; copy received command to WREG
-	xorlw	command_id			; exclusive-or with command ID
-	btfsc	STATUS,Z			; received command = command ID ?
-	goto	command_function	; YES - execute command
+	movf	lo,W									; copy received command to WREG
+	xorlw	command_id								; exclusive-or with  command ID
+	btfsc	STATUS,Z								; received command = command ID ?
+	goto	command_function						; YES - execute command
 	endm
 
+
 ;-----------------------------------------------------------------------------
-; Decode and execute a command
+; Decode and execute a Command
 ;
 comm_command_decode:
 	bcf		LEDr									; switch off red led
@@ -315,9 +373,9 @@
 	; decode and execute additional service mode commands
 	command_decode 0x23,comm_reset_battery_gauge	; #  reset the battery gauge registers
 	command_decode 0x22,comm_erase_complete_logbook	; "  reset all logbook pointers and the logbook
-	command_decode 0x20,comm_read_range				;' '  read a memory range from the external FLASH
-	command_decode 0x40,comm_erase_4kb				; @  erase one        4 kB block  - Warning: no confirmation or built-in safety here...
-	command_decode 0x42,comm_erase_range4kb			; B  erase a range of 4 kB blocks - Warning: no confirmation or built-in safety here...
+	command_decode 0x20,comm_read_range				;' ' read a memory range from the external FLASH
+	command_decode 0x40,comm_erase_single_4kb		; @  erase a single   4 kB block  - Warning: no confirmation or built-in safety here...
+	command_decode 0x42,comm_erase_range_4kb		; B  erase a range of 4 kB blocks - Warning: no confirmation or built-in safety here...
 	command_decode 0x30,comm_write_range_stream		; 0  write a stream of     bytes starting at ext_flash_address:3 until timeout
 	command_decode 0x31,comm_write_range_block		; 1  write a block  of 256 bytes starting at ext_flash_address:3
 	command_decode 0x50,comm_firmware_update		; P  initiate firmware update
@@ -330,10 +388,11 @@
 
 
 ;-----------------------------------------------------------------------------
-; Exit comm mode
+; Exit Comm Mode
 ;
 comm_service_exit:
 	WIN_SMALL comm_status3_column, comm_status3_row	; print "Exited" message
+	FONT_COLOR_MEMO									; set standard color
 	STRCPY_TEXT_PRINT	tUsbExit					; ...
 	bra		comm_service_exit_common				; acknowledge exit command and restart
 
@@ -345,15 +404,17 @@
 
 comm_service_exit_nousb:
 	WIN_SMALL comm_status3_column, comm_status3_row	; print "Port closed" message
+	FONT_COLOR_MEMO									; set standard color
 	STRCPY_TEXT_PRINT tUsbClosed					; ...
 	;bra	comm_service_exit_common				; proceed exiting
 
 comm_service_exit_common:
 	SERIAL_LC_SEND 0xFF								; acknowledge exit command
-	call	wait_1s									; wait <= 1 second
-	call	wait_1s									; wait    1 second
+	WAITS	.1										; wait 1 second to give the serial I/F time
+													; to send the 0xFF before it gets shut down
 	call	disable_rs232							; shut down comm port
 	bcf		LEDr									; switch off red LED
+	WAITS	.1										; wait 1 second for BT module supply to drain
 	goto	restart									; restart
 
 
@@ -361,220 +422,247 @@
 ; Set Real-Time-Clock
 ;
 comm_set_time:
+	bcf		INTCON,GIE					; disable all interrupts
 	SERIAL_LC_SEND 0x62					; acknowledge command
+	SERIAL_RR_RECEIVE mpr,.6			; (try to) receive 6 bytes: hour, minute, second, month, day, year
+	bsf		INTCON,GIE					; re-enable all interrupts
 
-	; receive 6 bytes coming in sequence: hour, minute, second, month, day, year
-	SERIAL_RR_RECEIVE_RAM mpr,.6
-
-	; got all 6 bytes?
-	btfsc	rs232_rx_timeout			; timeout?
-	bra		comm_command_timeout		; YES - abort, back to command loop
+	btfsc	rs232_rx_timeout			; got all 6 bytes?
+	bra		comm_command_timeout		; NO  - show rx timeout message and back to command loop
 
-	; map the received bytes onto the rtc_latched variables
-	movff	mpr+0,rtc_latched_hour
-	movff	mpr+1,rtc_latched_mins
-	movff	mpr+2,rtc_latched_secs
-	movff	mpr+3,rtc_latched_month
-	movff	mpr+4,rtc_latched_day
-	movff	mpr+5,rtc_latched_year
-
-	; set the RTC
+	movff	mpr+0,rtc_latched_hour		; map the received bytes onto the rtc_latched variables
+	movff	mpr+1,rtc_latched_mins		; ...
+	movff	mpr+2,rtc_latched_secs		; ...
+	movff	mpr+3,rtc_latched_month		; ...
+	movff	mpr+4,rtc_latched_day		; ...
+	movff	mpr+5,rtc_latched_year		; ...
 	call	rtc_set_rtc					; write time and date to RTC module
-
 	bra		comm_command_loop			; done, back to command loop
 
 
 ;-----------------------------------------------------------------------------
-; Write a 15 char text to the OSTC display
+; Write a 15 char Text to the OSTC Display
 ;
 comm_show_text:
-	; set font and output position of the text to show
+	; set font and output position (needs to be done before SERIAL_RR_RECEIVE)
 	WIN_SMALL comm_string_column, comm_string_row
+	FONT_COLOR_MEMO						; set standard color
 
+	bcf		INTCON,GIE					; disable all interrupts
 	SERIAL_LC_SEND 0x6E					; acknowledge command
+	SERIAL_RR_RECEIVE buffer,.16		; (try to) receive 16 chars into the string buffer
+	bsf		INTCON,GIE					; re-enable all interrupts
 
-	SERIAL_RR_RECEIVE_RAM buffer,.16	; (try to) receive 16 chars and write them to 'buffer' using FSR2
-	STRCAT_PRINT ""						; dump whatever was received to the screen
+	movlw	.15							; set maximum text length
+	call	TFT_buffer_trim_length		; fill or trim the text to correct length
+	PRINT								; print text to screen
+	bra		comm_command_loop			; done, back to command loop
+
+
+;-----------------------------------------------------------------------------
+; Send Serial (2 bytes low:high), Firmware (major.minor) and Custom Text
+;
+comm_identify:
+	SERIAL_LC_SEND 0x69					; acknowledge command
+
+	; send OSTC serial number
+	call	eeprom_serial_number_read	; read OSTC serial number
+	SERIAL_CC_SEND mpr+0				; send serial number, low  byte
+	SERIAL_CC_SEND mpr+1				; send serial number, high byte
+
+	; send firmware version
+	SERIAL_LC_SEND fw_version_major		; send firmware version, major
+	SERIAL_LC_SEND fw_version_minor		; send firmware version, minor
+
+	; send custom text
+	SERIAL_RR_SEND	opt_name,opt_name_length
 
 	bra		comm_command_loop			; done, back to command loop
 
 
 ;-----------------------------------------------------------------------------
-; Reply Serial (2 bytes low:high), firmware (major.minor) and custom text
+; Send short Hardware Descriptor
 ;
-comm_identify:
-	SERIAL_LC_SEND 0x69					; acknowledge command
-
-	;---- send OSTC serial number
-	call	eeprom_serial_number_read	; read OSTC serial number
-	SERIAL_CC_SEND mpr+0				; send serial number, low  byte
-	SERIAL_CC_SEND mpr+1				; send serial number, high byte
-
-	;---- send firmware version
-	SERIAL_LC_SEND fw_version_major		; send firmware version, major
-	SERIAL_LC_SEND fw_version_minor		; send firmware version, minor
-
-	;---- send custom text
-	SERIAL_RR_SEND_RAM	opt_name,opt_name_length
-
+comm_hardware_descriptor:
+	SERIAL_LC_SEND 0x6A					; acknowledge command
+	rcall	comm_helper_hw_descriptor	; send hardware descriptor
 	bra		comm_command_loop			; done, back to command loop
 
 
 ;-----------------------------------------------------------------------------
-; Reply hardware descriptor byte
+; Helper Function for sending Hardware Descriptor
 ;
-comm_hardware_descriptor:
-	SERIAL_LC_SEND 0x6A					; acknowledge command
-
+comm_helper_hw_descriptor:
 	movf	HW_descriptor,W				; get hardware descriptor
 	bcf		WREG,6						; clear bit 6 for reason of compatibility with 3rd party software
 	bcf		WREG,7						; clear bit 7 for reason of compatibility with 3rd party software
 	SERIAL_CC_SEND WREG					; send modified hardware descriptor
-
-	bra		comm_command_loop			; done, back to command loop
+	return
 
 
 ;-----------------------------------------------------------------------------
-; Reply detailed hardware descriptor
+; Send detailed Hardware Descriptor
 ;
 comm_feature_and_hardware:
 	SERIAL_LC_SEND 0x60					; acknowledge command
 
-	SERIAL_LC_SEND 0x00					; send hardware high byte (fixed zero)
-
-	movf	HW_descriptor,W				; get hardware descriptor
-	bcf		WREG,6						; clear bit 6 for reason of compatibility with 3rd party software
-	bcf		WREG,7						; clear bit 7 for reason of compatibility with 3rd party software
-	SERIAL_CC_SEND WREG					; send modified hardware low byte
-
-	SERIAL_LC_SEND 0x00					; send feature high byte (fixed zero)
-	SERIAL_LC_SEND 0x00					; send feature low  byte (fixed zero)
-
+	SERIAL_LC_SEND 0x00					; send hardware high byte    (fixed zero)
+	rcall	comm_helper_hw_descriptor	; send hardware descriptor
+	SERIAL_LC_SEND 0x00					; send feature high byte     (fixed zero)
+	SERIAL_LC_SEND 0x00					; send feature low  byte     (fixed zero)
 	SERIAL_LC_SEND 0x00					; send model descriptor byte (fixed zero)
 
 	bra		comm_command_loop			; done, back to command loop
 
 
 ;-----------------------------------------------------------------------------
-
-comm_send_headers_short:
-	SERIAL_LC_SEND 0x6D					; acknowledge command
-
-	; send short header (16 bytes/dive)
-	; index 0: 0x200009 - 0x200016  +  0x200050 - 0x200051  +  0x200008
-	;       1: 0x201009 - 0x201016  +  0x201050 - 0x201051  +  0x201008
-	;       2: 0x202009 - 0x202016  +  0x202050 - 0x202051  +  0x202008
-	;     ...
-	;     255: 0x2FF009 - 0x2FF016  +  0x2FF050 - 0x2FF051  +  0x2FF008
-
-	clrf	ex								; start with dive having index 0
-comm_send_headers_short_loop:
-	movf	ex,W							; get index into WREG
-	call	log_header_addr_by_index		; compute header start address from index, result in mpr
+; Helper Function to retrieve a Header, hide the internal Profile Version,
+;                 and to check if the Header is empty
+;
+comm_helper_read_header:
+	; copy header from FLASH into memory
+	call	log_header_addr_by_index					; compute header start address from index in WREG
+	FLASH_RR_READ header_buffer,.256					; copy from FLASH to header buffer
 
-	; assemble the short header - part 1
-	movlw	index_profile_byte_count		; adjust start address to first  block to go into the short header
-	movwf	mpr+0							; ...
-	FLASH_RR_READ mpr,header_buffer,.13		; read 13 bytes from header into buffer
-
-	; assemble the short header - part 2
-	movlw	index_total_dives				; adjust start address to second block to into the short header
-	movwf	mpr+0							; ...
-	FLASH_RR_READ mpr,header_buffer+.13,.2	; read  2 bytes from header into buffer
-
-	; assemble the short header - part 3
-	movlw	index_profile_version			; adjust start address to third  block to go into the short header
-	movwf	mpr+0							; ...
-	FLASH_RR_READ mpr,header_buffer+.15,.1	; read  1 byte  from header into buffer
-
-	; send the assembled short header
-	SERIAL_RR_SEND_RAM header_buffer,.16	; send buffer, 16 bytes to do
-
-	; go to next header
-	incfsz	ex								; increment index, wrap-around. i.e. all dives done ?
-	bra		comm_send_headers_short_loop	; NO  - loop
-	bra		comm_command_loop				; YES - done, back to command loop
+	; hide internal profile version ID from the outside
+	movff	header_buffer+index_profile_version,WREG	; get byte at the profile version position
+	infsnz	WREG,W										; was the byte = 0xFF (i.e. empty header) ?
+	return												; YES - leave it as it is (WREG now 0)
+	decf	WREG,W										; NO  - restore the profile version
+	andlw	b'00111111'									;     - keep only the external part
+	movff	WREG,header_buffer+index_profile_version	;     - write back the cleaned byte
+	return												;     - done (WREG now ext. profile version)
 
 
 ;-----------------------------------------------------------------------------
+; Send Dive Headers in short or full Format
+;
+comm_send_headers_short:
+	SERIAL_LC_SEND 0x6D					; acknowledge command
+	bcf		aux_flag					; send short headers
+	bra		comm_send_headers_common	; continue with common part
 
 comm_send_headers_full:
 	SERIAL_LC_SEND 0x61					; acknowledge command
+	bsf		aux_flag					; send full  headers
+	;bra	comm_send_headers_common	; continue with common part
 
-	; send complete headers (256 bytes/dive)
-	; index 0: 0x200000 - 0x2000FF
-	;       1: 0x201000 - 0x2010FF
-	;       2: 0x202000 - 0x2020FF
-	;     ...
-	;     255: 0x2FF000 - 0x2FF0FF
+comm_send_headers_common:
+	clrf	ex							; start with dive having index 0
+
+comm_send_headers_loop:
+	movf	ex,W						; get index  into WREG
+	rcall	comm_helper_read_header		; get header into header_buffer
+
+	btfss	aux_flag					; shall send full  headers?
+	bra		comm_send_headers_loop_short; NO  - send short headers
+	;bra	comm_send_headers_loop_full	; YES - send full  headers
 
-	clrf	ex								; start with dive having index 0
-comm_send_headers_full_loop:
-	movf	ex,W							; get index into WREG
-	call	log_header_addr_by_index		; compute header start address from index, result in mpr
-	FLASH_RR_READ  mpr,header_buffer,.256	; get header from FLASH into memory
-	SERIAL_RR_SEND_RAM header_buffer,.256	; send the header from memory to RS232
-	incfsz	ex								; increment index, wrap-around. i.e. all dives done ?
-	bra		comm_send_headers_full_loop		; NO  - loop
-	bra		comm_command_loop				; YES - done, back to command loop
+comm_send_headers_loop_full:
+	SERIAL_RR_SEND header_buffer,.256	; send the full header
+	bra		comm_send_headers_loop_com	; continue with common part
+
+comm_send_headers_loop_short:
+	; send the fractions of the short header (16 byte/dive)
+	SERIAL_RR_SEND header_buffer+index_profile_byte_count,.13
+	SERIAL_RR_SEND header_buffer+index_total_dives,        .2
+	SERIAL_CC_SEND header_buffer+index_profile_version   ; .1
+	;bra	comm_send_headers_loop_com	; continue with common part
+
+comm_send_headers_loop_com:
+	incfsz	ex							; increment index, wrap-around. i.e. all dives done ?
+	bra		comm_send_headers_loop		; NO  - loop
+	bra		comm_command_loop			; YES - done, back to command loop
 
 
 ;-----------------------------------------------------------------------------
-; Send one full dive
+; Send one full Dive
 ;
 comm_send_dive:
 	SERIAL_LC_SEND 0x66					; acknowledge command
 
-	SERIAL_CC_RECEIVE WREG				; (try to) receive the dive index (0-255)
+	SERIAL_CC_RECEIVE WREG				; (try to) receive the dive index
 	btfsc	rs232_rx_timeout			; got dive index?
-	bra		comm_command_timeout		; NO - abort, back to command loop
+	bra		comm_command_timeout		; NO - show rx timeout message and back to command loop
 
-	call	log_header_addr_by_index	; compute header start address from index, result in mpr
-	FLASH_RR_READ mpr,header_buffer,.256; copy the complete header into the buffer
+	rcall	comm_helper_read_header		; read header into header_buffer
+	bz		comm_send_dive_exit			; abort if header contains no dive
 
-	; get pointers and length of profile data
+	; get the start and end address of the profile data
 	MOVTT	header_buffer+index_profile_start_address,ext_flash_address
 	MOVTT	header_buffer+index_profile_end_address,  ext_flash_end_pointer
-	MOVTT	header_buffer+index_profile_byte_count,   ext_flash_length_counter
+
+	; header start code sequence present?
+	bcf		aux_flag					; default to no profile available
 
-	; check if profile data are available
-	movf	ext_flash_address+0,W		; compare low   byte of start and end pointer
-	cpfseq	ext_flash_end_pointer+0		; equal?
-	bra		comm_send_dive1				; NO - profile data available, continue
+	FLASH_CW_READ_0x20					; get the 1st byte of profile data
+	xorlw	0xFA						; 1st byte = header start byte?
+	bnz		comm_send_dive_modify_header; NO  - no profile data available
+
+	FLASH_CW_READ_0x20					; get the 2nd byte of profile data
+	xorlw	0xFA						; 2nd byte = header start byte?
+	bnz		comm_send_dive_modify_header; NO  - no profile data available
+
+	EXT_FLASH_INC_ADDRESS_0x20 .2		; skip the 3rd and 4th byte (dive number)
 
-	movf	ext_flash_address+1,W		; compare high  byte of start and end pointer
-	cpfseq	ext_flash_end_pointer+1		; equal?
-	bra		comm_send_dive1				; NO - profile data available, continue
+	FLASH_CW_READ_0x20					; get the 5th byte of profile data
+	xorlw	0xFA						; 5th byte = header start byte?
+	bnz		comm_send_dive_modify_header; NO  - no profile data available
+
+	FLASH_CW_READ_0x20					; get the 6th byte of profile data
+	xorlw	0xFA						; 6th byte = header start byte?
+	bnz		comm_send_dive_modify_header; NO  - no profile data available
 
-	movf	ext_flash_address+2,W		; compare upper byte of start and end pointer
-	cpfseq	ext_flash_end_pointer+2		; equal?
-	bra		comm_send_dive1				; NO - profile data available, continue
+	bsf		aux_flag					; memorize profile data available
+	bra		comm_send_dive_header		; continue with sending header 
 
-	bra		comm_command_loop			; start = end -> no profile data available, abort, back to command loop
+comm_send_dive_modify_header:
+	; set profile data start and end address to 0x000000
+	CLRR	header_buffer+index_profile_start_address,.6
+
+	; set hi = 0x00, lo = 0x08
+	MOVLI	0x0008,mpr
 
-comm_send_dive1:
-	; send the header from the buffer
-	SERIAL_RR_SEND_RAM header_buffer,.256
+	; set byte count to 0x000008
+	movff	lo,header_buffer+index_profile_byte_count+0		; = 0x08
+	movff	hi,header_buffer+index_profile_byte_count+1		; = 0x00
+	movff	hi,header_buffer+index_profile_byte_count+2		; = 0x00
+
+comm_send_dive_header:
+	SERIAL_RR_SEND header_buffer,.256	; send the header from the buffer
+
+	btfss	aux_flag					; profile data available?
+	bra		comm_send_dive_empty_profile; NO - send empty profile
+
+comm_send_dive_profile:
+	FLASH_CW_READ_0x20					; read one byte and increment address with rollover at 0x200000
+	SERIAL_CC_SEND WREG					; transmit the byte
+
+	; 24 bit compare of current address with end address
+	movf	ext_flash_end_pointer+0,W	; check low   byte of addresses
+	cpfseq	ext_flash_address+0			; current address = end address ?
+	bra		comm_send_dive_profile		; NO  - more bytes to do, loop
 
-	; send the profile directly from the FLASH
-	ext_flash_inc_address_0x20 .6		; skip the first 6 bytes (short header) of the profile data
-	ext_flash_dec_length .3				; adopt the length count (short by 3 bytes)
-	ext_flash_dec_length .1				; decrement length count by 1 so that all bytes will be
-										; done when the counter has wrapped around to 0xFFFFFF
-	movlw	0x20						; now the length count is allowed to be 0x1FFFFF at max
-	cpfslt	ext_flash_length_counter+2	; length count < 0x20(0000) ?
-	bra		comm_command_error			; NO - abort, back to command loop
-	call	ext_flash_read_block_start	; YES - read first byte from FLASH into WREG
-	bra		comm_send_dive_loop_start	;     - jump into transmit loop
-comm_send_dive_loop:
-	call	ext_flash_read_block_0x20	; read next byte into WREG
-comm_send_dive_loop_start:
-	SERIAL_CC_SEND WREG					; transmit byte
-	ext_flash_dec_length .1				; decrement length counter
-	btfss	ext_flash_length_counter+2,7; under-run?
-	bra		comm_send_dive_loop			; NO  - continue loop
-	call	ext_flash_read_block_stop	; YES - end reading from FLASH
-	bra		comm_command_loop			;     - done, back to command loop
+	movf	ext_flash_end_pointer+1,W	; check high  byte of addresses
+	cpfseq	ext_flash_address+1			; current address = end address ?
+	bra		comm_send_dive_profile		; NO  - more bytes to do, loop
+
+	movf	ext_flash_end_pointer+2,W	; check upper byte of addresses
+	cpfseq	ext_flash_address+2			; current address = end address ?
+	bra		comm_send_dive_profile		; NO  - more bytes to do, loop
+
+comm_send_dive_exit:
+	bra		comm_command_loop			; done, back to command loop
+
+comm_send_dive_empty_profile:
+
+	; send profile length
+	SERIAL_RR_SEND header_buffer+index_profile_byte_count,.3
+
+	SERIAL_LC_SEND 0xFD					; send end-of-profile sequence, byte 1
+	SERIAL_LC_SEND 0xFD					; send end-of-profile sequence, byte 2
+
+	bra		comm_command_loop			; done, back to command loop
 
 
 ;-----------------------------------------------------------------------------
@@ -587,16 +675,18 @@
 
 
 ;-----------------------------------------------------------------------------
-; Set Custom Text String (opt_name_length ASCII chars)
+; Set Custom Text (opt_name_length ASCII chars)
 ;
 comm_set_custom_text:
-	CLRR	opt_name,opt_name_length	; clear old custom text
-	SERIAL_LC_SEND 0x63					; acknowledge command
+	CLRR	opt_name,opt_name_length			; clear old custom text
 
-	; receive new custom text (less than opt_name_length characters may be sent)
-	SERIAL_RR_RECEIVE_RAM opt_name,opt_name_length
+	bcf		INTCON,GIE							; disable all interrupts
+	SERIAL_LC_SEND 0x63							; acknowledge command
+	SERIAL_RR_RECEIVE opt_name,opt_name_length	; receive new custom text
+	bsf		INTCON,GIE							; re-enable all interrupts
+	bsf		option_changed						; flag that EEPROM needs to be updated
 
-	bra		comm_command_loop			; done, back to command loop
+	bra		comm_command_loop					; done, back to command loop
 
 
 ;-----------------------------------------------------------------------------
@@ -612,9 +702,9 @@
 ; Erase complete Logbook
 ;
 comm_erase_complete_logbook:
-;	SERIAL_LC_SEND 0x22					; acknowledge command (not done)
-	call	erase_complete_logbook		; erase complete logbook
-	bra		comm_command_loop			; done, back to command loop
+;	SERIAL_LC_SEND 0x22						; acknowledge command (not done)
+	call	erase_complete_logbook			; erase complete logbook
+	bra		comm_command_loop				; done, back to command loop
 
 
 ;-----------------------------------------------------------------------------
@@ -622,10 +712,10 @@
 ;
 comm_cold_start:
 ;	SERIAL_LC_SEND 0xC1									; acknowledge command (not done)
-;	call	rs232_wait_tx								; wait for completion of transmit before hardware goes into reboot
 
-	WIN_SMALL comm_status3_column, comm_status3_row		; print "Low-level Bootloader" message
-	STRCPY_TEXT_PRINT tUsbLlBld							; ...
+	WIN_SMALL comm_status3_column, comm_status3_row		; set position
+	FONT_COLOR_MEMO										; set standard color
+	STRCPY_TEXT_PRINT tUsbLlBld							; print "Low-level Bootloader" message
 
 	WIN_TOP  comm_warning_row							; set row    for icon
 	WIN_LEFT comm_warning_column						; set column for icon
@@ -635,26 +725,31 @@
 
 	call	eeprom_deco_data_write						; update deco data     in EEPROM
 	call	eeprom_battery_gauge_write					; update battery gauge in EEPROM
-	btfsc	options_changed								; do the options need to be stored to EEPROM ?
+	btfsc	option_changed								; do the options need to be stored to EEPROM ?
 	call	option_check_and_store_all					; YES - check and store all option values in EEPROM
 
-	goto	0x1FF0C										; jump into the bootloader code
+;	WAITS	.1											; wait 1 second to give the serial I/F time
+;														; to send the ackn before it gets shut down
+
+	goto	0x1FF0C										; jump into the bootloader code for cold start
 
 
 ;-----------------------------------------------------------------------------
-; Send Firmware to Bootloader (aka initiate firmware update)
+; Send Firmware to Bootloader (aka initiate Firmware Update)
 ;
 comm_firmware_update:
+	bcf		INTCON,GIE					; disable all interrupts
 	SERIAL_LC_SEND 0x50					; acknowledge command
+	SERIAL_RR_RECEIVE buffer,.5			; (try to) receive 5 byte checksum
+	bsf		INTCON,GIE					; re-enable all interrupts
 
-	SERIAL_RR_RECEIVE_RAM buffer,.5		; (try to) receive 5 byte checksum
 	btfsc	rs232_rx_timeout			; got all 5 bytes?
 	bra		comm_send_firmware_abort	; NO  - abort
 
 	; check the checksum
 	movlw	0x55						; initialize checksum check-byte
 	movwf	hi							; store in hi
-	lfsr	FSR2,buffer					; load base address of buffer
+	INIT_BUFFER							; go back to start of the buffer
 	movlw	.5							; 5 bytes to process
 	movwf	lo							; initialize loop counter
 comm_firmware_update_loop:
@@ -668,146 +763,161 @@
 
 	; checksum is valid
 	SERIAL_LC_SEND 0x4C					; inform checksum is ok
-	call	rs232_wait_tx				; wait for completion of transmit before hardware goes into reboot
+	WAITS	.1							; wait 1 second to give the serial I/F time
+										; to send the 0x4C before it gets shut down
+	;bra	comm_firmware_update_exec	; execute update
 
+	global	comm_firmware_update_exec
+comm_firmware_update_exec:
+	call	eeprom_memorize_fw_checksum	; memorize fw checksum in EEPROM
 	call	eeprom_deco_data_write		; update deco data     in EEPROM
 	call	eeprom_battery_gauge_write	; update battery gauge in EEPROM
-	btfsc	options_changed				; do the options need to be stored to EEPROM ?
+	btfsc	option_changed				; do the options need to be stored to EEPROM ?
 	call	option_check_and_store_all	; YES - check and store all option values in EEPROM
+	goto	0x1FDF0						; jump into the bootloader code for firmware update
 
-	goto	0x1FDF0						; jump into the bootloader code
 
 comm_send_firmware_failed:
 	; select font and output position
 	WIN_SMALL comm_string_column, comm_string_row
-	call	TFT_warning_color			; select color
+	FONT_COLOR_WARNING					; set warning color
 	STRCPY_PRINT "Checksum failed"		; print failure message (fill to 15 chars)
-	call	TFT_standard_color			; back to standard color
 	;bra	comm_send_firmware_abort	; abort
 
 comm_send_firmware_abort:
-	SERIAL_LC_SEND 0xFF					; send abort message
+	SERIAL_LC_SEND 0xFF					; send checksum failure message
+	bra		comm_command_loop			; done, back to command loop
+
+
+;-----------------------------------------------------------------------------
+; Erase a single Block or a Range of Blocks
+;
+comm_erase_single_4kb:
+	bcf		INTCON,GIE					; disable all interrupts
+	bcf		aux_flag					; do a single block only
+;	SERIAL_LC_SEND 0x40					; acknowledge command (not done)
+	bra		comm_erase_get_start		; continue with getting start address
+
+comm_erase_range_4kb:
+	bcf		INTCON,GIE					; disable all interrupts
+	bsf		aux_flag					; do a range of blocks
+	SERIAL_LC_SEND 0x42					; acknowledge command
+	;bra	comm_erase_get_start		; continue with getting start address
+
+comm_erase_get_start:
+	rcall	comm_get_start_address		; (try to) get the start address
+	btfsc	rs232_rx_timeout			; got start address?
+	bra		comm_command_timeout		; NO  - show rx timeout message and back to command loop
+	btfsc	aux_flag					; YES - shall erase a range of blocks?
+	bra		comm_erase_get_count		;       YES - get the block count
+	movlw	.1							;       NO  - set   1 block to do
+	movwf	WREG						;           - ...
+	bra		comm_erase_common			;           - start the erasing
+
+comm_erase_get_count:
+	SERIAL_CC_RECEIVE WREG				; (try to) receive the block count
+	btfsc	rs232_rx_timeout			; got block count?
+	bra		comm_command_timeout		; NO  - show rx timeout message and back to command loop
+	tstfsz	WREG						; YES - block count = 0 ?
+	bra		comm_erase_common			;       NO  - start the erasing
+	bra		comm_command_error			;       YES - invalid, show error message and back to command loop
+
+comm_erase_common:
+	bsf		INTCON,GIE					; re-enable all interrupts
+	call	ext_flash_erase_range		; erase #WREG 4kB blocks starting at ext_flash_address
 	bra		comm_command_loop			; done, back to command loop
 
 
 ;-----------------------------------------------------------------------------
-; Erase a Memory Range given byte Start Address and Number of 4 kB Blocks
+; Write a Stream of Bytes to the FLASH beginning at given Start Address, finish on Timeout
 ;
-comm_erase_range4kb:
-	SERIAL_LC_SEND 0x42					; acknowledge command
-	bcf		INTCON,GIE					; disable all interrupts
-	rcall	comm_get_start_address		; (try to) get the start address
-	btfsc	rs232_rx_timeout			; got start address?
-	bra		comm_command_timeout		; NO  - abort, back to command loop
+comm_write_range_stream:
+	bcf		INTCON,GIE						; disable all interrupts
+	SERIAL_LC_SEND 0x30						; acknowledge command
 
-	; (try to) receive the block count (1 byte)
-	SERIAL_CC_RECEIVE ext_flash_length_counter
-	btfsc	rs232_rx_timeout			; got block count?
-	bra		comm_command_timeout		; NO  - abort, back to command loop
+	rcall	comm_get_start_address			; (try to) get the start address
+	btfsc	rs232_rx_timeout				; got a complete start address?
+	bra		comm_command_timeout			; NO  - show rx timeout message and back to command loop
+
+ IFDEF _comm_debug
+	CLRI	mpr								; clear mpr to be used as a 16 bit counter
+ ENDIF
 
-	; erase blocks (number of blocks to do was received in ext_flash_length_counter:1)
-comm_erase_range4kb_loop:
-	call	ext_flash_erase_4kB			; erase a 4 kB block
-										; increase start address by 0x1000 (4kB):
-										; nothing to do with low byte
-	movlw	0x10						; add 0x10...
-	addwf	ext_flash_address+1,F		; ... to high byte
-	movlw	0x00						; add 0x00...
-	addwfc	ext_flash_address+2,F		; ... plus carry bit to upper byte
-	btfsc	ext_flash_address+2,6		; reached 0x400000 ?
-	bra		comm_command_loop			; YES - at end of address range, back to command loop
-	decfsz	ext_flash_length_counter,F	; NO  - decrement number of blocks to do, all blocks done?
-	bra		comm_erase_range4kb_loop	;       NO  - loop
-	bra		comm_command_loop			;       YES - done, back to command loop
-
-
-;-----------------------------------------------------------------------------
-; Erase one Memory Block of 4 kB Size
-;
-comm_erase_4kb:
-;	SERIAL_LC_SEND 0x40					; acknowledge command (not done)
-	bcf		INTCON,GIE					; disable all interrupts
-	rcall	comm_get_start_address		; (try to) get the start address
-	btfsc	rs232_rx_timeout			; got a complete start address?
-	bra		comm_command_timeout		; NO  - abort, back to command loop
-	call	ext_flash_erase_4kB			; YES - erase memory block
-	bra		comm_command_loop			;     - done, back to command loop
+comm_write_range_stream_loop:
+	SERIAL_CC_RECEIVE WREG					; (try to) receive one byte
+	btfsc	rs232_rx_timeout				; got a byte?
+ IFNDEF _comm_debug
+	bra		comm_command_loop				; NO  - timeout, done, back to command loop
+ ELSE
+	bra		comm_command_debug				; NO  - timeout, done, show number of bytes received
+ ENDIF
+;	bsf		NCTS							; YES - hold    Bluetooth chip (requires PC/Android/iOS side to use flow control...)
+	call	ext_flash_write_byte_0x40_nowait;     - write byte to FLASH, increase address with rollover at 0x400000, does not wait on FLASH
+;	bcf		NCTS							;     - release Bluetooth chip (requires PC/Android/iOS side to use flow control...)
+ IFDEF _comm_debug
+	INCI	mpr								; increment counter
+ ENDIF
+	bra		comm_write_range_stream_loop	;     - loop
 
 
 ;-----------------------------------------------------------------------------
-; Write a stream of bytes to the FLASH beginning at given start address, end on timeout
+; Write a Block of 256 Bytes to the FLASH beginning at given Start Address (low byte needs to be zero)
 ;
-comm_write_range_stream:
-	SERIAL_LC_SEND 0x30						; acknowledge command
-	bcf		INTCON,GIE						; disable all interrupts
-	rcall	comm_get_start_address			; (try to) get the start address
-	btfsc	rs232_rx_timeout				; got a complete start address?
-	bra		comm_command_timeout			; NO  - abort, back to command loop
+comm_write_range_block:
+	bcf		INTCON,GIE					; disable all interrupts
+	SERIAL_LC_SEND 0x31					; acknowledge command
+
+	rcall	comm_get_start_address		; (try to) get the start address
+	btfsc	rs232_rx_timeout			; got a complete start address?
+	bra		comm_command_timeout		; NO  - show rx timeout message and back to command loop
 
-	; steam bytes to FLASH
-comm_write_range_loop:
-	SERIAL_CC_RECEIVE WREG					; (try to) receive a byte
-	btfsc	rs232_rx_timeout				; got a byte?
-	bra		comm_command_loop				; NO  - end of byte stream, done, back to command loop
-;	bsf		NCTS							; YES - hold    Bluetooth chip (requires PC/Android/iOS side to use flow control...)
-	call	write_byte_ext_flash_plus_comms	;     - write data byte to FLASH and increase address with rollover at 0x400000
-;	bcf		NCTS							;     - release Bluetooth chip (requires PC/Android/iOS side to use flow control...)
-	bra		comm_write_range_loop			;     - loop
+	tstfsz	ext_flash_address+0			; low byte of start address = 0 ?
+	bra		comm_command_error			; NO  - show error message and back to command loop
+
+	SERIAL_RR_RECEIVE buffer,.256		; (try to) receive 256 byte and buffer them in memory
+	bsf		INTCON,GIE					; re-enable all interrupts
+	btfsc	rs232_rx_timeout			; got all 256 bytes?
+	bra		comm_command_timeout		; NO  - show rx timeout message and back to command loop
+
+	FLASH_RR_WRITE buffer,.256 			; copy from memory to FLASH
+	bra		comm_command_loop			; done, back to command loop
 
 
 ;-----------------------------------------------------------------------------
-; Write a block of 256 bytes to the FLASH beginning at given start address (low byte needs to be zero)
-;
-comm_write_range_block:
-	SERIAL_LC_SEND 0x31						; acknowledge command
-	bcf		INTCON,GIE						; disable all interrupts
-
-	rcall	comm_get_start_address			; (try to) get the start address
-	btfsc	rs232_rx_timeout				; got a complete start address?
-	bra		comm_command_timeout			; NO  - abort, back to command loop
-
-	tstfsz	ext_flash_address+0				; low byte of address = 0 ?
-	bra		comm_command_error				; NO  - abort, back to command loop
-
-	SERIAL_RR_RECEIVE_RAM buffer,.256		; (try to) receive 256 byte and buffer them in memory
-	btfsc	rs232_rx_timeout				; got all 256 bytes?
-	bra		comm_command_timeout			; NO  - abort, back to command loop
-
-	FLASH_RR_WRITE buffer,ext_flash_address,.256 ; copy from memory to FLASH
-	bra		comm_command_loop					 ; done, back to command loop
-
-
-;-----------------------------------------------------------------------------
-; Read a range from FLASH given by start address and length
+; Read a Memory Range from FLASH given by Start Address and Byte Count
 ;
 comm_read_range:
+	bcf		INTCON,GIE					; disable all interrupts
 	SERIAL_LC_SEND 0x20					; acknowledge command
-	bcf		INTCON,GIE					; disable all interrupts
 
 	; receive start address
 	rcall	comm_get_start_address		; (try to) get the start address
 	btfsc	rs232_rx_timeout			; got a complete start address?
-	bra		comm_command_timeout		; NO - abort, back to command loop
+	bra		comm_command_timeout		; NO - show rx timeout message and back to command loop
+
+	; receive byte count
+	rcall	comm_get_length				; (try to) get the byte count
+	btfsc	rs232_rx_timeout			; got a complete byte count?
+	bra		comm_command_timeout		; NO - show rx timeout message and back to command loop
 
-	; receive length
-	rcall	comm_get_length				; (try to) get the length
-	btfsc	rs232_rx_timeout			; got a complete length?
-	bra		comm_command_timeout		; NO - abort, back to command loop
+	bsf		INTCON,GIE					; re-enable all interrupts
+
+	; decrement byte counter by 1 so that all bytes will be done when the counter wraps around to 0xFFFFFF
+	EXT_FLASH_DEC_LENGTH
+
+	; check validity of the byte count
+	movlw	0x40						; now the byte count is allowed to be 0x3FFFFF at max
+	cpfslt	ext_flash_length_counter+2	; length count < 0x40(0000) ?
+	bra		comm_command_error			; NO  - show error message and back to command loop
 
 	; stream bytes from FLASH
-	ext_flash_dec_length .1				; decrement length count by 1 so that all bytes will be
-										; done when the counter has wrapped around to 0xFFFFFF
-
-	movlw	0x40						; now the length count is allowed to be 0x3FFFFF at max
-	cpfslt	ext_flash_length_counter+2	; length count < 0x40(0000) ?
-	bra		comm_command_error			; NO  - abort, back to command loop
-	call	ext_flash_read_block_start	; YES - read first byte from FLASH into WREG
-	bra		comm_read_range_loop_start	;     - jump into transmit loop
+	call	ext_flash_read_block_start	; read first byte from FLASH into WREG
+	bra		comm_read_range_loop_start	; jump into transmit loop
 comm_read_range_loop:
 	call	ext_flash_read_block_0x40	; read next byte into WREG
 comm_read_range_loop_start:
 	SERIAL_CC_SEND WREG					; transmit byte
-	ext_flash_dec_length .1				; decrement length counter
+	EXT_FLASH_DEC_LENGTH				; decrement byte counter
 	btfss	ext_flash_length_counter+2,7; under-run?
 	bra		comm_read_range_loop		; NO  - continue loop
 	call	ext_flash_read_block_stop	; YES - end reading from FLASH
@@ -818,32 +928,32 @@
 ; Receive a 3 byte FLASH address (on serial: big-endian, in memory: little-endian)
 ;
 comm_get_start_address:
-	SERIAL_RR_RECEIVE_RAM ext_flash_address,.3	; receive 3 bytes
-	btfsc	rs232_rx_timeout					; timeout?
-	return										; YES - abort, no usable address available
+	SERIAL_RR_RECEIVE ext_flash_address,.3	; (try to) receive 3 bytes
+	btfsc	rs232_rx_timeout				; timeout?
+	return									; YES - abort, no usable address available
 
 	; remap address from network byte format (big endian) to host format (little-endian)
 	movf	ext_flash_address+0,W
 	movff	ext_flash_address+2,ext_flash_address+0
 	movwf	ext_flash_address+2
 
-	return										; done, complete start address available
+	return									; done, complete start address available
 
 
 ;-----------------------------------------------------------------------------
 ; Receive a 3 byte length (on serial: big-endian, in memory: little-endian)
 ;
 comm_get_length:
-	SERIAL_RR_RECEIVE_RAM ext_flash_length_counter,.3 	; receive 3 bytes
-	btfsc	rs232_rx_timeout							; timeout?
-	return												; YES - abort, no usable address available
+	SERIAL_RR_RECEIVE ext_flash_length_counter,.3 	; receive 3 bytes
+	btfsc	rs232_rx_timeout						; timeout?
+	return											; YES - abort, no usable address available
 
 	; remap address from network byte format (big endian) to host format (little-endian)
 	movf	ext_flash_length_counter+0,W
 	movff	ext_flash_length_counter+2,ext_flash_length_counter+0
 	movwf	ext_flash_length_counter+2
 
-	return												; done, complete start address available
+	return											; done, complete start address available
 
 
 ;-----------------------------------------------------------------------------
@@ -853,12 +963,12 @@
 	SERIAL_LC_SEND 0x72					; acknowledge command
 	SERIAL_CC_RECEIVE lo				; (try to) receive option index
 	btfsc	rs232_rx_timeout			; received option index?
-	bra		comm_command_loop			; NO - abort, back to command loop
+	bra		comm_command_loop			; NO - show rx timeout message and back to command loop
 
 	; option index 0x00 - 0x0F: unused
 	movlw	0x0F						; last option index of the unused range
 	cpfsgt	lo							; received option index > end of unused range ?
-	bra		comm_command_error			; NO  - abort, back to command loop
+	bra		comm_command_error			; NO  - show error message and back to command loop
 
 	; option index 0x10 - 0x19: gases & diluents
 	movlw	0x19						; last option index for gases / diluents
@@ -875,26 +985,23 @@
 	iorlw	0x49						; received option index for button polarity ?
 	bz		comm_read_button_polarity	; YES - process button polarity read
 
-	; option index 0x1F - 0xFF: options managed by option-table
-	call	option_read_serial			; try to find the option and read its value
-	tstfsz	WREG						; option found?
-	bra		comm_read_setting_fail		; NO  - send dummy value
-	SERIAL_CC_SEND	hi					; YES - send read  value
-	bra		comm_command_loop			;     - done, back to command loop
+	; option index 0x1F - 0xF9: options managed by option table
+	movlw	0xF9						; last option index for options
+	cpfsgt	lo							; received option index > end of options range?
+	bra		comm_read_option_index		; YES - process option value read via index
 
-comm_read_setting_fail:
-	SERIAL_LC_SEND	0x00				; send a dummy value
-	bra		comm_command_error			; back to command loop with failure message
+	bra		comm_command_error			; NO  - illegal option index
 
 
 ;-----------------------------------------------------------------------------
 ; Write an Option Value
 ;
 comm_write_option:
+	bcf		INTCON,GIE					; disable all interrupts
 	SERIAL_LC_SEND 0x77					; acknowledge command
 	SERIAL_CC_RECEIVE lo				; (try to) receive option index
 	btfsc	rs232_rx_timeout			; got a byte?
-	bra		comm_command_timeout		; NO - abort, back to command loop
+	bra		comm_command_timeout		; NO - show rx timeout message and back to command loop
 
 	; option index 0x00 - 0x0F: unused
 	movlw	0x0F						; last option index of the unused range
@@ -916,7 +1023,33 @@
 	iorlw	0x49						; received option index for button polarity ?
 	bz		comm_write_button_polarity	; YES - process button polarity write
 
-	; option index 0x1F - 0xFF: options managed by option-table
+	; option index 0x1F - 0xF9: options managed by option table
+	movlw	0xF9						; last option index for options
+	cpfsgt	lo							; received option index > end of options range?
+	bra		comm_write_option_index		; YES - process option value write via index
+
+	bra		comm_write_unused			; NO  - illegal option index
+
+
+;-----------------------------------------------------------------------------
+; Read an Option Value via its Serial Index
+;
+comm_read_option_index:
+	call	option_read_serial			; try to find the option and read its value
+	tstfsz	WREG						; option found?
+	bra		comm_read_setting_fail		; NO  - send dummy value
+	SERIAL_CC_SEND	hi					; YES - send read  value
+	bra		comm_command_loop			;     - done, back to command loop
+
+comm_read_setting_fail:
+	SERIAL_LC_SEND	0x00				; send a dummy value
+	bra		comm_command_error			; back to command loop with failure message
+
+
+;-----------------------------------------------------------------------------
+; Write an Option Value via its Serial Index
+;
+comm_write_option_index:
 	SERIAL_CC_RECEIVE hi				; (try to) receive option value
 	btfsc	rs232_rx_timeout			; got a byte?
 	bra		comm_command_timeout		; NO  - abort
@@ -931,7 +1064,7 @@
 
 
 ;-----------------------------------------------------------------------------
-; Read button polarity
+; Read Button Polarity
 ;
 comm_read_button_polarity:
 	SERIAL_CC_SEND	button_polarity		; send current button polarity setting
@@ -939,21 +1072,21 @@
 
 
 ;-----------------------------------------------------------------------------
-; Write button polarity
+; Write Button Polarity
 ; 
 comm_write_button_polarity:
 	SERIAL_CC_RECEIVE hi				; (try to) receive configuration value
 	btfsc	rs232_rx_timeout			; got configuration value?
-	bra		comm_command_timeout		; NO  - abort, back to command loop
+	bra		comm_command_timeout		; NO  - show rx timeout message and back to command loop
 	movff	hi,button_polarity			; YES - store button polarity in memory and EEPROM
 	EEPROM_CC_WRITE button_polarity,eeprom_button_polarity
 	bra		comm_command_loop			;     - done, back to command loop
 
 
 ;-----------------------------------------------------------------------------
-; Read a gas/diluent dataset
+; Read a Gas/Diluent Dataset
 ;
-; Memory map is as follows:
+; memory map is as follows:
 ; -------------------------
 ; opt_gas_O2_ratio			res 5		; O2 ratios of OC/bailout gases
 ; opt_dil_O2_ratio			res 5		; O2 ratios of diluents
@@ -979,9 +1112,9 @@
 
 
 ; ----------------------------------------------------------------------------
-; Write a gas/diluent dataset
+; Write a Gas/Diluent Dataset
 ;
-; Memory map is as follows:
+; memory map is as follows:
 ; -------------------------
 ; opt_gas_O2_ratio			res 5		; O2 ratios of OC/bailout gases
 ; opt_dil_O2_ratio			res 5		; O2 ratios of diluents
@@ -993,62 +1126,63 @@
 ; opt_dil_change			res 5		; change depths for diluents
 ;
 comm_write_gas_dil:
-	SERIAL_RR_RECEIVE_RAM hi,.4			; (try to) receive 4 option values
+	SERIAL_RR_RECEIVE hi,.4				; (try to) receive 4 option values
 	btfsc	rs232_rx_timeout			; got all 4 bytes?
-	bra		comm_command_timeout		; NO - abort, back to command loop
+	bra		comm_command_timeout		; NO - show rx timeout message and back to command loop
 
 	; check validity of O2 value
 	movlw	gaslist_min_o2-.1			; get min value minus 1
 	cpfsgt	hi							; received O2% >= min ?
-	bra		comm_command_error			; NO - abort, back to command loop
+	bra		comm_command_error			; NO - show error message and back to command loop
 	movlw	gaslist_max_o2+.1			; get max value plus 1
 	cpfslt	hi							; received O2% <= max ?
-	bra		comm_command_error			; NO - abort, back to command loop
+	bra		comm_command_error			; NO - show error message and back to command loop
 
 	; check validity of He value
 	movlw	gaslist_max_He+.1			; get max value plus 1
 	cpfslt	up							; received O2% <= max ?
-	bra		comm_command_error			; NO - abort, back to command loop
+	bra		comm_command_error			; NO - show error message and back to command loop
 
+ IFDEF _helium
 	; check O2% + He% <= 100%
-	movlw	.100						; load 100%
+	movlw	.100						; load WREG with 100%
 	bsf		STATUS,C					; set carry = clear borrow
-	subfwb	hi,W						; subtract O2% from 100%
+	subfwb	hi,W						; subtract O2% from WREG
+	subfwb	up,W						; subtract He% from WREG
 	btfss	STATUS,C					; result negative?
-	bra		comm_command_error			; YES - abort, back to command loop
-	subfwb	up,W						; NO  - subtract He%
-	btfss	STATUS,C					;     - now negative?
-	bra		comm_command_error			;       YES - abort, back to command loop
+	bra		comm_command_error			; YES - show error message and back to command loop
+ ENDIF	; _helium
 
 	; check validity of type
 	movlw	0x14						; last option index for gases
 	cpfsgt	lo							; received option index > end of gas range ?
-	bra		comm_write_dil				; YES - check type for diluents
-	;bra	comm_write_gas				; NO  - check type for gases
+	bra		comm_write_check_dil		; YES - check type for diluents
+	;bra	comm_write_check_gas		; NO  - check type for gases
 
-comm_write_gas:
+comm_write_check_gas:
 	; check validity of type for a gas
 	movlw	num_gas_types				; load number of gas types
-	bra		comm_write_gas_dil_common	; continue with common part
+	bra		comm_write_check_com		; continue with common part
 
-comm_write_dil:
+comm_write_check_dil:
 	; check validity of type for a diluent
 	movlw	num_dil_types				; load number of diluent types
-	;bra	comm_write_gas_dil_common	; continue with common part
+	;bra	comm_write_check_com		; continue with common part
 
-comm_write_gas_dil_common:
+comm_write_check_com:
 	cpfslt	ex							; received type < max ?
-	bra		comm_command_error			; NO  - abort, back to command loop
+	bra		comm_command_error			; NO  - show error message and back to command loop
 
 	; check validity of change depth
 	movlw	gaslist_max_change_depth+.1	; get max value plus 1
 	cpfslt	ul							; received change depth <= max ?
-	bra		comm_command_error			; NO - abort, back to command loop
+	bra		comm_command_error			; NO - show error message and back to command loop
 
 	; all values ok, can finally be written
 	lfsr	FSR0,opt_gas_O2_ratio		; load base address of gas data arrays
 	movlw	0x10						; compute gas index from option index...
 	subwf	lo,W						; ...making WREG          point to O2 ratio
+
 	movff	hi,PLUSW0					; set O2 ratio
 	addlw	.10							; increment WREG by 10 to point to He ratio
 	movff	up,PLUSW0					; set He ratio
@@ -1057,13 +1191,14 @@
 	addlw	.10							; increment WREG by 10 to point to change depth
 	movff	ul,PLUSW0					; set change depth
 
+	bsf		option_changed				; flag that EEPROM needs to be updated
 	bra		comm_command_loop			; done, back to command loop
 
 
 ;-----------------------------------------------------------------------------
-; Read a setpoint dataset
+; Read a Setpoint Dataset
 ;
-; Memory map is as follows:
+; memory map is as follows:
 ; -------------------------
 ; opt_setpoint_cbar			res 5	; setpoints in cbar
 ; opt_setpoint_change		res 5	; change depth for the setpoints in meter
@@ -1079,38 +1214,45 @@
 
 
 ;-----------------------------------------------------------------------------
-; Write a setpoint dataset
+; Write a Setpoint Dataset
 ;
-; Memory map is as follows:
+; memory map is as follows:
 ; -------------------------
 ; opt_setpoint_cbar			res 5	; setpoints     in cbar
 ; opt_setpoint_change		res 5	; change depths in meter
 ;
 comm_write_sp:
-	SERIAL_RR_RECEIVE_RAM hi,.2			; (try to) receive 2 option values
+	SERIAL_RR_RECEIVE hi,.2				; (try to) receive 2 option values
 	btfsc	rs232_rx_timeout			; got both bytes?
-	bra		comm_command_timeout		; NO - abort, back to command loop
+	bra		comm_command_timeout		; NO - show rx timeout message and back to command loop
 
 	; check validity of setpoint value
 	movlw	gaslist_sp_min-.1			; get min value minus 1
 	cpfsgt	hi							; received O2% >= min ?
-	bra		comm_command_error			; NO - abort, back to command loop
+	bra		comm_command_error			; NO - show error message and back to command loop
 	movlw	gaslist_sp_max+.1			; get max value plus 1
 	cpfslt	hi							; received O2% <= max ?
-	bra		comm_command_error			; NO - abort, back to command loop
+	bra		comm_command_error			; NO - show error message and back to command loop
 
 	; check validity of change depth
-	movlw	sp_max_change_depth+.1		; get max value plus 1
+	movlw	gaslist_sp_max_depth+.1		; get max value plus 1
 	cpfslt	up							; received change depth <= max ?
-	bra		comm_command_error			; NO - abort, back to command loop
+	bra		comm_command_error			; NO - show error message and back to command loop
 
 	lfsr	FSR0,opt_setpoint_cbar		; load base address of setpoint cbar values
 	movlw	0x1A						; compute SP index from option index...
 	subwf	lo,W						; ...making WREG         point to cbar value
+
+	bnz		comm_write_sp_exec			; selected SP is 2...5 -> execute write
+	tstfsz	up							; SP1: change depth = 0 ?
+	bra		comm_command_error			; NO - show error message and back to command loop
+
+comm_write_sp_exec:
 	movff	hi,PLUSW0					; set cbar value
 	addlw	.5							; increment WREG by 5 to point to change depth
 	movff	up,PLUSW0					; set change depth
 
+	bsf		option_changed				; flag that EEPROM needs to be updated
 	bra		comm_command_loop			; done, back to command loop
 
 ;-----------------------------------------------------------------------------