; ***************************************************************************
; 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_APPS_LIGHT_CONTROL_MAIN_ASM
#define AQH_AVR_APPS_LIGHT_CONTROL_MAIN_ASM


.equ APP_LIGHTCONTROL_LIGHT_LIMIT = 20




.cseg


; ---------------------------------------------------------------------------
; @routine AppLightControl_Init

AppLightControl_Init:
  ldi zl, LOW(appLightControlObjectFlash*2)
  ldi zh, HIGH(appLightControlObjectFlash*2)
  
  ; preset RAM
  lpm xl, Z+
  lpm xh, Z
  sbiw zh:zl, 1
  clr r16
  ldi r17,TCA_RAM_SIZE
  bigcall Utils_FillSram

  ; init base class
  bigcall TCA_Init

  ; preset source limits (low=1, high=65535)
  lpm yl, Z+
  lpm yh, Z
  sbiw zh:zl, 1
  ldi r16, 1
  std Y+(TCA_RAM_OFFS_TRIGGER_SOURCE1+TCA_SOURCE_OFFS_LOWLIM_LO), r16
  std Y+(TCA_RAM_OFFS_TRIGGER_SOURCE2+TCA_SOURCE_OFFS_LOWLIM_LO), r16
  ldi r16, 0xff
  std Y+(TCA_RAM_OFFS_TRIGGER_SOURCE1+TCA_SOURCE_OFFS_HIGHLIM_LO), r16
  std Y+(TCA_RAM_OFFS_TRIGGER_SOURCE1+TCA_SOURCE_OFFS_HIGHLIM_HI), r16
  std Y+(TCA_RAM_OFFS_TRIGGER_SOURCE2+TCA_SOURCE_OFFS_HIGHLIM_LO), r16
  std Y+(TCA_RAM_OFFS_TRIGGER_SOURCE2+TCA_SOURCE_OFFS_HIGHLIM_HI), r16

  ; preset guard limits
  clr r16
  std Y+(TCA_RAM_OFFS_GUARD_SOURCE+TCA_SOURCE_OFFS_LOWLIM_LO), r16
  std Y+(TCA_RAM_OFFS_GUARD_SOURCE+TCA_SOURCE_OFFS_LOWLIM_HI), r16
  ldi r16, LOW(APP_LIGHTCONTROL_LIGHT_LIMIT)
  ldi r17, HIGH(APP_LIGHTCONTROL_LIGHT_LIMIT)
  std Y+(TCA_RAM_OFFS_GUARD_SOURCE+TCA_SOURCE_OFFS_HIGHLIM_LO), r16
  std Y+(TCA_RAM_OFFS_GUARD_SOURCE+TCA_SOURCE_OFFS_HIGHLIM_HI), r17
  
  clr r16
  std Y+HTIM_RAM_OFFS_MODE, r16

  ; set default color to white
  clr r16
  std Y+APP_LIGHTCONTROL_RAM_OFFS_VALUE_RED, r16
  std Y+APP_LIGHTCONTROL_RAM_OFFS_VALUE_GREEN, r16
  std Y+APP_LIGHTCONTROL_RAM_OFFS_VALUE_BLUE, r16
  ldi r16, 32
  std Y+APP_LIGHTCONTROL_RAM_OFFS_VALUE_WHITE, r16

  ldi r16, 144
  std Y+APP_LIGHTCONTROL_RAM_OFFS_LEDCOUNT_LO, r16
  clr r16
  std Y+APP_LIGHTCONTROL_RAM_OFFS_LEDCOUNT_HI, r16

  ; setup from eeprom
  push yl
    push yh
      rcall appLightControlReadEeprom
    pop yh
  pop yl

  ; start in given mode
  rcall appLightControlUpdate
  ret
; @end



; ---------------------------------------------------------------------------
; @routine AppLightControl_OnEveryTick @global

AppLightControl_OnEveryTick:
  ldi zl, LOW(appLightControlObjectFlash*2)
  ldi zh, HIGH(appLightControlObjectFlash*2)

  lpm yl, Z+
  lpm yh, Z
  sbiw zh:zl, 1

  bigcall TCA_OnEveryTick

  ; check update flag
  ldd r16, Y+HTIM_RAM_OFFS_FLAGS
  sbrs r16, TCA_FLAGBIT_UPDATED
    rjmp AppLightControl_OnEveryTick_ret  ; jump if clear (value unchanged)
  ; value updated
  cbr r16, (1<<TCA_FLAGBIT_UPDATED)       ; clear update bit
  std Y+HTIM_RAM_OFFS_FLAGS, r16
  rcall appLightControlWriteEeprom
  rcall appLightControlUpdate
AppLightControl_OnEveryTick_ret:
  ret
; @end



; ---------------------------------------------------------------------------
; @routine appLightControlUpdate

appLightControlUpdate:
  ldd r18, Y+APP_LIGHTCONTROL_RAM_OFFS_LEDCOUNT_LO
  ldd r19, Y+APP_LIGHTCONTROL_RAM_OFFS_LEDCOUNT_HI
  bigcall SK6812_SetLedNum                         ; (none)
  
  ldd r16, Y+HTIM_RAM_OFFS_FLAGS
  ldd r17, Y+HTIM_RAM_OFFS_MODE
  cpi r17, 2                       ; auto?
  breq appLightControlUpdate_auto
  ; non-auto
  cbr r16, (1<<HTIM_FLAGBIT_ACTIVE) | (1<<HTIM_FLAGBIT_ACTORENABLED) ; disable timer
  std Y+HTIM_RAM_OFFS_FLAGS, r16
  cpi r17, 1                       ; on?
  breq appLightControlUpdate_on
  rcall appLightControlActorOff
  rjmp appLightControlUpdate_ret
appLightControlUpdate_auto:
  sbr r16, (1<<HTIM_FLAGBIT_ACTIVE) | (1<<HTIM_FLAGBIT_ACTORENABLED) ; enable timer
  std Y+HTIM_RAM_OFFS_FLAGS, r16
  bigcall HTIM_Trigger
;  sbrs r16, HTIM_FLAGBIT_STATE
;    rjmp appLightControlUpdate_ret   ; jump if clear (actor is off)
;  rcall appLightControlActorOn
; rjmp appLightControlUpdate_ret
appLightControlUpdate_on:
  rcall appLightControlActorOn
appLightControlUpdate_ret:
  ret
; @end



; ---------------------------------------------------------------------------
; @routine appLightControlReadEeprom
;
; @param  Y pointer to data in RAM

appLightControlReadEeprom:
  ldi r16, APP_LIGHTCONTROL_EEID
  bigcall EepromTlv_FindFirst
  brcc appLightControlReadEeprom_ret

  ; let base class read
  bigcall TCA_ReadEepromAt              ; (r16, r17, Y)
  brcc appLightControlReadEeprom_ret

  push yl
    push yh
      adiw yh:yl, APP_LIGHTCONTROL_RAM_OFFS_BEGIN
      ldi r17, (APP_LIGHTCONTROL_EE_SIZE-APP_LIGHTCONTROL_EE_OFFS_BEGIN)
      bigcall Eeprom_ReadBytes                    ; (r16, r17, X, Y)
    pop yh
  pop yl
appLightControlReadEeprom_ret:
  ret
; @end



; ---------------------------------------------------------------------------
; @routine appLightControlWriteEeprom
;
; @param  Y pointer to data in RAM

appLightControlWriteEeprom:
   ldi r16, APP_LIGHTCONTROL_EEID
   bigcall EepromTlv_FindFirst            ; X=ptr, r17=length (r16, r18)
   brcs appLightControlWriteEeprom_write
   ; create eeprom TLV
   ldi r16, APP_LIGHTCONTROL_EEID
   ldi r17, APP_LIGHTCONTROL_EE_SIZE
   bigcall EepromTlv_AddTlv               ; X=ptr (r16, r20, r21, r18)
   brcc appLightControlWriteEeprom_ret
appLightControlWriteEeprom_write:
  ; let base class write
  bigcall TCA_WriteEepromAt               ; 
  brcc appLightControlWriteEeprom_ret
  push yl
    push yh
      adiw yh:yl, APP_LIGHTCONTROL_RAM_OFFS_BEGIN
      ldi r17, (APP_LIGHTCONTROL_EE_SIZE-APP_LIGHTCONTROL_EE_OFFS_BEGIN)
      bigcall Eeprom_WriteBytes                    ; (r16, r17, r18, X, Y)
    pop yh
  pop yl
appLightControlWriteEeprom_ret:
  ret
; @end



; ---------------------------------------------------------------------------
; @routine appLightControlActorOn
; @param Z pointer to timer data in FLASH (byte address for lpm!)
; @param Y pointer to data in RAM

appLightControlActorOn:
  ldd r18, Y+APP_LIGHTCONTROL_RAM_OFFS_VALUE_RED
  ldd r19, Y+APP_LIGHTCONTROL_RAM_OFFS_VALUE_GREEN
  ldd r20, Y+APP_LIGHTCONTROL_RAM_OFFS_VALUE_BLUE
  ldd r21, Y+APP_LIGHTCONTROL_RAM_OFFS_VALUE_WHITE
  bigcall SK6812_SetRGBW                           ; (r16, r24, r25)

  bigcall AppLightControl_ReportState
  ret
; @end



; ---------------------------------------------------------------------------
; @routine appLightControlActorOff
;
; @param Z pointer to timer data in FLASH (byte address for lpm!)
; @param Y pointer to data in RAM

appLightControlActorOff:
  clr r18
  clr r19
  clr r20
  clr r21
  bigcall SK6812_SetRGBW   ; (r16, r24, r25)

  bigcall AppLightControl_ReportState
  ret
; @end





#if 0
appLightControlDebug:
  ; debug
  ldi r17, 0xf0
  ldd r18, Y+HTIM_RAM_OFFS_FLAGS
  ldd r19, Y+HTIM_RAM_OFFS_MODE
  ldd r20, Y+HTIM_RAM_OFFS_CURRVAL_LO
  ldd r21, Y+HTIM_RAM_OFFS_CURRVAL_HI
  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
#endif







appLightControlObjectFlash:
  .dw appLightControlObjectRam  ; HTIM_FLASH_OFFS_RAMPTR
  .dw appLightControlActorOn    ; HTIM_FLASH_OFFS_ON_PTR
  .dw appLightControlActorOff   ; HTIM_FLASH_OFFS_OFF_PTR
  .dw (10*60*10)                ; HTIM_FLASH_OFFS_RELOADVAL




.dseg


appLightControlObjectRam:
  .byte APP_LIGHTCONTROL_RAM_SIZE



#endif

