Files
aqhomecontrol/avr/modules/valsched/main.asm
Martin Preuss ea2162e8f4 added filter.
2025-04-21 00:44:04 +02:00

205 lines
5.4 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 VALSCHED_OFFS_TIMER = 0
.equ VALSCHED_OFFS_FLAGS = 1
.equ VALSCHED_DATA_SIZE = 2
.equ VALSCHED_FLAGS_VALUE_BIT = 0
.equ VALSCHED_FLAGS_TOSEND_BIT = 1
.equ VALSCHED_FLAGS_REPEAT_BIT = 2
.equ VALSCHED_FLAGS_REPEAT0_BIT = 6
.equ VALSCHED_FLAGS_REPEAT1_BIT = 7
.equ VALSCHED_REPORTTIME1 = 1 ; report after 100ms
.equ VALSCHED_REPORTTIME2 = 11 ; report after 1100ms
.equ VALSCHED_REPORTTIME3 = 22 ; report after 2200ms
.equ VALSCHED_INTERVAL = 200 ; 20s interval
; ***************************************************************************
; code
.cseg
; ---------------------------------------------------------------------------
; @routine ValueScheduler_Init @global
;
; @param Y pointer to instance data
ValueScheduler_Init:
clr r16
std Y+VALSCHED_OFFS_FLAGS, r16
dec r16
std Y+VALSCHED_OFFS_TIMER, r16 ; init timer in hold state
ret
; @end
; ---------------------------------------------------------------------------
; @routine ValueScheduler_Fini @global
;
; @param Y pointer to instance data
ValueScheduler_Fini:
ldi r16, 0xff
std Y+VALSCHED_OFFS_TIMER, r16
ret
; @end
; ---------------------------------------------------------------------------
; @routine ValueScheduler_Every100ms @global
;
; @param Y pointer to instance data
; @clobbers r16, r17
ValueScheduler_Every100ms:
ldd r16, Y+VALSCHED_OFFS_TIMER
inc r16
breq ValueScheduler_Every100ms_end ; timer on hold
std Y+VALSCHED_OFFS_TIMER, r16
cpi r16, VALSCHED_REPORTTIME1
breq ValueScheduler_Every100ms_setSendFlag
cpi r16, VALSCHED_REPORTTIME2
breq ValueScheduler_Every100ms_setSendFlag
cpi r16, VALSCHED_REPORTTIME3
breq ValueScheduler_Every100ms_setSendFlag
cpi r16, VALSCHED_INTERVAL
brne ValueScheduler_Every100ms_end
; interval finished, check for repeat
ldd r17, Y+VALSCHED_OFFS_FLAGS
clr r16
sbrs r16, VALSCHED_FLAGS_REPEAT_BIT
dec r17 ; bit not set, stop counter after this interval
std Y+VALSCHED_OFFS_TIMER, r17
rjmp ValueScheduler_Every100ms_end
ValueScheduler_Every100ms_setSendFlag:
ldd r16, Y+VALSCHED_OFFS_FLAGS
ori r16, (1<<VALSCHED_FLAGS_TOSEND_BIT)
std Y+VALSCHED_OFFS_FLAGS, r16
ValueScheduler_Every100ms_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine ValueScheduler_CheckSend @global
;
; Check whether the value should be sent.
;
; @param Y pointer to instance data
; @return CFLAG set if value should be sent, cleared otherwise
; @clobbers r16
ValueScheduler_CheckSend:
ldd r16, Y+VALSCHED_OFFS_FLAGS
andi r16, (1<<VALSCHED_FLAGS_TOSEND_BIT)
breq ValueScheduler_CheckSend_end
sec
ValueScheduler_CheckSend_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine ValueScheduler_MarkSent @global
;
; Tells this module that a value message has been sent.
;
; @param Y pointer to instance data
; @clobbers r16
ValueScheduler_MarkSent:
ldd r16, Y+VALSCHED_OFFS_FLAGS
andi r16, ~(1<<VALSCHED_FLAGS_TOSEND_BIT)
std Y+VALSCHED_OFFS_FLAGS, r16
ret
; @end
; ---------------------------------------------------------------------------
; @routine ValueScheduler_SetValue @global
;
; Reduces value to 1 bit.
;
; @param Y pointer to instance data
; @param r16 value
; @clobbers r17
ValueScheduler_SetValue:
mov r17, r16
rcall ValueScheduler_GetValue
cp r17, r16
breq ValueScheduler_SetValue_end
; value changed
mov r16, r17
tst r16
breq ValueScheduler_SetValue_set0
; set 1
ldd r17, Y+VALSCHED_OFFS_FLAGS
ori r17, (1<<VALSCHED_FLAGS_REPEAT_BIT) ; set repeat bit
sbrs r17, VALSCHED_FLAGS_REPEAT1_BIT
andi r17, ~(1<<VALSCHED_FLAGS_REPEAT_BIT) ; clear repeat bit if not wanted for "1"
ori r17, (1<<VALSCHED_FLAGS_VALUE_BIT) ; 1: set value bit and repeat bit
std Y+VALSCHED_OFFS_FLAGS, r17 ; store new byte
rjmp ValueScheduler_SetValue_resetTimer
ValueScheduler_SetValue_set0:
ldd r17, Y+VALSCHED_OFFS_FLAGS
ori r17, (1<<VALSCHED_FLAGS_REPEAT_BIT)
sbrs r17, VALSCHED_FLAGS_REPEAT0_BIT
andi r17, ~(1<<VALSCHED_FLAGS_REPEAT_BIT) ; clear repeat bit if not wanted for "0"
andi r17, ~(1<<VALSCHED_FLAGS_VALUE_BIT) ; 0: clear value bit and repeat bit
std Y+VALSCHED_OFFS_FLAGS, r17 ; store new byte
ValueScheduler_SetValue_resetTimer:
clr r17 ; reset timer
std Y+VALSCHED_OFFS_TIMER, r17
ValueScheduler_SetValue_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine ValueScheduler_GetValue @global
;
; Return current value (reduced to 1 bit).
;
; @param Y pointer to instance data
; @return R16 value (reduced to 1 bit!)
; @clobbers none
ValueScheduler_GetValue:
ldd r16, Y+VALSCHED_OFFS_FLAGS
lsr r16, VALSCHED_FLAGS_VALUE_BIT
andi r16, 1
ret
; @end