view src/comm.asm @ 40:1e2d2b0bca5b

Bugfix: Simulator in CC mode
author mh@mh-THINK.fritz.box
date Thu, 15 Aug 2013 14:34:50 +0200
parents 1ab317814dd7
children ec4d8503ec45
line wrap: on
line source

;=============================================================================
;
;   File comm.asm
;
;   RS232 via USB
;
;   Copyright (c) 2012, JD Gascuel, HeinrichsWeikamp, all right reserved.
;=============================================================================
; HISTORY
;  2011-08-22 : [mH] Creation
;  2012-02-11 : [jDG] Added "c" set custom text, and "i" identify.

#include "ostc3.inc"
#include "eeprom_rs232.inc"
#include "tft.inc"
#include "wait.inc"
#include "strings.inc"
#include "convert.inc"
#include "external_flash.inc"
#include "tft_outputs.inc"
#include "surfmode.inc"
#include "rtc.inc"
#include "adc_lightsensor.inc"

	extern  testloop,do_main_menu,new_battery_menu,restart,option_reset_all

#DEFINE timeout_comm_pre_mode   .120        ; Pre-loop
#DEFINE timeout_comm_mode       .120        ; Download mode
#DEFINE timeout_service_mode    .120        ; Service mode

#DEFINE	comm_title_row		.0
#DEFINE	comm_title_column	.50

#DEFINE	comm_string_row	.30
#DEFINE	comm_string_column	.40


#DEFINE	comm_status1_row		.70
#DEFINE	comm_status1_column	.10
#DEFINE	comm_status2_row		.100
#DEFINE	comm_status2_column	comm_status1_column
#DEFINE	comm_status3_row		.130
#DEFINE	comm_status3_column	comm_status1_column

#DEFINE	comm_warning_row		.160
#DEFINE	comm_warning_column     .65

comm code

	; test for comm
	global	comm_mode
comm_mode:
    call    TFT_ClearScreen
    WIN_COLOR   color_greenish
	WIN_SMALL	comm_title_column, comm_title_row
	STRCPY_TEXT_PRINT	tUsbTitle		; comm Mode
    call	TFT_standard_color
    WIN_TOP     .10
    WIN_LEFT    .1
    movlw   0xDE
    movwf   TBLPTRL
    movlw   0xEE
    movwf   TBLPTRH
    movlw   0x01
    movwf   TBLPTRU
    call    color_image                 ; Show usb logo
	WIN_SMALL	comm_status1_column, comm_status1_row
	STRCPY_TEXT_PRINT	tUsbStarting	; Starting...
    call	TFT_serial                  ; Show serial and firmware version
    bcf     enable_screen_dumps         ; =1: Ignore vin_usb, wait for "l" command (Screen dump)
	bcf		switch_right
    bcf     comm_service_enabled
    bsf     menubit
    bcf     battery_removed_in_usb      ; =1: The battery has been removed in USB
    movlw   timeout_comm_pre_mode
	movwf	timeout_counter
	WIN_SMALL	comm_status1_column+.80, comm_status1_row
	STRCPY_TEXT_PRINT	tUsbStartDone	; Done...
	call	enable_rs232				; Also sets to speed_normal ...
comm_mode1:
	bcf		onesecupdate
	bcf		LEDr
	dcfsnz 	timeout_counter,F
	bra		comm_service_exit           ; Timeout -> Exit
comm_mode2:
	call	get_battery_voltage			; gets battery voltage
    movlw   .3
    cpfslt  batt_voltage+1              ; Batt Voltage less then 3*256mV?
    bra     comm_mode3                  ; No
    ; Set flag
    bsf     battery_removed_in_usb      ; =1: The battery has been removed in USB
    bra     comm_mode4

comm_mode3:
    ; Voltage ok. Do we have a new battery now?
    btfsc   battery_removed_in_usb      ; =1: The battery has been removed in USB
    goto	new_battery_menu            ; show "New battery dialog"

comm_mode4:
	call	rs232_get_byte

    btfss   vusb_in                     ; USB plugged in?
    bra     comm_service_exit_nousb     ; Disconnected -> Exit

	btfsc	switch_right				; Abort with right
	bra		comm_service_exit

	btfsc	onesecupdate
	bra		comm_mode1

	movlw	0xAA						; start byte=0xAA?
	cpfseq	RCREG1
	bra		comm_mode2a
	bra		comm_mode2b             ; Startbyte for service mode found
comm_mode2a:
	movlw	0xBB						; start byte=0xBB?
	cpfseq	RCREG1
	bra		comm_mode2				; Cycle
	bra		comm_download_mode		; Startbyte for download mode found

comm_mode2b:
	; Startbyte found
	call	rs232_wait_tx			; Wait for UART
	movlw	0x4B
	movwf	TXREG1					; Send Answer
	; Now, check comm command

	call	rs232_get_byte				; first byte
	call	rs232_wait_tx               ; Wait for UART
    movff   RCREG1,TXREG1                 ; Echo
	movlw	UPPER comm_service_key
	cpfseq	RCREG1
    bra     comm_mode1               ; Wrong -> Restart
	call	rs232_get_byte				; second byte
	call	rs232_wait_tx			; Wait for UART
    movff   RCREG1,TXREG1                 ; Echo
	movlw	HIGH (comm_service_key & 0xFFFF)
	cpfseq	RCREG1
    bra     comm_mode1               ; Wrong -> Restart
	call	rs232_get_byte				; third byte
	call	rs232_wait_tx			; Wait for UART
    movff   RCREG1,TXREG1                 ; Echo
	movlw	LOW comm_service_key
	cpfseq	RCREG1
    bra     comm_mode1               ; Wrong -> Restart

	; Enable comm service mode
	WIN_SMALL	comm_status2_column, comm_status2_row
	STRCPY_TEXT_PRINT	tUsbServiceMode	; Service mode enabled
    bsf     comm_service_enabled
	bra		comm_download_mode0		; Startbyte for download mode found

comm_service_exit_nousb:                ; Disconnected -> Exit
	WIN_SMALL	comm_status3_column, comm_status3_row
	STRCPY_TEXT_PRINT	tUsbClosed      ; Port closed
    bra     comm_service_exit_common

comm_service_exit:
	WIN_SMALL	comm_status3_column, comm_status3_row
	STRCPY_TEXT_PRINT	tUsbExit        ; Exited

comm_service_exit_common:
	call	rs232_wait_tx				; Wait for UART
	movlw	0xFF                        ; Reply FF
	movwf	TXREG1						; Send Answer

	; Wait 1 second
	bcf		onesecupdate
	btfss	onesecupdate
	bra		$-2
	; Wait 1 second
	bcf		onesecupdate
	btfss	onesecupdate
	bra		$-2

	call	disable_rs232
	bcf		LEDr
    goto    restart

;-----------------------------------------------------------------------------

comm_service_ll_bootloader:
    bsf     LEDr
	WIN_SMALL	comm_status3_column, comm_status3_row
	STRCPY_TEXT_PRINT	tUsbLlBld               ; Low Level Bootloader started
    WIN_TOP  	comm_warning_row
	WIN_LEFT 	comm_warning_column
    TFT_WRITE_PROM_IMAGE dive_warning_block 	; Show Warning icon
    goto    0x1FF0C

;-----------------------------------------------------------------------------
; Sends external flash from 0x3E0000 to 0x3FD000 (118784bytes) via comm
;
comm_send_firmware:
    movlw   0x50                            ; send echo
    movwf   TXREG1
    call    rs232_wait_tx                   ; Wait for UART

    ; Read 5 bytes into buffer.
	lfsr	FSR2,buffer
	movlw	.5								; counter
	movwf	lo
	movlw   0x55                            ; 5'ft byte checksum.
	movwf   hi

comm_send_firmware_loop:
	call	rs232_get_byte
	btfsc	rs232_recieve_overflow			; Got byte?
	bra		comm_send_firmware_abort   ; No, abort!
	movf	RCREG1,W
	movwf   POSTINC2                        ; Store checksum byte.
	xorwf   hi,F                            ; Also xor into checksum
	rlncf   hi,F                            ; And rotate it.
	decfsz	lo,F
	bra		comm_send_firmware_loop
	
	; Check that 5ft byte checksum's checksum
	movf    hi,W
	bnz     comm_send_firmware_failed

    movlw   0x4C                            ; send OK
    movwf   TXREG1
    call    rs232_wait_tx                   ; Wait for UART

	; Passed: goto second stage verification.
	; NOTE: Bootloader is Bank0. With buffer at address 0x200.
	goto    0x1FDF0                         ; And pray...

comm_send_firmware_failed:
	WIN_SMALL	comm_string_column, comm_string_row
	TFT_WARNINGS_COLOR
	STRCPY_PRINT    "Checksum failed"

comm_send_firmware_abort:

    movlw   0xFF                            ; send ABORTED byte.
	movwf	TXREG1
	call	rs232_wait_tx                   ; Wait for UART
	bra		comm_download_mode0				; Done.

;-----------------------------------------------------------------------------
; Reset to Dive 1 in logbook

comm_reset_logbook_pointers:
	clrf    EEADRH                      ; Make sure to select eeprom bank 0
	clrf	EEDATA
	write_int_eeprom	.4
	write_int_eeprom	.5
	write_int_eeprom	.6
	write_int_eeprom	.2				; Also, delete total dive counter
	write_int_eeprom	.3				
	call	ext_flash_erase_logbook		; And complete logbook (!)
	bra		comm_download_mode0			; Done.

;-----------------------------------------------------------------------------
comm_reset_battery_gauge:           ; Resets battery gauge registers
    call    reset_battery_pointer   ; Resets battery pointer 0x07-0x0C and battery_gauge:5
    bra		comm_download_mode0		; Done.

;-----------------------------------------------------------------------------
; erases range in 4kB steps

comm_erase_range4kb:
    movlw   0x42                        ; send echo
    movwf   TXREG1
    call    rs232_wait_tx               ; Wait for UART

    bcf     INTCON,GIE	; All interrups off!

    rcall   comm_get_flash_address		; Get three bytes address or return
    btfsc   rs232_recieve_overflow      ; Got Data?
    bra     comm_download_mode0         ; No, Done.

    call    rs232_get_byte
    btfsc   rs232_recieve_overflow      ; Got byte?
    bra     comm_download_mode0         ; No, Done.
    movff   RCREG1,lo
; Got 4bytes: 3bytes address and 1 bytes (lo) amount of 4kB blocks

comm_erase_range4kb1:
    call    ext_flash_erase4kB          ; Erase block!

    movlw   0x10
    addwf   ext_flash_address+1,F
    movlw   .0
    addwfc  ext_flash_address+2,F       ; Increase address by .4096, or 0x1000
    decfsz  lo,F
    bra     comm_erase_range4kb1        ; Loop until lo=zero

    bra     comm_download_mode0         ; Done (Sends the 4C OK too).

;-----------------------------------------------------------------------------

comm_erase_4kb:				; Get 3 bytes start address
	bcf		INTCON,GIE	; All interrups off!	

	rcall	comm_get_flash_address		; Get three bytes address or return
	btfsc	rs232_recieve_overflow      ; Got Data?
	bra		comm_download_mode0         ; No, Done.

	call	ext_flash_erase4kB          ; Erase one block
	bra		comm_download_mode0 		; Done.

;-----------------------------------------------------------------------------

comm_write_range:				; Get 3 bytes start address
    movlw   0x30                        ; send echo
	movwf	TXREG1
	call	rs232_wait_tx               ; Wait for UART

	bcf		INTCON,GIE                  ; All interrups off!

	rcall	comm_get_flash_address		; Get three bytes address or return
	btfsc	rs232_recieve_overflow      ; Got Data?
	bra		comm_download_mode0  		; No, Done.

comm_write_range_loop:
	call	rs232_get_byte
	btfsc	rs232_recieve_overflow      ; Got byte?
	bra		comm_download_mode0         ; No, Done (and send OK byte too).
	movf	RCREG1,W
	call	ext_flash_byte_write        ; write one byte
	call	incf_ext_flash_address_p1   ; increase address+1
	bra		comm_write_range_loop

;-----------------------------------------------------------------------------

comm_send_range:				; Get 3 bytes start address and 3 bytes amount
    movlw   0x20                        ; send echo
    movwf   TXREG1
	call	rs232_wait_tx               ; Wait for UART

	bcf		INTCON,GIE	; All interrups off!	

	rcall	comm_get_flash_address		; Get three bytes address or return
	btfsc	rs232_recieve_overflow			; Got Data?
	bra		comm_download_mode0				; No, Done.

	call	rs232_get_byte
	btfsc	rs232_recieve_overflow			; Got byte?
	bra		comm_download_mode0				; No, Done.
	movff	RCREG1,up
	call	rs232_get_byte
	btfsc	rs232_recieve_overflow			; Got byte?
	bra		comm_download_mode0				; No, Done.
	movff	RCREG1,hi
	call	rs232_get_byte
	btfsc	rs232_recieve_overflow			; Got byte?
	bra		comm_download_mode0				; No, Done.
	movff	RCREG1,lo

    ; If lo==0, we must precondition hi because there is to many bytes send !
    movf    lo,W    
    bnz     $+4
    decf    hi,F

; 6bytes received, send data
comm_send_range2:						; needs ext_flash_address:3 start address and up:hi:lo amount
	call	ext_flash_read_block_start
	movwf	TXREG1

	bra		comm_send_range24		; counter 24bit
comm_send_range24_loop:
	call	ext_flash_read_block		; Read one byte
	movwf	TXREG1						; Start new transmit
comm_send_range24:
	call	rs232_wait_tx				; Wait for UART
	decfsz	lo,F
	bra		comm_send_range24_loop
	decf	hi,F
	movlw	0xFF
	cpfseq	hi
	bra		comm_send_range24_loop
	decf	up,F
	movlw	0xFF
	cpfseq	up
	bra		comm_send_range24_loop
	call	ext_flash_read_block_stop

	bra		comm_download_mode0			; Done.

;-----------------------------------------------------------------------------

comm_get_flash_address:
	call	rs232_get_byte
	btfsc	rs232_recieve_overflow			; Got byte?
	return									; No, return
	movff	RCREG1,ext_flash_address+2
	call	rs232_get_byte
	btfsc	rs232_recieve_overflow			; Got byte?
	return									; No, return
	movff	RCREG1,ext_flash_address+1
	call	rs232_get_byte
	btfsc	rs232_recieve_overflow			; Got byte?
	return									; No, return
	movff	RCREG1,ext_flash_address+0
	return

;-----------------------------------------------------------------------------

comm_download_mode:
	; Enable comm download mode
	WIN_SMALL	comm_status2_column, comm_status2_row
	STRCPY_TEXT_PRINT	tUsbDownloadMode; Download mode enabled
	bsf		INTCON,GIE					; All interrups on
	call	rs232_wait_tx				; Wait for UART
	movlw	0xBB                        ; Command Echo
	movwf	TXREG1						; Send Answer
comm_download_mode0:
    bsf		INTCON,GIE					; All interrups on
	call	rs232_wait_tx				; Wait for UART
    movlw   0x4C                        ; 4C in service mode
    btfss   comm_service_enabled
	movlw	0x4D                        ; 4D in download mode
	movwf	TXREG1						; Send Answer
	movlw	timeout_service_mode
	movwf	timeout_counter 			; Timeout
	bcf		switch_right
comm_download_mode1:
	bcf		onesecupdate
	dcfsnz 	timeout_counter,F
	bra		comm_service_exit           ; Timeout -> Exit
comm_download_mode2:
	call	rs232_get_byte              ; Check for a byte
    btfsc   comm_service_enabled
	btg     LEDr                        ; Blink in Service mode
    btfss   vusb_in                     ; USB plugged in?
    bra     comm_service_exit_nousb     ; Disconnected -> Exit
	btfsc	switch_right				; Abort with right
	bra		comm_service_exit
	btfsc	onesecupdate
	bra		comm_download_mode1
	btfsc	rs232_recieve_overflow
	bra		comm_download_mode2	; Wait for command byte

	; command received!
	bcf		LEDr
	movlw	0xFF
	cpfseq	RCREG1
	bra		$+4
	bra		comm_service_exit			; exit
	movlw	"a"
	cpfseq	RCREG1
	bra		$+4
	bra		comm_send_headers			; Send all 256 dive headers
	movlw	"b"
	cpfseq	RCREG1
	bra		$+4
	bra		comm_set_time				; Read time and date from the PC and set clock
	movlw	"c"
	cpfseq	RCREG1
	bra		$+4
	bra		comm_set_custom_text		; Send a opt_name_length byte string of custom text.
	movlw	"f"
	cpfseq	RCREG1
	bra		$+4
	bra		comm_send_dive				; Send header and profile for one dive
	movlw	"i"
	cpfseq	RCREG1
	bra		$+4
	bra		comm_identify               ; Send firmware, serial, etc.
	movlw	"n"
	cpfseq	RCREG1
	bra		$+4
	bra		comm_send_string			; Send a 15byte string to the screen
	movlw	"l"
	cpfseq	RCREG1
	bra		$+4
    call	TFT_dump_screen             ; Dump the screen contents

    btfss   comm_service_enabled        ; Done for Download mode
	bra		comm_download_mode0         ; Loop with timeout reset

	movlw	0x20
	cpfseq	RCREG1
	bra		$+4
	bra		comm_send_range             ; send hi:lo:temp1 bytes starting from ext_flash_address:3
	movlw	0x22
	cpfseq	RCREG1
	bra		$+4
	bra		comm_reset_logbook_pointers	; Resets all logbook pointers and the logbook (!)
	movlw	0x23
	cpfseq	RCREG1
	bra		$+4
	bra		comm_reset_battery_gauge    ; Resets battery gauge registers
	movlw	0x30
	cpfseq	RCREG1
	bra		$+4
	bra		comm_write_range            ; write bytes starting from ext_flash_address:3 (Stop when timeout)
	movlw	0x40
	cpfseq	RCREG1
	bra		$+4
	bra		comm_erase_4kb              ; erases 4kB block from ext_flash_address:3 (Warning: No confirmation or built-in security here...)
	movlw	0x42
	cpfseq	RCREG1
	bra		$+4
	bra		comm_erase_range4kb         ; erases range in 4kB steps (Get 3 bytes address and 1byte amount of 4kB blocks)
	movlw	0x50
	cpfseq	RCREG1
	bra		$+4
	bra		comm_send_firmware          ; sends firmware from external flash from 0x3E0000 to 0x3FD000 (118784bytes) via comm
	movlw	"t"
	cpfseq	RCREG1
	bra		$+4
    goto    testloop                    ; Start raw-data testloop
	movlw	"r"
	cpfseq	RCREG1
	bra		$+4
    call	option_reset_all        	; Reset all options to factory default.
	movlw	0xC1
	cpfseq	RCREG1
	bra		$+4
	bra 	comm_service_ll_bootloader  ; Start low-level bootloader
    bra		comm_download_mode0         ; Loop with timeout reset

;-----------------------------------------------------------------------------

comm_send_headers:
	movlw	"a"								; send echo
	movwf	TXREG1
	; Send 256 bytes/dive (Header)
	; 1st: 200000h-2000FFh
	; 2nd: 201000h-2010FFh
	; 3rd: 202000h-2020FFh
	; 100: 264000h-2640FFh
	; 256: 2FF000h-2FF0FFh
	movlw	0x1F
	movwf	ext_flash_address+2
	movlw	0xF0
	movwf	ext_flash_address+1

comm_send_headers2:
	movlw	0x00
	movwf	ext_flash_address+0
	; Adjust address for next dive
	movlw	0x10
	addwf	ext_flash_address+1
	movlw	0x00
	addwfc	ext_flash_address+2

	movlw	0x30
	cpfseq	ext_flash_address+2				; All 256 dive send?
	bra		comm_send_headers4			; No, continue
	bra		comm_download_mode0		; Done. Loop with timeout reset

comm_send_headers4:
	clrf	lo							; Counter	
	call	rs232_wait_tx				; Wait for UART
	call	ext_flash_read_block_start	; 1st byte
	movwf	TXREG1
	bra		comm_send_headers3		; counter 24bit
comm_send_headers_loop:
	call	ext_flash_read_block		; Read one byte
	movwf	TXREG1						; Start new transmit
comm_send_headers3:
	call	rs232_wait_tx				; Wait for UART
	decfsz	lo,F
	bra		comm_send_headers_loop
	call	ext_flash_read_block_stop
	bra		comm_send_headers2		; continue

;-----------------------------------------------------------------------------
;

comm_set_time:
	movlw	"b"								; send echo
	movwf	TXREG1

	call	rs232_wait_tx					; wait for UART
	call	rs232_get_byte
	btfsc	rs232_recieve_overflow			; Got byte?
	return                          		; No, abort!
	movff	RCREG1, hours
	movlw	d'24'
	cpfslt	hours
	clrf	hours
	call	rs232_get_byte
	btfsc	rs232_recieve_overflow			; Got byte?
	return                          		; No, abort!
	movff	RCREG1, mins
	movlw	d'60'
	cpfslt	mins
	clrf	mins
	call	rs232_get_byte
	btfsc	rs232_recieve_overflow			; Got byte?
	return                          		; No, abort!
	movff	RCREG1, secs
	movlw	d'60'
	cpfslt	secs
	clrf	secs
	call	rs232_get_byte
	btfsc	rs232_recieve_overflow			; Got byte?
	return                          		; No, abort!
	movff	RCREG1, month
	movlw	d'13'
	cpfslt	month
	movwf	month
	call	rs232_get_byte
	btfsc	rs232_recieve_overflow			; Got byte?
	return                          		; No, abort!
	rcall	comm_check_day                  ; Check day
	call	rs232_get_byte
	btfsc	rs232_recieve_overflow			; Got byte?
	return                          		; No, abort!
	movff	RCREG1, year
	movlw	d'100'
	cpfslt	year
	clrf	year
	; All ok, set RTCC
	call	rtc_set_rtc                     ; writes mins,sec,hours,day,month and year to rtc module
    bra		comm_download_mode0             ; Done. back to loop with timeout reset

;-----------------------------------------------------------------------------
; Set OSTC3 custom text string (opt_name_length ascii chars).
;

comm_set_custom_text:
    movlw	"c"								; send echo
    movwf	TXREG1
    call	rs232_wait_tx					; wait for UART
    lfsr	FSR2,opt_name
    movlw	opt_name_length
    movwf	lo								; counter
comm_set_ctext_loop:
    call	rs232_get_byte
    btfsc	rs232_recieve_overflow          ; Got byte?
    bra		comm_download_mode0             ; No, loop with timeout reset
    movff	RCREG1,POSTINC2                 ; Store character
    decfsz	lo,F
    bra		comm_set_ctext_loop
    bra		comm_download_mode0             ; Done. Loop with timeout reset

;-----------------------------------------------------------------------------
; Reply Serial (2 bytes low:high), firmware (major.minor) and custom text.
;
  
comm_identify:
    movlw	"i"								; send echo
    movwf	TXREG1
    call	rs232_wait_tx					; wait for UART

    ;---- Read serial from internal EEPROM address 0000
	clrf	EEADRH
	clrf	EEADR                       ; Get Serial number LOW
	call	read_eeprom                 ; read byte
	movff	EEDATA,lo
	incf	EEADR,F                     ; Get Serial number HIGH
	call	read_eeprom                 ; read byte
	movff	EEDATA,hi

    ;---- Emit serial number
	movff   lo,TXREG1
	call	rs232_wait_tx
	movff   hi,TXREG1
	call	rs232_wait_tx

	;---- Emit fiwmware hi.lo
	movlw   softwareversion_x
	movwf   TXREG1
	call	rs232_wait_tx
	movlw   softwareversion_y
	movwf   TXREG1
	call	rs232_wait_tx

	;---- Emit custom text
	movlw   opt_name_length
	movwf   hi
	lfsr    FSR2,opt_name

common_identify_loop:
    movff   POSTINC2,TXREG1
	call	rs232_wait_tx
	decfsz	hi,F
	bra		common_identify_loop

    bra     comm_download_mode0             ; Done.


;-----------------------------------------------------------------------------

comm_send_dive:
	movlw	"f"								; send echo
	movwf	TXREG1
	
	call	rs232_get_byte
	btfsc	rs232_recieve_overflow			; Got byte?
	bra		comm_download_mode0		; No, abort!
	movff	RCREG1,lo						; Store dive number (0-255)
; First, send the header (again)
	; Set ext_flash_address:3 to TOC entry of this dive
	; 1st: 200000h-200FFFh -> lo=0
	; 2nd: 201000h-201FFFh -> lo=1
	; 3rd: 202000h-202FFFh -> lo=2
	; 256: 2FF000h-2FFFFFh -> lo=255
	clrf	ext_flash_address+0
	clrf	ext_flash_address+1
	movlw	0x20
	movwf	ext_flash_address+2
	movlw	.16
	mulwf	lo				; lo*16 = offset to 0x2000 (up:hi)
	movf	PRODL,W
	addwf	ext_flash_address+1,F
	movf	PRODH,W
	addwfc	ext_flash_address+2,F

	incf_ext_flash_address	d'2'				; Skip 0xFA, 0xFA
	call		ext_flash_byte_read_plus		; Read start address of profile
	movff		temp1,ext_flash_log_pointer+0
	call		ext_flash_byte_read_plus		; Read start address of profile
	movff		temp1,ext_flash_log_pointer+1
	call		ext_flash_byte_read_plus		; Read start address of profile
	movff		temp1,ext_flash_log_pointer+2
	call		ext_flash_byte_read_plus		; Read end address of profile
	movff		temp1,convert_value_temp+0
	call		ext_flash_byte_read_plus		; Read end address of profile
	movff		temp1,convert_value_temp+1
	call		ext_flash_byte_read_plus		; Read end address of profile
	movff		temp1,convert_value_temp+2
	decf_ext_flash_address	d'8'				; Back again to first 0xFA in header

    movf        ext_flash_log_pointer+0,W
    cpfseq      convert_value_temp+0            ; Equal?
    bra         comm_send_dive1                 ; No, Send header

    movf        ext_flash_log_pointer+1,W
    cpfseq      convert_value_temp+1            ; Equal?
    bra         comm_send_dive1                 ; No, Send header

    movf        ext_flash_log_pointer+2,W
    cpfseq      convert_value_temp+2            ; Equal?
    bra         comm_send_dive1                 ; No, Send header

    ; Start=End -> Not good, abort
    bra		comm_download_mode0                 ; Done. Loop with timeout reset

comm_send_dive1:
	; Send header
	clrf	hi							; Counter	
	call	rs232_wait_tx				; Wait for UART
	call	ext_flash_read_block_start	; 1st byte
	movwf	TXREG1
	bra		comm_send_dive_header
comm_send_dive_header2:
	call	ext_flash_read_block		; Read one byte
	movwf	TXREG1						; Start new transmit
comm_send_dive_header:
	call	rs232_wait_tx				; Wait for UART
	decfsz	hi,F
	bra		comm_send_dive_header2
	call	ext_flash_read_block_stop

	; Set address for profile
	movff	ext_flash_log_pointer+0,ext_flash_address+0
	movff	ext_flash_log_pointer+1,ext_flash_address+1
	movff	ext_flash_log_pointer+2,ext_flash_address+2

	movlw	.6								; Skip 6byte short header in profile - only for internal use
	call	incf_ext_flash_address0_0x20	; increases bytes in ext_flash_address:3 with 0x200000 bank switching

comm_send_dive_profile:
	call	ext_flash_byte_read_plus_0x20	; Read one byte into temp1, takes care of banking at 0x200000
	call	rs232_wait_tx					; Wait for UART
	movff	temp1,TXREG1						; Send a byte
	
	; 24bit compare with end address
	movff	convert_value_temp+0,WREG
	cpfseq	ext_flash_address+0
	bra		comm_send_dive_profile
	movff	convert_value_temp+1,WREG
	cpfseq	ext_flash_address+1
	bra		comm_send_dive_profile
	movff	convert_value_temp+2,WREG
	cpfseq	ext_flash_address+2
	bra		comm_send_dive_profile
	
	call	rs232_wait_tx					; Wait for UART
	bra		comm_download_mode0		; Done. Loop with timeout reset

;-----------------------------------------------------------------------------

comm_send_string:
	movlw	"n"								; send echo
	movwf	TXREG1
	call	rs232_wait_tx					; Wait for UART
	WIN_SMALL	comm_string_column, comm_string_row
	lfsr	FSR2,buffer
	movlw	.16
	movwf	lo								; counter
comm_send_string_loop:
	call	rs232_get_byte
	btfsc	rs232_recieve_overflow			; Got byte?
	bra		comm_send_string_abort          ; No, abort!
	movff	RCREG1,POSTINC2					; Store character
	decfsz	lo,F
	bra		comm_send_string_loop
comm_send_string_abort:
	STRCAT_PRINT ""							; Show the text
    bra		comm_download_mode0             ; Done. Loop with timeout reset

;-----------------------------------------------------------------------------

comm_check_day:
	movff	RCREG1, day
	movff	month,lo		; new month
	dcfsnz	lo,F
	movlw	.31
	dcfsnz	lo,F
	movlw	.28
	dcfsnz	lo,F
	movlw	.31
	dcfsnz	lo,F
	movlw	.30
	dcfsnz	lo,F
	movlw	.31
	dcfsnz	lo,F
	movlw	.30
	dcfsnz	lo,F
	movlw	.31
	dcfsnz	lo,F
	movlw	.31
	dcfsnz	lo,F
	movlw	.30
	dcfsnz	lo,F
	movlw	.31
	dcfsnz	lo,F
	movlw	.30
	dcfsnz	lo,F
	movlw	.31
	cpfsgt	day						; day ok?
	return							; OK
	movlw	.1						; not OK, set to 1st
	movwf	day
	return	

;----------------------------------------------------------------------------
        END