Mercurial > public > hwos_code
view src/isr.asm @ 592:05053910d668
BUGFIX: Re-enable Sensors after sleep in PSCR mode
author | heinrichsweikamp |
---|---|
date | Wed, 18 Apr 2018 17:03:52 +0200 |
parents | b455b31ce022 |
children | ca4556fb60b9 |
line wrap: on
line source
;============================================================================= ; ; File isr.asm REFACTORED VERSION V2.98 ; ; 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 Interrupts bra HighInt nop nop nop nop nop nop bra HighInt isr_low CODE 0x00018 ; Low Priority Interrupts ; *** 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 link timer int 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 UD 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 machine ; 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 air pressure 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 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: ; called every second when not in divemode ; 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 consumption 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 consumption 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 receiver is on btfss ir_power ; IR enabled? bra isr_battery_gauge6 ; no movlw LOW current_ir_receiver addwf isr1_temp,F movlw HIGH current_ir_receiver 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 conversion. ; 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: ; called every minute when not in divemode 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_time_1 ; yes... ; int_O_desaturation_time is only computed while in start, surface mode, menue_tree or ghostwriter. ; So the ISR may clock surface_interval past the actual surface interval time. But TFT_surface_lastdive ; will check int_O_desaturation_time and in case int_O_desaturation_time is zero it will not show ; surface_interval but lastdive_time instead. So this glitch remains invisible. ; Increase surface interval timer banksel common infsnz surface_interval+0,F incf surface_interval+1,F return ; Done check_nofly_desat_time_1: 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