; ***************************************************************************
; copyright   : (C) 2024 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.   *
; ***************************************************************************


; ***************************************************************************
; defs

.equ MOTION_SEND_1_AFTER    = 1   ; send motion message after  100ms
.equ MOTION_SEND_2_AFTER    = 11  ; send motion message after 1100ms
.equ MOTION_RESTART_AFTER   = 100 ; restart motion report counter after 10s

.equ MOTION_UPCOUNTER_VALUE = 50  ; keep MOTION state active for at least 5s

.equ MOTION_FLAGS_REPORT_MOTION_BIT = 0



; ***************************************************************************
; data

.dseg

motionDataBegin:
  motionFlags:        .byte 1
  motionStateCounter: .byte 1
  motionUpCounter:    .byte 1
motionDataEnd:



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

.cseg




; ---------------------------------------------------------------------------
; @routine Motion_Init @global
;
; @return CFLAG set if okay, clear on error
; @clobbers R16, R17, X

Motion_Init:
  ; preset SRAM data area
  ldi xh, HIGH(motionDataBegin)
  ldi xl, LOW(motionDataBegin)
  clr r16
  ldi r17, (motionDataEnd-motionDataBegin)
  rcall Utils_FillSram                ; (R17, X)

  ; setup pins
  cbi MOTION_DDR, MOTION_PIN          ; set DATA port as input
  cbi MOTION_OUTPUT, MOTION_PIN       ; disable internal pullup for TXD
  sec
  ret
; @end



; ---------------------------------------------------------------------------
; @routine Motion_Fini @global
;
; @clobbers none

Motion_Fini:
  cbi MOTION_DDR, MOTION_PIN          ; set DATA port as input
  cbi MOTION_OUTPUT, MOTION_PIN       ; disable internal pullup for TXD
  ret
; @end



; ---------------------------------------------------------------------------
; @routine Motion_Run @global
;
; @clobbers none

Motion_Run:
  lds r16, motionFlags
  andi r16, (1<<MOTION_FLAGS_REPORT_MOTION_BIT)
  breq Motion_Run_retnc
  ldi r18, 1
  rcall Motion_SendReport
  brcc Motion_Run_retnc
  lds r16, motionFlags
  andi r16, ~(1<<MOTION_FLAGS_REPORT_MOTION_BIT)
  sts motionFlags, r16
  sec
  ret
Motion_Run_retnc:
  clc
  ret
; @end



; ---------------------------------------------------------------------------
; @routine Motion_Every100ms @global
;
; @clobbers any

Motion_Every100ms:
  clr r16
  sbic MOTION_INPUT, MOTION_PIN
    inc r16
  tst r16
  brne Motion_Every100ms_up
  ; motion pin is inactive, decrement counter
  lds r17, motionUpCounter
  tst r17
  breq Motion_Every100ms_end
  dec r17
  sts motionUpCounter, r17
  brne Motion_Every100ms_handleStateCounter
  ; reached 0, virtual state is now NO_MOTION
  sts motionStateCounter, r17
  ret
Motion_Every100ms_up:
  ; motion is active, keep uptimer up
  ldi r17, MOTION_UPCOUNTER_VALUE
  sts motionUpCounter, r17
  
Motion_Every100ms_handleStateCounter:
  tst r17                      ; motionUpCounter?
  breq Motion_Every100ms_end   ; 0, jmp
  lds r17, motionStateCounter
  inc r17
  sts motionStateCounter, r17
  cpi r17, MOTION_SEND_1_AFTER
  breq Motion_Every100ms_send
  cpi r17, MOTION_SEND_2_AFTER
  breq Motion_Every100ms_send
  cpi r17, MOTION_RESTART_AFTER
  brne Motion_Every100ms_end
  clr r17                      ; restart counter
  sts motionStateCounter, r17
  ret
Motion_Every100ms_send:
  lds r16, motionFlags
  ori r16, (1<<MOTION_FLAGS_REPORT_MOTION_BIT)
  sts motionFlags, r16
  ret
Motion_Every100ms_end:
  ret
; @end



; ---------------------------------------------------------------------------
; @routine Motion_SendReport @global
;
; @param R18 sensor value
; @return CFLAG set if okay, cleared on error
; @clobbers any

Motion_SendReport:
  ldi r16, 0xff                      ; destination address
  ldi r17, VALUE_ID_MOTION           ; value id
  ldi r22, AQHOME_VALUETYPE_MOTION
  clr r19
  ldi r20, 1                         ; denominator
  clr r21
  ldi xl, LOW(com2SendBuffer)
  ldi xh, HIGH(com2SendBuffer)
  rcall CPRO_WriteReportValue        ; (R16, R17, R18, R19, R20, R21)
  rjmp COM2_SendPacket               ; any (depending on implementation)
; @end






