; ***************************************************************************
; 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_Init @global
;

AppMotionLight_Init:
  ; preset SRAM data area
  ldi xh, HIGH(appMotionLightDataBegin)
  ldi xl, LOW(appMotionLightDataBegin)
  clr r16
  ldi r17, (appMotionLightDataEnd-appMotionLightDataBegin)
  rcall Utils_FillSram
  
  ldi r16, LOW(APP_MOTIONLIGHT_DEFAULT_ONTIME)
  sts appMotionLightOnTime, r16
  ldi r16, HIGH(APP_MOTIONLIGHT_DEFAULT_ONTIME)
  sts appMotionLightOnTime+1, r16

  rcall appMotionLightReadConfFromEeprom
 
  ret
; @end



; ---------------------------------------------------------------------------
; @routine AppMotionLight_Fini @global
;

AppMotionLight_Fini:
  clr r16
  sts appMotionLightTimer, r16   ; clear timer
  sts appMotionLightTimer+1, r16
  rjmp appMotionLightTurnOff
; @end



; ---------------------------------------------------------------------------
; @routine AppMotionLight_Every100ms @global
;
; @clobbers r16, r24, r26, (r17, r18, r19, r20, r21, r23)

AppMotionLight_Every100ms:
  lds r24, appMotionLightTimer
  lds r25, appMotionLightTimer+1
  sbiw r25:r24, 1
  brcs AppMotionLight_Every100ms_ret
  sts appMotionLightTimer, r24
  sts appMotionLightTimer+1, r25
  breq AppMotionLight_Every100ms_off
AppMotionLight_Every100ms_ret:
  ret
AppMotionLight_Every100ms_off:
  rjmp appMotionLightTurnOff   ; (r16, r17, r18, r19, r20, r21, r22, r23, r24, r25, X)
; @end



; ---------------------------------------------------------------------------
; @routine appMotionLightHasSource
;
; @return CFLAGS set if we have a matching source entry, cleared otherwise
; @param r17 value id
; @param r22 source address
; @clobbers r16, r24, Y

appMotionLightHasSource:
  ldi yl, LOW(appMotionLightSources)
  ldi yh, HIGH(appMotionLightSources)
  ldi r24, APP_MOTIONLIGHT_SOURCE_NUM
appMotionLightHasSource_loop:
    ldd r16, Y+APP_MOTIONLIGHT_SOURCE_OFFS_ADDR
    cp r16, r22
    brne appMotionLightHasSource_next
    ldd r16, Y+APP_MOTIONLIGHT_SOURCE_OFFS_VALUEID
    cp r16, r17
    brne appMotionLightHasSource_next
    sec
    ret
appMotionLightHasSource_next:
    adiw yh:yl, APP_MOTIONLIGHT_SOURCE_SIZE
    dec r24
  brne appMotionLightHasSource_loop
  clc
  ret
; @end



; ---------------------------------------------------------------------------
; @routine appMotionLightIsBrightnessSource
;
; @return CFLAGS set if we have a matching source entry, cleared otherwise
; @param r17 value id
; @param r22 source address
; @clobbers R16

appMotionLightIsBrightnessSource:
  lds r16, appMotionLightLSourceAddr
  cp r16, r22
  brne appMotionLightIsBrightnessSource_no
  lds r16, appMotionLightLSourceValueId
  cp r16, r17
  brne appMotionLightIsBrightnessSource_no
  sec
  rjmp appMotionLightIsBrightnessSource_ret
appMotionLightIsBrightnessSource_no:
  clc
appMotionLightIsBrightnessSource_ret:
  ret
; @end



; ---------------------------------------------------------------------------
; @routine appMotionLightStartTimer
;
; @clobbers r16

appMotionLightStartTimer:
  lds r16, appMotionLightOnTime
  sts appMotionLightTimer, r16
  lds r16, appMotionLightOnTime+1
  sts appMotionLightTimer+1, r16
  ret
; @end



; ---------------------------------------------------------------------------
; @routine appMotionLightTurnOn
;
; @clobbers r18 (r16, r17, r19, r20, r21, r22, r23, r24, r25, X)

appMotionLightTurnOn:
  ldi r18, 1
  rcall SK6812_SetState           ; (R16, R17, R18, R19, R20, R21, R23, R24, R25)
  ldi r18, 1
  rjmp appMotionLightReportState  ; (R16, R17, R18, R19, R20, R21, R22, R23, R24, R25, X)
; @end
  


; ---------------------------------------------------------------------------
; @routine appMotionLightTurnOff
;
; @clobbers r18 (r16, r17, r19, r20, r21, r22, r23, r24, r25, X)

appMotionLightTurnOff:
  clr r18
  rcall SK6812_SetState           ; (R16, R17, R18, R19, R20, R21, R23, R24, R25)
  clr r18
  rjmp appMotionLightReportState  ; (R16, R17, R18, R19, R20, R21, R22, R23, R24, R25, X)
; @end



; ---------------------------------------------------------------------------
; @routine appMotionLightReportState
;
; @param R18 state (0=off, 1=on)
; @clobbers (R16, R17, R18, R19, R20, R21, R22, R23, R24, R25, X)

appMotionLightReportState:
  ldi r17, VALUE_ID_MAL_STATE
  clr r19
  ldi r20, 1
  clr r21
  ldi r22, AQHOME_VALUETYPE_ONOFF
  push yl
    push yh
      rcall Main_SendValueReport       ; (R16, R17, R18, R19, R20, R21, R23, R24, R25, X)
    pop yh
  pop yl
  ret
; @end



; ---------------------------------------------------------------------------
; @routine appMotionLightReadConfFromEeprom
;
; @clobbers 

appMotionLightReadConfFromEeprom:
  push r15
    in r15, SREG
    cli
    ldi xl, LOW(EEPROM_OFFS_MAL_CONF_ONTIME)
    ldi xh, HIGH(EEPROM_OFFS_MAL_CONF_ONTIME)
    rcall Utils_ReadEepromIncr ; (R16)
    mov r18, r16
    rcall Utils_ReadEepromIncr ; (R16)
    mov r19, r16
    and r16, r18
    cpi r16, 0xff
    breq appMotionLightReadConfFromEeprom_end
    sts appMotionLightOnTime, r18
    sts appMotionLightOnTime+1, r19
    
    ; read source 1
    rcall Utils_ReadEepromIncr ; (R16)
    mov r18, r16
    rcall Utils_ReadEepromIncr ; (R16)
    mov r19, r16
    sts appMotionLightSources+APP_MOTIONLIGHT_SOURCE_OFFS_ADDR, r18
    sts appMotionLightSources+APP_MOTIONLIGHT_SOURCE_OFFS_VALUEID, r19

    ; read source 2
    rcall Utils_ReadEepromIncr ; (R16)
    mov r18, r16
    rcall Utils_ReadEepromIncr ; (R16)
    mov r19, r16
    sts appMotionLightSources+APP_MOTIONLIGHT_SOURCE_SIZE+APP_MOTIONLIGHT_SOURCE_OFFS_ADDR, r18
    sts appMotionLightSources+APP_MOTIONLIGHT_SOURCE_SIZE+APP_MOTIONLIGHT_SOURCE_OFFS_VALUEID, r19

    ; read brightness source
    rcall Utils_ReadEepromIncr ; (R16)
    sts appMotionLightLSourceAddr, r16

    rcall Utils_ReadEepromIncr ; (R16)
    sts appMotionLightLSourceValueId, r16

    ; read brightness limit
    rcall Utils_ReadEepromIncr ; (R16)
    mov r18, r16
    rcall Utils_ReadEepromIncr ; (R16)
    mov r19, r16
    sts appMotionLightLSourceValue, r18
    sts appMotionLightLSourceValue+1, r19
appMotionLightReadConfFromEeprom_end:
    out SREG, r15
  pop r15
  ret
; @end



; ---------------------------------------------------------------------------
; @routine appMotionLightWriteConfToEeprom
;
; @clobbers r16, r17, X

appMotionLightWriteConfToEeprom:
  push r15
    in r15, SREG
    cli
    ldi xl, LOW(EEPROM_OFFS_MAL_CONF_ONTIME)
    ldi xh, HIGH(EEPROM_OFFS_MAL_CONF_ONTIME)
    
    lds r16, appMotionLightOnTime
    rcall Eeprom_WriteByteIfChanged ; (R17)
    adiw xh:xl, 1
    lds r16, appMotionLightOnTime+1
    rcall Eeprom_WriteByteIfChanged ; (R17)
    adiw xh:xl, 1

    ; write source 1
    lds r16, appMotionLightSources+APP_MOTIONLIGHT_SOURCE_OFFS_ADDR
    rcall Eeprom_WriteByteIfChanged ; (R17)
    adiw xh:xl, 1
    lds r16, appMotionLightSources+APP_MOTIONLIGHT_SOURCE_OFFS_VALUEID
    rcall Eeprom_WriteByteIfChanged ; (R17)
    adiw xh:xl, 1

    ; write source 2
    lds r16, appMotionLightSources+APP_MOTIONLIGHT_SOURCE_SIZE+APP_MOTIONLIGHT_SOURCE_OFFS_ADDR
    rcall Eeprom_WriteByteIfChanged ; (R17)
    adiw xh:xl, 1
    lds r16, appMotionLightSources+APP_MOTIONLIGHT_SOURCE_SIZE+APP_MOTIONLIGHT_SOURCE_OFFS_VALUEID
    rcall Eeprom_WriteByteIfChanged ; (R17)
    adiw xh:xl, 1

    ; write brightness source
    lds r16, appMotionLightLSourceAddr
    rcall Eeprom_WriteByteIfChanged ; (R17)
    adiw xh:xl, 1
    lds r16, appMotionLightLSourceValueId
    rcall Eeprom_WriteByteIfChanged ; (R17)
    adiw xh:xl, 1

    ; write brightness limit
    lds r16, appMotionLightLSourceValue
    rcall Eeprom_WriteByteIfChanged ; (R17)
    adiw xh:xl, 1
    lds r16, appMotionLightLSourceValue+1
    rcall Eeprom_WriteByteIfChanged ; (R17)
    adiw xh:xl, 1

    out SREG, r15
  pop r15
  ret
; @end



