; *************************************************************************** ; 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. * ; *************************************************************************** ; *************************************************************************** ; defines .equ MOTIONLIGHT_DEFAULT_ONTIME = 3000 ; 5min (in 1/10 secs) .equ MOTIONLIGHT_SOURCE_NUM = 2 .equ MOTIONLIGHT_SOURCE_OFFS_ADDR = 0 .equ MOTIONLIGHT_SOURCE_OFFS_VALUEID = 1 .equ MOTIONLIGHT_SOURCE_SIZE = 2 ; *************************************************************************** ; data .dseg motionLightDataBegin: motionLightTimer: .byte 2 motionLightOnTime: .byte 2 motionLightColor: .byte 4 motionLightSources: .byte MOTIONLIGHT_SOURCE_NUM*MOTIONLIGHT_SOURCE_SIZE motionLightDataEnd: ; *************************************************************************** ; code .cseg MOTIONLIGHT_BEGIN: ; --------------------------------------------------------------------------- ; @routine MotionLight_Init @global ; MotionLight_Init: ; preset SRAM data area ldi xh, HIGH(motionLightDataBegin) ldi xl, LOW(motionLightDataBegin) clr r16 ldi r17, (motionLightDataEnd-motionLightDataBegin) rcall Utils_FillSram ldi xh, HIGH(motionLightColor) ldi xl, LOW(motionLightColor) clr r16 ldi r17, 0x80 st X+, r16 ; R st X+, r16 ; G st X+, r17 ; B st X+, r16 ; WW ldi r16, LOW(MOTIONLIGHT_DEFAULT_ONTIME) sts motionLightOnTime, r16 ldi r16, HIGH(MOTIONLIGHT_DEFAULT_ONTIME) sts motionLightOnTime+1, r16 rcall motionLightReadConfFromEeprom ret ; @end ; --------------------------------------------------------------------------- ; @routine MotionLight_Fini @global ; MotionLight_Fini: clr r16 sts motionLightTimer, r16 ; clear timer sts motionLightTimer+1, r16 rjmp motionLightTurnOff ; @end ; --------------------------------------------------------------------------- ; @routine MotionLight_Every100ms @global ; ; @clobbers r16, r24, r26, (r17, r18, r19, r20, r21, r23) MotionLight_Every100ms: lds r24, motionLightTimer lds r25, motionLightTimer+1 sbiw r25:r24, 1 brcs MotionLight_Every100ms_ret sts motionLightTimer, r24 sts motionLightTimer+1, r25 breq MotionLight_Every100ms_off MotionLight_Every100ms_ret: ret MotionLight_Every100ms_off: rjmp motionLightTurnOff ; (r16, r17, r18, r19, r20, r21, r23) ; @end ; --------------------------------------------------------------------------- ; @routine MotionLight_OnPacketReceived @global ; ; @clobbers any, -X MotionLight_OnPacketReceived: adiw xh:xl, 2 ; command ld r16, X sbiw xh:xl, 2 cpi r16, CPRO_CMD_VALUE_REPORT breq MotionLight_OnPacketReceived_report cpi r16, CPRO_CMD_VALUE_SET breq MotionLight_OnPacketReceived_set MotionLight_OnPacketReceived_clcRet: clc ; unexpected msg ret MotionLight_OnPacketReceived_report: rcall CPRO_ReadValue ; (none) mov r16, r18 or r16, r19 breq MotionLight_OnPacketReceived_clcRet ; zero value, ignore rcall motionLightHasSource ; (r16, r24, Y) brcs MotionLight_OnPacketReceived_turnOn ret MotionLight_OnPacketReceived_turnOn: lds r16, motionLightTimer lds r17, motionLightTimer+1 or r16, r17 brne MotionLight_OnPacketReceived_startTimer rcall motionLightTurnOn ; (r16, r17, r18, r19, r20, r21, r23) MotionLight_OnPacketReceived_startTimer: rcall motionLightStartTimer ret MotionLight_OnPacketReceived_set: rcall CPRO_ReadValue ; (none) cpi r17, VALUE_ID_MAL_RGBW_VALUE breq MotionLight_OnPacketReceived_setRGBW cpi r17, VALUE_ID_MAL_ONTIME breq MotionLight_OnPacketReceived_setOnTime cpi r17, VALUE_ID_MAL_SOURCE1 breq MotionLight_OnPacketReceived_setSource1 cpi r17, VALUE_ID_MAL_SOURCE2 breq MotionLight_OnPacketReceived_setSource2 clc ; unexpected message ret MotionLight_OnPacketReceived_setRGBW: sts motionLightColor, r18 sts motionLightColor+1, r19 sts motionLightColor+2, r20 sts motionLightColor+3, r21 rcall motionLightStartTimer ; immediately ON with new color rcall motionLightTurnOn rjmp MotionLight_OnPacketReceived_sendAck MotionLight_OnPacketReceived_setOnTime: sts motionLightOnTime, r18 sts motionLightOnTime+1, r19 rjmp MotionLight_OnPacketReceived_sendAck MotionLight_OnPacketReceived_setSource1: sts motionLightSources, r18 ; peerAddr sts motionLightSources+1, r19 ; valueId rjmp MotionLight_OnPacketReceived_sendAck MotionLight_OnPacketReceived_setSource2: sts motionLightSources+MOTIONLIGHT_SOURCE_SIZE, r18 ; peerAddr sts motionLightSources+MOTIONLIGHT_SOURCE_SIZE+1, r19 ; valueId MotionLight_OnPacketReceived_sendAck: ldi r16, CPRO_CMD_VALUE_SET_ACK rcall CPRO_SendSetValueResponse push xl push xh rcall motionLightWriteConfToEeprom pop xh pop xl sec ret ; @end ; --------------------------------------------------------------------------- ; @routine motionLightHasSource ; ; @return CFLAGS set if we have a matching source entry, cleared otherwise ; @param r17 value id ; @param r22 source address ; @clobbers r16, r24, Y motionLightHasSource: ldi yl, LOW(motionLightSources) ldi yh, HIGH(motionLightSources) ldi r24, MOTIONLIGHT_SOURCE_NUM motionLightHasSource_loop: ldd r16, Y+MOTIONLIGHT_SOURCE_OFFS_ADDR cp r16, r22 brne motionLightHasSource_next ldd r16, Y+MOTIONLIGHT_SOURCE_OFFS_VALUEID cp r16, r17 brne motionLightHasSource_next sec ret motionLightHasSource_next: adiw yh:yl, MOTIONLIGHT_SOURCE_SIZE dec r24 brne motionLightHasSource_loop clc ret ; @end ; --------------------------------------------------------------------------- ; @routine motionLightStartTimer ; ; @clobbers r16 motionLightStartTimer: lds r16, motionLightOnTime sts motionLightTimer, r16 lds r16, motionLightOnTime+1 sts motionLightTimer+1, r16 ret ; @end ; --------------------------------------------------------------------------- ; @routine motionLightTurnOn ; ; @clobbers r18, r19, r20, r21 (r16, t17, r23) motionLightTurnOn: lds r18, motionLightColor lds r19, motionLightColor+1 lds r20, motionLightColor+2 lds r21, motionLightColor+3 rjmp SK6812_SetAllColor ; (r16, r17, r23) ; @end ; --------------------------------------------------------------------------- ; @routine motionLightTurnOff ; ; @clobbers r18, r19, r20, r21 (r16, t17, r23) motionLightTurnOff: clr r18 clr r19 clr r20 clr r21 rjmp SK6812_SetAllColor ; (r16, r17, r23) ; @end ; --------------------------------------------------------------------------- ; @routine motionLightReadConfFromEeprom ; ; @clobbers motionLightReadConfFromEeprom: 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 motionLightReadConfFromEeprom_end sts motionLightOnTime, r18 sts motionLightOnTime+1, r19 ; read source 1 rcall Utils_ReadEepromIncr ; (R16) mov r18, r16 rcall Utils_ReadEepromIncr ; (R16) mov r19, r16 sts motionLightSources+MOTIONLIGHT_SOURCE_OFFS_ADDR, r18 sts motionLightSources+MOTIONLIGHT_SOURCE_OFFS_VALUEID, r19 ; read source 2 rcall Utils_ReadEepromIncr ; (R16) mov r18, r16 rcall Utils_ReadEepromIncr ; (R16) mov r19, r16 sts motionLightSources+MOTIONLIGHT_SOURCE_SIZE+MOTIONLIGHT_SOURCE_OFFS_ADDR, r18 sts motionLightSources+MOTIONLIGHT_SOURCE_SIZE+MOTIONLIGHT_SOURCE_OFFS_VALUEID, r19 motionLightReadConfFromEeprom_end: out SREG, r15 pop r15 ret ; @end ; --------------------------------------------------------------------------- ; @routine motionLightWriteConfToEeprom ; ; @clobbers r15, r16, r17, X motionLightWriteConfToEeprom: push r15 in r15, SREG cli ldi xl, LOW(EEPROM_OFFS_MAL_CONF_ONTIME) ldi xh, HIGH(EEPROM_OFFS_MAL_CONF_ONTIME) lds r16, motionLightOnTime rcall Utils_WriteEepromIncr ; (R17) lds r16, motionLightOnTime+1 rcall Utils_WriteEepromIncr ; (R17) ; write source 1 lds r16, motionLightSources+MOTIONLIGHT_SOURCE_OFFS_ADDR rcall Utils_WriteEepromIncr ; (R16) lds r16, motionLightSources+MOTIONLIGHT_SOURCE_OFFS_VALUEID rcall Utils_WriteEepromIncr ; (R16) ; write source 2 lds r16, motionLightSources+MOTIONLIGHT_SOURCE_SIZE+MOTIONLIGHT_SOURCE_OFFS_ADDR rcall Utils_WriteEepromIncr ; (R16) lds r16, motionLightSources+MOTIONLIGHT_SOURCE_SIZE+MOTIONLIGHT_SOURCE_OFFS_VALUEID rcall Utils_WriteEepromIncr ; (R16) out SREG, r15 pop r15 ret ; @end MOTIONLIGHT_END: .equ MODULE_SIZE_MOTIONLIGHT = MOTIONLIGHT_END-MOTIONLIGHT_BEGIN