moved multiplication function to "common" dir, added divide routine.
This commit is contained in:
@@ -5,9 +5,11 @@
|
|||||||
<extradist>
|
<extradist>
|
||||||
crc8.asm
|
crc8.asm
|
||||||
debug.asm
|
debug.asm
|
||||||
|
divide.asm
|
||||||
m_fixedbuffers.asm
|
m_fixedbuffers.asm
|
||||||
m_ringbuffer.asm
|
m_ringbuffer.asm
|
||||||
m_ringbuffer_y.asm
|
m_ringbuffer_y.asm
|
||||||
|
multiply.asm
|
||||||
ringbuffer.asm
|
ringbuffer.asm
|
||||||
ringbuffer_y.asm
|
ringbuffer_y.asm
|
||||||
shared.asm
|
shared.asm
|
||||||
|
|||||||
59
avr/common/divide.asm
Normal file
59
avr/common/divide.asm
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
; ***************************************************************************
|
||||||
|
; copyright : (C) 2025 by Martin Preuss
|
||||||
|
; email : martin@libchipcard.de
|
||||||
|
;
|
||||||
|
; ***************************************************************************
|
||||||
|
; * This file is part of the project "AqHome". *
|
||||||
|
; * Please see toplevel file COPYING of that project for license details. *
|
||||||
|
; ***************************************************************************
|
||||||
|
|
||||||
|
#ifndef COMMON_DIVIDE_H
|
||||||
|
#define COMMON_DIVIDE_H
|
||||||
|
|
||||||
|
|
||||||
|
; ---------------------------------------------------------------------------
|
||||||
|
; @routine Utils_Divu16_16_16
|
||||||
|
;
|
||||||
|
; Divides two unsigned 16 bit values resulting in one 16 bit value.
|
||||||
|
; This is a rather simple but reasonable fast routine working just like you would
|
||||||
|
; when doing divisions with pen and paper.
|
||||||
|
;
|
||||||
|
; R17:R16 = R21:R20 / R23:R22
|
||||||
|
; R19:R18 = R21:R20 mod R23:R22
|
||||||
|
|
||||||
|
; TODO: adapt for signed values
|
||||||
|
;
|
||||||
|
; @param R21:R20 16 bit value A
|
||||||
|
; @param R23:R22 16 bit value B
|
||||||
|
; @return R17:R16 16 bit result
|
||||||
|
; @return R19:R18 16 bit remainder
|
||||||
|
; @clobbers
|
||||||
|
|
||||||
|
Utils_Divu16_16_16:
|
||||||
|
mov r16, r20 ; r17:r16=result (intitially: dividend)
|
||||||
|
mov r17, r21
|
||||||
|
clr r18 ; r19:r18=remainder
|
||||||
|
clr r19
|
||||||
|
ldi r26, 16 ; 16 bits to divide
|
||||||
|
Utils_Divu16_16_16_loop:
|
||||||
|
lsl r16 ; shift 0 bit into result
|
||||||
|
rol r17
|
||||||
|
rol r18
|
||||||
|
rol r19
|
||||||
|
|
||||||
|
sub r18, r22 ; try to subtract divisor from value
|
||||||
|
sbc r19, r23
|
||||||
|
brcs Utils_Divu16_16_16_nofit ; jmp if dividend < divisor
|
||||||
|
ori r16, 1 ; otherwise set bit in result
|
||||||
|
rjmp Utils_Divu16_16_16_loop_end
|
||||||
|
Utils_Divu16_16_16_nofit:
|
||||||
|
add r18, r22 ; undo subtraction
|
||||||
|
adc r19, r23
|
||||||
|
; r17:r16=result
|
||||||
|
Utils_Divu16_16_16_loop_end:
|
||||||
|
dec r26
|
||||||
|
brne Utils_Divu16_16_16_loop
|
||||||
|
ret
|
||||||
|
; @end
|
||||||
|
|
||||||
|
|
||||||
69
avr/common/multiply.asm
Normal file
69
avr/common/multiply.asm
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
; ***************************************************************************
|
||||||
|
; copyright : (C) 2025 by Martin Preuss
|
||||||
|
; email : martin@libchipcard.de
|
||||||
|
;
|
||||||
|
; ***************************************************************************
|
||||||
|
; * This file is part of the project "AqHome". *
|
||||||
|
; * Please see toplevel file COPYING of that project for license details. *
|
||||||
|
; ***************************************************************************
|
||||||
|
|
||||||
|
#ifndef COMMON_MULTIPLY_H
|
||||||
|
#define COMMON_MULTIPLY_H
|
||||||
|
|
||||||
|
|
||||||
|
; ---------------------------------------------------------------------------
|
||||||
|
; @routine Utils_Mulu16x16_32
|
||||||
|
;
|
||||||
|
; Multiplies two unsigned 16 bit values resulting in one 32 bit value.
|
||||||
|
; This is a rather simple but reasonable fast routine working just like you would
|
||||||
|
; when doing multiplications with pen and paper.
|
||||||
|
;
|
||||||
|
; R19:R18:R17:R16 = R21:R20 * R23:R22
|
||||||
|
;
|
||||||
|
; TODO: adapt for signed values
|
||||||
|
;
|
||||||
|
; @param R21:R20 16 bit value A
|
||||||
|
; @param R23:R22 16 bit value B
|
||||||
|
; @return R19:R18:R17:R16 32 bit result
|
||||||
|
; @clobbers R16, R17, R18, R19, R20, R21, R22, R23, R24, R25, R26
|
||||||
|
|
||||||
|
Utils_Mulu16x16_32:
|
||||||
|
clr r19
|
||||||
|
clr r18
|
||||||
|
clr r17
|
||||||
|
clr r16
|
||||||
|
clr r25
|
||||||
|
clr r24
|
||||||
|
ldi r26, 16 ; 16 bit multiplicator
|
||||||
|
Utils_Mulu16x16_32_loop:
|
||||||
|
lsr r23
|
||||||
|
ror r22
|
||||||
|
brcc Utils_Mulu16x16_32_noadd ; current digit in B is 0, don't add shifted A to result
|
||||||
|
add r16, r22
|
||||||
|
adc r17, r23
|
||||||
|
adc r18, r24
|
||||||
|
adc r19, r25
|
||||||
|
; brcs Utils_Mulu16x16_32_overflow ; can't happen
|
||||||
|
Utils_Mulu16x16_32_noadd:
|
||||||
|
dec r26
|
||||||
|
breq Utils_Mulu16x16_32_done
|
||||||
|
lsl r20
|
||||||
|
rol r21
|
||||||
|
rol r24
|
||||||
|
rol r25
|
||||||
|
; brcs Utils_Mulu16x16_32_overflow ; can't happen
|
||||||
|
rjmp Utils_Mulu16x16_32_loop
|
||||||
|
Utils_Mulu16x16_32_done:
|
||||||
|
clc
|
||||||
|
ret
|
||||||
|
;Utils_Mulu16x16_32_overflow: ; never reached. Multiplying 2 16 bit values can't overflow 32 bit
|
||||||
|
; sec
|
||||||
|
; ret
|
||||||
|
; @end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif ; COMMON_MULTIPLY_H
|
||||||
|
|
||||||
@@ -82,6 +82,7 @@
|
|||||||
#ifdef MODULES_NETWORK
|
#ifdef MODULES_NETWORK
|
||||||
.include "modules/si7021/send.asm"
|
.include "modules/si7021/send.asm"
|
||||||
#endif
|
#endif
|
||||||
|
.include "common/multiply.asm"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef MODULES_OWI_MASTER
|
#ifdef MODULES_OWI_MASTER
|
||||||
|
|||||||
@@ -306,7 +306,7 @@ si7021CalcTemp:
|
|||||||
mov r21, r19
|
mov r21, r19
|
||||||
ldi r23, HIGH(17572)
|
ldi r23, HIGH(17572)
|
||||||
ldi r22, LOW(17572)
|
ldi r22, LOW(17572)
|
||||||
rcall si7021Mulu16x16_32 ; result is in R19:R18:R17:R16, we only use R19-R18 -> /65536
|
rcall Utils_Mulu16x16_32 ; result is in R19:R18:R17:R16, we only use R19-R18 -> /65536
|
||||||
ldi r16, LOW(4685)
|
ldi r16, LOW(4685)
|
||||||
ldi r17, HIGH(4685)
|
ldi r17, HIGH(4685)
|
||||||
sub r18, r16
|
sub r18, r16
|
||||||
@@ -332,7 +332,7 @@ si7021CalcHumidity:
|
|||||||
mov r21, r19
|
mov r21, r19
|
||||||
clr r23
|
clr r23
|
||||||
ldi r22, 125
|
ldi r22, 125
|
||||||
rcall si7021Mulu16x16_32 ; result is in R19:R18:R17:R16, we only use R19-R18 -> /65536
|
rcall Utils_Mulu16x16_32 ; result is in R19:R18:R17:R16, we only use R19-R18 -> /65536
|
||||||
ldi r16, 6
|
ldi r16, 6
|
||||||
clr r17
|
clr r17
|
||||||
sub r18, r16
|
sub r18, r16
|
||||||
@@ -341,57 +341,6 @@ si7021CalcHumidity:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
; ---------------------------------------------------------------------------
|
|
||||||
; si7021Mulu16x16_32
|
|
||||||
;
|
|
||||||
; Multiplies two unsigned 16 bit values resulting in one 32 bit value.
|
|
||||||
; This is a rather simple but reasonable fast routine working just like you would
|
|
||||||
; when doing multiplications with pen and paper.
|
|
||||||
; TODO: adapt for signed values
|
|
||||||
;
|
|
||||||
; IN:
|
|
||||||
; - R21:R20: 16 bit value A
|
|
||||||
; - R23:R22: 16 bit value B
|
|
||||||
; OUT:
|
|
||||||
; - R19:R18:R17:R16: 32 bit result
|
|
||||||
; USED: R16, R17, R18, R19, R20, R21, R22, R23, R24, R25, R26
|
|
||||||
; R19:R18:R17:R16 = R21:R20 * R23:R22
|
|
||||||
; R19:R18:R17:R16 = R25:R24:R21:R20 * R23:R22
|
|
||||||
si7021Mulu16x16_32:
|
|
||||||
clr r19
|
|
||||||
clr r18
|
|
||||||
clr r17
|
|
||||||
clr r16
|
|
||||||
clr r25
|
|
||||||
clr r24
|
|
||||||
ldi r26, 16 ; 16 bit multiplicator
|
|
||||||
si7021Muls16x16_32_loop:
|
|
||||||
lsr r23
|
|
||||||
ror r22
|
|
||||||
brcc si7021Muls16x16_32_noadd ; current digit in B is 0, don't add shifted A to result
|
|
||||||
add r16, r22
|
|
||||||
adc r17, r23
|
|
||||||
adc r18, r24
|
|
||||||
adc r19, r25
|
|
||||||
; brcs si7021Muls16x16_32_overflow ; can't happen
|
|
||||||
si7021Muls16x16_32_noadd:
|
|
||||||
dec r26
|
|
||||||
breq si7021Muls16x16_32_done
|
|
||||||
lsl r20
|
|
||||||
rol r21
|
|
||||||
rol r24
|
|
||||||
rol r25
|
|
||||||
; brcs si7021Muls16x16_32_overflow ; can't happen
|
|
||||||
rjmp si7021Muls16x16_32_loop
|
|
||||||
si7021Muls16x16_32_done:
|
|
||||||
clc
|
|
||||||
ret
|
|
||||||
;si7021Muls16x16_32_overflow: ; never reached. Multiplying 2 16 bit values can't overflow 32 bit
|
|
||||||
; sec
|
|
||||||
; ret
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
; ---------------------------------------------------------------------------
|
; ---------------------------------------------------------------------------
|
||||||
; @routine SI7021_GetValue @global
|
; @routine SI7021_GetValue @global
|
||||||
;
|
;
|
||||||
|
|||||||
Reference in New Issue
Block a user