comparison code_part1/OSTC_code_asm_part1/ms5535.asm @ 161:8d6aca08f66b

Use signed arithmetic for pressure/temperature compensation.
author JeanDo
date Tue, 18 Jan 2011 23:57:33 +0100
parents 3e351e25f5d1
children e26f49674956
comparison
equal deleted inserted replaced
160:0ee809806454 161:8d6aca08f66b
14 ; You should have received a copy of the GNU General Public License 14 ; You should have received a copy of the GNU General Public License
15 ; along with this program. If not, see <http://www.gnu.org/licenses/>. 15 ; along with this program. If not, see <http://www.gnu.org/licenses/>.
16 16
17 17
18 ; routines for Intersema MS5535A, MS5541B and MS5541C 18 ; routines for Intersema MS5535A, MS5541B and MS5541C
19 ; written by: Matthias Heinrichs, info@heinrichsweikamp.com 19 ; history:
20 ; written: 9/26/05 20 ; 2005-09-26: Written by Matthias Heinrichs, info@heinrichsweikamp.com
21 ; last updated: 08/08/31 21 ; 2008-08-21: MH last updated
22 ; 2011-01-19: jDG Clean up using true signed arithmetics.
22 ; known bugs: 23 ; known bugs:
23 ; ToDo: 24 ; ToDo:
24 25
25 ; with second order temperature compensation 26 ; with second order temperature compensation
26 27
27 calculate_compensation: 28 calculate_compensation:
28 ; calculate xdT 29 ; calculate UT1 = 8*C5 + 10000 (u16 range 10.000 .. +42.760)
29 clrf isr_xA+1 30 clrf isr_xA+1
30 movlw d'8' 31 movlw d'8'
31 movwf isr_xA+0 32 movwf isr_xA+0
32 movff C5+0,isr_xB+0 33 movff C5+0,isr_xB+0
33 movff C5+1,isr_xB+1 34 movff C5+1,isr_xB+1
34 call isr_mult16x16 ;isr_xA*isr_xB=isr_xC 35 call isr_unsigned_mult16x16 ;isr_xA*isr_xB=isr_xC
35 movlw LOW d'10000' 36 movlw LOW d'10000'
36 addwf isr_xC+0, f 37 addwf isr_xC+0, f
37 movlw HIGH d'10000' 38 movlw HIGH d'10000'
38 addwfc isr_xC+1, f ;isr_xC= 8*C5 + 10000 39 addwfc isr_xC+1, f ;isr_xC= 8*C5 + 10000
39 movff D2+0,isr_sub_a+0 40
40 movff D2+1,isr_sub_a+1 41 ; xdT = D2 - UT1 (s16 range -11.400 .. +12.350)
41 movff isr_xC+0,isr_sub_b+0 42 movf isr_xC+0,W ; Get Value to be subtracted
42 movff isr_xC+1,isr_sub_b+1 43 subwf D2+0,W ; Do the Low Byte
43 call isr_sub16 ; isr_sub_c = isr_sub_a - isr_sub_b 44 movwf xdT+0
44 movff isr_sub_c+0,xdT+0 45 movf isr_xC+1,W ; Then the high byte.
45 movff isr_sub_c+1,xdT+1 46 subwfb D2+1,W
46 47 movwf xdT+1
47 ; Second order temperature calculation 48
48 btfsc neg_flag_isr 49 ; Second order temperature calculation
49 bra dTzero_yes 50 ; xdT/128 is in range -89..+96, hence signed 8bit. dT/128 = (2*dT)/256
50 ; dT>0 51 rlcf xdT+0,W ; put hit bit in carry.
51 bcf neg_flag_xdT 52 rlcf xdT+1,W ; inject in high byte.
52 movff xdT+0,isr_xA+0 53 movwf isr_xA+0 ; and put result in low byte.
53 movff xdT+1,isr_xA+1 54 clrf isr_xA+1
54 movff xdT+0,isr_xB+0 55 btfsc xdT+1,7 ; If dT < 0
55 movff xdT+1,isr_xB+1 56 setf isr_xA+1 ; then signextend to -1
56 call isr_mult16x16 ;isr_xA*isr_xB=isr_xC 57 movff isr_xA+0,isr_xB+0 ; copy A to B
57 movlw d'17' ; 2^17=(128*128)*8 58 movff isr_xA+1,isr_xB+1
58 movwf isr_divB 59 call isr_signed_mult16x16 ; dT*dT --> xC (32 bits)
59 call isr_div32 ; isr_xC=isr_xC(32Bit)/2^isr_divB (isr_divB: 8Bit only!) 60
60 movff xdT+0,isr_sub_a+0 61 ; dT >= 0: divide by 8, ie. 3 shifts rights.
61 movff xdT+1,isr_sub_a+1 62 ; dT < 0: divide by 2, ie. 1 shifts rights.
62 movff isr_xC+0,isr_sub_b+0 63 movlw .3
63 movff isr_xC+1,isr_sub_b+1 64 btfss xdT+1,7 ; Was dT negatif ?
64 call isr_sub16 ; isr_sub_c = isr_sub_a - isr_sub_b 65 movlw .1
65 movff isr_sub_c+0,xdT2+0 66 calc_loop_1:
66 movff isr_sub_c+1,xdT2+1 67 bcf STATUS,C ;dT^2 is positiv, so injected zeros.
67 bra OFF_calc ; Done 68 rrcf isr_xC+1,F
68 69 rrcf isr_xC+0,F
69 dTzero_yes: 70 decfsz WREG
70 ; dT<0 71 bra calc_loop_1
71 bsf neg_flag_xdT 72
72 movff xdT+0,isr_xA+0 73 movf isr_xC+0,W ; dT2 = dT - (dT/128)*(dT/128)/(2 ...or... 8)
73 movff xdT+1,isr_xA+1 74 subwf xdT+0,W
74 movff xdT+0,isr_xB+0 75 movwf xdT2+0
75 movff xdT+1,isr_xB+1 76 movf isr_xC+1,W
76 call isr_mult16x16 ;isr_xA*isr_xB=isr_xC 77 subwfb xdT+1,W
77 movlw d'15' ; 2^15=(128*128)*2 78 movwf xdT2+1
78 movwf isr_divB 79
79 call isr_div32 ; isr_xC=isr_xC(32Bit)/2^isr_divB (isr_divB: 8Bit only!) 80 ; Calculate OFF = C2 + ((C4-250)*dT2)/2^12 + 10000
80 81 ; (range +9.246 .. +18.887)
81 movf xdT+0,W 82 movlw LOW(-.250) ; C4 - 250 --> A
82 addwf isr_xC+0,F 83 addwf C4+0,W
83 movf xdT+1,W 84 movwf isr_xA+0
84 addwfc isr_xC+1,F 85 movlw -1 ; HIGH(- .250) is not hunderstood...
85 movff isr_xC+0,xdT2+0 86 addwfc C4+1,W
86 movff isr_xC+1,xdT2+1 87 movwf isr_xA+1
87 88
88 OFF_calc: 89 movff xdT2+0,isr_xB+0 ; dT2 --> B
89 ; calculate OFF 90 movff xdT2+1,isr_xB+1
90 movff C4+0,isr_sub_a 91 call isr_signed_mult16x16
91 movff C4+1,isr_sub_a+1 92 movlw .12-.8 ; A 12bit shift = 1 byte + 4 bits.
92 movlw d'250' 93 call isr_shift_C31
93 movwf isr_sub_b 94
94 clrf isr_sub_b+1 95 movlw LOW(.10000) ; Add 10000
95 call isr_sub16 ; (C4-250) - Sets neg_flag_isr! 96 addwf isr_xC+1,F
96 movff isr_sub_c,isr_xA 97 movlw HIGH(.10000)
97 movff isr_sub_c+1,isr_xA+1 98 addwfc isr_xC+2,F
98 movff xdT+0,isr_xB 99
99 movff xdT+0+1,isr_xB+1 100 movf C2+0,W ; Add C2, and save into OFF
100 call isr_mult16x16 ; (C4-250)*dT 101 addwf isr_xC+1,W
101 movff isr_xC+0,isr_divA 102 movwf OFF+0
102 movff isr_xC+1,isr_divA+1
103 movlw d'12'
104 movwf isr_divB
105 call isr_div16 ; [(C4-250)*dT]/2^12
106 movff isr_divA+0,isr_xC+0
107 movff isr_divA+1,isr_xC+1 ; isr_xC= {[(C4-250)*dT]/2^12}
108 btfss neg_flag_isr ; neg_flag_isr=1?
109 bra OFF_calc2 ; Yes, do C2 - isr_xC
110 ; no, so do C2 + isr_xC
111 movf C2+0,W
112 addwf isr_xC+0, f
113 movf C2+1,W 103 movf C2+1,W
114 addwfc isr_xC+1, f ; isr_xC= C2 + {[(C4-250)*dT/2^12]} 104 addwfc isr_xC+2,W
115 OFF_calc3: 105 movwf OFF+1
116 movlw LOW d'10000' 106
117 addwf isr_xC+0, f 107 ; Calculate SENS = C1/2 + ((C3+200)*dT)/2^13 + 3000
118 movlw HIGH d'10000' 108 movlw LOW(.200) ; C3+200 --> A
119 addwfc isr_xC+1, f ; isr_xC=[(C4-250)*dT/2^12] + 10000 109 addwf C3+0,W
120 movff isr_xC+0,OFF+0 110 movwf isr_xA+0
121 movff isr_xC+1,OFF+1 111 movlw HIGH(.200)
122 bra calculate_SENS ; Done with OFF 112 addwfc C3+1,W
123 113 movwf isr_xA+1
124 OFF_calc2: 114 ; B still contains dT2
125 movff C2+0,isr_sub_a+0 115 call isr_signed_mult16x16 ; A*B --> C
126 movff C2+1,isr_sub_a+1 116 movlw .13-.8 ; A 13bit shift = 1 byte + 5 bits.
127 movff isr_xC+0,isr_sub_b+0 117 call isr_shift_C31
128 movff isr_xC+1,isr_sub_b+1 118
129 call isr_sub16 ; isr_sub_c = isr_sub_a - isr_sub_b 119 bcf STATUS,C ; SENS = C1 / 2
130 ; isr_xC= C2 - {[(C4-250)*dT/2^12]} 120 rrcf C1+1,W
131 movff isr_sub_c+0,isr_xC+0 121 movwf SENS+1
132 movff isr_sub_c+1,isr_xC+1 ; Done with OFF 122 rrcf C1+0,W
133 bra OFF_calc3 123 movwf SENS+0
134 124
135 calculate_SENS: 125 movlw LOW(.3000) ; Add 3000
136 movff C3+0, C3_temp+0 126 addwf isr_xC+1,F
137 movff C3+1, C3_temp+1 127 movlw HIGH(.3000)
138 movlw d'200' 128 addwfc isr_xC+2,F
139 addwf C3_temp+0, f 129
140 movlw d'0' 130 movf isr_xC+1,W ; And sum into SENS
141 addwfc C3_temp+1, f ; C3 no longer valid! 131 addwf SENS+0,F
142 movff C3_temp+0, isr_xA 132 movf isr_xC+2,W
143 movff C3_temp+1, isr_xA+1 133 addwfc SENS+1,F
144 movff xdT+0, isr_xB 134
145 movff xdT+1, isr_xB+1 135 ; calculate amb_pressure = (sens * (d1-off))/2^12 + 1000
146 call isr_mult16x16 136 movf OFF+0,W ; d1-off --> a
147 movff isr_xC+0,isr_divA 137 subwf D1+0,W
148 movff isr_xC+1,isr_divA+1 138 movwf isr_xA+0
149 movlw d'13' 139 movf OFF+1,W
150 movwf isr_divB 140 subwfb D1+1,W
151 call isr_div16 141 movwf isr_xA+1
152 movff isr_divA,SENS+0 142
153 movff isr_divA+1,SENS+1 143 movff SENS+0,isr_xB+0 ; sens --> b
154 movff C1+0,isr_divA 144 movff SENS+1,isr_xB+1
155 movff C1+1,isr_divA+1 145 call isr_signed_mult16x16
156 movlw d'1' 146 movlw .12-.8 ; a 12bit shift = 1 byte + 4 bits.
157 movwf isr_divB 147 call isr_shift_C31
158 call isr_div16 148
159 movf isr_divA,W 149 movlw LOW(.1000) ; add 1000, and save into amb_pressure
160 addwf SENS+0, f 150 addwf isr_xC+1,W
161 movf isr_divA+1,W 151 movwf amb_pressure+0
162 addwfc SENS+1, f 152 movlw HIGH(.1000)
163 movlw d'184' 153 addwfc isr_xC+2,W
164 addwf SENS+0, f 154 movwf amb_pressure+1
165 movlw d'11'
166 addwfc SENS+1, f
167
168 ; calculate amb_pressure
169 movff D1+0,isr_sub_a
170 movff D1+1,isr_sub_a+1
171 movff OFF+0,isr_sub_b
172 movff OFF+1,isr_sub_b+1
173 call isr_sub16
174 movff isr_sub_c,isr_xA
175 movff isr_sub_c+1,isr_xA+1
176 movff SENS+0,isr_xB
177 movff SENS+1,isr_xB+1
178 call isr_mult16x16
179 movlw d'12'
180 movwf isr_divB
181 call isr_div32
182 btfsc neg_flag_isr ; invert isr_xC+0 and isr_xC+1
183 call isr_invert_xC
184 movlw LOW d'1000'
185 addwf isr_xC+0, f
186 movlw HIGH d'1000'
187 addwfc isr_xC+1, f
188 movff isr_xC+0,amb_pressure+0
189 movff isr_xC+1,amb_pressure+1
190 155
191 btfss simulatormode_active ; are we in simulator mode? 156 btfss simulatormode_active ; are we in simulator mode?
192 bra calc_pressure_done ; no 157 bra calc_pressure_done ; no
193 158
194 movff sim_pressure+0,amb_pressure+0 ; override readings with simulator values 159 movff sim_pressure+0,amb_pressure+0 ; override readings with simulator values
195 movff sim_pressure+1,amb_pressure+1 160 movff sim_pressure+1,amb_pressure+1
196 161
197 calc_pressure_done: 162 calc_pressure_done:
198 163 ; calculate temp = 200 + dT*(C6+100)/2^11
199 ; calculate temp 164 movlw LOW(.100) ; C6 + 100 --> A
200 movff C6+0, C3_temp+0 165 addwf C6+0,W
201 movff C6+1, C3_temp+1 166 movwf isr_xA+0
202 movlw d'100' 167 movlw HIGH(.100)
203 addwf C3_temp+0, f 168 addwfc C6+1,W
204 movlw d'0' 169 movwf isr_xA+1
205 addwfc C3_temp+1, f 170
206 movff C3_temp+0,isr_xA+0 171 movff xdT2+0,isr_xB+0 ; dT2 --> B
207 movff C3_temp+1,isr_xA+1 172 movff xdT2+1,isr_xB+1
208 movff xdT2+0,isr_xB+0 173 call isr_signed_mult16x16 ; A*B
209 movff xdT2+1,isr_xB+1 174 movlw .11-.8 ; A 12bit shift = 1 byte + 3 bits.
210 call isr_mult16x16 175 call isr_shift_C31
211 movlw d'11' 176
212 movwf isr_divB 177 movlw LOW(.200) ; Add 200, and save into temperature
213 call isr_div32 178 addwf isr_xC+1,W
214 bcf neg_temp ; Temperatur positive 179 movwf temperature+0
215 180 movlw HIGH(.200)
216 btfsc neg_flag_xdT ; was xdT negative? 181 addwfc isr_xC+2,W
217 bra neg_sub_temp ; yes, 200 - dT*(.... 182 movwf temperature+1
218 ; No, 200 + dT*(.... 183
219 ; movf temperature_correction,W 184 bcf neg_temp
220 ; addlw d'200' 185 bnn calc_pos_temp ; Is Temp° negativ ?
221 ; btfsc STATUS,C 186
222 ; incf isr_xC+1,F 187 bsf neg_temp ; Yes: set flag and store -temp
223 188 comf temperature+1
224 movlw d'200' 189 negf temperature+0
225 addwf isr_xC+0, f 190 btfsc STATUS,C
226 movlw d'0' 191 incf temperature+1
227 addwfc isr_xC+1, f 192
228 movff isr_xC+0,temperature+0 193 calc_pos_temp:
229 movff isr_xC+1,temperature+1 194 return ; Fertig mit allem
230 return ; done
231
232 neg_sub_temp: ; 200 - dT*(....
233 ; movf temperature_correction,W
234 ; addlw d'200'
235 ; btfsc STATUS,C
236 ; decf isr_xC+1,F
237
238 movlw d'200'
239 neg_sub_temp3:
240 movwf isr_sub_a+0
241 clrf isr_sub_a+1
242 movff isr_xC+0, isr_sub_b+0
243 movff isr_xC+1, isr_sub_b+1
244 call isr_sub16 ; isr_sub_c = isr_sub_a - isr_sub_b
245 btfsc neg_flag_isr ; below zero?
246 bsf neg_temp ; temperature negative!
247
248 movff isr_sub_c+0,temperature+0
249 movff isr_sub_c+1,temperature+1
250 return ; Fertig mit allem
251
252 195
253 get_pressure_start: 196 get_pressure_start:
254 rcall reset_MS5535A 197 rcall reset_MS5535A
255 movlw b'10100000' ;+3*high as start and 1+low as stop! 198 movlw b'10100000' ;+3*high as start and 1+low as stop!
256 get_pressure_start2: 199 get_pressure_start2: