Mercurial > public > mk2
diff code_part1/OSTC_code_asm_part1/isr.asm @ 0:96a35aeda5f2
Initial setup
author | heinrichsweikamp |
---|---|
date | Tue, 12 Jan 2010 15:05:59 +0100 |
parents | |
children | 3b30cd739782 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code_part1/OSTC_code_asm_part1/isr.asm Tue Jan 12 15:05:59 2010 +0100 @@ -0,0 +1,394 @@ + +; 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/>. + + +; written by: Matthias Heinrichs, info@heinrichsweikamp.com +; written: 10/30/05 +; last updated: 05/16/08 +; known bugs: +; ToDo: + +; the timer1 module interrupts every 62.5ms (16x/second) +; temperature and pressure is averaged over 4 measurements +; flag pressure_refresh is set every 500ms +; and provides accurate pressure (+/-1mBar stable) and temperature (0.1C stable) + +uartint: + btfsc simulatormode_active ; are we in simulatormode? + bra simulator_int ; Yes, reading is depth in m! + + movff RCREG,uart1_temp + movlw d'96' + subwf uart1_temp,F + dcfsnz uart1_temp,F ; "a" + bsf dump_external_eeprom ; set flag + dcfsnz uart1_temp,F ; "b" + bsf uart_settime ; set flag + dcfsnz uart1_temp,F ; "c" + bsf simulatormode_active ; set flag + dcfsnz uart1_temp,F ; "d" + bsf internal_eeprom_write ; set flag + dcfsnz uart1_temp,F ; "e" + bsf uart_send_hash ; set flag + dcfsnz uart1_temp,F ; "f" + bsf uart_compensate_temp ; set flag + dcfsnz uart1_temp,F ; "g" + bsf uart_send_int_eeprom ; set flag + dcfsnz uart1_temp,F ; "h" + bsf uart_reset_decodata ; set flag + dcfsnz uart1_temp,F ; "i" + bsf internal_eeprom_write2 ; set flag + dcfsnz uart1_temp,F ; "j" + bsf uart_send_int_eeprom2 ; set flag + dcfsnz uart1_temp,F ; "k" + bsf uart_store_tissue_data ; set flag + + +uartint1: + movf RCREG,w ; unload RCREG in stand-alone simulator mode + bcf PIR1,RCIF ; Clear flag + bcf RCSTA,CREN ; Clear receiver status + bsf RCSTA,CREN + return + +simulator_int: + btfsc standalone_simulator ; ignore in standalone simulator mode + bra uartint1 + + call set_LEDusb + tstfsz RCREG ; =0x00? + bra simulator_int1 ; No + incf RCREG,F ; Yes, so force RCREG=1 + +simulator_int1: + movf RCREG,w ; depth in m + mullw d'100' ; result will be mbar + movff PRODL,sim_pressure+0 ; stored for pressure overwrite + movff PRODH,sim_pressure+1 + bra uartint1 ; exit uart int + +schalter_links: ; + bcf INTCON,INT0IF ; Clear flag + + btfsc T0CON,TMR0ON ; Timer0 running? + bra timer0_restart ; Yes, restart + + bsf switch_left ; Set flag, button press is OK + + bsf T0CON,TMR0ON ; Start Timer 0 + return + + +schalter_rechts: ; + bcf INTCON3,INT1IF ; Clear flag + + btfsc T0CON,TMR0ON ; Timer0 running? + bra timer0_restart ; Yes, restart + + bsf switch_right ; Set flag, button press is OK + + bsf T0CON,TMR0ON ; Start Timer 0 + return + +timer0_restart: + bcf INTCON,TMR0IF ; Clear flag + + clrf T0CON ; Timer0 + clrf TMR0H + clrf TMR0L + bsf T0CON,TMR0ON ; Start Timer 0 + return + +timer0int: + bcf INTCON,TMR0IF ; Clear flag + bcf T0CON,TMR0ON ; Stop Timer 0 + clrf TMR0H + clrf TMR0L + return + + +timer0int_left_reset: + bcf INTCON2, INTEDG0 ; Interrupt on faling edge again + bcf switch_left_isr ; Clear flag, button press is done + + movlw T0CON_debounce ; Timer0 + movwf T0CON + + bsf T0CON,TMR0ON ; Start Timer 0 + return + +timer0int_left: + bsf INTCON2, INTEDG0 ; Interrupt on rising edge again + return + +timer0int_right_reset: + bcf INTCON2, INTEDG1 ; Interrupt on faling edge again + bcf switch_right_isr ; Clear flag, button press is done + + movlw T0CON_debounce ; Timer0 + movwf T0CON + + bsf T0CON,TMR0ON ; Start Timer 0 + return + +timer0int_right: + bsf INTCON2, INTEDG1 ; Interrupt on rising edge again + return + +timer3int: + bcf PIR2,TMR3IF ; Clear flag + bcf T3CON,TMR0ON ; Stop Timer 3 + bcf T2CON,2 ; stop Timer 2 + return + +timer1int: + bcf PIR1,TMR1IF ; Clear flag + +timer1int_debug: + + call clear_LEDr ; LEDr off (For charge indicator) + + movlw 0x08 ; Timer1 int after 62.5ms (=16/second) + cpfslt TMR1H ; Did we miss a 1/16 second? + incf timer1int_counter1,F ; Yes, add extra 1/16 second + + movlw 0x08 ; Timer1 int after 62.5ms (=16/second) + subwf TMR1H,F + + incf timer1int_counter1,F + movlw d'15' ; One second 16 + cpfsgt timer1int_counter1 + bra sensor_int_pre ; only pressure sensor + call RTCisr ; adjust time, then query pressure sensor + +sensor_int_pre: + btfss sleepmode ; In sleepmode? + bra sensor_int ; No + return + +sensor_int: + btfsc no_sensor_int ; No sensor interrupt (because it's addressed during sleep) + return + + incf timer1int_counter2,F ; counts to eight for state maschine + + movlw d'1' + cpfseq timer1int_counter2 ; State 1? + bra sensor_int1 ; No + + bcf pressure_refresh ; clear flags + clrf isr3_temp+0 ; pressure average registers + clrf isr3_temp+1 + clrf temperature_temp+0 + clrf temperature_temp+1 +sensor_int0: + call get_temperature_value ; State 1: Get temperature + call get_pressure_start ; and start pressure integration. + return ; Done. +sensor_int1: + movlw d'2' + cpfseq timer1int_counter2 ; State 2? + bra sensor_int2 ; No + +sensor_int1_1: + 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) + movf amb_pressure+0,W + addwf isr3_temp+0 ; average pressure + movf amb_pressure+1,W + addwfc isr3_temp+1 + movf temperature+0,W + addwf temperature_temp+0 ; average temperature + movf temperature+1,W + addwfc temperature_temp+1 + return +sensor_int2: + movlw d'3' + cpfseq timer1int_counter2 ; State 3? + bra sensor_int3 ; No + bra sensor_int0 ; Yes, but same as State 1! +sensor_int3: + movlw d'4' + cpfseq timer1int_counter2 ; State 4? + bra sensor_int4 ; No + bra sensor_int1_1 ; Yes, but same as State 2! +sensor_int4: + movlw d'5' + cpfseq timer1int_counter2 ; State 5? + bra sensor_int5 ; No + bra sensor_int0 ; Yes, but same as State 1! +sensor_int5: + movlw d'6' + cpfseq timer1int_counter2 ; State 6? + bra sensor_int6 ; No + bra sensor_int1_1 ; Yes, but same as State 2! +sensor_int6: + movlw d'7' + cpfseq timer1int_counter2 ; State 7? + bra sensor_int7 ; No + bra sensor_int0 ; Yes, but same as State 1! +sensor_int7: + rcall sensor_int1_1 ; Do State 2... + clrf timer1int_counter2 ; ..then reset State counter... + movlw d'2' ; and calculate average! + movwf isr2_temp +sensor_int8: + bcf STATUS,C + rrcf isr3_temp+1 ; isr3_temp / 2 + rrcf isr3_temp+0 + bcf STATUS,C + rrcf temperature_temp+1 ; temperature_temp /2 + rrcf temperature_temp+0 + decfsz isr2_temp,F + bra sensor_int8 ; once more + + movff isr3_temp+1,amb_pressure+1 ; copy into actual register + movff isr3_temp+0,amb_pressure+0 + + movff temperature_temp+1,temperature+1 + movff temperature_temp+0,temperature+0 + + bsf pressure_refresh ; Set flag! Temp and pressure were updated! + + btfss simulatormode_active ; are we in simulator mode? + bra comp_air_pressure ; no + +comp_air_pressure0: + movlw LOW d'1000' ; yes, so simulate 1Bar surface pressure + movwf last_surfpressure+0 + movlw HIGH d'1000' + movwf last_surfpressure+1 + +comp_air_pressure: + bcf neg_flag + 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? + return + clrf rel_pressure+0 ; Yes, do not display negative depths + clrf rel_pressure+1 ; e.g. when surface air pressure dropped during the dive + return + +RTCisr: + clrf timer1int_counter1 ; counts to 16 (one second / 62.5ms) + bsf onesecupdate ; we have a new second! + + bcf STATUS,Z ; are we in dive mode? + btfss divemode + bra RTCisr2 ; No, must be surface or sleepmode + + incf samplesecs,F ; CF20 diving seconds done + decf samplesecs_value,W ; holds CF20 value (minus 1 into WREG) + cpfsgt samplesecs + bra RTCisr1 ; no + + clrf samplesecs ; clear counter... + bsf store_sample ; ...and set bit for profile storage +RTCisr1: +; Increase re-setable average depth divetime counter + incf average_divesecs+0,F ; increase divetime registers + btfsc STATUS,Z + incf average_divesecs+1,F ; increase divetime registers + + btfss divemode2 ; displayed divetime is running? + bra RTCisr2 ; No (e.g. too shallow) + + incf divesecs,F ; increase divetime registers + movlw d'59' + cpfsgt divesecs + bra RTCisr1a + clrf divesecs + bsf realdive ; this bit is always set (again) if the dive is longer then one minute + + incf divemins+0,F ; increase divemins + btfsc STATUS,Z + incf divemins+1,F ; and now do the realtime clock routine anyway + +RTCisr1a: + btfss FLAG_apnoe_mode ; Are we in Apnoe mode? + bra RTCisr2 ; No, skip the following + + incf apnoe_secs,F ; increase descent registers + movlw d'59' + cpfsgt apnoe_secs + bra RTCisr2 + clrf apnoe_secs + + incf apnoe_mins,F ; increase descent mins + ; Now, do the RTC routine.... +RTCisr2: + incf secs,F ; adjusts seconds, minutes, hours, day, month and year. Checks for a leap year and works until 2099! + movlw d'59' + cpfsgt secs + return + clrf secs + bsf oneminupdate + incf mins,F + movlw d'59' + cpfsgt mins + return + clrf mins + incf hours,F + movlw d'23' + cpfsgt hours + return + clrf hours + incf day,F +check_date: + movff month,isr_divB ; new month? + dcfsnz isr_divB,F + movlw .31 + dcfsnz isr_divB,F + movlw .28 + dcfsnz isr_divB,F + movlw .31 + dcfsnz isr_divB,F + movlw .30 + dcfsnz isr_divB,F + movlw .31 + dcfsnz isr_divB,F + movlw .30 + dcfsnz isr_divB,F + movlw .31 + dcfsnz isr_divB,F + movlw .31 + dcfsnz isr_divB,F + movlw .30 + dcfsnz isr_divB,F + movlw .31 + dcfsnz isr_divB,F + movlw .30 + dcfsnz isr_divB,F + movlw .31 + cpfsgt day,1 + return + movlw .1 + movwf day + incf month,F + movlw .12 + cpfsgt month,1 + return + movlw .1 + movwf month + incf year,F + return \ No newline at end of file