Mercurial > public > mk2
diff code_part1/OSTC_code_asm_part1/altimeter.asm @ 125:2907b42c195b
Altimeter:
- use H = 19902 log10(P0/P)
- Interface to select sea level mbars.
- Average over 32 values, using 1/16 of mbar.
- Display in customview area.
- Fix display ****m when not yet computed
- Fix reset when exiting sleep mode
- Fix : edit menu in 1/4 of mbar.
- Fix use CF#49 to enable/disable altimeter, also in altimeter menu.
- Fix visible in Menu 2
author | JeanDo |
---|---|
date | Wed, 29 Dec 2010 01:41:13 +0100 |
parents | |
children | 49bb155ddfbf |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code_part1/OSTC_code_asm_part1/altimeter.asm Wed Dec 29 01:41:13 2010 +0100 @@ -0,0 +1,369 @@ +;============================================================================= +; +; File altimeter.asm +; +; Altimeter function prototype. +; +; 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/>. +; +; Copyright (c) 2010, JD Gascuel. +;============================================================================= +; HISTORY +; 2010-12-15 : [jDG] First prototype with quadratic polynomial ant tp°. +; 2010-12-28 : [jDG] Use MPLAB Math and C libraries for FP32 computations. +; 2011-01-02 : [jDG] Edit reference pressure by 0.25 mbar. +; +altimeter_calc: + movlb HIGH(pressureAvg) + + movf pressureRef+0,W ; Already initialized ? + iorwf pressureRef+1,W + bnz altimeter_1 ; Yes... + + movlw LOW(4*.1013+1) ; Init see level at 1013,25 mbar. + movwf pressureRef+0 + movlw HIGH(4*.1013+1) + movwf pressureRef+1 + +; Reset computation. Eg. after a sleep, enables to faster restart with correct +; values... +altimeter_reset: + movlb HIGH(pressureAvg) + clrf pressureSum+0 ; Init averaging area + clrf pressureSum+1 + clrf pressureCount + + clrf altitude+0 ; Mark as not computed yet. + clrf altitude+1 + + movff amb_pressure+0,pressureAvg+0 ; And init first average. + movff amb_pressure+1,pressureAvg+1 + + movlw 4 ; And multiply AVG by 16 to be coherent. +altimeter_reset_1: + bcf STATUS,C + rlcf pressureAvg+0 + rlcf pressureAvg+1 + decfsz WREG + bra altimeter_reset_1 + + movlb 1 ; Back to normal bank1. + return + +altimeter_1: + ;---- Do a bank-safe 16bit summing ----------------------------------- + movff amb_pressure+0,WREG + addwf pressureSum+0,F + movff amb_pressure+1,WREG + addwfc pressureSum+1,F + + incf pressureCount ; Increment count too. + movlw .32 ; Already 32 done ? + subwf pressureCount,W + bnz altimeter_4 ; NO: skip update. + + ;---- Update altitude every 32 pressure measures -------------------- + bcf STATUS,C ; Divide by 2, to store pressure x16 + rrcf pressureSum+1 + rrcf pressureSum+0 + + movff pressureSum+0,pressureAvg+0 + movff pressureSum+1,pressureAvg+1 + + rcall compute_altitude ; Compute from the averaged value... + + clrf pressureSum+0 ; And reset sum zone for next averaging. + clrf pressureSum+1 + clrf pressureCount + +altimeter_4: + movlb 1 ; make sure to be in normal bank1 + return + + ;---- Display result ------------------------------------------------- +altimeter_display: + GETCUSTOM8 .49 ; Check CF#49 + btfss WREG,0 ; Enabled ? + return ; NO: return + + WIN_TOP .35 ; Custom view drawing zone... + WIN_LEFT .90 + WIN_INVERT .0 + WIN_FONT .0 + call PLED_standard_color + + STRCPY "Alt:" + + movff altitude+0,lo ; BANK-SAFE read altitude + movff altitude+1,hi + movf lo,W ; Is it zero (not computed yet) ? + iorwf hi,W + bz altimeter_2 + + bsf leftbind + output_16 + bcf leftbind + bra altimeter_3 + +altimeter_2: + STRCAT "****" + +altimeter_3: + STRCAT_PRINT "m " + return + +;============================================================================= +; Compute altitude, using the formula: +; H(P) = 18.787 log10(P0/P) (Log base 10) + +;---- Interface the the Mayh library ----------------------------------------- + extern __AARGB2 ; A float in fA2, fA1, fA0, fAExo + extern __BARGB2 ; B float in fB2, fB1, fB0, fBExo + extern FLO1632U ; convert uint16 fA+1 --> fp32 fA + extern FPD32 ; fp32 divide fA/fB --> fA + extern FPM32 ; fp32 multiply fA*fB --> fA + extern INT3216 ; convert fp32 fA --> int16 fA+1 +#define fA __AARGB2 +#define fB __BARGB2 + +;---- Interface to the C library --------------------------------------------- + extern __AARGB3 + extern log10 ; float32 log(auto float32) +#define fRet __AARGB3 + +compute_altitude: + ; Setup C-code stack, to enable calling the log() function. + lfsr FSR1, c_code_data_stack + lfsr FSR2, c_code_data_stack + + ; Convert pressure to float, --> fB + movff pressureAvg+0, fA+1 + movff pressureAvg+1, fA+2 + call FLO1632U ; u16 fA[1:2] --> fp32 fA + movff fA+0, fB+0 + movff fA+1, fB+1 + movff fA+2, fB+2 + movff fA+3, fB+3 + + ; Convert sea-level reference pressure to float, --> fB + movff pressureRef+0, fA+1 ; Get sea level pressure. + movff pressureRef+1, fA+2 + bcf STATUS,C ; Multiply by 4. + rlcf fA+1 + rlcf fA+2 + bcf STATUS,C + rlcf fA+1 + rlcf fA+2 + call FLO1632U ; to float: u16 fA[1:2] --> fp32 fA + + ; Divide + call FPD32 ; fp32 X/Y --> X + + ; log10() + movff fA+0, POSTINC1 ; Push X to stack + movff fA+1, POSTINC1 + movff fA+2, POSTINC1 + movff fA+3, POSTINC1 + call log10 ; log(P0/P) + + movf POSTDEC1,F,ACCESS ; pop argument + movf POSTDEC1,F,ACCESS + movf POSTDEC1,F,ACCESS + movf POSTDEC1,F,ACCESS + + ; Move log10(P0/P) to fB + movff fRet+0,fB+0 ; move result to fB + movff fRet+1,fB+1 + movff fRet+2,fB+2 + movff fRet+3,fB+3 + + ; Multiply by scaling factor for meters, and standatd atmosphere. + movlw LOW(.18787) + movff WREG, fA+1 + movlw HIGH(.18787) + movff WREG, fA+2 + call FLO1632U ; u16 fA[1:2] --> fp32 fA + call FPM32 ; altitute --> fp32 fA + + ; Convert result to int16 --> altitude. + call INT3216 ; fp32 fA --> int16 fA+1 + movff fA+1, altitude+0 + movff fA+2, altitude+1 + + return + +;============================================================================= +; Altimeter menu +; +; Edit reference (where altitude = 0) pressure, while displaying corresponding +; altitude. +; +altimeter_menu: + call PLED_ClearScreen ; Menu header. + call PLED_standard_color + call PLED_topline_box + WIN_INVERT .1 ; Init new Wordprocessor + WIN_FONT .0 + WIN_LEFT .80-7*7 + WIN_TOP .0 + STRCPY_PRINT "Set Altimeter:" + + movlw 3 ; Start menu on line 3. + movwf menupos + +altimeter_menu_2: + WIN_FONT .0 ; Reset, because compute erase that... + WIN_INVERT .0 + WIN_LEFT .20 ; First line: + WIN_TOP .35 + STRCPY "Sea ref:" + + movff pressureRef+0, lo + movff pressureRef+1, hi + bcf STATUS,C ; Divide ref pressure by 4 + rrcf hi ; to get the integer part of it: + rrcf lo + bcf STATUS,C + rrcf hi + rrcf lo + bsf leftbind + output_16 + + PUTC '.' + movff pressureRef+0, hi ; Decimal part is constructed + clrf WREG ; from the 2 lower bits. + btfsc hi,0 + addlw .25 + btfsc hi,1 + addlw .50 + movwf lo + output_99x + + STRCAT_PRINT "mbar " + + WIN_TOP .65 ; Second line: + STRCPY "Alt:" + movff altitude+0, lo + movff altitude+1, hi + bcf leftbind + output_16 + STRCAT_PRINT "m " + + WIN_TOP .95 ; Action enable + STRCPY "Enabled: " + GETCUSTOM8 .49 + btfss WREG,0 + bra alt_menu_1 + STRCAT_PRINT "ON " + bra alt_menu_2 +alt_menu_1: + STRCAT_PRINT "OFF" +alt_menu_2: + + WIN_TOP .125 ; Action add + STRCPY_PRINT "+0.25 mbar" + WIN_TOP .155 ; Action sub + STRCPY_PRINT "-0.25 mbar" + WIN_TOP .185 ; Action exit + STRCPY_PRINT "Exit" + +alt_menu_loop: + call PLED_menu_cursor ; Display cursor + bcf switch_left ; reset buttons state + bcf switch_right + +alt_menu_loop1: ; Wait for button. + btfsc switch_right ; [[MENU]] button + bra alt_menu_next + + btfsc switch_left ;[[ENTER]] button + bra alt_menu_do_it + + btfsc divemode ; Diving stared ? + goto restart ; YES: quit this menu ! + + btfsc onesecupdate ; Check what should be every 1sec. + call timeout_surfmode + + btfsc onesecupdate + call set_dive_modes + + bcf onesecupdate ; end of 1sek. tasks + + btfsc sleepmode ; Sleep mode entered ? + bra alt_menu_exit + + bra alt_menu_loop1 + +;---- Move to next line ------------------------------------------------------ + +alt_menu_next: + incf menupos ; next line. + movlw .7 + cpfseq menupos ; Below last line ? + bra alt_menu_loop + movlw .3 ; Yes: back to line no 3. + movwf menupos + bra alt_menu_loop + +;----- Execute menu line ----------------------------------------------------- + +alt_menu_do_it: + movf menupos,W ; test line value + addlw -3 + bz alt_menu_enable + dcfsnz WREG + bra alt_menu_plus1 ; 4 --> +1 + dcfsnz WREG + bra alt_menu_minus1 ; 5 --> -1 + bra alt_menu_exit ; else --> exit + +;---- Toggle altimeter (CF#49) ----------------------------------------------- +alt_menu_enable: + GETCUSTOM8 .49 ; Read CF#49 + btg WREG,0 ; Toggle boolean value + movwf EEDATA + movlw d'1' ; Upper EEPROM Bank + movwf EEADRH + movlw 4*(.49-.32) + 0x82 ; CF#49 low byte address in EEPROM + movwf EEADR + call write_eeprom + bra altimeter_menu_2 + +;---- Increment sea level pressure ------------------------------------------- + +alt_menu_plus1: + movlb HIGH(pressureRef) ; Setup our own ram bank + infsnz pressureRef+0 ; 16bit inc. + incf pressureRef+1 + bra alt_menu_recompute ; then recompute altitude. + +;---- Decrement sea level pressure ------------------------------------------- + +alt_menu_minus1: + movlb HIGH(pressureRef) ; Setup our own ram bank + decf pressureRef+0 ; 16bit decrement + movlw 0 + subwfb pressureRef+1 + +alt_menu_recompute: + rcall compute_altitude ; Recompute altitude + movlb 1 ; Go back to normal bank1 + bra altimeter_menu_2 + +;---- Exit altimeter menu ---------------------------------------------------- +alt_menu_exit: + movlw .5 ; reset position to Altimeter line. + movwf menupos ; + goto more_menu2 ; in the More... menu.