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

Use signed arithmetic for pressure/temperature compensation.
author JeanDo
date Tue, 18 Jan 2011 23:57:33 +0100
parents 64109f6fb3d1
children 06299199dfb9
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 ; Math routines 18 ; Math routines
19 ; written by: Matthias Heinrichs, info@heinrichsweikamp.com 19 ; history:
20 ; written: 10/30/05 20 ; 2005-10-30: Written by Matthias Heinrichs, info@heinrichsweikamp.com
21 ; last updated: 06/21/07 21 ; 2007-06-21: MH last updated
22 ; 2011-01-19: Clean up of isr variante.
22 ; known bugs: 23 ; known bugs:
23 ; ToDo: clean up! 24 ; ToDo: clean up!
24 25
25 26
26 convert_time: ; converts hi:lo in minutes to hours (hi) and minutes (lo) 27 convert_time: ; converts hi:lo in minutes to hours (hi) and minutes (lo)
40 rrcf divA+1 41 rrcf divA+1
41 rrcf divA 42 rrcf divA
42 decfsz divB 43 decfsz divB
43 bra div16 44 bra div16
44 return 45 return
45
46 div32:
47 ; xC=xC(32Bit)/2^divB (divB: 8Bit only!)
48 bcf STATUS,C
49 rrcf xC+3
50 rrcf xC+2
51 rrcf xC+1
52 rrcf xC+0
53 decfsz divB
54 bra div32
55 return
56
57 invert_xC:
58 movf xC+1, w ; inverses xC+0:xC+1
59 sublw 0xFF
60 movwf xC+1
61 movf xC+0, w
62 bcf STATUS,C
63 sublw 0xFF
64 movwf xC+0
65 return
66
67 46
68 sub16: 47 sub16:
69 ; sub_c = sub_a - sub_b 48 ; sub_c = sub_a - sub_b
70 bcf neg_flag 49 bcf neg_flag
71 movf sub_b+0, W ; Get Value to be subtracted 50 movf sub_b+0, W ; Get Value to be subtracted
229 rlcf xC+3,F 208 rlcf xC+3,F
230 decfsz divB,F ; loop until all bits checked 209 decfsz divB,F ; loop until all bits checked
231 goto div32x16_2 210 goto div32x16_2
232 return 211 return
233 212
234 213 ;=============================================================================
235 isr_div16: 214 ; u16 * u16 --> 32bit multiply (xA * xB --> xC)
236 ; divA=divA/2^divB (divB: 8Bit only!) 215 ; Used in interupt service routines, to compute temperature and pressure.
237 bcf STATUS,C 216 ;
238 rrcf isr_divA+1
239 rrcf isr_divA
240 decfsz isr_divB
241 bra isr_div16
242 return
243
244 isr_div32:
245 ; xC=xC(32Bit)/2^divB (divB: 8Bit only!)
246 bcf STATUS,C
247 rrcf isr_xC+3
248 rrcf isr_xC+2
249 rrcf isr_xC+1
250 rrcf isr_xC+0
251 decfsz isr_divB
252 bra isr_div32
253 return
254
255 isr_invert_xC:
256 movf isr_xC+1, w ; inverses xC+0:xC+1
257 sublw 0xFF
258 movwf isr_xC+1
259 movf isr_xC+0, w
260 bcf STATUS,C
261 sublw 0xFF
262 movwf isr_xC+0
263 return
264
265
266 isr_sub16:
267 ; sub_c = sub_a - sub_b
268 bcf neg_flag_isr
269 movf isr_sub_b+0, w ; Get Value to be subtracted
270 subwf isr_sub_a+0, w ; Do the High Byte
271 movwf isr_sub_c+0
272 movf isr_sub_b+1, w ; Get the Value to be Subbed
273 subwfb isr_sub_a+1, w
274 movwf isr_sub_c+1
275 btfsc STATUS,C
276 return ; result positve
277 ; sub_c = sub_a - sub_b
278 bsf neg_flag_isr ; result negative
279 movff isr_sub_c+0,isr_sub_b+0
280 movff isr_sub_c+1,isr_sub_b+1
281 setf isr_sub_a
282 setf isr_sub_a+1
283 movf isr_sub_b+0, w ; Get Value to be subtracted
284 subwf isr_sub_a+0, w ; Do the High Byte
285 movwf isr_sub_c+0
286 movf isr_sub_b+1, w ; Get the Value to be Subbed
287 subwfb isr_sub_a+1, w
288 movwf isr_sub_c+1
289 return
290
291
292 isr_mult16x16: 217 isr_mult16x16:
293 ;xA*xB=xC
294 clrf isr_xC+2 ; Clear the High-Order Bits 218 clrf isr_xC+2 ; Clear the High-Order Bits
295 clrf isr_xC+3 219 clrf isr_xC+3
296 movf isr_xA, w ; Do the "L" Multiplication first 220 movf isr_xA, w ; Do the "L" Multiplication first
297 mulwf isr_xB 221 mulwf isr_xB
298 movf PRODL, w ; Save result 222 movf PRODL, w ; Save result
299 movwf isr_xC 223 movwf isr_xC+0
300 movf PRODH, w 224 movf PRODH, w
301 movwf isr_xC+1 225 movwf isr_xC+1
302 movf isr_xA, w ; Do the "I" Multiplication 226 movf isr_xA+0, w ; Do the "I" Multiplication
303 mulwf isr_xB+1 227 mulwf isr_xB+1
304 movf PRODL, w ; Save the Most Significant Byte First 228 movf PRODL, w ; Save the Most Significant Byte First
305 addwf isr_xC+1, f 229 addwf isr_xC+1, f
306 movf PRODH, w 230 movf PRODH, w
307 addwfc isr_xC+2, f ; Add to the Last Result 231 addwfc isr_xC+2, f ; Add to the Last Result
318 movf PRODL, w 242 movf PRODL, w
319 addwf isr_xC+2, f 243 addwf isr_xC+2, f
320 movf PRODH, w 244 movf PRODH, w
321 addwfc isr_xC+3, f 245 addwfc isr_xC+3, f
322 return 246 return
323 247
248 ;=============================================================================
249 ; 24bit shift, repeted WREG times.
250 ; Because we shift less than 8bits, and keep only C[2:1], we don't care what
251 ; bit is inserted...
252 ;
253 isr_shift_C31:
254 rrcf isr_xC+3,F ; Shift the three bytes...
255 rrcf isr_xC+2,F
256 rrcf isr_xC+1,F
257 decfsz WREG
258 bra isr_shift_C31
259 return
260
261 ;=============================================================================
262 ; s16 * s16 --> 32bit multiply (xA * xB --> xC)
263 ; Signed multiplication.
264 ; Code from... the Pic18F documentation ;-)
265 isr_unsigned_mult16x16:
266 MOVF isr_xA+0, W ; Lowest is simply a[0] * b[0]
267 MULWF isr_xB+0
268 MOVFF PRODL, isr_xC+0
269 MOVFF PRODH, isr_xC+1
270 ;
271 MOVF isr_xA+1, W ; And highest a[1] * b[1]
272 MULWF isr_xB+1
273 MOVFF PRODL, isr_xC+2
274 MOVFF PRODH, isr_xC+3
275 ;
276 MOVF isr_xA+0, W ; Intermediates do propagate:
277 MULWF isr_xB+1
278 MOVF PRODL, W
279 ADDWF isr_xC+1, F ; Add cross products
280 MOVF PRODH, W
281 ADDWFC isr_xC+2, F ; with propagated carry
282 CLRF WREG
283 ADDWFC isr_xC+3, F ; on the three bytes.
284 ;
285 MOVF isr_xA+1, W ; And the second one, similarly.
286 MULWF isr_xB+0
287 MOVF PRODL, W
288 ADDWF isr_xC+1, F ; Add cross products
289 MOVF PRODH, W
290 ADDWFC isr_xC+2, F
291 CLRF WREG
292 ADDWFC isr_xC+3, F
293 return
294
295 isr_signed_mult16x16:
296 rcall isr_unsigned_mult16x16
297
298 ; Manage sign extension of operand B
299 BTFSS isr_xB+1,7 ; Is B negatif ?
300 BRA isr_signed_mult_checkA ; No: check ARG1
301 MOVF isr_xA+0, W ; Yes: add -65536 * A
302 SUBWF isr_xC+2, F
303 MOVF isr_xA+1, W
304 SUBWFB isr_xC+3, F
305 ; And of operand A
306 isr_signed_mult_checkA
307 BTFSS isr_xA+1, 7 ; Is A negatif ?
308 RETURN ; No: done
309 MOVF isr_xB+0, W
310 SUBWF isr_xC+2, F
311 MOVF isr_xB+1, W
312 SUBWFB isr_xC+3, F
313 RETURN