Mercurial > public > hwos_code
diff src/ms5541.asm @ 0:11d4fc797f74
init
author | heinrichsweikamp |
---|---|
date | Wed, 24 Apr 2013 19:22:45 +0200 |
parents | |
children | 50c3e2c7ba7a |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/ms5541.asm Wed Apr 24 19:22:45 2013 +0200 @@ -0,0 +1,512 @@ +;============================================================================= +; +; File ms5541.asm +; +; Sensor subroutines +; +; Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved. +;============================================================================= +; HISTORY +; 2011-08-03 : [mH] moving from OSTC code + +#include "ostc3.inc" ; Mandatory header +#include "math.inc" ; Math routines + +sensors CODE + +;============================================================================= +; Expose internal variables, to ease debug: + global D1, D2 + global C1, C2, C3, C4, C5, C6 + global xdT, xdT2, OFF, SENS, amb_pressure_avg, temperature_avg + +;============================================================================= + global calculate_compensation +calculate_compensation: + ; xdT = D2 - C5 (s16 range -11.400 .. +12.350) + movf C5+0,W ; Get Value to be subtracted + subwf D2+0,W ; Do the Low Byte + movwf xdT+0 + movf C5+1,W ; Then the high byte. + subwfb D2+1,W + movwf xdT+1 + + ; Second order temperature calculation + ; xdT/128 is in range -89..+96, hence signed 8bit. dT/128 = (2*dT)/256 + rlcf xdT+0,W ; put hit bit in carry. + rlcf xdT+1,W ; inject in high byte. + movwf isr_xA+0 ; and put result in low byte. + clrf isr_xA+1 + btfsc xdT+1,7 ; If dT < 0 + setf isr_xA+1 ; then signextend to -1 + movff isr_xA+0,isr_xB+0 ; copy A to B + movff isr_xA+1,isr_xB+1 + call isr_signed_mult16x16 ; dT*dT --> xC (32 bits) + + ; dT >= 0: divide by 8, ie. 3 shifts rights. + ; dT < 0: divide by 2, ie. 1 shifts rights. + movlw .3 + btfss xdT+1,7 ; Was dT negative ? + movlw .1 +calc_loop_1: + bcf STATUS,C ;dT^2 is positive, so injected zeros. + rrcf isr_xC+1,F + rrcf isr_xC+0,F + decfsz WREG + bra calc_loop_1 + + movf isr_xC+0,W ; dT2 = dT - (dT/128)*(dT/128)/(2 ...or... 8) + subwf xdT+0,W + movwf xdT2+0 + movf isr_xC+1,W + subwfb xdT+1,W + movwf xdT2+1 + + ; Calculate OFF = C2 + ((C4-250)*dT2)/2^12 + 10000 + ; (range +9.246 .. +18.887) + movff C4+0,isr_xA+0 + movff C4+1,isr_xA+1 +; movlw LOW(-.250) ; C4 - 250 --> A +; addwf C4+0,W +; movwf isr_xA+0 +; movlw -1 ; HIGH(- .250) is not understood... +; addwfc C4+1,W +; movwf isr_xA+1 + + movff xdT2+0,isr_xB+0 ; dT2 --> B + movff xdT2+1,isr_xB+1 + call isr_signed_mult16x16 + movlw .12-.8 ; A 12bit shift = 1 byte + 4 bits. + call isr_shift_C31 + + movlw LOW(.10000) ; Add 10000 + addwf isr_xC+1,F + movlw HIGH(.10000) + addwfc isr_xC+2,F + + movf C2+0,W ; Add C2, and save into OFF + addwf isr_xC+1,W + movwf OFF+0 + movf C2+1,W + addwfc isr_xC+2,W + movwf OFF+1 + + ; Calculate SENS = C1/2 + ((C3+200)*dT)/2^13 + 3000 + movlw LOW(.200) ; C3+200 --> A + addwf C3+0,W + movwf isr_xA+0 + movlw HIGH(.200) + addwfc C3+1,W + movwf isr_xA+1 + ; B still contains dT2 + call isr_signed_mult16x16 ; A*B --> C + movlw .13-.8 ; A 13bit shift = 1 byte + 5 bits. + call isr_shift_C31 + + bcf STATUS,C ; SENS = C1 / 2 + rrcf C1+1,W + movwf SENS+1 + rrcf C1+0,W + movwf SENS+0 + + movlw LOW(.3000) ; Add 3000 + addwf isr_xC+1,F + movlw HIGH(.3000) + addwfc isr_xC+2,F + + movf isr_xC+1,W ; And sum into SENS + addwf SENS+0,F + movf isr_xC+2,W + addwfc SENS+1,F + + ; calculate amb_pressure = (sens * (d1-off))/2^12 + 1000 + movf OFF+0,W ; d1-off --> a + subwf D1+0,W + movwf isr_xA+0 + movf OFF+1,W + subwfb D1+1,W + movwf isr_xA+1 + + movff SENS+0,isr_xB+0 ; sens --> b + movff SENS+1,isr_xB+1 + call isr_signed_mult16x16 + movlw .12-.8 ; a 12bit shift = 1 byte + 4 bits. + call isr_shift_C31 + + movlw LOW(.1000) ; add 1000 + addwf isr_xC+1,F + movlw HIGH(.1000) + addwfc isr_xC+2,F + + banksel common + btfss simulatormode_active ; are we in simulator mode? + bra calc_compensation_2 ; no + banksel isr_backup + + movff sim_pressure+0,isr_xC+1 ; override readings with simulator values + movff sim_pressure+1,isr_xC+2 + +calc_compensation_2: + banksel isr_backup + movf isr_xC+1,W ; Then sum_up to pressure averaging buffer. + addwf amb_pressure_avg+0,F + movf isr_xC+2,W + addwfc amb_pressure_avg+1,F + + ; calculate temp = 200 + dT*(C6+100)/2^11 + movlw LOW(.100) ; C6 + 100 --> A + addwf C6+0,W + movwf isr_xA+0 + movlw HIGH(.100) + addwfc C6+1,W + movwf isr_xA+1 + + movff xdT2+0,isr_xB+0 ; dT2 --> B + movff xdT2+1,isr_xB+1 + call isr_signed_mult16x16 ; A*B + movlw .11-.8 ; A 12bit shift = 1 byte + 3 bits. + call isr_shift_C31 + + movlw LOW(.200) ; Add 200 + addwf isr_xC+1,F + movlw HIGH(.200) + addwfc isr_xC+2,F + + movf isr_xC+1,W + addwf temperature_avg+0,F + movf isr_xC+2,W + addwfc temperature_avg+1,F + + return ; Done. + +;============================================================================= + global get_pressure_start +get_pressure_start: + rcall reset_MS5541 + movlw b'10100000' ;+3*high as start and 1+low as stop! +get_pressure_start2: + movwf isr1_temp + movlw d'12' + rcall send_data_MS5541 + return + + global get_pressure_value +get_pressure_value: + btfsc MS5541_miso ; Conversion done? + return ; No, Return + rcall get_2bytes_MS5541 + movff dMSB,D1+1 + movff dLSB,D1+0 + return + +;============================================================================= + global get_temperature_start +get_temperature_start: + rcall reset_MS5541 + movlw b'10010000' ;+3*high as start and 1+low as stop! + bra get_pressure_start2 ; continue in "get_pressure" + + global get_temperature_value +get_temperature_value: + btfsc MS5541_miso ; Conversion done? + return ; No, Return + rcall get_2bytes_MS5541 + movff dMSB,D2+1 + movff dLSB,D2+0 + return + +;============================================================================= + global get_calibration_data +get_calibration_data: + banksel common + bsf no_sensor_int ; disable sensor interrupts + banksel isr_backup ; Back to Bank0 ISR data + + rcall reset_MS5541 + movlw b'01010100' ;+3*high as start and 1+low as stop! + movwf isr1_temp + movlw d'13' + rcall send_data_MS5541 + rcall get_2bytes_MS5541 + movff dMSB,W1+1 + movff dLSB,W1+0 + + movlw b'01011000' ;+3*high as start and 1+low as stop! + movwf isr1_temp + movlw d'13' + rcall send_data_MS5541 + rcall get_2bytes_MS5541 + movff dMSB,W2+1 + movff dLSB,W2+0 + + movlw b'01100100' ;+3*high as start and 1+low as stop! + movwf isr1_temp + movlw d'13' + rcall send_data_MS5541 + rcall get_2bytes_MS5541 + movff dMSB,W3+1 + movff dLSB,W3+0 + + movlw b'01101000' ;+3*high as start and 1+low as stop! + movwf isr1_temp + movlw d'13' + rcall send_data_MS5541 + rcall get_2bytes_MS5541 + movff dMSB,W4+1 + movff dLSB,W4+0 + +; calculate C1 (16Bit) + movff W1+1, C1+1 + bcf STATUS,C + rrcf C1+1 + bcf STATUS,C + rrcf C1+1 + bcf STATUS,C + rrcf C1+1 + movff W1+0, C1+0 + bsf STATUS,C + btfss W1+1,0 + bcf STATUS,C + rrcf C1+0 + bsf STATUS,C + btfss W1+1,1 + bcf STATUS,C + rrcf C1+0 + bsf STATUS,C + btfss W1+1,2 + bcf STATUS,C + rrcf C1+0 + +; calculate C2 (16Bit) + movff W2+0, C2+0 + bsf STATUS,C + btfss W2+1,0 + bcf STATUS,C + rrcf C2+0 + bsf STATUS,C + btfss W2+1,1 + bcf STATUS,C + rrcf C2+0 + bsf STATUS,C + btfss W2+1,2 + bcf STATUS,C + rrcf C2+0 + bsf STATUS,C + btfss W2+1,3 + bcf STATUS,C + rrcf C2+0 + bsf STATUS,C + btfss W2+1,4 + bcf STATUS,C + rrcf C2+0 + bsf STATUS,C + btfss W2+1,5 + bcf STATUS,C + rrcf C2+0 + + movff W2+1, C2+1 + bsf STATUS,C + btfss W1+0,0 + bcf STATUS,C + rrcf C2+1 + bsf STATUS,C + btfss W1+0,1 + bcf STATUS,C + rrcf C2+1 + bsf STATUS,C + btfss W1+0,2 + bcf STATUS,C + rrcf C2+1 + bcf STATUS,C + rrcf C2+1 + bcf STATUS,C + rrcf C2+1 + bcf STATUS,C + rrcf C2+1 + +; calculate C3 (16Bit) + movff W3+1,C3+0 + bsf STATUS,C + btfss W3+0,7 + bcf STATUS,C + rlcf C3+0 + bsf STATUS,C + btfss W3+0,6 + bcf STATUS,C + rlcf C3+0 + clrf C3+1 + btfsc W3+1,7 + bsf C3+1,1 + btfsc W3+1,6 + bsf C3+1,0 + +; calculate C4 (16Bit) + movff W4+1,C4+0 + bsf STATUS,C + btfss W4+0,7 + bcf STATUS,C + rlcf C4+0 + clrf C4+1 + btfsc W4+1,7 + bsf C4+1,0 + +; C4=C4-250 + movlw LOW(-.250) ; C4 - 250 --> C4 + addwf C4+0,W + movwf C4+0 + movlw -1 ; HIGH(- .250) is not understood... + addwfc C4+1,W + movwf C4+1 + +; calculate C5 (16Bit) + movff W3+0,C5+0 + bcf C5+0,6 + btfsc W2+0,0 + bsf C5+0,6 + bcf C5+0,7 + btfsc W2+0,1 + bsf C5+0,7 + clrf C5+1 + btfsc W2+0,2 + bsf C5+1,0 + btfsc W2+0,3 + bsf C5+1,1 + btfsc W2+0,4 + bsf C5+1,2 + btfsc W2+0,5 + bsf C5+1,3 + + ; calculate C5 = UT1 + ; C5 = 8*C5 + 10000 (u16 range 10.000 .. +42.760) + clrf isr_xA+1 + movlw d'8' + movwf isr_xA+0 + movff C5+0,isr_xB+0 + movff C5+1,isr_xB+1 + call isr_unsigned_mult16x16 ;isr_xA*isr_xB=isr_xC + movff isr_xC+0,C5+0 + movff isr_xC+1,C5+1 + movlw LOW d'10000' + addwf C5+0,F + movlw HIGH d'10000' + addwfc C5+1,F ; = 8*C5 + 10000 + +; calculate C6 (16Bit) + clrf C6+1 + movff W4+0,C6+0 + bcf C6+0,7 + + banksel common + bcf no_sensor_int ; enable sensor interrupts + bcf pressure_refresh ; Clear flag + banksel isr_backup ; Back to Bank0 ISR data + + clrf sensor_state_counter ; Then reset State counter + + return + +;============================================================================= +reset_MS5541_one: + bsf MS5541_mosi + bra send_clk_pulse ; Send one high-low sequence on MS5541_clk -> and return + +reset_MS5541_zero: + bcf MS5541_mosi + bra send_clk_pulse ; Send one high-low sequence on MS5541_clk -> and return + +reset_MS5541: + rcall reset_MS5541_one ;0 + rcall reset_MS5541_zero + rcall reset_MS5541_one + rcall reset_MS5541_zero + rcall reset_MS5541_one + rcall reset_MS5541_zero + rcall reset_MS5541_one + rcall reset_MS5541_zero + rcall reset_MS5541_one + rcall reset_MS5541_zero + rcall reset_MS5541_one + rcall reset_MS5541_zero + rcall reset_MS5541_one + rcall reset_MS5541_zero + rcall reset_MS5541_one + rcall reset_MS5541_zero ;15 + rcall reset_MS5541_zero + rcall reset_MS5541_zero + rcall reset_MS5541_zero + rcall reset_MS5541_zero + rcall reset_MS5541_zero ;20 + return + +get_2bytes_MS5541: + movlw d'8' + movwf clock_count + rcall recieve_loop + movff isr1_temp,dMSB + + movlw d'8' + movwf clock_count + rcall recieve_loop + movff isr1_temp,dLSB + bra send_clk_pulse ; Send one high-low sequence on MS5541_clk -> and return + ;return + +recieve_loop: + rcall send_clk_pulse ; Send one high-low sequence on MS5541_clk + btfss MS5541_miso ;MSB first + bcf STATUS,C + btfsc MS5541_miso ;MSB first + bsf STATUS,C + rlcf isr1_temp,F + decfsz clock_count,F + bra recieve_loop + return + +send_clk_pulse: + bsf MS5541_clk + nop + nop + nop + nop + bcf MS5541_clk + nop + nop + return + +send_data_MS5541: + movwf clock_count ; From WREG + ; send three startbits first + bcf MS5541_clk + bsf MS5541_mosi + movlw d'3' + subwf clock_count,F ; total bit counter + rcall send_clk_pulse ; Send one high-low sequence on MS5541_clk + rcall send_clk_pulse ; Send one high-low sequence on MS5541_clk + rcall send_clk_pulse ; Send one high-low sequence on MS5541_clk + ; now send 8 bytes from isr_temp1 and fill-up with zeros +send_data_MS5541_2: + bcf MS5541_clk + + btfss isr1_temp,7 ;MSB first + bcf MS5541_mosi + btfsc isr1_temp,7 ;MSB first + bsf MS5541_mosi + + bsf MS5541_clk + + bcf STATUS,C + rlcf isr1_temp,F +; nop +; nop +; nop +; nop +; nop +; nop +; bcf MS5541_clk + + decfsz clock_count,F + bra send_data_MS5541_2 + bcf MS5541_clk + return + + END \ No newline at end of file