Mercurial > public > hwos_code
view src/eeprom_rs232.asm @ 655:c7b7b8a358cd default tip
hwOS tech 3.22 release
author | heinrichsweikamp |
---|---|
date | Mon, 29 Apr 2024 13:05:18 +0200 |
parents | 75e90cd0c2c3 |
children |
line wrap: on
line source
;============================================================================= ; ; File eeprom_rs232.asm * combined next generation V3.09.4n ; ; Internal EEPROM, RS232 ; ; Copyright (c) 2011, JD Gascuel, heinrichs weikamp gmbh, all right reserved. ;============================================================================= ; HISTORY ; 2011-08-06 : [mH] moving from OSTC code #include "hwos.inc" #include "wait.inc" #include "shared_definitions.h" #include "rtc.inc" #include "external_flash.inc" #DEFINE INSIDE_EEPROM_RS232 #include "eeprom_rs232.inc" extern lt2942_charge_done ;============================================================================= eeprom CODE ;============================================================================= ;----------------------------------------------------------------------------- ; ; EEPROM Functions - for EEPROM Macros and Memory Map, see eeprom_rs232.inc ; ;----------------------------------------------------------------------------- ;----------------------------------------------------------------------------- ; Read from internal EEPROM ; ; Input: EEADRH:EEADR = EEPROM address ; Output: EEDATA ; Trashed: NONE ; global read_eeprom read_eeprom: bcf EECON1,EEPGD ; access data EEPROM bcf EECON1,CFGS ; ... bsf EECON1,RD ; initiate reading return ; done ;----------------------------------------------------------------------------- ; Write into internal EEPROM ; ; Input: EEADRH:EEADR = EEPROM address ; EEDATA = byte to write ; Trashed: WREG ; global write_eeprom write_eeprom: bcf EECON1,EEPGD ; access data EEPROM bcf EECON1,CFGS ; ... bsf EECON1,WREN ; enable writing bcf INTCON,GIE ; disable interrupts movlw 0x55 ; unlock sequence movwf EECON2 ; ... movlw 0xAA ; ... movwf EECON2 ; ... bsf EECON1,WR ; start write operation write_eeprom_loop: btfsc EECON1,WR ; write completed? bra write_eeprom_loop ; NO - loop waiting btfsc EECON1,WRERR ; All ok? rcall write_eeprom_error ; NO, something failed. bcf EECON1,WREN ; YES - disable writing bsf INTCON,GIE ; - re-enable interrupts return ; - done write_eeprom_error: bsf eeprom_write_error_flag ; Set error flag ; Try again (once) movlw 0x55 ; unlock sequence movwf EECON2 ; ... movlw 0xAA ; ... movwf EECON2 ; ... bsf EECON1,WR ; start write operation write_eeprom_loop2: btfsc EECON1,WR ; write completed? bra write_eeprom_loop2 ; NO - loop waiting return ;----------------------------------------------------------------------------- ; EEPROM read and write Functions to be used via Macros ; global eeprom_read_common eeprom_read_common: movwf eeprom_loop ; initialize loop counter eeprom_read_common_loop: rcall read_eeprom ; execute read movff EEDATA,POSTINC1 ; copy byte from EEPROM data register to memory incf EEADR,F ; advance to next EEPROM cell decfsz eeprom_loop,F ; decrement loop counter, all done? bra eeprom_read_common_loop ; NO - loop return ; YES - done global eeprom_write_common eeprom_write_common: movwf eeprom_loop ; initialize loop counter eeprom_write_common_loop: movff POSTINC1,EEDATA ; copy byte from memory to EEPROM data register rcall write_eeprom ; execute write incf EEADR,F ; advance to next EEPROM cell decfsz eeprom_loop,F ; decrement loop counter, all done? bra eeprom_write_common_loop ; NO - loop return ; YES - done ;----------------------------------------------------------------------------- ; Read OSTC Serial Number ; global eeprom_serial_number_read eeprom_serial_number_read: EEPROM_II_READ eeprom_ostc_serial,mpr ; read serial number return ; done ;----------------------------------------------------------------------------- ; Read and Write Dive Number Offset ; global eeprom_log_offset_read eeprom_log_offset_read: EEPROM_II_READ eeprom_log_offset,mpr ; read log offset return ; done global eeprom_log_offset_write eeprom_log_offset_write: EEPROM_II_WRITE mpr,eeprom_log_offset ; write log-offset return ; done ;----------------------------------------------------------------------------- ; Read and Write total Number of Dives ; global eeprom_total_dives_read eeprom_total_dives_read: EEPROM_II_READ eeprom_num_dives,mpr ; read total dives return ; done global eeprom_total_dives_write eeprom_total_dives_write: EEPROM_II_WRITE mpr,eeprom_num_dives ; write total dives return ; done ;----------------------------------------------------------------------------- ; Read and Write the Battery Type and Gauge Reading ; global eeprom_battery_gauge_read eeprom_battery_gauge_read: ; retrieve battery gauge from EEPROM 0x07-0x0C bsf block_battery_gauge ; suspend ISR from accessing the battery gauge EEPROM_CC_READ eeprom_battery_type, battery_type ; 1 byte read from EEPROM EEPROM_RR_READ eeprom_battery_gauge,battery_gauge,.6 ; 6 byte read from EEPROM EEPROM_RR_READ eeprom_charge_cycles,charge_cycles,.2 ; 2 byte read from EEPROM bcf block_battery_gauge ; allow ISR to access the battery gauge again return ; done global eeprom_battery_gauge_write eeprom_battery_gauge_write: bsf block_battery_gauge ; suspend ISR from accessing the battery gauge EEPROM_CC_WRITE battery_type, eeprom_battery_type ; 1 byte write to EEPROM update_battery_gauge: EEPROM_RR_WRITE battery_gauge,eeprom_battery_gauge,.6 ; 6 byte write to EEPROM EEPROM_RR_WRITE charge_cycles,eeprom_charge_cycles,.2 ; 2 byte write to EEPROM bcf block_battery_gauge ; allow ISR to access the battery gauge again return ; done ;----------------------------------------------------------------------------- ; Memorize the Checksum of the Firmware in the update Storage ; global eeprom_memorize_fw_checksum eeprom_memorize_fw_checksum: EXT_FLASH_ADDR 0x3E000D ; address firmware ID at 0x3E000D FLASH_CW_READ_0x40 ; read firmware ID to WREG movff WREG,buffer+.5 ; append firmware ID to checksum EEPROM_RR_WRITE buffer,eeprom_fw_chksum_current,.6 ; do a 6 byte write to EEPROM return ; done ;----------------------------------------------------------------------------- ; Read and Write the Deco Status ; global eeprom_deco_data_read eeprom_deco_data_read: btfsc RCON,POR ; was there a power outage? bra eeprom_deco_data_read_1 ; NO - RTC is up-to-date EEPROM_RR_READ eeprom_deco_data_timestamp,rtc_latched_year,.6 ; 6 byte read from EEPROM call rtc_set_rtc ; recover RTC to last known time & date eeprom_deco_data_read_1: ; restore surface interval EEPROM_II_READ eeprom_deco_data_surfinterval,mpr ; 2 byte read from EEPROM SMOVII mpr,surface_interval_mins ; ISR-safe copy of surface interval ; bank 3: restore desaturation status EEPROM_RR_READ eeprom_deco_data_bank3,0x300,.9 ; 9 byte read from EEPROM ; bank 5: restore CNS EEPROM_RR_READ eeprom_deco_data_bank5,0x500,.4 ; 4 byte read from EEPROM ; bank 7: restore tissue pressures EEPROM_RR_READ eeprom_deco_data_bank7,0x700,.128 ; 128 byte read from EEPROM return ; done global eeprom_deco_data_write eeprom_deco_data_write: ; invalidate current data in vault movlw DECO_DATA_INVALID_TOKEN ; deco data invalid token EEPROM_CC_WRITE WREG,eeprom_deco_data_validity ; 1 byte write to EEPROM ; store vault version movlw eeprom_vault_version ; deco data format version EEPROM_CC_WRITE WREG,eeprom_deco_data_version ; 1 byte write to EEPROM ; store date/time SMOVSS rtc_year,rtc_latched_year ; ISR-safe 6 byte copy of date and time EEPROM_RR_WRITE rtc_latched_year,eeprom_deco_data_timestamp,.6 ; 6 byte write to EEPROM ; store surface interval SMOVII surface_interval_mins,mpr ; ISR-safe copy of surface interval EEPROM_II_WRITE mpr,eeprom_deco_data_surfinterval ; 2 byte write to EEPROM ; bank 3: store desaturation status EEPROM_RR_WRITE 0x300,eeprom_deco_data_bank3,.9 ; 9 byte write to EEPROM ; bank 5: store CNS EEPROM_RR_WRITE 0x500,eeprom_deco_data_bank5,.4 ; 4 byte write to EEPROM ; bank 7: store tissue pressures EEPROM_RR_WRITE 0x700,eeprom_deco_data_bank7,.128 ; 128 byte write to EEPROM ; indicate new valid data in vault movlw DECO_DATA_VALID_TOKEN ; deco data valid token EEPROM_CC_WRITE WREG,eeprom_deco_data_validity ; 1 byte write to EEPROM return ; done ;============================================================================= rs232 CODE ;============================================================================= ;----------------------------------------------------------------------------- ; ; RS232 Functions ; ;----------------------------------------------------------------------------- ;----------------------------------------------------------------------------- ; Switch-On the IR/S8 Port ; global enable_ir_s8_analog enable_ir_s8_analog: ;initialize serial port2 (TRISG2) btfsc ext_input_s8_ana ; do we have an S8/analog input? bra enable_s8_analog ; YES - enable S8/analog input ;bra enable_ir ; NO - enable IR digital input enable_ir: banksel BAUDCON2 ; select bank for IO register access movlw b'00100000' ; speed generator configuration: BRG16=0, inverted for IR movwf BAUDCON2 ; ... movlw b'00100000' ; TX configuration: BRGH=0, SYNC=0 movwf TXSTA2 ; ... movlw .102 ; speed configuration: SPBRGH:SPBRG = .102 : 2403 BAUD @ 16 MHz movwf SPBRG2 ; ... clrf SPBRGH2 ; ... movlw b'10010000' ; RX configuration movwf RCSTA2 ; ... banksel common ; back to bank common bsf ir_power ; power-up IR btfss ir_power ; power-up confirmed? bra $-6 ; NO - loop and wait bsf PIE3,RC2IE ; enable RC2 INT return ; done enable_s8_analog: banksel TXSTA2 ; select bank for IO register access clrf TXSTA2 ; reset UART 2 TX function clrf RCSTA2 ; reset UART 2 RX function banksel common ; back to bank common bsf mcp_power ; power-up instrumentation amp (used by S8 and analog input) btfss mcp_power ; power-up completed? bra $-4 ; NO - loop ; branch according to S8 / analog selection TSTOSS opt_s8_mode ; =0: analog, =1: digital RS232 bra enable_analog ; -> analog ; configure S8 digital interface bcf s8_npower ; power S8 HUD (inverted via P-MOS transistor) WAITMS d'30' ; NO - wait 30 ms banksel BAUDCON2 ; select bank for IO register access movlw b'00000000' ; speed generator configuration: BRG16=0, normal for S8 movwf BAUDCON2 ; ... movlw b'00100000' ; TX configuration: BRGH=0, SYNC=0 movwf TXSTA2 ; ... movlw .25 ; speed configuration: SPBRGH:SPBRG = .25 : 9615 BAUD @ 16 MHz movwf SPBRG2 ; ... movlw b'10010000' ; RX configuration movwf RCSTA2 ; ... banksel common ; back to bank common bsf PIE3,RC2IE ; enable RC2 INT return enable_analog: ; S8 analog interface bcf PIE3,RC2IE ; disable RC2 INT bsf s8_npower ; power-down S8 digital interface return ; done ;----------------------------------------------------------------------------- ; Shut-Down the IR/S8 Port ; global disable_ir_s8_analog disable_ir_s8_analog: banksel TXSTA2 ; select bank for IO register access clrf TXSTA2 ; shut down TX function clrf RCSTA2 ; shut down RX function banksel common ; back to bank common bcf PIE3,RC2IE ; disable RC2 INT bcf ir_power ; power down IR receiver bcf mcp_power ; power-down instrumentation amp bsf s8_npower ; power-down S8 digital interface return ; done ;----------------------------------------------------------------------------- ; Send Byte in WREG via the IR/S8 Port ; global ir_s8_tx_single ir_s8_tx_single: banksel TXSTA2 ; UART 2 is outside of the access RAM movwf TXREG2 ; transmit byte ir_s8_tx_single_loop: btfss TXSTA2,TRMT ; TX completed? bra ir_s8_tx_single_loop ; NO - wait... banksel common ; YES - back to bank common return ; - done ;----------------------------------------------------------------------------- ; Switch-On USB/BT Port ; global enable_rs232 enable_rs232: call request_speed_normal ; request CPU speed change to normal speed enable_rs232_1: btfss speed_is_normal ; speed = normal? bra enable_rs232_1 ; NO - loop waiting for ISR to have adjusted the speed bsf TRISC,7 bcf ble_npower ; YES - switch port to comm bsf PORTJ,2 ; - /Reset (required for very old OSTC sport) movlw b'00100100' ; - TX configuration: TX enabled, async, high speed movwf TXSTA1 ; - ... movlw b'10010000' ; - RX configuration: port enabled, RX enabled movwf RCSTA1 ; - ... IFNDEF _comm_debug movlw HIGH(.65536-rx_timeout*.32) ; - define TMR5H initialization value for RX timeout (rx_timeout defined in hwos.inc) ELSE include "math.inc" movff opt_comm_timeout,xA+0 ; - get timeout setting in multiples of 10 ms (opt_comm_timeout: 10 .. 200 x 10 ms) clrf xA+1 ; - ... MOVLI .320,xB ; - multiply with 10 to get timeout in ms and 32 because tmr5 ticks 32x per ms call mult16x16 ; - xC = xA * xB = timer ticks to go until timeout MOVII xC,sub_b ; - multiplication result is max. 64000 MOVLI .65535,sub_a ; - timer wraps around after 65535 call subU16 ; - sub_c = sub_a - sub_b = start value for timer movlw .244 ; safety maximum value for rx_timeout_tmr5h_load (minimum timeout interval) cpfslt sub_c+1 ; result > safety value? movwf sub_c+1 ; YES - revert to safety value movf sub_c+1,W ; - keep only the upper byte as TMR5H initialization value for RX timeout ENDIF movwf rx_timeout_tmr5h_load ; - store for later use return ; - done ;----------------------------------------------------------------------------- ; Shut-Down USB/BT Port ; global disable_rs232 disable_rs232: clrf RCSTA1 ; disable RX clrf TXSTA1 ; disable TX bcf PORTC,6 ; switch TX pin hard to GND bsf ble_npower ; power down BT chip bcf PORTJ,2 ; /Reset (required for very old OSTC sport) bcf TRISC,7 bcf PORTC,7 ; switch RX pin hard to GND return ;----------------------------------------------------------------------------- ; Wait for last Byte to be sent out of USB/BT Port ; global rs232_wait_tx ; ++++ do not touch WREG here! ++++ rs232_wait_tx: btfss TXSTA1,TRMT ; last byte completely shifted out on TX pin? bra rs232_wait_tx ; NO - wait... btfss ble_available ; YES - OSTC running with Bluetooth? return ; NO - done btfsc NRTS ; YES - Bluetooth module also completed TX? bra rs232_wait_tx ; NO - wait... return ; YES - done ;----------------------------------------------------------------------------- ; Receive one Byte via the USB/BT Port ; ; ++++ make this code as fast as possible! ++++ ; ++++ do not touch WREG here! ++++ ; global serial_rx_single serial_rx_single: bcf rs232_rx_timeout ; clear timeout flag btfsc PIR1,RCIF ; received a data byte? (bit is set on RX completion and reset on reading RCREG1) return ; YES - done (fast path) movff rx_timeout_tmr5h_load,TMR5H ; NO - load TMR5 high with timeout value clrf TMR5L ; - load TMR5 low with a zero, writing low starts the timer bcf PIR5,TMR5IF ; - clear timer overflow flag serial_rx_single_loop: btfsc PIR1,RCIF ; received a data byte? return ; YES - done btfss PIR5,TMR5IF ; NO - timer overflow (timeout)? bra serial_rx_single_loop ; NO - continue waiting ;bra serial_rx_timeout ; YES - timeout ;----------------------------------------------------------------------------- ; Helper Function: Timeout in serial_rx_single / serial_tx_steam ; serial_rx_timeout: bsf rs232_rx_timeout ; set timeout flag bcf RCSTA1,CREN ; clear receiver status: disable RX, bsf RCSTA1,CREN ; ... enable again RX return ; done ;----------------------------------------------------------------------------- ; Send and Receive Functions to be used via Macros ;----------------------------------------------------------------------------- ;----------------------------------------------------------------------------- ; Send a Range of 1-256 Bytes from Memory via the USB/BT Port ; global serial_tx_steam serial_tx_steam: movwf eeprom_loop ; initialize loop counter (eeprom variable used here) serial_tx_ram_loop: rcall rs232_wait_tx ; wait for completion of last transmit movff POSTINC2,TXREG1 ; send a byte from memory to serial decfsz eeprom_loop,F ; decrement loop counter, became zero? bra serial_tx_ram_loop ; NO - loop return ; YES - done ;----------------------------------------------------------------------------- ; Receive a Range of 1-256 Byte via the USB/BT Port and write them to Memory ; ++++ make this code as fast as possible! ++++ ; global serial_rx_stream serial_rx_stream: movwf eeprom_loop ; initialize loop counter (eeprom variable used here) serial_rx_stream_loop: btfss PIR1,RCIF ; received a data byte? (bit is set on RX complete and reset on reading RCREG1) bra serial_rx_stream_tmr ; NO - enter receive loop with timeout ;bra serial_rx_stream_received ; YES - copy to memory, tick counter, ... serial_rx_stream_received: movff RCREG1,POSTINC2 ; copy received byte to memory decfsz eeprom_loop,F ; decrement loop counter, became zero? bra serial_rx_stream_loop ; NO - await next byte bcf rs232_rx_timeout ; YES - clear timeout flag return ; - all bytes received, done serial_rx_stream_tmr: movff rx_timeout_tmr5h_load,TMR5H ; load TMR5 high with timeout value clrf TMR5L ; load TMR5 low with a zero, writing to low starts the timer bcf PIR5,TMR5IF ; clear timer overflow flag serial_rx_stream_tmr_loop: btfsc PIR1,RCIF ; received a data byte? (bit is set on RX complete and reset on reading RCREG1) bra serial_rx_stream_received ; YES - copy to memory, tick counter, ... btfss PIR5,TMR5IF ; NO - timer overflow (timeout)? bra serial_rx_stream_tmr_loop ; NO - continue waiting bra serial_rx_timeout ; YES - timeout ;----------------------------------------------------------------------------- ;----------------------------------------------------------------------------- ; Add new services and characteristics to new BLE (type 2) module ;----------------------------------------------------------------------------- global ble2_configure ble2_configure: rcall enable_rs232 bcf NCTS ; Clear to send call wait_1s call wait_1s call wait_1s call wait_1s bcf PORTB,6 nop bsf PORTB,6 ; rising edge -> Command mode ; point to config table movlw LOW ble_AT1 movwf TBLPTRL movlw HIGH ble_AT1 movwf TBLPTRH movlw UPPER ble_AT1 movwf TBLPTRU rcall ble_init_loop rcall disable_rs232 bcf PORTB,6 ; keep low for min. current consumption return ; done. ble_init_loop: TBLRD*+ movlw 0xFF ; end cpfseq TABLAT bra ble_init_loop1 ; not end ; quit (return) return ; done. ble_init_loop1: movlw 0xFE ; WAIT 20ms cpfseq TABLAT bra ble_init_loop2 ; not wait 20ms WAITMS d'20' bra ble_init_loop ble_init_loop2: movlw 0xFD ; WAIT 1s cpfseq TABLAT bra ble_init_loop3 ; not wait 1s call wait_1s bra ble_init_loop ble_init_loop3: movf TABLAT,W SERIAL_CC_SEND WREG bra ble_init_loop ble_AT1: ; config table ; 0xFF at the end ; 0xFE: 20ms delay ; 0xFD: 1s delay ; .13: cr character db 0xFD,0xFD,0xFD,0xFD ; Wait 4 seconds db "AT+UDSC=0,0",.13,0xFE,0xFE ; Disable SPP Server on ID0 (and wait 40ms) db "AT+UDSC=0,3",.13,0xFE,0xFE ; SPP Server on ID0 (and wait 40ms) db "AT+UDSC=1,0",.13,0xFE,0xFE ; Disable SPS Server on ID1 (and wait 40ms) db "AT+UDSC=1,6",.13,0xFE,0xFE ; SPS Server on ID1 (and wait 40ms) db "AT&W",.13,0xFE ; write settings into eeprom (and wait 20ms) db "AT+CPWROFF",.13,0xFD,0xFD,0xFF ; save and reboot (and wait 2 seconds) END