Mercurial > public > hwos_code
view src/comm.asm @ 631:185ba2f91f59
3.09 beta 1 release
author | heinrichsweikamp |
---|---|
date | Fri, 28 Feb 2020 15:45:07 +0100 |
parents | cd58f7fc86db |
children | 4050675965ea |
line wrap: on
line source
;============================================================================= ; ; File comm.asm combined next generation V3.08.8 ; ; RS232 via USB ; ; Copyright (c) 2012, JD Gascuel, HeinrichsWeikamp, all right reserved. ;============================================================================= ; HISTORY ; 2011-08-22 : [mH] Creation ; 2012-02-11 : [jDG] Added 0x63 set custom text, and "i" identify #include "hwos.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" #include "shared_definitions.h" #include "math.inc" #include "i2c.inc" #include "logbook.inc" extern restart extern option_reset_all extern option_check_and_store_all extern option_read_serial extern option_write_serial extern gaslist_cleanup_list extern eeprom_deco_data_write ; timeouts #DEFINE timeout_comm_pre_mode .240 ; [sec] timeout before communication is established #DEFINE timeout_service_mode .120 ; [sec] timeout when communication is established ; positioning of title #DEFINE comm_title_row .0 #DEFINE comm_title_column_usb .40 #DEFINE comm_title_column_ble .25 ; positioning of host-sent text messages #DEFINE comm_string_row .30 #DEFINE comm_string_column .40 ; positioning of COMM mode status messages #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_status4_row .160 #DEFINE comm_status4_column comm_status1_column ; positioning of COMM mode warning icon #DEFINE comm_warning_row .160 #DEFINE comm_warning_column .65 ;#DEFINE testloop_avail ; uncomment if testloop code is available comm CODE ;============================================================================= global comm_mode_usb comm_mode_usb: ; entry point for comm mode via USB WAITMS d'1' ; wait 1 ms btfss vusb_in ; USB still plugged in? return ; NO - it was only a glitch, abort WAITMS d'1' ; YES - wait 1 ms btfss vusb_in ; - USB still plugged in? return ; NO - it was only a glitch, abort 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 bcf aux_flag ; remember to show BLE title ;bra comm_mode_common ; continue with common part comm_mode_common: clrf STKPTR ; reset addresses stack call TFT_ClearScreen ; clear screen WIN_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 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_2: call TFT_standard_color ; set standard color 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 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_4: WIN_SMALL comm_status1_column,comm_status1_row ; print status message "starting..." STRCPY_TEXT_PRINT tUsbStarting ; ... WIN_TINY .40,.240-.16 ; set output position to bottom line call TFT_show_serial_and_firmware ; show serial number and firmware version IFDEF _screendump bcf screen_dump_avail ; disable screen dump function ENDIF 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 ; ... movlw timeout_comm_pre_mode ; get timeout for phase without communication established yet movwf comm_timeout_timer ; initialize timeout counter comm_mode_selection_loop: bcf trigger_full_second ; clear 'one second elapsed' flag bcf LEDr ; switch off red LED / power down TR co-processor dcfsnz comm_timeout_timer,F ; decrement timeout, reached zero? bra comm_service_exit ; YES - timeout, exit comm mode ;bra comm_mode_selection_loop_1 ; NO - try to receive a byte comm_mode_selection_loop_1: SERIAL_CC_RECEIVE lo ; (try to) receive 1 byte btfsc rs232_rx_timeout ; timeout? bra comm_mode_selection_loop_2 ; YES - check for comm mode termination movf lo,W ; NO - copy received byte to lo xorlw 0xAA ; - service mode start byte received? 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 comm_mode_selection_loop_2: btfsc ble_available ; BLE 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 ;bra comm_mode_selection_loop_3 ; YES - check for exit button or continue looping comm_mode_selection_loop_3: btfsc switch_right ; right button pressed? bra comm_service_exit ; YES - exit comm mode btfsc trigger_full_second ; NO - did 1 second elapsed meanwhile? bra comm_mode_selection_loop ; YES - loop with clocking down timeout counter bra comm_mode_selection_loop_1 ; NO - loop without clocking down timeout counter ;----------------------------------------------------------------------------- ; Received start byte for service mode, await service key ; 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 clrf WREG ; clear WREG SERIAL_CC_RECEIVE lo ; receive 1st byte, store in lo xorwf lo,W ; exclusive-or received byte into WREG xorlw UPPER (comm_service_key) ; exclusive-or expected byte into WREG SERIAL_CC_SEND lo ; echo 1st byte SERIAL_CC_RECEIVE lo ; receive 2nd byte, store in lo xorwf lo,W ; exclusive-or received byte into WREG xorlw HIGH (comm_service_key & 0xFFFF) ; exclusive-or expected byte into WREG SERIAL_CC_SEND lo ; echo 2nd byte SERIAL_CC_RECEIVE lo ; receive 3rd byte, store in lo xorwf lo,W ; exclusive-or received byte into WREG xorlw LOW (comm_service_key & 0xFFFF) ; exclusive-or expected byte into WREG SERIAL_CC_SEND lo ; echo 3rd byte ; check for correct service key 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 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 ; 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 ; ... bcf comm_service_mode ; disable service mode commands 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 ; comm_command_loop: ; (re-)initialize bsf INTCON,GIE ; re-enable all interrupts movlw timeout_service_mode ; get timeout value movwf comm_timeout_timer ; reload timeout timer ; request peer to send a command movlw 0x4D ; default request code is 0x4D for download mode active btfsc comm_service_mode ; service mode enabled? movlw 0x4C ; YES - change request to 0x4C for service mode active SERIAL_CC_SEND WREG ; send request ; wait for peer to send a command comm_command_loop_wait: SERIAL_CC_RECEIVE lo ; (try to) receive a command byte btfss rs232_rx_timeout ; timeout? 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? 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 comm_command_loop_wait_1: btfsc switch_right ; right button (abort) pressed? bra comm_service_exit ; YES - exit comm mode btfss trigger_full_second ; NO - did 1 second elapsed meanwhile? bra comm_command_loop_wait ; NO - loop dcfsnz comm_timeout_timer,F ; YES - decrement the timeout timer, reached zero? bra comm_service_exit ; YES - exit comm mode bcf trigger_full_second ; NO - clear 'one second elapsed' flag bra comm_command_loop_wait ; - loop ;----------------------------------------------------------------------------- ; 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 endm ;----------------------------------------------------------------------------- ; Decode and execute a command ; comm_command_decode: bcf LEDr ; switch off red led ; decode and execute standard commands command_decode 0x6E,comm_show_text ; n show a text on the screen command_decode 0x69,comm_identify ; i send ID: serial, firmware, and custom text command_decode 0x6A,comm_hardware_descriptor ; j send ID: hardware descriptor byte command_decode 0x60,comm_feature_and_hardware ; ' send ID: more detailed information command_decode 0x6D,comm_send_headers_short ; m send all headers in compact format command_decode 0x61,comm_send_headers_full ; a send all headers is full format command_decode 0x66,comm_send_dive ; f send header and profile for one dive command_decode 0x62,comm_set_time ; b set the real time clock command_decode 0x63,comm_set_custom_text ; c write a new custom text command_decode 0x72,comm_read_option ; r read an option value command_decode 0x77,comm_write_option ; w write an option value (into RAM) command_decode 0x78,comm_option_reset_all ; x reset all option values to their factory default command_decode 0xFF,comm_service_exit ; exit comm mode IFDEF _screendump command_decode 0x6C,TFT_dump_screen ; l dump the screen contents ENDIF btfss comm_service_mode ; service mode enabled? bra comm_command_loop ; NO - ignore unrecognized command, back to command loop ; 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 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 command_decode 0xC1,comm_cold_start ; start low-level bootloader IFDEF testloop_avail command_decode 0x74,testloop ; t start raw-data test loop ENDIF bra comm_command_loop ; ignore unrecognized command, back to command loop ;----------------------------------------------------------------------------- ; Exit comm mode ; comm_service_exit: WIN_SMALL comm_status3_column, comm_status3_row ; print "Exited" message STRCPY_TEXT_PRINT tUsbExit ; ... bra comm_service_exit_common ; acknowledge exit command and restart comm_service_exit_nousb_delay: WAITMS d'200' ; wait 200 ms btfsc vusb_in ; USB sensed again? bra comm_mode_selection_loop_3 ; YES - was just a glitch, continue ;bra comm_service_exit_nousb ; NO - proceed exiting comm_service_exit_nousb: WIN_SMALL comm_status3_column, comm_status3_row ; print "Port closed" message 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 call disable_rs232 ; shut down comm port bcf LEDr ; switch off red LED goto restart ; restart ;----------------------------------------------------------------------------- ; Set Real-Time-Clock ; comm_set_time: SERIAL_LC_SEND 0x62 ; acknowledge command ; 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 ; 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 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 ; comm_show_text: ; set font and output position of the text to show WIN_SMALL comm_string_column, comm_string_row SERIAL_LC_SEND 0x6E ; acknowledge command 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 bra comm_command_loop ; done, back to command loop ;----------------------------------------------------------------------------- ; Reply 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_RAM opt_name,opt_name_length bra comm_command_loop ; done, back to command loop ;----------------------------------------------------------------------------- ; Reply hardware descriptor byte ; comm_hardware_descriptor: SERIAL_LC_SEND 0x6A ; acknowledge command 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 ;----------------------------------------------------------------------------- ; Reply 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 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 ; 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 ;----------------------------------------------------------------------------- comm_send_headers_full: SERIAL_LC_SEND 0x61 ; acknowledge command ; send complete headers (256 bytes/dive) ; index 0: 0x200000 - 0x2000FF ; 1: 0x201000 - 0x2010FF ; 2: 0x202000 - 0x2020FF ; ... ; 255: 0x2FF000 - 0x2FF0FF 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 ;----------------------------------------------------------------------------- ; 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) btfsc rs232_rx_timeout ; got dive index? bra comm_command_timeout ; NO - abort, 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 ; get pointers and length of 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 ; 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 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 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 bra comm_command_loop ; start = end -> no profile data available, abort, back to command loop comm_send_dive1: ; send the header from the buffer SERIAL_RR_SEND_RAM header_buffer,.256 ; 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 ;----------------------------------------------------------------------------- ; Reset all Options to Factory Default ; comm_option_reset_all: SERIAL_LC_SEND 0x78 ; acknowledge command call option_reset_all ; reset all options to factory default bra comm_command_loop ; done, back to command loop ;----------------------------------------------------------------------------- ; Set Custom Text String (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 ; receive new custom text (less than opt_name_length characters may be sent) SERIAL_RR_RECEIVE_RAM opt_name,opt_name_length bra comm_command_loop ; done, back to command loop ;----------------------------------------------------------------------------- ; Reset Battery Gauge ; comm_reset_battery_gauge: ; SERIAL_LC_SEND 0x23 ; acknowledge command (not done) call reset_battery_gauge_and_lt2942 ; reset battery registers and battery gauge chip bra comm_command_loop ; done, back to command loop ;----------------------------------------------------------------------------- ; 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 ;----------------------------------------------------------------------------- ; Start Bootloader (aka perform cold start) ; 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_TOP comm_warning_row ; set row for icon WIN_LEFT comm_warning_column ; set column for icon TFT_WRITE_PROM_IMAGE_BY_LABEL dive_warning2_block ; show a warning icon bsf LEDr ; switch on red LED 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 ? call option_check_and_store_all ; YES - check and store all option values in EEPROM goto 0x1FF0C ; jump into the bootloader code ;----------------------------------------------------------------------------- ; Send Firmware to Bootloader (aka initiate firmware update) ; comm_firmware_update: SERIAL_LC_SEND 0x50 ; acknowledge command 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 movlw .5 ; 5 bytes to process movwf lo ; initialize loop counter comm_firmware_update_loop: movf POSTINC2,W ; get a checksum byte xorwf hi,F ; xor checksum byte with check-byte rlncf hi,F ; rotate check-byte decfsz lo,F ; decrement loop counter, done? bra comm_firmware_update_loop ; NO - loop tstfsz hi ; YES - check-byte zero? bra comm_send_firmware_failed ; NO - checksum not valid ; 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 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 ? call option_check_and_store_all ; YES - check and store all option values in EEPROM 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 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 bra comm_command_loop ; done, back to command loop ;----------------------------------------------------------------------------- ; Erase a Memory Range given byte Start Address and Number of 4 kB Blocks ; 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 ; (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 ; 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 ;----------------------------------------------------------------------------- ; Write a stream of bytes to the FLASH beginning at given start address, end on timeout ; 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 ; 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 ;----------------------------------------------------------------------------- ; 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 ; comm_read_range: 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 ; 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 ; 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 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 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 bra comm_command_loop ; - done, back to command loop ;----------------------------------------------------------------------------- ; 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 ; 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 ;----------------------------------------------------------------------------- ; 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 ; 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 ;----------------------------------------------------------------------------- ; Read an Option Value ; comm_read_option: 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 ; 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 ; option index 0x10 - 0x19: gases & diluents movlw 0x19 ; last option index for gases / diluents cpfsgt lo ; received option index > end of gas/dil range ? bra comm_read_gas_dil ; NO - process gas/dil read ; option index 0x1A - 0x1E: setpoints movlw 0x1E ; last option index for setpoint cpfsgt lo ; received option index > end of setpoint range ? bra comm_read_sp ; NO - process setpoint read ; option index = 0x49 - special handling button polarity movf lo,W ; copy option index to WREG 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 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 ; comm_write_option: 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 ; 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_write_unused ; NO - but need to consume the option value ; option index 0x10 - 0x19: gases & diluents movlw 0x19 ; last option index for gases / diluents cpfsgt lo ; received option index > end of gas/dil range ? bra comm_write_gas_dil ; NO - process gas/dil write ; option index 0x1A - 0x1E: setpoints movlw 0x1E ; last option index for setpoint cpfsgt lo ; received option index > end of setpoint range ? bra comm_write_sp ; NO - process setpoint write ; option index = 0x49 - special handling button polarity movf lo,W ; copy option index to WREG 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 SERIAL_CC_RECEIVE hi ; (try to) receive option value btfsc rs232_rx_timeout ; got a byte? bra comm_command_timeout ; NO - abort call option_write_serial ; YES - try to find the option and write new value tstfsz WREG ; - option found and new value valid ? bra comm_command_error ; NO - back to command loop with failure message bra comm_command_loop ; YES - done, back to command loop comm_write_unused: SERIAL_CC_RECEIVE WREG ; consume unused option value bra comm_command_error ; done, back to command loop ;----------------------------------------------------------------------------- ; Read button polarity ; comm_read_button_polarity: SERIAL_CC_SEND button_polarity ; send current button polarity setting bra comm_command_loop ; done, back to command loop ;----------------------------------------------------------------------------- ; 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 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 ; ; 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 ; opt_gas_He_ratio res 5 ; He ratios of OC/bailout gases ; opt_dil_He_ratio res 5 ; He ratios of diluents ; opt_gas_type res 5 ; OC/bailout gas type ; opt_dil_type res 5 ; dil type ; opt_gas_change res 5 ; change depths for OC/Bailout gases ; opt_dil_change res 5 ; change depths for diluents ; comm_read_gas_dil: 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 SERIAL_CC_SEND PLUSW0 ; send O2 ratio addlw .10 ; increment WREG by 10 to point to He ratio SERIAL_CC_SEND PLUSW0 ; send He ratio addlw .10 ; increment WREG by 10 to point to gas/diluent type SERIAL_CC_SEND PLUSW0 ; send gas/diluent type addlw .10 ; increment WREG by 10 to point to change depth SERIAL_CC_SEND PLUSW0 ; send change depth bra comm_command_loop ; done, back to command loop ; ---------------------------------------------------------------------------- ; Write a gas/diluent dataset ; ; 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 ; opt_gas_He_ratio res 5 ; He ratios of OC/bailout gases ; opt_dil_He_ratio res 5 ; He ratios of diluents ; opt_gas_type res 5 ; OC/bailout gas type ; opt_dil_type res 5 ; dil type ; opt_gas_change res 5 ; change depths for OC/Bailout gases ; 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 btfsc rs232_rx_timeout ; got all 4 bytes? bra comm_command_timeout ; NO - abort, 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 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 ; 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 ; check O2% + He% <= 100% movlw .100 ; load 100% bsf STATUS,C ; set carry = clear borrow subfwb hi,W ; subtract O2% from 100% 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 ; 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 comm_write_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 comm_write_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 comm_write_gas_dil_common: cpfslt ex ; received type < max ? bra comm_command_error ; NO - abort, 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 ; 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 addlw .10 ; increment WREG by 10 to point to gas/dil type movff ex,PLUSW0 ; set gas/dil type addlw .10 ; increment WREG by 10 to point to change depth movff ul,PLUSW0 ; set change depth bra comm_command_loop ; done, back to command loop ;----------------------------------------------------------------------------- ; Read a setpoint dataset ; ; 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 ; comm_read_sp: 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 SERIAL_CC_SEND PLUSW0 ; send setpoint cbar value addlw .5 ; increment WREG by 5 to point to change depth SERIAL_CC_SEND PLUSW0 ; send change depth bra comm_command_loop ; done, back to command loop ;----------------------------------------------------------------------------- ; Write a setpoint dataset ; ; 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 btfsc rs232_rx_timeout ; got both bytes? bra comm_command_timeout ; NO - abort, 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 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 ; check validity of change depth movlw sp_max_change_depth+.1 ; get max value plus 1 cpfslt up ; received change depth <= max ? bra comm_command_error ; NO - abort, 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 movff hi,PLUSW0 ; set cbar value addlw .5 ; increment WREG by 5 to point to change depth movff up,PLUSW0 ; set change depth bra comm_command_loop ; done, back to command loop ;----------------------------------------------------------------------------- END