Files
aqhomecontrol/avr/modules/f_stabilize/main.asm
2025-04-21 00:32:30 +02:00

195 lines
6.5 KiB
NASM

; ***************************************************************************
; 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. *
; ***************************************************************************
; ***************************************************************************
; defines
.equ FILTER_STABILIZE_OFFS_STATUSBYTE = 0
.equ FILTER_STABILIZE_OFFS_TIMER = 1
.equ FILTER_STABILIZE_OFFS_COUNTER = 2
.equ FILTER_STABILIZE_OFFS_STABLECOUNTVAL = 3
.equ FILTER_STABILIZE_DATA_SIZE = 4
.equ FILTER_STABILIZE_STATUS_LASTVALUE_BIT = 0
.equ FILTER_STABILIZE_STATUS_STABLEVALUE_BIT = 1
.equ FILTER_STABILIZE_STATUS_REPORT0_BIT = 4
.equ FILTER_STABILIZE_STATUS_REPORT1_BIT = 5
.equ FILTER_STABILIZE_STATUS_REPEAT0_BIT = 6
.equ FILTER_STABILIZE_STATUS_REPEAT1_BIT = 7
.equ FILTER_STABILIZE_REPORTTIME1 = 1 ; report after 100ms
.equ FILTER_STABILIZE_REPORTTIME2 = 11 ; report after 1100ms
.equ FILTER_STABILIZE_REPORTTIME3 = 22 ; report after 2200ms
.equ FILTER_STABILIZE_REPEATTIME = 200 ; 20s
; ***************************************************************************
; code
.cseg
; ---------------------------------------------------------------------------
; @routine FilterStabilize_Init @global
;
; @param Y pointer to filter data
FilterStabilize_Init:
clr r16
std Y+FILTER_STABILIZE_OFFS_COUNTER, r16
std Y+FILTER_STABILIZE_OFFS_STATUSBYTE, r16
dec r16
std Y+FILTER_STABILIZE_OFFS_TIMER, r16 ; hold timer
ret
; @end
; ---------------------------------------------------------------------------
; @routine FilterStabilize_Fini @global
;
; @param Y pointer to filter data
FilterStabilize_Fini:
; nothing to do
ret
; @end
; ---------------------------------------------------------------------------
; @routine FilterStabilize_GetValue @global
;
; Values are reduced to 1 bit (i.e. either "0" or "1").
;
; @param Y pointer to filter data
; @return R19:R18 value
FilterStabilize_GetValue:
ldd r18, Y+FILTER_STABILIZE_OFFS_STATUSBYTE
lsr r18, FILTER_STABILIZE_STATUS_STABLEVALUE_BIT
andi r18, 1
clr r19
ret
; @end
; ---------------------------------------------------------------------------
; @routine FilterStabilize_SetValue @global
;
; The stored value is reduced to 1 bit (i.e. either "0" or "1").
;
; @param Y pointer to filter data
; @param R19:R18 value
; @clobbers r16, r17
FilterStabilize_SetValue:
mov r16, r18
or r16, r19
breq FilterStabilize_SetValue_set
ldi r16, (1<<FILTER_STABILIZE_STATUS_LASTVALUE_BIT)
FilterStabilize_SetValue_set:
ldd r17, Y+FILTER_STABILIZE_OFFS_STATUSBYTE
eor r17, r16
andi r17, FILTER_STABILIZE_STATUS_LASTVALUE_BIT
breq FilterStabilize_SetValue_noChange ; no change
; changed
ldd r16, Y+FILTER_STABILIZE_OFFS_STATUSBYTE
eor r16, r17 ; change lastValue bit in status byte
std Y+FILTER_STABILIZE_OFFS_STATUSBYTE, r16
clr r16 ; reset counter
std Y+FILTER_STABILIZE_OFFS_COUNTER, r16
dec r16
std Y+FILTER_STABILIZE_OFFS_TIMER, r16 ; timer=255 (hold timer)
rjmp FilterStabilize_SetValue_end
FilterStabilize_SetValue_noChange:
ldd r16, Y+FILTER_STABILIZE_OFFS_COUNTER
inc r16
breq FilterStabilize_SetValue_end ; stop counter at 255
std Y+FILTER_STABILIZE_OFFS_COUNTER, r16
ldd r17, Y+FILTER_STABILIZE_OFFS_STABLECOUNTVAL
cpi r16, r17
brne FilterStabilize_SetValue_end
; copy last value to stable value
ldd r16, Y+FILTER_STABILIZE_OFFS_STATUSBYTE
mov r17, r16
lsl r17, (FILTER_STABILIZE_STATUS_STABLEVALUE_BIT-FILTER_STABILIZE_STATUS_LASTVALUE_BIT) ; r17=new value
andi r17, (1<<FILTER_STABILIZE_STATUS_STABLEVALUE_BIT) ; isolate new stable bit
andi r16, ~(1<<FILTER_STABILIZE_STATUS_STABLEVALUE_BIT) ; clear stable bit
or r16, r17 ; or-in new stable bit
std Y+FILTER_STABILIZE_OFFS_STATUSBYTE, r16
; start timer
clr r16
std Y+FILTER_STABILIZE_OFFS_TIMER, r16
FilterStabilize_SetValue_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine FilterStabilize_Every100ms @global
;
; @return CFLAG set if value should be reported, cleared otherwise
; @param Y pointer to filter data
; @clobbers r16, r18, r19
FilterStabilize_Every100ms:
ldd r16, Y+FILTER_STABILIZE_OFFS_TIMER
inc r16
breq FilterStabilize_Every100ms_clcRet ; hold counter at 255
std Y+FILTER_STABILIZE_OFFS_TIMER, r16
cpi r16, FILTER_STABILIZE_REPEATTIME
breq FilterStabilize_Every100ms_repeat
cpi r16, FILTER_STABILIZE_REPORTTIME1
breq FilterStabilize_Every100ms_report
cpi r16, FILTER_STABILIZE_REPORTTIME2
breq FilterStabilize_Every100ms_report
cpi r16, FILTER_STABILIZE_REPORTTIME3
breq FilterStabilize_Every100ms_report
rjmp FilterStabilize_Every100ms_clcRet
FilterStabilize_Every100ms_report:
ldd r18, Y+FILTER_STABILIZE_OFFS_STATUSBYTE
sbrc r18, FILTER_STABILIZE_STATUS_STABLEVALUE_BIT
rjmp FilterStabilize_Every100ms_report1
FilterStabilize_Every100ms_report0: ; value is 0
sbrs r18, FILTER_STABILIZE_STATUS_REPORT0_BIT
rjmp FilterStabilize_Every100ms_clcRet ; REPORT0 not set
rjmp FilterStabilize_Every100ms_secRet
FilterStabilize_Every100ms_report1: ; value is 1
sbrs r18, FILTER_STABILIZE_STATUS_REPORT1_BIT
rjmp FilterStabilize_Every100ms_clcRet ; REPORT1 not set
rjmp FilterStabilize_Every100ms_secRet
FilterStabilize_Every100ms_repeat:
ldd r18, Y+FILTER_STABILIZE_OFFS_STATUSBYTE
sbrc r18, FILTER_STABILIZE_STATUS_STABLEVALUE_BIT
rjmp FilterStabilize_Every100ms_repeat1
FilterStabilize_Every100ms_repeat0: ; value is 0
sbrs r18, FILTER_STABILIZE_STATUS_REPEAT0_BIT
rjmp FilterStabilize_Every100ms_clcRet ; REPEAT0 not set
rjmp FilterStabilize_Every100ms_resetTimer
FilterStabilize_Every100ms_repeat1: ; value is 1
sbrs r18, FILTER_STABILIZE_STATUS_REPEAT1_BIT
rjmp FilterStabilize_Every100ms_clcRet ; REPEAT1 not set
FilterStabilize_Every100ms_resetTimer:
clr r16
std Y+FILTER_STABILIZE_OFFS_TIMER, r16
FilterStabilize_Every100ms_clcRet:
clc
ret
FilterStabilize_Every100ms_secRet:
sec
ret
; @end