line source
;=============================================================================+ −
;+ −
; File isr.asm REFACTORED VERSION V2.92+ −
;+ −
; INTERUPT subroutines+ −
;+ −
; Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved.+ −
;=============================================================================+ −
; HISTORY+ −
; 2011-05-24 : [jDG] Cleanups from initial Matthias code.+ −
+ −
#include "hwos.inc"+ −
#include "shared_definitions.h" ; Mailbox from/to p2_deco.c+ −
#include "ms5541.inc"+ −
#include "adc_lightsensor.inc"+ −
#include "eeprom_rs232.inc"+ −
+ −
;=============================================================================+ −
+ −
extern start+ −
+ −
isr_high CODE 0x0008 ; High Priority Interrups+ −
bra HighInt+ −
nop + −
nop+ −
nop+ −
nop+ −
nop+ −
nop+ −
bra HighInt+ −
+ −
isr_low CODE 0x00018 ; Low Priority Interrups+ −
; *** low priority interrupts not used+ −
retfie FAST ; Restores BSR, STATUS and WREG+ −
+ −
HighInt:+ −
movff PRODL,isr_prod+0+ −
movff PRODH,isr_prod+1+ −
+ −
; Buttons+ −
btfsc PIR1,TMR1IF ; Timer1 INT (Button hold-down Timer)+ −
rcall timer1int+ −
btfsc INTCON,INT0IF ; Buttons+ −
rcall isr_switch_right+ −
btfsc INTCON3,INT1IF ; Buttons+ −
rcall isr_switch_left+ −
+ −
; IR/S8-Linktimer1int+ −
btfsc PIR3,RC2IF ; UART2+ −
rcall isr_uart2 ; IR/S8-Link+ −
btfsc PIR2,TMR3IF ; Timer 3+ −
rcall isr_timer3 ; IR-Link Timeout+ −
+ −
; Pressure sensor and others+ −
btfsc PIR5,TMR7IF ; Timer 7+ −
rcall isr_tmr7 ; Every 62,5ms+ −
+ −
; RTCC+ −
btfsc PIR3,RTCCIF ; Real-time-clock interrupt+ −
rcall isr_rtcc ; May return in bank common!+ −
+ −
movff isr_prod+1,PRODH+ −
movff isr_prod+0,PRODL+ −
retfie FAST ; Restores BSR, STATUS and WREG+ −
+ −
isr_set_speed_to_normal:+ −
; Set Speed to normal+ −
movlw b'01110010'+ −
movwf OSCCON ; 16MHz INTOSC+ −
movlw b'00000000' + −
movwf OSCTUNE ; 4x PLL Disable (Bit6) - only works with 8 or 16MHz (=32 or 64MHz)+ −
movlw b'00001101' ; 1:2 Postscaler, 1:4 Prescaler, Timer 2 start -> 1960Hz (no-flicker)+ −
movwf T2CON+ −
btfss OSCCON,HFIOFS+ −
bra $-2 ; Wait until clock is stable+ −
return+ −
+ −
isr_dimm_tft: ; Adjust until max_CCPR1L=CCPR1L !+ −
banksel common+ −
btfsc tft_is_dimming ; Ignore while dimming+ −
return+ −
banksel isr_backup+ −
movf max_CCPR1L,W+ −
cpfsgt CCPR1L ; CCPR1L>max_CCPR1L?+ −
bra isr_dimm_tft2 ; No, dimm up+ −
; dimm down+ −
decf CCPR1L,F ; -1+ −
return+ −
isr_dimm_tft2:+ −
movf max_CCPR1L,W+ −
sublw ambient_light_min_eco+ −
cpfsgt CCPR1L ; CCPR1L>max_CCPR1L-ambient_light_min_eco?+ −
bra isr_dimm_tft3 ; No, dimm up slow+ −
; dimm up faster+ −
movlw .10+ −
addwf CCPR1L,F+ −
isr_dimm_tft3:+ −
incf CCPR1L,F ; +1+ −
return+ −
nop+ −
nop ; block flash here+ −
+ −
isr_restore CODE 0x00080 ; Restore first flash page from EEPROM+ −
restore_flash_0x00080:+ −
goto restore_flash+ −
+ −
isr_routines; CODE+ −
;=============================================================================+ −
+ −
isr_uart2: ; IR/S8-Link+ −
banksel RCREG2+ −
movf RCREG2,W+ −
bcf RCSTA2,CREN ; Clear receiver status+ −
bsf RCSTA2,CREN+ −
banksel isr_backup+ −
incf ir_s8_counter,F ; Increase counter+ −
movff ir_s8_counter,isr1_temp ; Copy+ −
dcfsnz isr1_temp,F+ −
movwf ir_s8_buffer+.0+ −
dcfsnz isr1_temp,F+ −
movwf ir_s8_buffer+.1+ −
dcfsnz isr1_temp,F+ −
movwf ir_s8_buffer+.2+ −
dcfsnz isr1_temp,F+ −
movwf ir_s8_buffer+.3+ −
dcfsnz isr1_temp,F+ −
movwf ir_s8_buffer+.4+ −
dcfsnz isr1_temp,F+ −
movwf ir_s8_buffer+.5+ −
dcfsnz isr1_temp,F+ −
movwf ir_s8_buffer+.6+ −
dcfsnz isr1_temp,F+ −
movwf ir_s8_buffer+.7+ −
dcfsnz isr1_temp,F+ −
movwf ir_s8_buffer+.8+ −
dcfsnz isr1_temp,F+ −
movwf ir_s8_buffer+.9+ −
dcfsnz isr1_temp,F+ −
movwf ir_s8_buffer+.10+ −
dcfsnz isr1_temp,F+ −
movwf ir_s8_buffer+.11+ −
dcfsnz isr1_temp,F+ −
movwf ir_s8_buffer+.12+ −
dcfsnz isr1_temp,F+ −
movwf ir_s8_buffer+.13+ −
dcfsnz isr1_temp,F+ −
movwf ir_s8_buffer+.14+ −
dcfsnz isr1_temp,F+ −
movwf ir_s8_buffer+.15+ −
dcfsnz isr1_temp,F+ −
movwf ir_s8_buffer+.16+ −
dcfsnz isr1_temp,F+ −
movwf ir_s8_buffer+.17+ −
+ −
clrf TMR3L ; Preload timer+ −
movlw .253+ −
movwf TMR3H+ −
bsf T3CON,TMR3ON ; (Re)Start Timeout counter+ −
return+ −
+ −
isr_timer3: ; IR/S8-Link Timeout+ −
bcf T3CON,TMR3ON ; Stop Timer3+ −
banksel isr_backup ; Select Bank0 for ISR data.+ −
movlw .15+ −
cpfseq ir_s8_counter ; Got exact 15bytes?+ −
bra isr_timer3_1 ; No, test for 16bytes+ −
bra isr_timer3_ir ; Got 15 bytes, compute local checksum+ −
isr_timer3_1:+ −
movlw .16+ −
cpfseq ir_s8_counter ; Got exact 16bytes?+ −
bra isr_timer3_2 ; No, test for 17bytes+ −
tstfsz ir_s8_buffer+.15 ; Last byte=0x00+ −
bra isr_timer3_exit ; No, exit+ −
bra isr_timer3_ir ; Got 16 bytes, compute local checksum+ −
isr_timer3_2:+ −
movlw .17+ −
cpfseq ir_s8_counter ; Got exact 17bytes?+ −
bra isr_timer3_exit ; No, exit+ −
bra isr_timer3_s8 ; S8 data+ −
+ −
isr_timer3_ir: ; IR input+ −
movff ir_s8_buffer+.0,PRODL+ −
clrf PRODH+ −
movf ir_s8_buffer+.1,W+ −
rcall isr_timer3_checksum+ −
movf ir_s8_buffer+.2,W+ −
rcall isr_timer3_checksum+ −
movf ir_s8_buffer+.3,W+ −
rcall isr_timer3_checksum+ −
movf ir_s8_buffer+.4,W+ −
rcall isr_timer3_checksum+ −
movf ir_s8_buffer+.5,W+ −
rcall isr_timer3_checksum+ −
movf ir_s8_buffer+.6,W+ −
rcall isr_timer3_checksum+ −
movf ir_s8_buffer+.7,W+ −
rcall isr_timer3_checksum+ −
movf ir_s8_buffer+.8,W+ −
rcall isr_timer3_checksum+ −
movf ir_s8_buffer+.9,W+ −
rcall isr_timer3_checksum+ −
movf ir_s8_buffer+.10,W+ −
rcall isr_timer3_checksum+ −
movf ir_s8_buffer+.11,W+ −
rcall isr_timer3_checksum+ −
movf ir_s8_buffer+.12,W+ −
rcall isr_timer3_checksum+ −
+ −
; Compare checksum+ −
movf ir_s8_buffer+.13,W+ −
cpfseq PRODL ; Checksum ok?+ −
bra isr_timer3_exit ; No, exit+ −
movf ir_s8_buffer+.14,W+ −
cpfseq PRODH ; Checksum ok?+ −
bra isr_timer3_exit ; No, exit+ −
+ −
; Checksum OK, copy results+ −
movff ir_s8_buffer+.1,hud_status_byte+ −
movff ir_s8_buffer+.2,o2_mv_sensor1+0+ −
movff ir_s8_buffer+.3,o2_mv_sensor1+1+ −
movff ir_s8_buffer+.4,o2_mv_sensor2+0+ −
movff ir_s8_buffer+.5,o2_mv_sensor2+1+ −
movff ir_s8_buffer+.6,o2_mv_sensor3+0+ −
movff ir_s8_buffer+.7,o2_mv_sensor3+1+ −
movff ir_s8_buffer+.8,o2_ppo2_sensor1+ −
movff ir_s8_buffer+.9,o2_ppo2_sensor2+ −
movff ir_s8_buffer+.10,o2_ppo2_sensor3+ −
movff ir_s8_buffer+.11,hud_battery_mv+0+ −
movff ir_s8_buffer+.12,hud_battery_mv+1+ −
+ −
movlw ir_timeout_value ; multiples of 62,5ms+ −
movwf ir_S8_timeout ; Reload timeout+ −
+ −
banksel hud_status_byte+ −
bsf hud_connection_ok ; Set manually for hwHUD w/o the HUD module...+ −
banksel isr_backup ; Select Bank0 for ISR data.+ −
+ −
isr_timer3_exit:+ −
clrf ir_s8_counter ; Clear pointer+ −
bcf PIR2,TMR3IF ; Clear flag+ −
return+ −
+ −
isr_timer3_checksum:+ −
addwf PRODL,F+ −
movlw .0+ −
addwfc PRODH,F+ −
return+ −
+ −
isr_timer3_s8: ; S8 input+ −
movff ir_s8_buffer+.0,PRODL+ −
clrf PRODH+ −
movf ir_s8_buffer+.1,W+ −
rcall isr_timer3_checksum+ −
movf ir_s8_buffer+.2,W+ −
rcall isr_timer3_checksum+ −
movf ir_s8_buffer+.3,W+ −
rcall isr_timer3_checksum+ −
movf ir_s8_buffer+.4,W+ −
rcall isr_timer3_checksum+ −
movf ir_s8_buffer+.5,W+ −
rcall isr_timer3_checksum+ −
movf ir_s8_buffer+.6,W+ −
rcall isr_timer3_checksum+ −
movf ir_s8_buffer+.7,W+ −
rcall isr_timer3_checksum+ −
movf ir_s8_buffer+.8,W+ −
rcall isr_timer3_checksum+ −
movf ir_s8_buffer+.9,W+ −
rcall isr_timer3_checksum+ −
movf ir_s8_buffer+.10,W+ −
rcall isr_timer3_checksum+ −
movf ir_s8_buffer+.11,W+ −
rcall isr_timer3_checksum+ −
movf ir_s8_buffer+.12,W+ −
rcall isr_timer3_checksum+ −
movf ir_s8_buffer+.13,W+ −
rcall isr_timer3_checksum+ −
movf ir_s8_buffer+.14,W+ −
rcall isr_timer3_checksum+ −
+ −
; Compare checksum+ −
movf ir_s8_buffer+.15,W+ −
cpfseq PRODL ; Checksum ok?+ −
bra isr_timer3_exit ; No, exit+ −
movf ir_s8_buffer+.16,W+ −
cpfseq PRODH ; Checksum ok?+ −
bra isr_timer3_exit ; No, exit+ −
+ −
; Checksum OK, copy results+ −
movff ir_s8_buffer+.3,hud_status_byte+ −
movff ir_s8_buffer+.13,hud_battery_mv+0+ −
movff ir_s8_buffer+.14,hud_battery_mv+1+ −
+ −
banksel common+ −
btfsc new_s8_data_available ; =1: Old data already processed?+ −
bra isr_timer3_skip ; No, skip copying new results+ −
+ −
movff ir_s8_buffer+.6,s8_rawdata_sensor1+2+ −
movff ir_s8_buffer+.5,s8_rawdata_sensor1+1+ −
movff ir_s8_buffer+.4,s8_rawdata_sensor1+0+ −
movff ir_s8_buffer+.9,s8_rawdata_sensor2+2+ −
movff ir_s8_buffer+.8,s8_rawdata_sensor2+1+ −
movff ir_s8_buffer+.7,s8_rawdata_sensor2+0+ −
movff ir_s8_buffer+.12,s8_rawdata_sensor3+2+ −
movff ir_s8_buffer+.11,s8_rawdata_sensor3+1+ −
movff ir_s8_buffer+.10,s8_rawdata_sensor3+0+ −
banksel common+ −
bsf new_s8_data_available ; set flag+ −
+ −
isr_timer3_skip:+ −
banksel ir_S8_timeout+ −
movlw ir_timeout_value ; multiples of 62,5ms+ −
movwf ir_S8_timeout ; Reload timeout+ −
bra isr_timer3_exit ; Exit+ −
+ −
+ −
;=============================================================================+ −
+ −
isr_tmr7: ; each 62,5ms+ −
bcf PIR5,TMR7IF ; clear flag+ −
banksel 0xF16 ; Addresses, F16h through F5Fh, are also used by SFRs, but are not part of the Access RAM.+ −
movlw .248+ −
movwf TMR7H ; -> Rollover after 2048 cycles -> 62,5ms+ −
+ −
banksel common+ −
call get_analog_switches ; Get analog readings+ −
btfss INTCON3,INT1IE+ −
bra isr_tmr7_a+ −
btfsc analog_sw2_pressed+ −
rcall isr_switch_left+ −
isr_tmr7_a:+ −
banksel common+ −
btfss INTCON,INT0IE+ −
bra isr_tmr7_b+ −
btfsc analog_sw1_pressed+ −
rcall isr_switch_right+ −
isr_tmr7_b:+ −
banksel common+ −
btfss no_sensor_int ; No sensor interrupt (because it's addressed during sleep)+ −
bra isr_tmr7_c ; No, continue+ −
banksel isr_backup ; Back to Bank0 ISR data+ −
return + −
isr_tmr7_c:+ −
banksel isr_backup+ −
movf max_CCPR1L,W ; Dimm value+ −
cpfseq CCPR1L ; = current PWM value?+ −
rcall isr_dimm_tft ; No, adjust until max_CCPR1L=CCPR1L !+ −
+ −
banksel isr_backup+ −
decfsz ir_S8_timeout,F ; IR Data still valid?+ −
bra isr_tmr7_2 ; Yes, continue+ −
; timeout, clear IR-Data+ −
+ −
movlw ir_timeout_value ; multiples of 62,5ms+ −
movwf ir_S8_timeout ; Reload timeout+ −
+ −
banksel common+ −
btfss analog_o2_input+ −
bra isr_tmr7_1a ; Always with normal ostc3 hardware+ −
btfss s8_digital+ −
bra isr_tmr7_2 ; only when digital+ −
isr_tmr7_1a:+ −
clrf o2_mv_sensor1+0 ; S8/IR timeout clears all analog input readings to zero -> Fallback will be triggered when sensor mode was used+ −
clrf o2_mv_sensor1+1+ −
clrf o2_mv_sensor2+0+ −
clrf o2_mv_sensor2+1+ −
clrf o2_mv_sensor3+0+ −
clrf o2_mv_sensor3+1+ −
banksel hud_battery_mv+ −
clrf hud_battery_mv+0+ −
clrf hud_battery_mv+1+ −
banksel hud_status_byte+ −
clrf hud_status_byte+ −
clrf o2_ppo2_sensor1 ; For IR/S8 HUD+ −
clrf o2_ppo2_sensor2+ −
clrf o2_ppo2_sensor3+ −
banksel common+ −
bsf new_s8_data_available ; set flag to update in surface mode+ −
+ −
isr_tmr7_2:+ −
banksel common+ −
btfss no_sensor_int ; No sensor interrupt (because it's addressed during sleep)+ −
bra isr_sensor_state2 ; No, continue+ −
banksel isr_backup ; Back to Bank0 ISR data+ −
return + −
+ −
isr_sensor_state2:+ −
banksel common+ −
movff sensor_state_counter,WREG+ −
btfss WREG,0 ; every 1/4 second+ −
bsf quarter_second_update ; Set flag+ −
banksel isr_backup ; Back to Bank0 ISR data+ −
movlw d'2'+ −
cpfseq speed_setting ; Set to normal in case it's not already in normal speed mode+ −
rcall isr_set_speed_to_normal+ −
+ −
incf sensor_state_counter,F ; counts to eight for state maschine+ −
+ −
; State 1: Clear flags and average registers, get temperature (51us) and start pressure integration (73,5us)+ −
; State 2: Get pressure (51us), start temperature integration (73,5us) and calculate temperature compensated pressure (233us)+ −
; State 3: Get temperature (51us) and start pressure integration (73,5us)+ −
; State 4: Get pressure (51us), start temperature integration (73,5us) and calculate temperature compensated pressure (233us)+ −
; State 5: Get temperature (51us) and start pressure integration (73,5us)+ −
; State 6: Get pressure (51us), start temperature integration (73,5us) and calculate temperature compensated pressure (233us)+ −
; State 7: Get temperature (51us) and start pressure integration (73,5us)+ −
; State 8: Get pressure (51us), start temperature integration (73,5us), calculate temperature compensated pressure (233us) and build average for half-second update of tempperature and pressure+ −
+ −
movff sensor_state_counter,WREG ; WREG used as temp here...+ −
dcfsnz WREG,F+ −
bra sensor_int_state1_plus_restart ; Do State 1+ −
dcfsnz WREG,F+ −
bra sensor_int_state2 ; Do State 2+ −
dcfsnz WREG,F+ −
bra sensor_int_state1 ; Do State 3+ −
dcfsnz WREG,F+ −
bra sensor_int_state2 ; Do State 4+ −
dcfsnz WREG,F+ −
bra sensor_int_state1 ; Do State 5+ −
dcfsnz WREG,F+ −
bra sensor_int_state2 ; Do State 6+ −
dcfsnz WREG,F+ −
bra sensor_int_state1 ; Do State 7+ −
; bra sensor_int2_plus_average ; Do State 8+ −
;sensor_int2_plus_average:+ −
; First, do state2:+ −
call get_pressure_value ; State2: Get pressure (51us)+ −
call get_temperature_start ; and start temperature integration (73,5us)+ −
call calculate_compensation ; calculate temperature compensated pressure (27us)+ −
; Build average+ −
bcf STATUS,C ; clear carry bit.+ −
rrcf amb_pressure_avg+1 ; amb_pressure sum / 2+ −
rrcf amb_pressure_avg+0+ −
bcf STATUS,C ; clear carry bit, twice.+ −
rrcf amb_pressure_avg+1 ; amb_pressure sum / 4+ −
rrcf amb_pressure_avg+0+ −
+ −
movff amb_pressure_avg+1,amb_pressure+1 ; copy into actual register+ −
movff amb_pressure_avg+0,amb_pressure+0+ −
+ −
bcf STATUS,C+ −
btfsc temperature_avg+1,7 ; Copy sign bit to carry+ −
bsf STATUS,C+ −
rrcf temperature_avg+1 ; Signed temperature /2+ −
rrcf temperature_avg+0+ −
bcf STATUS,C+ −
btfsc temperature_avg+1,7 ; Copy sign bit to carry+ −
bsf STATUS,C+ −
rrcf temperature_avg+1 ; Signed temperature /4+ −
rrcf temperature_avg+0+ −
+ −
movff temperature_avg+1,temperature+1 ; copy into actual register+ −
movff temperature_avg+0,temperature+0+ −
+ −
banksel common ; flag1 is in Bank1+ −
bcf temp_changed ; Clear flag for temperature update+ −
bcf pressure_refresh ; Clear flag for pressure update+ −
banksel isr_backup ; Back to Bank0 ISR data+ −
+ −
; Temp changed?+ −
movf temperature+0,W+ −
cpfseq last_temperature+0+ −
bra isr_sensor_state2_2 ; Yes+ −
movf temperature+1,W+ −
cpfseq last_temperature+1+ −
bra isr_sensor_state2_2 ; Yes+ −
+ −
bra isr_sensor_state2_3 ; no change+ −
+ −
isr_sensor_state2_2:+ −
banksel common ; flag1 is in Bank1+ −
bsf temp_changed ; Yes+ −
banksel isr_backup ; Back to Bank0 ISR data+ −
isr_sensor_state2_3:+ −
movff temperature+0,last_temperature+0 ; Copy for compare+ −
movff temperature+1,last_temperature+1+ −
+ −
movf amb_pressure+0,W+ −
cpfseq last_pressure+0+ −
bra isr_sensor_state2_4 ; Yes+ −
movf amb_pressure+1,W+ −
cpfseq last_pressure+1+ −
bra isr_sensor_state2_4 ; Yes+ −
+ −
bra isr_sensor_state2_5 ; No change+ −
isr_sensor_state2_4:+ −
banksel common ; flag1 is in Bank1+ −
bsf pressure_refresh ; Yes+ −
banksel isr_backup ; Back to Bank0 ISR data+ −
isr_sensor_state2_5:+ −
movff amb_pressure+0,last_pressure+0 ; Copy for compare+ −
movff amb_pressure+1,last_pressure+1+ −
+ −
clrf sensor_state_counter ; Then reset State counter+ −
banksel common ; flag2 is in Bank1+ −
btfss simulatormode_active ; are we in simulator mode?+ −
bra comp_air_pressure ; no+ −
; Always set pressure_refresh flag in simulator mode+ −
bsf pressure_refresh ; Yes+ −
banksel isr_backup ; Back to Bank0 ISR data+ −
movlw LOW d'1000' ; yes, so simulate 1000mbar surface pressure+ −
movwf last_surfpressure+0+ −
movlw HIGH d'1000'+ −
movwf last_surfpressure+1+ −
+ −
comp_air_pressure:+ −
banksel isr_backup ; Back to Bank0 ISR data+ −
movf last_surfpressure+0,W ; compensate airpressure+ −
subwf amb_pressure+0,W + −
movwf rel_pressure+0 ; rel_pressure stores depth!+ −
+ −
movf last_surfpressure+1,W+ −
subwfb amb_pressure+1,W+ −
movwf rel_pressure+1+ −
btfss STATUS,N ; result is below zero?+ −
bra sensor_int_state_exit+ −
clrf rel_pressure+0 ; Yes, do not display negative depths+ −
clrf rel_pressure+1 ; e.g. when surface air pressure dropped during the dive+ −
bra sensor_int_state_exit+ −
+ −
sensor_int_state1_plus_restart:+ −
clrf amb_pressure_avg+0 ; pressure average registers+ −
clrf amb_pressure_avg+1+ −
clrf temperature_avg+0+ −
clrf temperature_avg+1+ −
+ −
sensor_int_state1:+ −
call get_temperature_value ; State 1: Get temperature+ −
call get_pressure_start ; and start pressure integration.+ −
bra sensor_int_state_exit+ −
+ −
sensor_int_state2:+ −
call get_pressure_value ; State2: Get pressure (51us)+ −
call get_temperature_start ; and start temperature integration (73,5us)+ −
call calculate_compensation ; calculate temperature compensated pressure (233us)+ −
; bra sensor_int_state_exit+ −
sensor_int_state_exit:+ −
rcall isr_restore_clock ; Restore clock+ −
return+ −
;=============================================================================+ −
+ −
+ −
+ −
isr_rtcc: ; each second+ −
bcf PIR3,RTCCIF ; clear flag+ −
banksel 0xF16 ; Addresses, F16h through F5Fh, are also used by SFRs, but are not part of the Access RAM.+ −
bsf RTCCFG,RTCPTR1+ −
bsf RTCCFG,RTCPTR0 ; year+ −
movff RTCVALL,year ; format is BCD!+ −
movff RTCVALH,day ; dummy read+ −
movff RTCVALL,day ; format is BCD!+ −
movff RTCVALH,month ; format is BCD!+ −
movff RTCVALL,hours ; format is BCD!+ −
movff RTCVALH,secs ; format is BCD!+ −
movff RTCVALL,secs ; format is BCD!+ −
movff RTCVALH,mins ; format is BCD!+ −
banksel isr_backup ; Back to Bank0 ISR data+ −
+ −
; Convert BCD to DEC and set registers+ −
movff mins, isr1_temp+ −
rcall isr_rtcc_convert ; Converts to dec with result in WREG+ −
movff WREG,mins+ −
movff secs, isr1_temp+ −
rcall isr_rtcc_convert ; Converts to dec with result in WREG+ −
movff WREG,secs+ −
movff hours, isr1_temp+ −
rcall isr_rtcc_convert ; Converts to dec with result in WREG+ −
movff WREG,hours+ −
movff month, isr1_temp+ −
rcall isr_rtcc_convert ; Converts to dec with result in WREG+ −
movff WREG,month+ −
movff day, isr1_temp+ −
rcall isr_rtcc_convert ; Converts to dec with result in WREG+ −
movff WREG,day+ −
movff year, isr1_temp+ −
rcall isr_rtcc_convert ; Converts to dec with result in WREG+ −
movff WREG,year+ −
+ −
; Place once/second tasks for ISR here (Be sure of the right bank!)+ −
banksel common ; flag1 is in Bank1+ −
btfss sleepmode ; in Sleepmode?+ −
call get_ambient_level ; No, get ambient light level and set max_CCPR1L+ −
+ −
rcall isr_battery_gauge ; Add amount of battery consumption to battery_gauge:6+ −
+ −
; update uptime+ −
banksel uptime+0+ −
incf uptime+0,F+ −
movlw .0+ −
addwfc uptime+1,F+ −
addwfc uptime+2,F+ −
addwfc uptime+3,F+ −
+ −
banksel common ; flag1 is in Bank1+ −
bsf onesecupdate ; A new second has begun+ −
btfsc divemode ; in divemode?+ −
rcall isr_divemode_1sec ; Yes, do some divemode stuff in bank common+ −
+ −
btfss divemode ; in divemode?+ −
rcall isr_update_lastdive_time ; No, update the lastdive timer+ −
+ −
tstfsz secs ; Secs == 0 ?+ −
return ; No, Done.+ −
+ −
bsf oneminupdate ; A new minute has begun+ −
+ −
btfss divemode ; In Divemode?+ −
rcall check_nofly_desat_time ; No, so reduce NoFly and Desat and increase interval+ −
+ −
; Check if a new hour has just begun+ −
tstfsz mins ; mins=0?+ −
bra isr_rtcc2 ; No+ −
bsf onehourupdate ; Yes, set flag+ −
+ −
isr_rtcc2:+ −
banksel isr_backup ; Back to Bank0 ISR data+ −
return ; Done.+ −
+ −
isr_update_lastdive_time:+ −
; update uptime+ −
banksel lastdive_time+0+ −
incf lastdive_time+0,F+ −
movlw .0+ −
addwfc lastdive_time+1,F+ −
addwfc lastdive_time+2,F+ −
addwfc lastdive_time+3,F+ −
banksel common+ −
return+ −
+ −
isr_battery_gauge: + −
banksel isr_backup ; Bank0 ISR data+ −
movlw current_sleepmode ; 100µA/3600 -> nAs (Sleepmode current)+ −
movwf isr1_temp ; Store value (low byte)+ −
clrf isr2_temp ; High byte+ −
+ −
banksel common ; flag1 is in Bank1+ −
btfss sleepmode ; in Sleepmode?+ −
rcall isr_battery_gauge2 ; No, compute current consumtion value into isr1_temp and isr2_temp+ −
+ −
banksel isr_backup ; Bank0 ISR data+ −
movf isr1_temp,W ; 48Bit add of isr1_temp and isr2_temp into battery_gauge:6+ −
addwf battery_gauge+0,F+ −
movf isr2_temp,W+ −
addwfc battery_gauge+1,F+ −
movlw .0+ −
addwfc battery_gauge+2,F+ −
addwfc battery_gauge+3,F+ −
addwfc battery_gauge+4,F+ −
addwfc battery_gauge+5,F+ −
return+ −
+ −
isr_battery_gauge2:+ −
; set consumtion rate in nAs for an one second interval+ −
; Example:+ −
; movlw LOW .55556 ; 0,2A/3600*1e9s = nAs+ −
; movwf isr1_temp ; Low byte+ −
; movlw HIGH .55556 ; 0,2A/3600*1e9s = nAs+ −
; movwf isr2_temp ; High byte+ −
+ −
; Current consumption for LED backlight is 47*CCPR1L+272+ −
movf CCPR1L,W+ −
mullw current_backlight_multi+ −
movlw LOW current_backlight_offset+ −
addwf PRODL,F+ −
movlw HIGH current_backlight_offset+ −
addwfc PRODH,F+ −
movff PRODL,isr1_temp+ −
movff PRODH,isr2_temp ; isr1_temp and isr2_temp hold value for backlight+ −
+ −
; Add current for CPU and GPU + −
; speed_setting=1: ECO (3,1mA -> 861nAs), =2: NORMAL (5,50mA -> 1528nAs) or =3: FASTEST (8,04mA -> 2233nAs)+ −
banksel isr_backup ; Bank0 ISR data+ −
movlw .1+ −
cpfseq speed_setting+ −
bra isr_battery_gauge3+ −
movlw LOW current_speed_eco+ −
addwf isr1_temp,F+ −
movlw HIGH current_speed_eco+ −
addwfc isr2_temp,F+ −
bra isr_battery_gauge5+ −
isr_battery_gauge3:+ −
movlw .2+ −
cpfseq speed_setting+ −
bra isr_battery_gauge4+ −
movlw LOW current_speed_normal+ −
addwf isr1_temp,F+ −
movlw HIGH current_speed_normal+ −
addwfc isr2_temp,F+ −
bra isr_battery_gauge5+ −
isr_battery_gauge4:+ −
movlw LOW current_speed_fastest+ −
addwf isr1_temp,F+ −
movlw HIGH current_speed_fastest+ −
addwfc isr2_temp,F+ −
isr_battery_gauge5:+ −
; Add current if IR reciever is on+ −
btfss ir_power ; IR enabled?+ −
bra isr_battery_gauge6 ; no+ −
movlw LOW current_ir_reciever+ −
addwf isr1_temp,F+ −
movlw HIGH current_ir_reciever+ −
addwfc isr2_temp,F+ −
isr_battery_gauge6:+ −
; Add current for compass/accelerometer+ −
btfss compass_enabled ; compass active?+ −
bra isr_battery_gauge7 ; no+ −
movlw LOW current_compass+ −
addwf isr1_temp,F+ −
movlw HIGH current_compass+ −
addwfc isr2_temp,F+ −
isr_battery_gauge7:+ −
return+ −
+ −
isr_divemode_1sec:+ −
incf samplesecs,F ; "samplingrate" diving seconds done + −
decf samplesecs_value,W ; holds "samplingrate" value (minus 1 into WREG)+ −
cpfsgt samplesecs ; Done?+ −
bra isr_divemode_1sec2 ; no+ −
+ −
clrf samplesecs ; clear counter...+ −
bsf store_sample ; ...and set bit for profile storage+ −
isr_divemode_1sec2:+ −
; Increase re-setable average depth divetime counter+ −
infsnz average_divesecs+0,F ; increase stopwatch registers+ −
incf average_divesecs+1,F ; increase stopwatch registers+ −
; Increase total divetime (Regardless of start_dive_threshold)+ −
infsnz total_divetime_seconds+0,F+ −
incf total_divetime_seconds+1,F ; Total dive time (Regardless of start_dive_threshold)+ −
+ −
btfss divemode2 ; displayed divetime is running?+ −
return ; No (e.g. too shallow)+ −
+ −
; increase divetime registers (Displayed dive time)+ −
incf divesecs,F + −
movlw d'59'+ −
cpfsgt divesecs+ −
bra isr_divemode_1sec2a+ −
+ −
clrf divesecs+ −
bsf realdive ; this bit is always set (again) if the dive is longer then one minute+ −
infsnz divemins+0,F+ −
incf divemins+1,F ; increase divemins+ −
+ −
isr_divemode_1sec2a: + −
btfss FLAG_apnoe_mode ; Are we in Apnoe mode?+ −
return ; No+ −
+ −
incf apnoe_secs,F ; increase descent registers+ −
movlw d'59'+ −
cpfsgt apnoe_secs ; full minute?+ −
return ; No+ −
clrf apnoe_secs+ −
incf apnoe_mins,F ; increase descent mins+ −
return+ −
+ −
;=============================================================================+ −
; BCD to Binary convertion.+ −
; Input: isr1_temp = Value in BCD+ −
; Output WREG = value in binary.+ −
isr_rtcc_convert:+ −
swapf isr1_temp, W+ −
andlw 0x0F ; W= tens+ −
rlncf WREG, W ; W= 2*tens+ −
subwf isr1_temp, F ; 16*tens + ones - 2*tens+ −
subwf isr1_temp, F ; 14*tens + ones - 2*tens+ −
subwf isr1_temp, W ; 12*tens + ones - 2*tens+ −
return+ −
+ −
;=============================================================================+ −
+ −
isr_switch_right: ; + −
bcf INTCON,INT0IE ; Disable INT0+ −
banksel common ; flag1 is in Bank1+ −
btfss flip_screen ; 180° flipped?+ −
bsf switch_right ; Set flag+ −
btfsc flip_screen ; 180° flipped?+ −
bsf switch_left ; Set flag+ −
bra isr_switch_common ; Continue...+ −
+ −
isr_switch_left: ; + −
bcf INTCON3,INT1IE ; Disable INT1+ −
banksel common ; flag1 is in Bank1+ −
btfss flip_screen ; 180° flipped?+ −
bsf switch_left ; Set flag+ −
btfsc flip_screen ; 180° flipped?+ −
bsf switch_right ; Set flag+ −
isr_switch_common:+ −
; load timer1 for first press+ −
clrf TMR1L+ −
movlw TMR1H_VALUE_FIRST ; in steps of 7,8125ms+ −
movwf TMR1H+ −
bsf T1CON,TMR1ON ; Start Timer 1+ −
banksel isr_backup ; Select Bank0 for ISR data.+ −
bcf INTCON3,INT1IF ; Clear flag+ −
bcf INTCON,INT0IF ; Clear flag+ −
return+ −
+ −
timer1int:+ −
bcf PIR1,TMR1IF ; Clear flag+ −
banksel common ; flag1 is in Bank1+ −
bcf INTCON,INT0IF ; Clear flag+ −
bcf INTCON3,INT1IF ; Clear flag+ −
; digital+ −
btfss switch_left1 ; Left button hold-down?+ −
bra timer1int_left ; Yes+ −
btfss switch_right2 ; Right button hold-down?+ −
bra timer1int_right ; Yes+ −
+ −
; Analog+ −
btfsc analog_sw2_pressed ; Left button hold-down?+ −
bra timer1int_left ; Yes+ −
btfsc analog_sw1_pressed ; Right button hold-down?+ −
bra timer1int_right ; Yes+ −
+ −
; No button hold-down, stop Timer 1+ −
bcf T1CON,TMR1ON ; Stop Timer 1+ −
bsf INTCON,INT0IE ; Enable INT0+ −
bsf INTCON3,INT1IE ; Enable INT1+ −
return+ −
+ −
timer1int_left:+ −
btfss flip_screen ; 180° flipped?+ −
bsf switch_left ; (Re-)Set flag+ −
btfsc flip_screen ; 180° flipped?+ −
bsf switch_right ; (Re-)Set flag+ −
bra timer1int_common ; Continue+ −
timer1int_right:+ −
btfss flip_screen ; 180° flipped?+ −
bsf switch_right ; Set flag+ −
btfsc flip_screen ; 180° flipped?+ −
bsf switch_left ; Set flag+ −
timer1int_common:+ −
; load timer1 for next press+ −
clrf TMR1L+ −
movlw TMR1H_VALUE_CONT ; Surface mode+ −
btfsc divemode+ −
movlw TMR1H_VALUE_CONT_DIVE ; Dive mode+ −
movwf TMR1H+ −
return ; Return from timer1int with timer1 kept running+ −
+ −
;=============================================================================+ −
+ −
check_nofly_desat_time:+ −
+ −
; DELETE - no-fly time is now re-computed every second ## no fly+ −
; ; REPLACE ## no fly+ −
; ; movf nofly_time+0,W ; Is nofly null ?+ −
; ; iorwf nofly_time+1,W+ −
; ; BY+ −
; banksel int_O_nofly_time+ −
; movf int_O_nofly_time+0,W ; Is nofly null ?+ −
; iorwf int_O_nofly_time+1,W+ −
+ −
; bz check_nofly_desat_time2 ; yes...+ −
+ −
; movlw d'1'+ −
; ; REPLACE ## no fly+ −
; ; subwf nofly_time+0,F+ −
; ; BY+ −
; subwf int_O_nofly_time+0,F+ −
+ −
; movlw d'0'+ −
+ −
; ; REPLACE ## no fly+ −
; ; subwfb nofly_time+1,F ; reduce by one+ −
; ; BY+ −
; subwfb int_O_nofly_time+1,F ; reduce by one+ −
+ −
check_nofly_desat_time2:+ −
; REPLACE+ −
; movf desaturation_time+0,W ; Is Desat null ?+ −
; iorwf desaturation_time+1,W+ −
; BY+ −
banksel int_O_desaturation_time+ −
movf int_O_desaturation_time+0,W ; Is Desat null ?+ −
iorwf int_O_desaturation_time+1,W+ −
+ −
bz check_nofly_desat_time3 ; yes...+ −
+ −
; DELETE - desat-time is now re-computed every second ## no fly+ −
; movlw d'1'+ −
; ; REPLACE ## no fly+ −
; ; subwf desaturation_time+0,F+ −
; ; BY+ −
; subwf int_O_desaturation_time+0,F+ −
+ −
; movlw d'0'+ −
+ −
; ; REPLACE ## no fly+ −
; ; subwfb desaturation_time+1,F ; reduce by one...+ −
; ; by+ −
; subwfb int_O_desaturation_time+1,F ; reduce by one...+ −
banksel common+ −
+ −
; Increase surface interval timer+ −
infsnz surface_interval+0,F+ −
incf surface_interval+1,F+ −
return ; Done+ −
+ −
check_nofly_desat_time3:+ −
; NEW ## no fly+ −
banksel common+ −
+ −
clrf surface_interval+0+ −
clrf surface_interval+1 ; Clear surface interval timer+ −
return ; Done.+ −
+ −
;=============================================================================+ −
+ −
isr_restore_clock:+ −
banksel isr_backup+ −
movlw d'1'+ −
cpfseq speed_setting+ −
bra isr_restore_speed2+ −
; Reset to eco + −
movlw b'00000000' + −
movwf OSCTUNE ; 4x PLL Disable (Bit6) - only works with 8 or 16MHz (=32 or 64MHz)+ −
movlw b'00110010'+ −
movwf OSCCON ; 1MHz INTOSC+ −
movlw T2CON_ECO+ −
movwf T2CON+ −
bra isr_restore_exit+ −
isr_restore_speed2:+ −
movlw d'2'+ −
cpfseq speed_setting+ −
bra isr_restore_speed3+ −
; Reset to normal+ −
movlw b'01110010'+ −
movwf OSCCON ; 16MHz INTOSC+ −
movlw b'00000000'+ −
movwf OSCTUNE ; 4x PLL Disable (Bit6) - only works with 8 or 16MHz (=32 or 64MHz)+ −
movlw T2CON_NORMAL+ −
movwf T2CON+ −
bra isr_restore_exit+ −
+ −
isr_restore_speed3:+ −
; Reset to fastest+ −
movlw b'01110010' ; 16MHz INTOSC+ −
movwf OSCCON + −
movlw b'01000000' + −
movwf OSCTUNE ; 4x PLL Enable (Bit6) - only works with 8 or 16MHz (=32 or 64MHz)+ −
movlw T2CON_FASTEST+ −
movwf T2CON+ −
; bra isr_restore_exit+ −
isr_restore_exit:+ −
btfss OSCCON,HFIOFS+ −
bra isr_restore_exit ; loop until PLL is stable+ −
return+ −
+ −
+ −
restore_flash: ; Restore first flash page from eeprom+ −
banksel common+ −
; Start address in internal flash+ −
movlw 0x00+ −
movwf TBLPTRL+ −
movwf TBLPTRH+ −
movwf TBLPTRU+ −
+ −
movlw b'10010100' ; Setup erase+ −
rcall Write ; Write!+ −
+ −
movlw .128+ −
movwf lo ; Byte counter+ −
clrf EEADR+ −
movlw .3+ −
movwf EEADRH ; Setup backup address+ −
+ −
TBLRD*- ; Dummy read to be in 128 byte block+ −
restore_flash_loop:+ −
call read_eeprom+ −
incf EEADR,F+ −
movff EEDATA,TABLAT ; put 1 byte+ −
tblwt+* ; Table Write with Pre-Increment+ −
decfsz lo,F ; 128byte done?+ −
bra restore_flash_loop ; No+ −
+ −
movlw b'10000100' ; Setup writes+ −
rcall Write ; Write!+ −
+ −
reset ; Done, reset CPU+ −
+ −
Write:+ −
movwf EECON1 ; Type of memory to write in+ −
movlw 0x55+ −
movwf EECON2+ −
movlw 0xAA+ −
movwf EECON2+ −
bsf EECON1,WR ; Write+ −
nop+ −
nop + −
return+ −
+ −
+ −
END+ −