Files
aqhomecontrol/avr/modules/lcd2/gui/generic/screensaver.asm
2026-02-16 01:09:39 +01:00

472 lines
13 KiB
NASM

; ***************************************************************************
; 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_GUI2_SCREENSAVER_ASM
#define AQH_AVR_GUI2_SCREENSAVER_ASM
; ***************************************************************************
; defines
.equ SCREENSAVER_TIMER100ms = 6000 ; 10mins
;.equ SCREENSAVER_TIMER100ms = 300 ; 30 secs
; SDRAM data
.equ SCREENSAVER_SD_OFFS_BEGIN = WIDGET_SD_SIZE
.equ SCREENSAVER_SD_OFFS_TIMER_LO = SCREENSAVER_SD_OFFS_BEGIN+0
.equ SCREENSAVER_SD_OFFS_TIMER_HI = SCREENSAVER_SD_OFFS_BEGIN+1
.equ SCREENSAVER_SD_OFFS_PREV_VIEW_LO = SCREENSAVER_SD_OFFS_BEGIN+2
.equ SCREENSAVER_SD_OFFS_PREV_VIEW_HI = SCREENSAVER_SD_OFFS_BEGIN+3
.equ SCREENSAVER_SD_OFFS_NODEADDR1 = SCREENSAVER_SD_OFFS_BEGIN+4
.equ SCREENSAVER_SD_OFFS_VALUEID1 = SCREENSAVER_SD_OFFS_BEGIN+5
.equ SCREENSAVER_SD_OFFS_NODEADDR2 = SCREENSAVER_SD_OFFS_BEGIN+6
.equ SCREENSAVER_SD_OFFS_VALUEID2 = SCREENSAVER_SD_OFFS_BEGIN+7
.equ SCREENSAVER_SD_SIZE = SCREENSAVER_SD_OFFS_BEGIN+8
; EEPROM data
.equ SCREENSAVER_EE_OFFS_NODEADDR1 = 0
.equ SCREENSAVER_EE_OFFS_VALUEID1 = 1
.equ SCREENSAVER_EE_OFFS_NODEADDR2 = 2
.equ SCREENSAVER_EE_OFFS_VALUEID2 = 3
.equ SCREENSAVER_EE_SIZE = 4
; signals
.equ SCREENSAVER_SIGNAL_SETSOURCE1 = WIDGET_SIGNAL_NEXTFREE+0
.equ SCREENSAVER_SIGNAL_SETSOURCE2 = WIDGET_SIGNAL_NEXTFREE+1
.equ SCREENSAVER_SIGNAL_NEXTFREE = WIDGET_SIGNAL_NEXTFREE+2
; ***************************************************************************
; code
.cseg
; ---------------------------------------------------------------------------
; @routine ScreenSaver_KeepAlive @global
;
; @param Z byte address of widget object (for LPM!)
; @clobbers any, !Y, !Z
ScreenSaver_KeepAlive:
push yl
push yh
bigcall Widget_GetSdramPtr ; Y:=SDRAM data for widget (none)
ldd r24, Y+SCREENSAVER_SD_OFFS_TIMER_LO
ldd r25, Y+SCREENSAVER_SD_OFFS_TIMER_HI
mov r16, r24
or r16, r25
brne ScreenSaver_KeepAlive_restartCounter
; counter is 0, screen saver active, leave
rcall ScreenSaver_Leave ; (any, !Z)
ScreenSaver_KeepAlive_restartCounter:
ldi r16, LOW(SCREENSAVER_TIMER100ms)
std Y+SCREENSAVER_SD_OFFS_TIMER_LO, r16
ldi r16, HIGH(SCREENSAVER_TIMER100ms)
std Y+SCREENSAVER_SD_OFFS_TIMER_HI, r16
ScreenSaver_KeepAlive_ret:
pop yh
pop yl
ret
; @end
; ---------------------------------------------------------------------------
; @routine ScreenSaver_Enter @global
;
; @param Z byte address of widget object (for LPM!)
; @clobbers any, !Z
ScreenSaver_Enter:
bigcall Widget_GetApp ; r19;r18=app
push zl
push zh
mov zl, r18
mov zh, r19
bigcall GuiApp_GetCurrentView ; X=current view (Y)
pop zh
pop zl
bigcall Widget_GetSdramPtr ; Y:=SDRAM data for widget (none)
cp xl, zl
brne ScreenSaver_Enter_store
cp xh, zh
breq ScreenSaver_Enter_ret
ScreenSaver_Enter_store:
std Y+SCREENSAVER_SD_OFFS_PREV_VIEW_LO, xl
std Y+SCREENSAVER_SD_OFFS_PREV_VIEW_HI, xh
clr r16
std Y+SCREENSAVER_SD_OFFS_TIMER_LO, r16
std Y+SCREENSAVER_SD_OFFS_TIMER_HI, r16
push zl
push zh
mov xl, zl
mov xh, zh
mov zl, r18
mov zh, r19
bigcall GuiApp_ShowView ; select view: screensaver
pop zh
pop zl
clr r16
bigcall Display_SetBacklight
ScreenSaver_Enter_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine ScreenSaver_Leave @global
;
; @param Z byte address of widget object (for LPM!)
; @clobbers any, !Z
ScreenSaver_Leave:
bigcall Widget_GetSdramPtr ; Y:=SDRAM data for widget (none)
ldd xl, Y+SCREENSAVER_SD_OFFS_PREV_VIEW_LO
ldd xh, Y+SCREENSAVER_SD_OFFS_PREV_VIEW_HI
; restart screen saver timer
ldi r16, LOW(SCREENSAVER_TIMER100ms)
std Y+SCREENSAVER_SD_OFFS_TIMER_LO, r16
ldi r16, HIGH(SCREENSAVER_TIMER100ms)
std Y+SCREENSAVER_SD_OFFS_TIMER_HI, r16
; show previous view
bigcall Widget_GetApp ; r19;r18=app
push zl
push zh
mov zl, r18
mov zh, r19
bigcall GuiApp_ShowView
pop zh
pop zl
ldi r16, 0xff
bigcall Display_SetBacklight
ret
; @end
; ---------------------------------------------------------------------------
; @routine ScreenSaver_OnTimer @global
;
; @param Z byte address of widget object (for LPM!)
; @clobbers any, !Z
ScreenSaver_OnTimer:
bigcall Widget_GetSdramPtr ; Y:=SDRAM data for widget (none)
ldd r24, Y+SCREENSAVER_SD_OFFS_TIMER_LO
ldd r25, Y+SCREENSAVER_SD_OFFS_TIMER_HI
mov r16, r24
or r16, r25
breq ScreenSaver_OnTimer_ret
sbiw r25:r24, 1
std Y+SCREENSAVER_SD_OFFS_TIMER_LO, r24
std Y+SCREENSAVER_SD_OFFS_TIMER_HI, r25
brne ScreenSaver_OnTimer_ret
rcall ScreenSaver_Enter ; (any, !Z)
ScreenSaver_OnTimer_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine ScreenSaver_OnCreate @global
;
; @param Z byte address of widget object (for LPM!)
; @return CFLAG set if signal handled
; @clobbers any, !Z
ScreenSaver_OnCreate:
bigcall OBJ_IsObject ; (none)
brcc ScreenSaver_OnCreate_ret
; preset SDRAM
bigcall Widget_GetSdramPtr ; (none)
clr r16
ldi r17, SCREENSAVER_SD_SIZE
push yl
push yh
ScreenSaver_OnCreate_loop:
st Y+, r16
dec r17
brne ScreenSaver_OnCreate_loop
pop yh
pop yl
push yl
push yh
bigcall Widget_OnCreate
pop yh
pop yl
ldi r16, LOW(SCREENSAVER_TIMER100ms)
std Y+SCREENSAVER_SD_OFFS_TIMER_LO, r16
ldi r16, HIGH(SCREENSAVER_TIMER100ms)
std Y+SCREENSAVER_SD_OFFS_TIMER_HI, r16
ldi r16, 0xff
bigcall Display_SetBacklight
rcall screenSaverReadFromEeprom
ScreenSaver_OnCreate_ret:
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine ScreenSaver_OnTouch @global
;
; @param Z byte address of widget object (for LPM!)
; @param X pointer to TOUCH event (see @ref WIDGET_DATA_TOUCH_OFFS_X_LO)
; @return CFLAG set if signal handled
; @clobbers any, !Z
ScreenSaver_OnTouch:
bigcall Widget_GetSdramPtr ; Y:=SDRAM data for widget
; read touch signal data from X
adiw xh:xl, WIDGET_DATA_TOUCH_OFFS_STATE
ld r22, X ; WIDGET_DATA_TOUCH_OFFS_STATE
sbiw xh:xl, WIDGET_DATA_TOUCH_OFFS_STATE
sbrs r22, DISPLAY_IFLAGS_PRESSED_BIT
rjmp ScreenSaver_OnTouch_up
; down (active touch), switch display on
ldi r16, 0xff
bigcall Display_SetBacklight
rjmp ScreenSaver_OnTouch_ret
ScreenSaver_OnTouch_up:
rcall ScreenSaver_Leave
ScreenSaver_OnTouch_ret:
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine ScreenSaver_OnMsgReceived @global
;
; @param Z byte address of widget object (for LPM!)
; @param XL node addr
; @param XH value id
; @return CFLAG set if signal handled
; @clobbers any, !Z
ScreenSaver_OnMsgReceived:
push zl
push zh
mov yl, zl
mov yh, zh
ldi zl, LOW(ScreenSaver_MsgTable*2)
ldi zh, HIGH(ScreenSaver_MsgTable*2)
bigcall Main_HandleValueMsg ; (any)
pop zh
pop zl
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine screenSaverHandleSetSource1
;
; @param Y byte address of widget object (for LPM!)
; @param R17 value id
; @param R19:R18 value
; @param R21:R20 denom (e.g. 100, meaning value must be divided by 100)
; @param R22 source address
; @param R23 command
; @param R25:R24 message id
; @return CFLAG set if ACK/NACK requested
; @return R23 command value for ACK/NACK message
; @clobbers R16, R17, R18, R20, R21, X, Y, Z
screenSaverHandleSetSource1:
mov zl, yl
mov zh, yh
bigcall Widget_GetSdramPtr ; Y:=SDRAM data for widget
std Y+SCREENSAVER_SD_OFFS_NODEADDR1, r18
std Y+SCREENSAVER_SD_OFFS_VALUEID1, r19
rcall screenSaverWriteToEeprom ; (R16, R17, R18, R20, R21, X, Y)
ldi r23, NETMSG_CMD_VALUE_SET_ACK
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine screenSaverHandleSetSource2
;
; @param Y byte address of widget object (for LPM!)
; @param R17 value id
; @param R19:R18 value
; @param R21:R20 denom (e.g. 100, meaning value must be divided by 100)
; @param R22 source address
; @param R23 command
; @param R25:R24 message id
; @return CFLAG set if ACK/NACK requested
; @return R23 command value for ACK/NACK message
; @clobbers R16, R17, R18, R20, R21, X, Y, Z
screenSaverHandleSetSource2:
mov zl, yl
mov zh, yh
bigcall Widget_GetSdramPtr ; Y:=SDRAM data for widget
std Y+SCREENSAVER_SD_OFFS_NODEADDR1, r18
std Y+SCREENSAVER_SD_OFFS_VALUEID1, r19
rcall screenSaverWriteToEeprom ; (R16, R17, R18, R20, R21, X, Y)
ldi r23, NETMSG_CMD_VALUE_SET_ACK
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine screenSaverHandleReport
;
; @param Y byte address of widget object (for LPM!)
; @param R17 value id
; @param R19:R18 value
; @param R21:R20 denom (e.g. 100, meaning value must be divided by 100)
; @param R22 source address
; @param R23 command
; @param R25:R24 message id
; @return CFLAG cleared (no ACK/NACK requested)
; @clobbers any
screenSaverHandleReport:
mov zl, yl
mov zh, yh
bigcall Widget_GetSdramPtr ; Y:=SDRAM data for widget
mov r16, r18 ; check for non-zero value
or r16, r19
breq screenSaverHandleReport_end
ldd r16, Y+SCREENSAVER_SD_OFFS_NODEADDR1
cp r16, r22
brne screenSaverHandleReport_l1
ldd r16, Y+SCREENSAVER_SD_OFFS_VALUEID1
cp r16, r17
breq screenSaverHandleReport_matches
screenSaverHandleReport_l1:
ldd r16, Y+SCREENSAVER_SD_OFFS_NODEADDR2
cp r16, r22
brne screenSaverHandleReport_end
ldd r16, Y+SCREENSAVER_SD_OFFS_VALUEID2
cp r16, r17
brne screenSaverHandleReport_end
screenSaverHandleReport_matches:
rcall ScreenSaver_KeepAlive
screenSaverHandleReport_end:
clc ; no ACK needed
ret
; @end
; ---------------------------------------------------------------------------
; @routine screenSaverWriteToEeprom
;
; @param Z byte address of widget object (for LPM!)
; @return CFLAG set if data found and read, cleared on error
; @clobbers R16, R17, R18, R20, R21, X, Y
screenSaverWriteToEeprom:
ldi r16, EEID_SCREENSAVER
bigcall EepromTlv_FindFirst ; (R18)
brcs screenSaverWriteToEeprom_write
ldi r16, EEID_SCREENSAVER
ldi r17, SCREENSAVER_EE_SIZE
bigcall EepromTlv_AddTlv ; X=pointer to EEPROM data (R16, R18, R20, R21)
brcc screenSaverWriteToEeprom_ret
screenSaverWriteToEeprom_write:
bigcall Widget_GetSdramPtr ; (none)
adiw yh:yl, SCREENSAVER_SD_OFFS_NODEADDR1
ldi r18, SCREENSAVER_EE_SIZE
screenSaverWriteToEeprom_loop:
ld r16, Y+
bigcall Eeprom_WriteByteIfChanged ; (R17)
brcc screenSaverWriteToEeprom_ret
adiw xh:xl, 1
dec r18
brne screenSaverWriteToEeprom_loop
sec
screenSaverWriteToEeprom_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine screenSaverReadFromEeprom
;
; @param Z byte address of widget object (for LPM!)
; @return CFLAG set if data found and read, cleared on error
; @clobbers R16, R18, X, Y
screenSaverReadFromEeprom:
ldi r16, EEID_SCREENSAVER
bigcall EepromTlv_FindFirst ; (R18)
brcc screenSaverReadFromEeprom_ret
bigcall Widget_GetSdramPtr ; (none)
adiw yh:yl, SCREENSAVER_SD_OFFS_NODEADDR1
ldi r18, SCREENSAVER_EE_SIZE
screenSaverReadFromEeprom_loop:
bigcall Eeprom_ReadByte ; R16=byte (none)
brcc screenSaverReadFromEeprom_ret
st Y+, r16
adiw xh:xl, 1
dec r18
brne screenSaverReadFromEeprom_loop
sec
screenSaverReadFromEeprom_ret:
ret
; @end
ScreenSaver_MsgTable:
.dw NETMSG_CMD_VALUE_SET | (VALUE_ID_SCREENSAVER_SETSOURCE1<<8), screenSaverHandleSetSource1
.dw NETMSG_CMD_VALUE_SET | (VALUE_ID_SCREENSAVER_SETSOURCE2<<8), screenSaverHandleSetSource2
.dw NETMSG_CMD_VALUE_REPORT, screenSaverHandleReport
.dw 0, 0
ScreenSaver_DefaultSignalmap:
.db 0, OBJECT_SIGNAL_TIMER, LOW(ScreenSaver_OnTimer), HIGH(ScreenSaver_OnTimer)
.db 0, WIDGET_SIGNAL_TOUCH, LOW(ScreenSaver_OnTouch), HIGH(ScreenSaver_OnTouch)
.db 0, OBJECT_SIGNAL_RECVMSG, LOW(ScreenSaver_OnMsgReceived), HIGH(ScreenSaver_OnMsgReceived)
.db 0, WIDGET_SIGNAL_DRAW, LOW(Widget_OnDraw), HIGH(Widget_OnDraw)
.db 0, OBJECT_SIGNAL_CREATE, LOW(ScreenSaver_OnCreate), HIGH(ScreenSaver_OnCreate)
.db 0, 0, 0, 0 ; end of table
#endif