; ***************************************************************************
; copyright   : (C) 2026 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 AQH_AVR_MODULES_TRIGGERACTOR_RECV_ASM
#define AQH_AVR_MODULES_TRIGGERACTOR_RECV_ASM




; ---------------------------------------------------------------------------
; @routine TCA_HandleMsg @global
;
; @param  X       pointer to msg received
; @param  Y       pointer to data in RAM
; @param  R17     value id
; @param  R19:R18 value
; @param  R22     src addr
; @clobbers any, !X, !Y, !Z

TCA_HandleMsg:
  push xl
    push xh
      mov xl, yl
      mov xh, yh
      adiw xh:xl, TCA_RAM_OFFS_GUARD_SOURCE
      rcall tcaCheckGuardSource              ; enable or disable actor, if matching msg
      adiw xh:xl, TCA_SOURCE_SIZE
      rcall tcaCheckTriggerSource            ; trigger, if matching msg
      adiw xh:xl, TCA_SOURCE_SIZE
      rcall tcaCheckTriggerSource            ; trigger, if matching msg
    pop xh
  pop xl
TCA_HandleMsg_ret:
  clc
  ret
; @end



; ---------------------------------------------------------------------------
; @routine tcaCheckTriggerSource
;
; @param  Z pointer to data in FLASH (byte address for lpm!)
; @param  Y pointer to data in RAM
; @param  X pointer to TCA_SOURCE object
; @param  R17     value id
; @param  R19:R18 value
; @param  R22     src addr
; @clobbers R16, R24, R25, (any), !Z, !Y

tcaCheckTriggerSource:
  rcall tcaCheckSourceAndValue    ; (r16)
  brcc tcaCheckTriggerSource_ret
  ; we have a value

  rcall tcaCheckValue             ; (r24, r25)
  brcc tcaCheckTriggerSource_ret

  ldd r16, Y+HTIM_RAM_OFFS_FLAGS
  sbr r16, (1<<TCA_FLAGBITS_NEED_TRIGGER)
  std Y+HTIM_RAM_OFFS_FLAGS, r16

tcaCheckTriggerSource_ret:
  ret
; @end



; ---------------------------------------------------------------------------
; @routine tcaCheckGuardSource
;
; @param  X pointer to TCA_SOURCE object
; @param  R17     value id
; @param  R19:R18 value
; @param  R22     src addr
; @clobbers R16, R24, R25, (any), !Z, !Y

tcaCheckGuardSource:
  rcall tcaCheckSourceAndValue    ; (r16)
  brcc tcaCheckGuardSource_ret
  ; we have a value
  rcall tcaCheckValue
  ldd r16, Y+HTIM_RAM_OFFS_FLAGS
  brcc tcaCheckGuardSource_noMatch
  sbr r16, (1<<TCA_FLAGBITS_NEED_ENABLE)
  rjmp tcaCheckGuardSource_done
tcaCheckGuardSource_noMatch:
  sbr r16, (1<<TCA_FLAGBITS_NEED_DISABLE)
tcaCheckGuardSource_done:
  std Y+HTIM_RAM_OFFS_FLAGS, r16

tcaCheckGuardSource_ret:
  ret
; @end



; ---------------------------------------------------------------------------
; @routine tcaCheckSourceAndValue
;
; @param  X       pointer to TCA_SOURCE object
; @param  R17     value id
; @param  R22     src addr
; @clobbers r16

tcaCheckSourceAndValue:
  ld r16, X
  cp r16, r22                        ; compare src addr
  brne tcaCheckSourceAndValue_clcRet
  adiw xh:xl, TCA_SOURCE_OFFS_VALUEID
  ld r16, X
  sbiw xh:xl, TCA_SOURCE_OFFS_VALUEID
  cp r16, r17                        ; compare value id
  brne tcaCheckSourceAndValue_clcRet
  sec
  rjmp tcaCheckSourceAndValue_ret    ; matches
tcaCheckSourceAndValue_clcRet:
  clc
tcaCheckSourceAndValue_ret:
  ret
; @end



; ---------------------------------------------------------------------------
; @routine tcaCheckValue
;
; @param  Z       pointer to data in FLASH (byte address for lpm!)
; @param  Y       pointer to TCA_SOURCE object
; @param  R19:R18 value
; @clobbers r24, r25

tcaCheckValue:
  adiw xh:xl, TCA_SOURCE_OFFS_LOWLIM_LO
  ld r24, X+
  ld r25, X
  sbiw xh:xl, (TCA_SOURCE_OFFS_LOWLIM_LO+1)
  cp r18, r24
  cpc r19, r25
  brcs tcaCheckValue_clcRet
  adiw xh:xl, TCA_SOURCE_OFFS_HIGHLIM_LO
  ld r24, X+
  ld r25, X
  sbiw xh:xl, (TCA_SOURCE_OFFS_HIGHLIM_LO+1)
  cp r24, r18
  cpc r25, r19
  brcs tcaCheckValue_clcRet
  sec
  rjmp tcaCheckValue_ret
tcaCheckValue_clcRet:
  clc
tcaCheckValue_ret:
  ret
; @end



; ---------------------------------------------------------------------------
; @routine TCA_SetValue_GuardSrc

; @param  Y       pointer to TCA data in RAM

TCA_SetValue_GuardSrc:                   ; value is in R18-R21 (R16, R17, X)
  std Y+(TCA_RAM_OFFS_GUARD_SOURCE+TCA_SOURCE_OFFS_ADDR), r18
  std Y+(TCA_RAM_OFFS_GUARD_SOURCE+TCA_SOURCE_OFFS_VALUEID), r19
  rjmp TCA_SetValueACK
; @end



; ---------------------------------------------------------------------------
; @routine TCA_SetValue_GuardLimits

; @param  Y       pointer to TCA data in RAM

TCA_SetValue_GuardLimits:                   ; value is in R18-R21 (R16, R17, X)
  std Y+(TCA_RAM_OFFS_GUARD_SOURCE+TCA_SOURCE_OFFS_LOWLIM_LO), r18
  std Y+(TCA_RAM_OFFS_GUARD_SOURCE+TCA_SOURCE_OFFS_LOWLIM_HI), r19
  std Y+(TCA_RAM_OFFS_GUARD_SOURCE+TCA_SOURCE_OFFS_HIGHLIM_LO), r20
  std Y+(TCA_RAM_OFFS_GUARD_SOURCE+TCA_SOURCE_OFFS_HIGHLIM_HI), r21
  rjmp TCA_SetValueACK
; @end



; ---------------------------------------------------------------------------
; @routine TCA_SetValue_Trigger1Src

; @param  Y       pointer to TCA data in RAM

TCA_SetValue_Trigger1Src:                   ; value is in R18-R21 (R16, R17, X)
  std Y+(TCA_RAM_OFFS_TRIGGER_SOURCE1+TCA_SOURCE_OFFS_ADDR), r18
  std Y+(TCA_RAM_OFFS_TRIGGER_SOURCE1+TCA_SOURCE_OFFS_VALUEID), r19
  rjmp TCA_SetValueACK
; @end



; ---------------------------------------------------------------------------
; @routine TCA_SetValue_Trigger1Limits

; @param  Y       pointer to TCA data in RAM

TCA_SetValue_Trigger1Limits:                   ; value is in R18-R21 (R16, R17, X)
  std Y+(TCA_RAM_OFFS_TRIGGER_SOURCE1+TCA_SOURCE_OFFS_LOWLIM_LO), r18
  std Y+(TCA_RAM_OFFS_TRIGGER_SOURCE1+TCA_SOURCE_OFFS_LOWLIM_HI), r19
  std Y+(TCA_RAM_OFFS_TRIGGER_SOURCE1+TCA_SOURCE_OFFS_HIGHLIM_LO), r20
  std Y+(TCA_RAM_OFFS_TRIGGER_SOURCE1+TCA_SOURCE_OFFS_HIGHLIM_HI), r21
  rjmp TCA_SetValueACK
; @end



; ---------------------------------------------------------------------------
; @routine TCA_SetValue_Trigger2Src

; @param  Y       pointer to TCA data in RAM

TCA_SetValue_Trigger2Src:                   ; value is in R18-R21 (R16, R17, X)
  std Y+(TCA_RAM_OFFS_TRIGGER_SOURCE2+TCA_SOURCE_OFFS_ADDR), r18
  std Y+(TCA_RAM_OFFS_TRIGGER_SOURCE2+TCA_SOURCE_OFFS_VALUEID), r19
  rjmp TCA_SetValueACK
; @end



; ---------------------------------------------------------------------------
; @routine TCA_SetValue_Trigger2Limits

; @param  Y       pointer to TCA data in RAM

TCA_SetValue_Trigger2Limits:                   ; value is in R18-R21 (R16, R17, X)
  std Y+(TCA_RAM_OFFS_TRIGGER_SOURCE2+TCA_SOURCE_OFFS_LOWLIM_LO), r18
  std Y+(TCA_RAM_OFFS_TRIGGER_SOURCE2+TCA_SOURCE_OFFS_LOWLIM_HI), r19
  std Y+(TCA_RAM_OFFS_TRIGGER_SOURCE2+TCA_SOURCE_OFFS_HIGHLIM_LO), r20
  std Y+(TCA_RAM_OFFS_TRIGGER_SOURCE2+TCA_SOURCE_OFFS_HIGHLIM_HI), r21
  rjmp TCA_SetValueACK
; @end



; ---------------------------------------------------------------------------
; @routine TCA_SetValue_HoldTime

; @param  Y       pointer to TCA data in RAM

TCA_SetValue_HoldTime:
  std Y+HTIM_RAM_OFFS_RELOAD_LO, r18
  std Y+HTIM_RAM_OFFS_RELOAD_HI, r19
  rjmp TCA_SetValueACK
; @end



; ---------------------------------------------------------------------------
; @routine TCA_SetValue_Mode

; @param  Y       pointer to TCA data in RAM

TCA_SetValue_Mode:
  std Y+HTIM_RAM_OFFS_MODE, r18
  rjmp TCA_SetValueACK
; @end



; ---------------------------------------------------------------------------
; @routine TCA_SetValueACK

TCA_SetValueACK:
  ldd r16, Y+HTIM_RAM_OFFS_FLAGS
  sbr r16, (1<<TCA_FLAGBIT_UPDATED)
  std Y+HTIM_RAM_OFFS_FLAGS, r16

  ldi r23, NETMSG_CMD_VALUE_SET_ACK
  sec
  ret
; @end






#endif

