Mercurial > public > mk2
diff code_part1/OSTC_code_asm_part1/sleepmode.asm @ 0:96a35aeda5f2
Initial setup
author | heinrichsweikamp |
---|---|
date | Tue, 12 Jan 2010 15:05:59 +0100 |
parents | |
children | 01510acaeb11 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code_part1/OSTC_code_asm_part1/sleepmode.asm Tue Jan 12 15:05:59 2010 +0100 @@ -0,0 +1,233 @@ +; OSTC - diving computer code +; Copyright (C) 2008 HeinrichsWeikamp GbR +; This program is free software: you can redistribute it and/or modify +; it under the terms of the GNU General Public License as published by +; the Free Software Foundation, either version 3 of the License, or +; (at your option) any later version. +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; You should have received a copy of the GNU General Public License +; along with this program. If not, see <http://www.gnu.org/licenses/>. +; Routines for sleepmode +; written by: Matthias Heinrichs, info@heinrichsweikamp.com +; written: 050520 +; last updated: 090507 +; known bugs: +; ToDo: +sleeploop: ; enter sleepmode! +; first check if the 16 hash char are=0 + lfsr FSR2, char_O_hash + movlw d'16' + movwf temp1 +sleeploop1: + tstfsz POSTINC2 ; Test hash values + bra sleeploop2 ; At least one char is not zero -> Do not build hash + decfsz temp1,F + bra sleeploop1 + ; build hash (about 90sek @ 16MHz) + call PLED_ClearScreen ; clear + DISPLAYTEXT .1 ; "Building MD2 hash" + DISPLAYTEXT .2 ; "Please wait..." + call deco_main_hash ; calculate MD2 hash + movlb b'00000001' ; Back to Bank1 +sleeploop2: + call PLED_DisplayOff ; display off + call disable_rs232 ; disable UART module + clrf divemins+0 + clrf divemins+1 + bcf TRISB,6 + bcf TRISB,7 + bcf PORTB,6 + bcf PORTB,7 ; Disable UART +sleeploop_loop: + btfsc oneminupdate ; one minute in sleep? + rcall onemin_sleep ; do oneminute tasks, e.g. calculate desaturation + + btfsc onesecupdate ; one second in sleep? + rcall onesec_sleep ; check switches, check pressure sensor, etc. + + btfss sleepmode ; wake up? (This bit will be set in other routines) + goto restart ; yes + nop + sleep ; Sleep until Timer1 will wake up the device + nop + bra sleeploop_loop ; do loop until someting happens + + +onemin_sleep: + call get_battery_voltage ; get battery voltage + btfsc enter_error_sleep ; Enter Fatal Error Routine? + goto fatal_error_sleep ; Yes (In Sleepmode_vxx.asm!) + + call calc_surface_interval ; Increases Surface-Interval time + call nofly_timeout60 ; check for no fly time + ; adjust airpressure compensation any 15 minutes + incf divemins+1,F ; counts to 14... + movlw d'14' + cpfsgt divemins+1 + bra onemin_sleep2 ; 15 minutes not done! + + rcall pressuretest_sleep_fast ; Gets pressure without averaging (faster!) + + call check_temp_extrema ; Check for temperature extremas + + call main_calc_CNS_decrease_15min ; compute CNS decay in sleep only + movlb b'00000001' + movff last_surfpressure_15min+0,last_surfpressure_30min+0 ; save older airpressure + movff last_surfpressure_15min+1,last_surfpressure_30min+1 ; save older airpressure + movff amb_pressure+0,last_surfpressure_15min+0 ; save new airpressure + movff amb_pressure+1,last_surfpressure_15min+1 ; save new airpressure + + clrf divemins+1 ; reset counter + GETCUSTOM15 d'7' ; loads max_sufpressure into lo, hi + movff lo,sub_a+0 ; max. "allowed" airpressure in mBar + movff hi,sub_a+1 + movff last_surfpressure_15min+0,sub_b+0 + movff last_surfpressure_15min+1,sub_b+1 + call sub16 ; sub_c = sub_a - sub_b + btfsc neg_flag + bra onemin_sleep1 + bra onemin_sleep2 ; current airpressure is lower then "allowed" airpressure, ok! +onemin_sleep1: ; not ok! Overwrite with max. "allowed" airpressure + GETCUSTOM15 d'7' ; loads max_sufpressure into lo, hi + movff lo,last_surfpressure_15min+0 ; max. "allowed" airpressure in mBar + movff hi,last_surfpressure_15min+1 ; max. "allowed" airpressure in mBar + +onemin_sleep2: +;calc_deko_sleepmode: + movff amb_pressure+0,int_I_pres_respiration+0 ; LOW copy pressure to deco routine + movff amb_pressure+1,int_I_pres_respiration+1 ; HIGH + GETCUSTOM8 d'11' ; Saturation multiplier % + movwf wait_temp + movff wait_temp,char_I_saturation_multiplier + GETCUSTOM8 d'12' ; Desaturation multiplier % + movwf wait_temp + movff wait_temp,char_I_desaturation_multiplier + call deco_main_calc_wo_deco_step_1_m ; "calc_tissue_sleep" + movlb b'00000001' ; RAM Bank1 selected + + bcf oneminupdate ; all done + return + +onesec_sleep: + call test_charger ; charger on? + + btfss nofly_active + bra onesec_sleep_nonofly + + call set_LEDnofly ; Set nofly LED + + nop + sleep + nop + +onesec_sleep_nonofly: + call clear_LEDnofly ; Clear nofly LED + incf divemins+0,F ; counts to #test_pressure_in_sleep (5) + movlw d'5' + cpfsgt divemins+0 ; here: temp variable + bra onesec_sleep1 ; #test_pressure_in_sleep not done yet + rcall pressuretest_sleep_fast ; Gets pressure without averaging (faster!) + + ; compare current ambient pressure with threshold + GETCUSTOM15 d'6' ; loads pressure threshold into lo,hi + movff lo,sub_a+0 ; power on if ambient pressure is greater threshold + movff hi,sub_a+1 + movff amb_pressure+0,sub_b+0 + movff amb_pressure+1,sub_b+1 + call sub16 ; sub_c = sub_a - sub_b + bsf sleepmode + btfsc neg_flag ; Wake up from Sleep? + bcf sleepmode ; amb_pressure>pressure_offset_divemode: wake up! + clrf divemins+0 +onesec_sleep1: + bcf onesecupdate ; all done. + btfsc switch_left + bra onesec_sleep1a + btfsc switch_right + bra onesec_sleep1a +; No button pressed + bcf INTCON,INT0IF ; Clear flag + bcf INTCON3,INT1IF ; Clear flag + bcf switch_right_isr + bcf switch_left_isr + bcf switch_right + bcf switch_left + bcf T0CON,TMR0ON ; Stop Timer 0 + return +onesec_sleep1a: ; At least one button pressed.... + bcf INTCON,INT0IF ; Clear flag + bcf INTCON3,INT1IF ; Clear flag + bcf switch_right_isr + bcf switch_left_isr + bcf switch_right + bcf switch_left + bcf T0CON,TMR0ON ; Stop Timer 0 + bcf sleepmode ; wake up! + bsf show_startup_screen ; + return + +pressuretest_sleep_fast: ; Get pressure without averaging (Faster to save some power in sleep mode) + call get_temperature_start ; and start temperature integration (73,5us) + sleep + nop + sleep + nop + sleep ; Wait at least 35ms (every 16.5ms Timer1 wakeup) + call get_temperature_value ; State 1: Get temperature + call get_pressure_start ; Start pressure integration. + sleep + nop + sleep + nop + sleep ; Wait at least 35ms (every 16.5ms Timer1 wakeup) + call get_pressure_value ; State2: Get pressure (51us) + call calculate_compensation ; calculate temperature compensated pressure (233us) + return + +fatal_error_sleep: + clrf INTCON + clrf INTCON2 + clrf INTCON3 + bcf ADCON0,0 ; AD converter off + call disable_rs232 ; disable UART module + movlw b'00010000' + movwf TRISA + clrf PORTA ; And pulled to GND + clrf TRISB ; All output + clrf PORTB ; And pulled to GND + movlw b'00011101' ; UART + movwf TRISC + clrf PORTC ; And pulled to GND + clrf TRISD ; All output + clrf PORTD ; And pulled to GND + clrf TRISE ; All output + clrf PORTE ; And pulled to GND + clrf T0CON ; Timer OFF + clrf T1CON ; Timer OFF + clrf T2CON ; Timer OFF + clrf OSCTUNE + movlw b'00000010' ; 31kHz + movwf OSCCON + bsf WDTCON,0 ; Watchdog timer on... +fatal_error_sleep_loop: ; Device will never quit this loop! + movff fatal_error_code,temp4 + movlw d'15' + movwf temp1 +fatal_error_sleep_loop1: + sleep + nop + decfsz temp1,F + bra fatal_error_sleep_loop1 +fatal_error_sleep_loop2: + call set_LEDy + clrwdt + WAIT10US d'5' + call clear_LEDy + sleep + nop + decfsz temp4,F + bra fatal_error_sleep_loop2 + bra fatal_error_sleep_loop \ No newline at end of file