; ***************************************************************************
; 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.   *
; ***************************************************************************


; ***************************************************************************
; code

.cseg



; ---------------------------------------------------------------------------
; @routine AppMotionLight_OnPacketReceived @global
;
; @clobbers any, -X

AppMotionLight_OnPacketReceived:
  adiw xh:xl, 2                                   ; command
  ld r16, X
  sbiw xh:xl, 2
  cpi r16, NETMSG_CMD_VALUE_SET
  breq AppMotionLight_OnPacketReceived_set
  cpi r16, NETMSG_CMD_VALUE_REPORT
  breq AppMotionLight_OnPacketReceived_report
  clc                                                          ; unexpected msg
  ret
; "report value" message
AppMotionLight_OnPacketReceived_report:
  rcall NETMSG_ValueRead                                       ; (none)
  rcall appMotionLightIsBrightnessSource                       ; (R16)
  brcs AppMotionLight_OnPacketReceived_isBrightness
  mov r16, r18
  or r16, r19
  breq AppMotionLight_OnPacketReceived_clcRet                  ; zero value, ignore
  rcall appMotionLightHasSource                                ; (r16, r24, Y)
  brcs AppMotionLight_OnPacketReceived_turnOn
  ret
AppMotionLight_OnPacketReceived_turnOn:
  lds r16, appMotionLightLSourceAddr                           ; do we have a source for brightness value?
  tst r16
  breq AppMotionLight_OnPacketReceived_checkTimer              ; no, jmp and don't check brightness
  lds r16, appMotionLightFlags                                 ; check last brightness reported
  andi r16, APP_MOTIONLIGHT_FLAGS_HAVELIGHT
  breq AppMotionLight_OnPacketReceived_secRet                  ; no brightness, yet
AppMotionLight_OnPacketReceived_checkBrightness:
  lds r16, appMotionLightLSourceValue                          ; check last brightness reported
  lds r17, appMotionLightLSourceValue+1
  lds r24, appMotionLightLastBrightness                        ; r25:r24>r17:r16?
  lds r25, appMotionLightLastBrightness+1                      ; appMotionLightLastBrightness>appMotionLightLSourceValue?
  sub r16, r24
  sbc r17, r25
  brcs AppMotionLight_OnPacketReceived_secRet                  ; yes, too bright to turn on
AppMotionLight_OnPacketReceived_checkTimer:
  lds r16, appMotionLightTimer                                 ; time up?
  lds r17, appMotionLightTimer+1
  or r16, r17
  brne AppMotionLight_OnPacketReceived_startTimer              ; no, just restart timer (light already on)
  push xl
    push xh
      rcall appMotionLightTurnOn                               ; (r16, r17, r18, r19, r20, r21, r22, r23, r24, r25, X)
    pop xh
  pop xl
AppMotionLight_OnPacketReceived_startTimer:                      
  rcall appMotionLightStartTimer
AppMotionLight_OnPacketReceived_secRet:
  sec
  ret
AppMotionLight_OnPacketReceived_isBrightness:
  sts appMotionLightLastBrightness, r18
  sts appMotionLightLastBrightness+1, r19
  lds r16, appMotionLightFlags
  ori r16, APP_MOTIONLIGHT_FLAGS_HAVELIGHT
  sts appMotionLightFlags, r16
  sec
  ret
; "set value" message
AppMotionLight_OnPacketReceived_set:
  rcall NETMSG_ValueRead                                       ; (none)
  cpi r17, VALUE_ID_MAL_ONTIME
  breq AppMotionLight_OnPacketReceived_setOnTime
  cpi r17, VALUE_ID_MAL_SOURCE1
  breq AppMotionLight_OnPacketReceived_setSource1
  cpi r17, VALUE_ID_MAL_SOURCE2
  breq AppMotionLight_OnPacketReceived_setSource2
  cpi r17, VALUE_ID_MAL_BSOURCE
  breq AppMotionLight_OnPacketReceived_setBSource
  cpi r17, VALUE_ID_MAL_BVALUE
  breq AppMotionLight_OnPacketReceived_setBValue
AppMotionLight_OnPacketReceived_clcRet:
  clc                                                          ; unexpected message
  ret
AppMotionLight_OnPacketReceived_setBSource:                    ; setValue "nodes/XXXXXXXX/MALSOURCEB 0xVVNN" (VV=value id, NN=node addr)
  sts appMotionLightLSourceAddr, r18
  sts appMotionLightLSourceValueId, r19
  rjmp AppMotionLight_OnPacketReceived_sendAck
AppMotionLight_OnPacketReceived_setBValue:                     ; "setValue nodes/XXXXXXXX/MALVALUEB n" (n brightness value)
  sts appMotionLightLSourceValue, r18
  sts appMotionLightLSourceValue+1, r19
  rjmp AppMotionLight_OnPacketReceived_sendAck
AppMotionLight_OnPacketReceived_setOnTime:                     ; "setValue nodes/XXXXXXXX/MALONTIME n" (n in 1/10 secs)
  sts appMotionLightOnTime, r18
  sts appMotionLightOnTime+1, r19
  lds r16, appMotionLightTimer                                 ; timer active?
  lds r17, appMotionLightTimer+1
  or r16, r17
  breq AppMotionLight_OnPacketReceived_sendAck                 ; nope, just set it and leave
  sts appMotionLightTimer, r18                                 ; restart timer with new value
  sts appMotionLightTimer+1, r19
  rjmp AppMotionLight_OnPacketReceived_sendAck
AppMotionLight_OnPacketReceived_setSource1:                    ; setValue "nodes/XXXXXXXX/MALSOURCE1 0xVVNN" (VV=value id, NN=node addr)
  sts appMotionLightSources, r18                               ; peerAddr
  sts appMotionLightSources+1, r19                             ; valueId
  rjmp AppMotionLight_OnPacketReceived_sendAck
AppMotionLight_OnPacketReceived_setSource2:                    ; setValue "nodes/XXXXXXXX/MALSOURCE2 0xVVNN" (VV=value id, NN=node addr)
  sts appMotionLightSources+APP_MOTIONLIGHT_SOURCE_SIZE, r18   ; peerAddr
  sts appMotionLightSources+APP_MOTIONLIGHT_SOURCE_SIZE+1, r19 ; valueId
AppMotionLight_OnPacketReceived_sendAck:
  push xl
    push xh
      ldi r23, NETMSG_CMD_VALUE_SET_ACK
      rcall Main_SendValueResponse                             ; (clobbers all, including Y)
      rcall appMotionLightWriteConfToEeprom                    ; (r16, r17, X)
    pop xh
  pop xl
  sec
  ret
; @end



