avr: removed old lcd2/gui, replaced by lcd2/gui2.

This commit is contained in:
Martin Preuss
2026-04-14 23:53:30 +02:00
parent 7fb21a2f06
commit 0df5c68fb3
34 changed files with 51 additions and 4835 deletions

View File

@@ -2,10 +2,16 @@
<gwbuild>
<subdirs>
aqhome
base
screensavers
</subdirs>
<extradist>
sensorwatch.asm
README.md
</extradist>
</gwbuild>

View File

@@ -0,0 +1,14 @@
AqHome Control System GUI
This is a simple GUI which allows microcontrollers to use a display.
It is completely written in AVR assembler and therefore rather small
and fast.
It provides layout elements (horizontal, vertical, matrix) which allow for
dynamic GUI elements. With those elements the widgets don't have to be
individually placed by hand, rather placement is delegated to those layout
elements.
This makes it very easy to change existing dialogs since the placement doesn't
have to be recalculated manually.

View File

@@ -1,207 +0,0 @@
object:
- next 2 2
- parent 2 4
- child 2 6
- opts 2 8
- flags 1 9
- selector 1 10
- target 2 12
- signalMap 2 14
widget:
- X 1 15
- Y 1 16
- W 1 17
- H 1 18
- style 2 (ptr) 20
- frontCol 2 2
- backCol 2 4
- borderCol 2 6
- borderWidth 1 7
- font 2 9
- charWidth 1 10
- charHeight 1 11
page: light
- up to 8 light bulbs, each for one device
- lightPage:
- SDRAM: ptr to lightData
- address of target device (1 byte)
- currentMode (1 byte)
- currentColor (4 bytes)
- sensor watch:
- SDRAM vars:
- change limits
- SENSORWATCH_SD_OFFS_UPPERLIMIT_WARN_LO
- SENSORWATCH_SD_OFFS_LOWERLIMIT_WARN_LO
- SENSORWATCH_SD_OFFS_UPPERLIMIT_CRIT_LO
- SENSORWATCH_SD_OFFS_LOWERLIMIT_CRIT_LO
- add private flags (HAVE_VALUE, USE_UPPERWARNLIMIT, USE_LOWERWARNLIMIT, USE_UPPERCRITLIMIT, USE_LOWERCRITLIMIT)
- widgets:
Mode: [Auto] [On] [Off]
Color: [Preset1] [Preset2] [Preset3]
Red: [123]
Green: [123]
Blue: [123]
White: [123]
page: numInput (g_win_numinput)
- SDRAM:
- prevPage
- flags
- minNum
- maxNum
- currPos
- editBuffer[7]
- widgets:
textField:
- SDRAM:
- ptrText
- slots:
- setText(newText)
- draw(): draw text and a cursor behind it
[123 ]
------------
[7] [8] [9]
[4] [5] [6]
[1] [2] [3]
[,] [0] [<]
------------
[Okay] [Abort]
- new pages:
- main window
- buttons for climate, netstats, light, doors
- about window (version, logo etc)
- lights
- mode: on, off, auto
- color: R, G, B, W
- calibrate screen
- digitEdit
- arrow_up, below digit, below arrow_down
- label:
- use ressource id instead of pointer to text!
- print hex numbers (bytes, words, dwords)
- room value:
- bits 0-2: cardinal number (0-7, as in "Buero 1")
- bits 7-3: room type number (32)
- Flur
- Wohnzimmer
- Schlafzimmer
- Kueche
- Buero
- Kinderzimmer
- Abstellraum
- Bad
- new classes:
- choice
- "< TEXT >" (choose by clicking buttons left/right)
- roomLabel (uses room value to print a string)
- flashingLabel
- use timer to blink/flash label, e.g. when values change
- widgets:
- value (flashingLabel)
- imageViewer (use code from testWin)
- generate bigger images (96x96 px)
- light
- window_open
- window_closed
|--------------------------------------|
| CO2-Value Temp Humidity |
| |--------| |--------| |--------| |
| | Cloud | | Temp | | Hum | |
| | | | | | | |
| |--------| |--------| |--------| |
| |
| |-----------| |---| |
| | 1 7 : 4 5 | | S | |
| |-----------| |---| |
| |
|--------------------------------------|
|--------------------------------------|
| CO2-Value Temp Humidity |
| |--------| |--------| |--------| |
| | Cloud | | Temp | | Hum | |
| | | | | | | |
| |--------| |--------| |--------| |
| |
| |---| |---| |---| |---| |---| |
| | < | | N | | L | | ? | | > | |
| |---| |---| |---| |---| |---| |
| |
|--------------------------------------|
Object:
- next
- parent
- firstChild
- options (2 bytes)
- signal handling
- targetAddr (like in FOX)
- selector
- handlerMap:
- selector/signal (00: end), handlerAddr
Widgets:
- x (2 bytes)
- y (2 bytes)
- width (2 bytes)
- height (2 bytes)
- font (2 bytes)
- frontColor (2 bytes)
- backColor (2 bytes)
Labels:
- text
Signals:
- CREATE
- DESTROY
- SHOW
- HIDE
- DRAW
- TIMER
- TOUCH
[- KEY]
- USER = 16
OBJ:
- SDRAM pointer hierher verschieben
- speichere dort:
- FLAGS_LO, FLAGS_HI (2 bytes)
- NEXT, PARENT, CHILD (6 bytes)
- OBJ_AddNeighbour()
- OBJ_AddChild()
- OBJ_Unlink()

View File

@@ -0,0 +1,11 @@
<?xml?>
<gwbuild>
<extradist>
sensorwatch.asm
</extradist>
</gwbuild>

View File

@@ -0,0 +1,663 @@
; ***************************************************************************
; 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_SENSORWATCH_ASM
#define AQH_AVR_GUI2_SENSORWATCH_ASM
; ***************************************************************************
; defines
.equ SENSORWATCH_OFFS_BEGIN = VLAYOUT_SIZE
.equ SENSORWATCH_OFFS_BASEVALUEID = SENSORWATCH_OFFS_BEGIN+0
.equ SENSORWATCH_OFFS_EEPROMID = SENSORWATCH_OFFS_BEGIN+1
.equ SENSORWATCH_OFFS_NODEADDR = SENSORWATCH_OFFS_BEGIN+2
.equ SENSORWATCH_OFFS_VALUEID = SENSORWATCH_OFFS_BEGIN+3
.equ SENSORWATCH_OFFS_UPPER_LIMIT_WARN_LO = SENSORWATCH_OFFS_BEGIN+4
.equ SENSORWATCH_OFFS_UPPER_LIMIT_WARN_HI = SENSORWATCH_OFFS_BEGIN+5
.equ SENSORWATCH_OFFS_LOWER_LIMIT_WARN_LO = SENSORWATCH_OFFS_BEGIN+6
.equ SENSORWATCH_OFFS_LOWER_LIMIT_WARN_HI = SENSORWATCH_OFFS_BEGIN+7
.equ SENSORWATCH_OFFS_UPPER_LIMIT_CRIT_LO = SENSORWATCH_OFFS_BEGIN+8
.equ SENSORWATCH_OFFS_UPPER_LIMIT_CRIT_HI = SENSORWATCH_OFFS_BEGIN+9
.equ SENSORWATCH_OFFS_LOWER_LIMIT_CRIT_LO = SENSORWATCH_OFFS_BEGIN+10
.equ SENSORWATCH_OFFS_LOWER_LIMIT_CRIT_HI = SENSORWATCH_OFFS_BEGIN+11
.equ SENSORWATCH_OFFS_VALUE_LO = SENSORWATCH_OFFS_BEGIN+12
.equ SENSORWATCH_OFFS_VALUE_HI = SENSORWATCH_OFFS_BEGIN+13
.equ SENSORWATCH_OFFS_TYPE = SENSORWATCH_OFFS_BEGIN+14
.equ SENSORWATCH_SIZE = SENSORWATCH_OFFS_BEGIN+15
; values (not used for now)
.equ SENSORWATCH_VALUE = WIDGET_VALUE_NEXTFREE+0
.equ SENSORWATCH_VALUE_NEXTFREE = SENSORWATCH_VALUE+1
; sensor types
.equ SENSORWATCH_TYPE_CO2 = 1
.equ SENSORWATCH_TYPE_TEMP = 2
.equ SENSORWATCH_TYPE_HUM = 3
.equ SENSORWATCH_TYPE_NEXTFREE = 4
; indices of child widgets
.equ SENSORWATCH_CHILDIDX_TITLE = 0
.equ SENSORWATCH_CHILDIDX_IMAGEVIEW = 1
.equ SENSORWATCH_CHILDIDX_VALUELABEL = 2
; descriptors
.equ SENSORWATCH_DESCR_OFFS_TITLERES = 0
.equ SENSORWATCH_DESCR_OFFS_IMGRES = 2
.equ SENSORWATCH_DESCR_OFFS_POSTKOMMADIGITS = 4
; EEPROM data for SensorWatch
.equ SENSORWATCH_EE_OFFS_NODEADDR = 0
.equ SENSORWATCH_EE_OFFS_VALUEID = 1
.equ SENSORWATCH_EE_OFFS_UPPER_LIMIT_WARN_LO = 2
.equ SENSORWATCH_EE_OFFS_UPPER_LIMIT_WARN_HI = 3
.equ SENSORWATCH_EE_OFFS_LOWER_LIMIT_WARN_LO = 4
.equ SENSORWATCH_EE_OFFS_LOWER_LIMIT_WARN_HI = 5
.equ SENSORWATCH_EE_OFFS_UPPER_LIMIT_CRIT_LO = 6
.equ SENSORWATCH_EE_OFFS_UPPER_LIMIT_CRIT_HI = 7
.equ SENSORWATCH_EE_OFFS_LOWER_LIMIT_CRIT_LO = 8
.equ SENSORWATCH_EE_OFFS_LOWER_LIMIT_CRIT_HI = 9
.equ SENSORWATCH_EE_SIZE = 10
; ***************************************************************************
; code
.cseg
; ---------------------------------------------------------------------------
; @routine SensorWatch_new @global
;
; @return CFLAG set of okay, cleared otherwise
; @return Y address of newly created object
; @param X parent widget
; @param r16 value for OBJECT_OFFS_OPTS
; @param r17 value for WIDGET_OFFS_PACK
; @param r20 base value id
; @param r21 eeprom id
; @param r22 type (see @ref SENSORWATCH_TYPE_CO2)
; @clobbers any
SensorWatch_new:
push r20
push r21
push r22
ldi r24, LOW(SENSORWATCH_SIZE)
ldi r25, HIGH(SENSORWATCH_SIZE)
bigcall Object_Alloc ; (!r16, !r17, !X)
pop r22
pop r21
pop r20
brcc SensorWatch_new_ret
rcall SensorWatch_Init ; (r16, r17, X)
sec
SensorWatch_new_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine SensorWatch_Init @global
;
; @param Y address of widget
; @param X parent widget (if any)
; @param r16 value for OBJECT_OFFS_OPTS
; @param r17 value for WIDGET_OFFS_PACK
; @param r20 base value id
; @param r21 eeprom id
; @param r22 type (see @ref SENSORWATCH_TYPE_CO2)
; @clobbers r16, r17, X
SensorWatch_Init:
push r20
push r21
push r22
; call base class
ldi r20, VLAYOUT_MODE_EXPAND
bigcall VLayout_Init
pop r22
pop r21
pop r20
; setup sensorWatch data
std Y+SENSORWATCH_OFFS_BASEVALUEID, r20
std Y+SENSORWATCH_OFFS_EEPROMID, r21
std Y+SENSORWATCH_OFFS_TYPE, r22
; set default signal map
ldi r16, LOW(SensorWatch_DefaultSignalmap*2)
std Y+OBJECT_OFFS_SIGNALMAP_LO, r16
ldi r16, HIGH(SensorWatch_DefaultSignalmap*2)
std Y+OBJECT_OFFS_SIGNALMAP_HI, r16
; create sub windows
rcall sensorWatchCreateTitleLabel
rcall sensorWatchCreateImageViewer
rcall sensorWatchCreateValueLabel
rcall sensorWatchReadFromEeprom ; (R16, R18, X)
ret
; @end
; ---------------------------------------------------------------------------
; @routine sensorWatchGetTitleResId
;
; @param r16 sensor type (see @ref SENSORWATCH_TYPE_CO2)
; @return r21:r20 ressource for sensor title
sensorWatchGetTitleResId:
rcall sensorWatchGetDescriptor ; (r17, r18, r19)
adiw zh:zl, SENSORWATCH_DESCR_OFFS_TITLERES
lpm r20, Z+
lpm r21, Z
ret
; @end
; ---------------------------------------------------------------------------
; @routine sensorWatchGetImgResId
;
; @param r16 sensor type (see @ref SENSORWATCH_TYPE_CO2)
; @return r21:r20 ressource for sensor title
sensorWatchGetImgResId:
rcall sensorWatchGetDescriptor ; (r17, r18, r19)
adiw zh:zl, SENSORWATCH_DESCR_OFFS_IMGRES
lpm r20, Z+
lpm r21, Z
ret
; @end
; ---------------------------------------------------------------------------
; @routine sensorWatchGetPostKommaDigits
;
; @param r16 sensor type (see @ref SENSORWATCH_TYPE_CO2)
; @return r20 postkomma digits
sensorWatchGetPostKommaDigits:
rcall sensorWatchGetDescriptor ; (r17, r18, r19)
adiw zh:zl, SENSORWATCH_DESCR_OFFS_POSTKOMMADIGITS
lpm r20, Z
ret
; @end
; ---------------------------------------------------------------------------
; @routine sensorWatchGetDescriptor
;
; @param r16 sensor type (see @ref SENSORWATCH_TYPE_CO2)
; @return Z byte address of start of descriptor for sensor type (for LPM!)
; @clobbers r17, r18, r19
sensorWatchGetDescriptor:
cpi r16, SENSORWATCH_TYPE_NEXTFREE
brcs sensorWatchGetDescriptor_get
clr r16 ; default to entry 0
sensorWatchGetDescriptor_get:
ldi zl, LOW(SensorWatch_Descriptors*2)
ldi zh, HIGH(SensorWatch_Descriptors*2)
clr r17
mov r18, r16
mov r19, r17
lsl r18 ; *2
rol r19
add r18, r16 ; *3
adc r19, r17
lsl r18 ; *6
rol r19
add zl, r18
adc zh, r19
ret
; @end
; ---------------------------------------------------------------------------
; @routine sensorWatchCreateTitleLabel
;
; @param Y address of main window widget
; @param r21:r20 ressource id for title
; @return CFLAG set of okay, cleared otherwise
sensorWatchCreateTitleLabel:
push yl
push yh
ldd r16, Y+SENSORWATCH_OFFS_TYPE
rcall sensorWatchGetTitleResId ; r21:r20=ressource id for title
mov xl, yl
mov xh, yh
ldi r16, 0
ldi r17, (WIDGET_PACK_CENTER<<WIDGET_PACK_HSELF0_BIT) | (WIDGET_PACK_BEGIN<<WIDGET_PACK_VSELF0_BIT) | \
(WIDGET_PACK_CENTER<<WIDGET_PACK_HCONTENT0_BIT) | (WIDGET_PACK_CENTER<<WIDGET_PACK_VCONTENT0_BIT)
bigcall Label_new
pop yh
pop yl
ret
; @end
; ---------------------------------------------------------------------------
; @routine sensorWatchCreateImageViewer
;
; @param Y address of main window widget
; @param r21:r20 ressource id for image
; @return CFLAG set of okay, cleared otherwise
sensorWatchCreateImageViewer:
push yl
push yh
ldd r16, Y+SENSORWATCH_OFFS_TYPE
rcall sensorWatchGetImgResId ; r21:r20=ressource id for image
mov xl, yl
mov xh, yh
ldi r16, 0
ldi r17, (WIDGET_PACK_CENTER<<WIDGET_PACK_HSELF0_BIT) | (WIDGET_PACK_BEGIN<<WIDGET_PACK_VSELF0_BIT) | \
(WIDGET_PACK_CENTER <<WIDGET_PACK_HCONTENT0_BIT) | (WIDGET_PACK_CENTER<<WIDGET_PACK_VCONTENT0_BIT)
bigcall ImageView_new
pop yh
pop yl
ret
; @end
; ---------------------------------------------------------------------------
; @routine sensorWatchCreateValueLabel
;
; @param Y address of main window widget
; @return CFLAG set of okay, cleared otherwise
sensorWatchCreateValueLabel:
push yl
push yh
ldd r16, Y+SENSORWATCH_OFFS_TYPE
rcall sensorWatchGetPostKommaDigits ; r20=postkomma digits
mov xl, yl
mov xh, yh
ldi r16, 0
ldi r17, (WIDGET_PACK_FILLED<<WIDGET_PACK_HSELF0_BIT) | (WIDGET_PACK_BEGIN<<WIDGET_PACK_VSELF0_BIT) | \
(WIDGET_PACK_CENTER <<WIDGET_PACK_HCONTENT0_BIT) | (WIDGET_PACK_CENTER<<WIDGET_PACK_VCONTENT0_BIT)
bigcall ValueLabel_new
pop yh
pop yl
ret
; @end
; ---------------------------------------------------------------------------
; @routine SensorWatch_GetImageView @global
;
; @param Y pointer to widget
; @return CFLAG set if widget found, cleared otherwise
; @return R19:R18 byte address pointer to image view (for LPM!)
; @clobbers R16
SensorWatch_GetImageView:
ldi r16, SENSORWATCH_CHILDIDX_IMAGEVIEW
bigcall OBJ_GetChildAt
ret
; @end
; ---------------------------------------------------------------------------
; @routine SensorWatch_GetValueLabel @global
;
; @param Y pointer to widget
; @return CFLAG set if widget found, cleared otherwise
; @return R19:R18 byte address pointer to image view (for LPM!)
; @clobbers R16
SensorWatch_GetValueLabel:
ldi r16, SENSORWATCH_CHILDIDX_VALUELABEL
bigcall OBJ_GetChildAt
ret
; @end
; ---------------------------------------------------------------------------
; @routine SensorWatch_OnRecvReport @global
;
; @param Y pointer to widget
; @param X pointer to message
SensorWatch_OnRecvReport:
bigcall NETMSG_ValueRead ; R17=valueId, R22=nodeAddr R19:R18=value (none)
; check node addr
ldd r16, Y+SENSORWATCH_OFFS_NODEADDR
cp r16, r22
brne SensorWatch_OnRecvReport_ret
; check value id
ldd r16, Y+SENSORWATCH_OFFS_VALUEID
cp r16, r17
brne SensorWatch_OnRecvReport_ret
; store value
std Y+SENSORWATCH_OFFS_VALUE_LO, r18
std Y+SENSORWATCH_OFFS_VALUE_HI, r19
; setup background color
push xl
push xh
rcall sensorWatchSetColor ; (any, !Y)
rcall sensorWatchSetValueLabel ; (any, !Y)
pop xh
pop xl
SensorWatch_OnRecvReport_ret:
clc
ret
; @end
; ---------------------------------------------------------------------------
; @routine SensorWatch_OnRecvSet @global
;
; @param Y pointer to widget
; @param X pointer to message
SensorWatch_OnRecvSet:
bigcall NETMSG_ValueRead ; R17=valueId, R22=nodeAddr R19:R18=value (none)
ldd r16, Y+SENSORWATCH_OFFS_BASEVALUEID
sub r17, r16
brcs SensorWatch_OnRecvSet_clcRet
cpi r17, 0
breq SensorWatch_OnRecvSet_setSource
cpi r17, 1
breq SensorWatch_OnRecvSet_setLimWarn
cpi r17, 2
breq SensorWatch_OnRecvSet_setLimCrit
rjmp SensorWatch_OnRecvSet_clcRet
SensorWatch_OnRecvSet_setSource:
std Y+SENSORWATCH_OFFS_NODEADDR, r18
std Y+SENSORWATCH_OFFS_VALUEID, r19
rjmp SensorWatch_OnRecvSet_sendACK
SensorWatch_OnRecvSet_setLimWarn:
std Y+SENSORWATCH_OFFS_LOWER_LIMIT_WARN_LO, r18
std Y+SENSORWATCH_OFFS_LOWER_LIMIT_WARN_HI, r19
std Y+SENSORWATCH_OFFS_UPPER_LIMIT_WARN_LO, r20
std Y+SENSORWATCH_OFFS_UPPER_LIMIT_WARN_HI, r21
rjmp SensorWatch_OnRecvSet_sendACK
SensorWatch_OnRecvSet_setLimCrit:
std Y+SENSORWATCH_OFFS_LOWER_LIMIT_CRIT_LO, r18
std Y+SENSORWATCH_OFFS_LOWER_LIMIT_CRIT_HI, r19
std Y+SENSORWATCH_OFFS_UPPER_LIMIT_CRIT_LO, r20
std Y+SENSORWATCH_OFFS_UPPER_LIMIT_CRIT_HI, r21
SensorWatch_OnRecvSet_sendACK:
add r17, r16 ; restore valueId
push xl
push xh
push yl
push yh
ldi r23, NETMSG_CMD_VALUE_SET_ACK
bigcall Main_SendValueResponse ; (clobbers all except Z)
pop yh
pop yl
rcall sensorWatchSetColor ; (any, !Y)
rcall sensorWatchWriteToEeprom ; (R16, R17, R18, R20, R21, X)
pop xh
pop xl
sec
rjmp SensorWatch_OnRecvSet_ret
SensorWatch_OnRecvSet_clcRet:
clc
SensorWatch_OnRecvSet_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine sensorWatchSetValueLabel
;
; @param Z byte address of widget object (for LPM!)
; @param Y pointer to SDRAM data
; @clobbers any, !Y, !Z
sensorWatchSetValueLabel:
rcall SensorWatch_GetValueLabel ; (none)
brcc sensorWatchSetValueLabel_ret
push yl
push yh
ldd xl, Y+SENSORWATCH_OFFS_VALUE_LO
ldd xh, Y+SENSORWATCH_OFFS_VALUE_HI
mov yl, r18
mov yh, r19
ldi r17, VLABEL_VALUE
bigcall Widget_SetValue ; (any, !Y)
pop yh
pop yl
sensorWatchSetValueLabel_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine sensorWatchSetColor
;
; @param Y pointer to widget
; @clobbers any, !Y
sensorWatchSetColor:
; default color is green
ldi xl, LOW(DISPLAY_COLOR_DARKGREEN)
ldi xh, HIGH(DISPLAY_COLOR_DARKGREEN)
ldd r20, Y+SENSORWATCH_OFFS_VALUE_LO
ldd r21, Y+SENSORWATCH_OFFS_VALUE_HI
mov r16, r20
or r16, r21
breq sensorWatchSetColor_ret ; do nothing
; check against critical limits
mov zl, yl
mov zh, yh
adiw zh:zl, SENSORWATCH_OFFS_UPPER_LIMIT_CRIT_LO
rcall sensorWatchCheckAgainstLimit ; (r16, r17, r22, r23)
brcs sensorWatchSetColor_setRed
; check against warning limits
mov zl, yl
mov zh, yh
adiw zh:zl, SENSORWATCH_OFFS_UPPER_LIMIT_WARN_LO
rcall sensorWatchCheckAgainstLimit ; (r16, r17, r22, r23)
brcs sensorWatchSetColor_setYellow
; set green background
rjmp sensorWatchSetColor_setColor
sensorWatchSetColor_setRed:
ldi xl, LOW(DISPLAY_COLOR_RED)
ldi xh, HIGH(DISPLAY_COLOR_RED)
rjmp sensorWatchSetColor_setColor
sensorWatchSetColor_setYellow:
ldi xl, LOW(DISPLAY_COLOR_YELLOW)
ldi xh, HIGH(DISPLAY_COLOR_YELLOW)
sensorWatchSetColor_setColor:
rcall SensorWatch_GetImageView ; (r16)
brcc sensorWatchSetColor_ret
push yl
push yh
mov yl, r18
mov yh, r19
ldi r17, IMAGEVIEW_VALUE_BGCOL
bigcall Widget_SetValue ; (any, !Y)
pop yh
pop yl
sensorWatchSetColor_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine sensorWatchCheckAgainstLimit
;
; @param R21:R20 value to check against limit
; @param Z points to upper limit (lo/hi), followed by lower limit (lo/hi)
; @return CFLAG set if limit triggered, cleared if between upper and lower limit
; @clobbers r16, r17, r22, r23
sensorWatchCheckAgainstLimit:
; check against upper limit (if any)
ld r22, Z+
ld r23, Z+
mov r16, r22
or r16, r23 ; zero?
breq sensorWatchCheckAgainstLimit_checkLower
; r23:r22=upper limit
cp r20, r22 ; upper limit > value?
cpc r21, r23
brcc sensorWatchCheckAgainstLimit_secRet ; no, upper limit breached
sensorWatchCheckAgainstLimit_checkLower:
; check against lower limit (if any)
ld r22, Z+
ld r23, Z+
mov r16, r22
or r16, r23 ; zero?
clc
breq sensorWatchCheckAgainstLimit_ret ; yes, jmp
cp r20, r22 ; value below lower limit?
cpc r21, r23
brcs sensorWatchCheckAgainstLimit_secRet ; yes -> lower limit breached
clc ; limit not breached
rjmp sensorWatchCheckAgainstLimit_ret
sensorWatchCheckAgainstLimit_secRet:
sec
sensorWatchCheckAgainstLimit_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine sensorWatchWriteToEeprom
;
; @param Y pointer to widget
; @return CFLAG set if data found and read, cleared on error
; @clobbers R16, R17, R18, R20, R21, X
sensorWatchWriteToEeprom:
ldd r16, Y+SENSORWATCH_OFFS_EEPROMID
tst r16
clc
breq sensorWatchWriteToEeprom_ret
push r16
bigcall EepromTlv_FindFirst ; (R18)
pop r16
brcs sensorWatchWriteToEeprom_write
ldi r17, SENSORWATCH_EE_SIZE
bigcall EepromTlv_AddTlv ; X=pointer to EEPROM data (R16, R18, R20, R21)
brcc sensorWatchWriteToEeprom_ret
sensorWatchWriteToEeprom_write:
push yl
push yh
adiw yh:yl, SENSORWATCH_OFFS_NODEADDR
ldi r18, SENSORWATCH_EE_SIZE
sensorWatchWriteToEeprom_loop:
ld r16, Y+
bigcall Eeprom_WriteByteIfChanged ; (R17)
brcc sensorWatchWriteToEeprom_loopEnd
adiw xh:xl, 1
dec r18
brne sensorWatchWriteToEeprom_loop
sec
sensorWatchWriteToEeprom_loopEnd:
pop yh
pop yl
sensorWatchWriteToEeprom_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine sensorWatchReadFromEeprom
;
; @param Y pointer to widget
; @return CFLAG set if data found and read, cleared on error
; @clobbers R16, R18, X
sensorWatchReadFromEeprom:
ldd r16, Y+SENSORWATCH_OFFS_EEPROMID
bigcall EepromTlv_FindFirst ; (R18)
brcc sensorWatchReadFromEeprom_ret
push yl
push yh
adiw yh:yl, SENSORWATCH_OFFS_NODEADDR
ldi r18, SENSORWATCH_EE_SIZE
sensorWatchReadFromEeprom_loop:
bigcall Eeprom_ReadByte ; R16=byte (none)
brcc sensorWatchReadFromEeprom_loopEnd
st Y+, r16
adiw xh:xl, 1
dec r18
brne sensorWatchReadFromEeprom_loop
sec
sensorWatchReadFromEeprom_loopEnd:
pop yh
pop yl
sensorWatchReadFromEeprom_ret:
ret
; @end
; ***************************************************************************
; data in FLASH
SensorWatch_DefaultSignalmap:
; header
.dw VLayout_DefaultSignalmap*2 ; next table to use
; entries
.db 0, WIDGET_SIGNAL_DRAW, LOW(Widget_OnDraw), HIGH(Widget_OnDraw)
.db NETMSG_CMD_VALUE_REPORT, OBJECT_SIGNAL_RECVMSG, LOW(SensorWatch_OnRecvReport), HIGH(SensorWatch_OnRecvReport)
.db NETMSG_CMD_VALUE_SET, OBJECT_SIGNAL_RECVMSG, LOW(SensorWatch_OnRecvSet), HIGH(SensorWatch_OnRecvSet)
.db 0, 0, 0, 0 ; end of table
SensorWatch_Descriptors:
; res for title res for image post-komma digits
.dw RESSSOURCE_TXT_UNKNOWN_S, RESSSOURCE_IMG_CLOUD96, 0 ; unknown
.dw RESSSOURCE_TXT_CO2_S, RESSSOURCE_IMG_CLOUD96, 0 ; co2
.dw RESSSOURCE_TXT_TEMP_S, RESSSOURCE_IMG_TEMP96, 2 ; temp
.dw RESSSOURCE_TXT_HUM_S, RESSSOURCE_IMG_HUMIDITY96, 0 ; hum
#endif

View File

@@ -5,11 +5,16 @@
<extradist>
button.asm
guiapp.asm
hlayout.asm
imageview.asm
label.asm
layout.asm
mainwindow.asm
mclayout.asm
object.asm
rootwidget.asm
rootwindow.asm
valuelabel.asm
vlayout.asm
widget.asm
</extradist>

View File

@@ -0,0 +1,348 @@
; ***************************************************************************
; 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_BUTTON_ASM
#define AQH_AVR_GUI2_BUTTON_ASM
; ***************************************************************************
; defines
.equ BUTTON_OFFS_BEGIN = WIDGET_SIZE
.equ BUTTON_OFFS_MODE = BUTTON_OFFS_BEGIN+0
.equ BUTTON_OFFS_STATE = BUTTON_OFFS_BEGIN+1
.equ BUTTON_OFFS_TIMER = BUTTON_OFFS_BEGIN+2
.equ BUTTON_SIZE = BUTTON_OFFS_BEGIN+3
.equ BUTTON_REPEAT_TIMER_WAITREPEAT = 10
.equ BUTTON_REPEAT_TIMER_REPEAT = 7
; button modes
.equ BUTTON_MODE_NORMAL = 0
.equ BUTTON_MODE_REPEATED = 1
; button states
.equ BUTTON_STATE_INACTIVE = 0
.equ BUTTON_STATE_ACTIVE = 1
.equ BUTTON_STATE_WAITREPEAT = 2
.equ BUTTON_STATE_REPEATING = 3
; ***************************************************************************
; code
.cseg
; ---------------------------------------------------------------------------
; @routine Button_new @global
;
; @return CFLAG set of okay, cleared otherwise
; @return Y address of newly created object
; @param X parent widget
; @param r16 value for OBJECT_OFFS_OPTS
; @param r17 value for WIDGET_OFFS_PACK
; @param r20 mode
; @clobbers any
Button_new:
push r20
ldi r24, LOW(BUTTON_SIZE)
ldi r25, HIGH(BUTTON_SIZE)
bigcall Object_Alloc ; (!r16, !r17, !X)
pop r20
brcc Button_new_ret
rcall Button_Init ; (r16, r17, X)
sec
Button_new_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine Button_Init @global
;
; @param Y address of widget
; @param X parent widget (if any)
; @param r16 value for OBJECT_OFFS_OPTS
; @param r17 value for WIDGET_OFFS_PACK
; @param r20 mode
; @clobbers r16, r17, X
Button_Init:
push r20
; call base class
bigcall Widget_Init ; (r16, r17, X)
pop r20
; setup button data
std Y+BUTTON_OFFS_MODE, r20
; set input opts
ldd r16, Y+OBJECT_OFFS_OPTS
sbr r16, (1<<WIDGET_OPTS_INPUT_BIT)
std Y+OBJECT_OFFS_OPTS, r16
; set default signal map
ldi r16, LOW(Button_DefaultSignalmap*2)
std Y+OBJECT_OFFS_SIGNALMAP_LO, r16
ldi r16, HIGH(Button_DefaultSignalmap*2)
std Y+OBJECT_OFFS_SIGNALMAP_HI, r16
ret
; @end
; ---------------------------------------------------------------------------
; @routine Button_OnTouchBegin @global
;
; @param Y address of widget
; @param xl param1
; @param xh param2
; @return CFLAG set if signal handled
; @clobbers any, !Y
Button_OnTouchBegin:
ldi r16, (1<<WIDGET_FLAGS_ACTIVATED_BIT) | (1<<WIDGET_FLAGS_DIRTY_BIT)
bigcall OBJ_AddFlagsDown ; (r17, r18, r19)
ldd r16, Y+BUTTON_OFFS_MODE
cpi r16, BUTTON_MODE_REPEATED
breq Button_OnTouchBegin_repeated
ldi r16, BUTTON_STATE_ACTIVE
std Y+BUTTON_OFFS_STATE, r16
clr r16
std Y+BUTTON_OFFS_TIMER, r16
rjmp Button_OnTouchBegin_done
Button_OnTouchBegin_repeated:
ldi r16, BUTTON_STATE_WAITREPEAT
std Y+BUTTON_OFFS_STATE, r16
ldi r16, BUTTON_REPEAT_TIMER_WAITREPEAT
std Y+BUTTON_OFFS_TIMER, r16
Button_OnTouchBegin_done:
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine Button_OnTouchEnd @global
;
; @param Y address of widget
; @param xl param1
; @param xh param2
; @return CFLAG set if signal handled
; @clobbers any, !Y
Button_OnTouchEnd:
ldi r16, (1<<WIDGET_FLAGS_ACTIVATED_BIT)
bigcall OBJ_SubFlagsDown ; (r17, r18, r19)
ldi r16, (1<<WIDGET_FLAGS_DIRTY_BIT)
bigcall OBJ_AddFlagsDown ; (r17, r18, r19)
clr r16
std Y+BUTTON_OFFS_TIMER, r16
ldd r16, Y+BUTTON_OFFS_STATE
cpi r16, BUTTON_STATE_REPEATING
breq Button_OnTouchEnd_done
ldi r16, WIDGET_SIGNAL_COMMAND
bigcall OBJ_EmitSignal
Button_OnTouchEnd_done:
ldi r16, BUTTON_STATE_INACTIVE
std Y+BUTTON_OFFS_STATE, r16
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine Button_OnTouchMove @global
;
; @param Y address of widget
; @param xl param1
; @param xh param2
; @return CFLAG set if signal handled
; @clobbers any, !Y
Button_OnTouchMove:
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine Button_OnTimer @global
;
; @param Y address of widget
; @param xl param1
; @param xh param2
; @return CFLAG set if signal handled
; @clobbers any, !Y
Button_OnTimer:
ldd r16, Y+BUTTON_OFFS_TIMER
tst r16
breq Button_OnTimer_ret
dec r16
std Y+BUTTON_OFFS_TIMER, r16
brne Button_OnTimer_ret
; timer elapsed
ldd r17, Y+BUTTON_OFFS_STATE
cpi r17, BUTTON_STATE_WAITREPEAT
breq Button_OnTimer_waitRepeat
cpi r17, BUTTON_STATE_REPEATING
breq Button_OnTimer_repeating
rjmp Button_OnTimer_ret
Button_OnTimer_waitRepeat:
ldi r17, BUTTON_STATE_REPEATING
std Y+BUTTON_OFFS_STATE, r17
Button_OnTimer_repeating:
ldi r16, BUTTON_REPEAT_TIMER_REPEAT
std Y+BUTTON_OFFS_TIMER, r16
ldi r16, WIDGET_SIGNAL_COMMAND
bigcall OBJ_EmitSignal
Button_OnTimer_ret:
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine Button_OnGetDefaultWidth @global
;
; @param Y address of widget
; @param r17 value requested
; @param xl param1
; @param xh param2
; @return CFLAG set if signal handled
; @return r19:r18 value
; @clobbers any, !Y
Button_OnGetDefaultWidth:
bigcall OBJ_GetFirstChild
brcc Button_OnGetDefaultWidth_ret
push yl
push yh
mov yl, r18
mov yh, r19
bigcall Widget_GetDefaultWidth
pop yh
pop yl
Button_OnGetDefaultWidth_ret:
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine Button_OnGetDefaultHeight @global
;
; @param Y address of widget
; @param xl param1
; @param xh param2
; @return CFLAG set if signal handled
; @return r19:r18 value
; @clobbers any, !Y
Button_OnGetDefaultHeight:
bigcall OBJ_GetFirstChild
brcc Button_OnGetDefaultHeight_ret
push yl
push yh
mov yl, r18
mov yh, r19
bigcall Widget_GetDefaultHeight
pop yh
pop yl
Button_OnGetDefaultHeight_ret:
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine Button_OnLayout @global
;
; @param Y address of widget
; @return CFLAG set if signal handled
; @clobbers any, !Y
Button_OnLayout:
bigcall OBJ_GetFirstChild
brcc Button_OnLayout_ret
ldd r16, Y+WIDGET_OFFS_WIDTH_LO
ldd r17, Y+WIDGET_OFFS_WIDTH_HI
ldd r20, Y+WIDGET_OFFS_HEIGHT_LO
ldd r21, Y+WIDGET_OFFS_HEIGHT_HI
push yl
push yh
mov yl, r18
mov yh, r19
std Y+WIDGET_OFFS_WIDTH_LO, r16
std Y+WIDGET_OFFS_WIDTH_HI, r17
std Y+WIDGET_OFFS_HEIGHT_LO, r20
std Y+WIDGET_OFFS_HEIGHT_HI, r21
clr r16
std Y+WIDGET_OFFS_X_LO, r16
std Y+WIDGET_OFFS_X_HI, r16
std Y+WIDGET_OFFS_Y_LO, r16
std Y+WIDGET_OFFS_Y_HI, r16
; force layout and redraw
ldd r16, Y+OBJECT_OFFS_FLAGS
ori r16, (1<<WIDGET_FLAGS_LAYOUT_BIT) | (1<<WIDGET_FLAGS_DIRTY_BIT)
std Y+OBJECT_OFFS_FLAGS, r16
pop yh
pop yl
Button_OnLayout_ret:
ldd r16, Y+OBJECT_OFFS_FLAGS
cbr r16, (1<<WIDGET_FLAGS_LAYOUT_BIT)
std Y+OBJECT_OFFS_FLAGS, r16
sec
ret
; @end
; ***************************************************************************
; data in FLASH
Button_DefaultSignalmap:
; header
.dw Widget_DefaultSignalmap*2 ; next table to use
; entries
.db 0, OBJECT_SIGNAL_TIMER, LOW(Button_OnTimer), HIGH(Button_OnTimer)
.db 0, WIDGET_SIGNAL_DRAW, LOW(Widget_OnDrawNop), HIGH(Widget_OnDrawNop)
.db 0, WIDGET_SIGNAL_TOUCH, LOW(Widget_OnTouch), HIGH(Widget_OnTouch)
.db 0, WIDGET_SIGNAL_TOUCH_BEGIN, LOW(Button_OnTouchBegin), HIGH(Button_OnTouchBegin)
.db 0, WIDGET_SIGNAL_TOUCH_END, LOW(Button_OnTouchEnd), HIGH(Button_OnTouchEnd)
.db 0, WIDGET_SIGNAL_TOUCH_MOVE, LOW(Button_OnTouchMove), HIGH(Button_OnTouchMove)
.db 0, WIDGET_SIGNAL_LAYOUT, LOW(Button_OnLayout), HIGH(Button_OnLayout)
.db WIDGET_VALUE_DEFAULT_WIDTH, WIDGET_SIGNAL_GETVALUE, LOW(Button_OnGetDefaultWidth), HIGH(Button_OnGetDefaultWidth)
.db WIDGET_VALUE_DEFAULT_HEIGHT, WIDGET_SIGNAL_GETVALUE, LOW(Button_OnGetDefaultHeight), HIGH(Button_OnGetDefaultHeight)
.db 0, 0, 0, 0 ; end of table
#endif

View File

@@ -0,0 +1,775 @@
; ***************************************************************************
; 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_GUIAPP_ASM
#define AQH_AVR_GUI2_GUIAPP_ASM
; ***************************************************************************
; defines
.equ GUIAPP_WINDOWSTACK_ENTRIES = 8
; Widget in flash
.equ GUIAPP_OFFS_BEGIN = OBJECT_SIZE
.equ GUIAPP_OFFS_ROOTWINDOW_LO = GUIAPP_OFFS_BEGIN+0
.equ GUIAPP_OFFS_ROOTWINDOW_HI = GUIAPP_OFFS_BEGIN+1
.equ GUIAPP_OFFS_SCREENSAVER_LO = GUIAPP_OFFS_BEGIN+2
.equ GUIAPP_OFFS_SCREENSAVER_HI = GUIAPP_OFFS_BEGIN+3
.equ GUIAPP_OFFS_CURRENTWINDOW_LO = GUIAPP_OFFS_BEGIN+4
.equ GUIAPP_OFFS_CURRENTWINDOW_HI = GUIAPP_OFFS_BEGIN+5
.equ GUIAPP_OFFS_TOUCHWIDGET_LO = GUIAPP_OFFS_BEGIN+6
.equ GUIAPP_OFFS_TOUCHWIDGET_HI = GUIAPP_OFFS_BEGIN+7
.equ GUIAPP_OFFS_GUITIMER = GUIAPP_OFFS_BEGIN+8
.equ GUIAPP_OFFS_WINDOWSTACK_POS = GUIAPP_OFFS_BEGIN+9
.equ GUIAPP_OFFS_WINDOWSTACK_BEGIN = GUIAPP_OFFS_BEGIN+10
.equ GUIAPP_SIZE = GUIAPP_OFFS_WINDOWSTACK_BEGIN+(GUIAPP_WINDOWSTACK_ENTRIES*2)
.equ GUIAPP_GUITIMER = 2
; ***************************************************************************
; data
.dseg
guiapp_touch_event:
.byte WIDGET_TOUCH_SIZE
; ***************************************************************************
; code
.cseg
; ---------------------------------------------------------------------------
; @routine GuiApp_new @global
;
; @return CFLAG set of okay, cleared otherwise
; @return Y address of newly created object
; @param r16 value for OBJECT_OFFS_OPTS
; @clobbers any
GuiApp_new:
ldi r24, LOW(GUIAPP_SIZE)
ldi r25, HIGH(GUIAPP_SIZE)
bigcall Object_Alloc ; (!r16, !r17)
brcc GuiApp_new_ret
rcall GuiApp_Init ; (r16, r17, X)
sec
GuiApp_new_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine GuiApp_Init @global
;
; @param Y address of object in SDRAM
; @param r16 value for OBJECT_OFFS_OPTS
; @clobbers r16, r17, X
GuiApp_Init:
; call base class
bigcall OBJ_Init ; (r16, r17, X)
; set default signal map
ldi r16, LOW(GuiApp_DefaultSignalmap*2)
std Y+OBJECT_OFFS_SIGNALMAP_LO, r16
ldi r16, HIGH(GuiApp_DefaultSignalmap*2)
std Y+OBJECT_OFFS_SIGNALMAP_HI, r16
; create root window
push yl
push yh
mov xl, yl
mov xh, yh
ldi r16, 0 ; opts
ldi r17, 0 ; pack
bigcall RootWindow_new
; always visible
ldd r16, Y+OBJECT_OFFS_FLAGS
sbr r16, (1<<WIDGET_FLAGS_VISIBLE_BIT) | (1<<WIDGET_FLAGS_LAYOUT_BIT) | (1<<WIDGET_FLAGS_DIRTY_BIT)
std Y+OBJECT_OFFS_FLAGS, r16
mov xl, yl
mov xh, yh
pop yh
pop yl
brcc GuiApp_Init_ret
std Y+GUIAPP_OFFS_ROOTWINDOW_LO, xl
std Y+GUIAPP_OFFS_ROOTWINDOW_HI, xh
ldi r16, GUIAPP_GUITIMER
std Y+GUIAPP_OFFS_GUITIMER, r16
GuiApp_Init_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine GuiApp_Every100ms @global
;
; @param Y address of object in SDRAM
GuiApp_Every100ms:
ldi r16, OBJECT_SIGNAL_TIMER
clr r17
bigcall OBJ_HandleSignal
ret
; @end
; ---------------------------------------------------------------------------
; @routine GuiApp_MsgReceived @global
;
; @param Y address of object in SDRAM
GuiApp_MsgReceived:
ldi r16, OBJECT_SIGNAL_RECVMSG
clr r17
bigcall OBJ_HandleSignal
ret
; @end
; ---------------------------------------------------------------------------
; @routine GuiApp_PreventScreenSaver @global
;
; @param Y address of object in SDRAM
; @clobbers any, !Y
GuiApp_PreventScreenSaver:
rcall GuiApp_GetScreenSaver
brcc GuiApp_PreventScreenSaver_ret
push yl
push yh
mov yl, r18
mov yh, r19
ldi r16, WIDGET_SIGNAL_KEEPALIVE
clr r17
bigcall OBJ_HandleSignal
pop yh
pop yl
GuiApp_PreventScreenSaver_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine GuiApp_GrabTouchEvents
;
; @param Y address of object in SDRAM
; @param X byte address of widget grabbing touch events
; @return CFLAG set if grabbed, cleared otherwise
; @clobbers R16, R17
GuiApp_GrabTouchEvents:
ldd r16, Y+GUIAPP_OFFS_TOUCHWIDGET_LO
ldd r17, Y+GUIAPP_OFFS_TOUCHWIDGET_HI
or r16, r17
clc
brne GuiApp_GrabTouchEvents_ret ; only grab if not already grabbed!
std Y+GUIAPP_OFFS_TOUCHWIDGET_LO, xl
std Y+GUIAPP_OFFS_TOUCHWIDGET_HI, xh
sec
GuiApp_GrabTouchEvents_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine GuiApp_UngrabTouchEvents
;
; @param Y address of object in SDRAM
; @param X byte address of widget ungrabbing touch events
; @return CFLAG set if ungrabbed, cleared otherwise
; @clobbers R16, R17
GuiApp_UngrabTouchEvents:
ldd r16, Y+GUIAPP_OFFS_TOUCHWIDGET_LO
ldd r17, Y+GUIAPP_OFFS_TOUCHWIDGET_HI
eor r16, xl
eor r17, xh
or r16, r17
clc
brne GuiApp_UngrabTouchEvents_ret ; only ungrab same widget!
clr r16
std Y+GUIAPP_OFFS_TOUCHWIDGET_LO, r16
std Y+GUIAPP_OFFS_TOUCHWIDGET_HI, r16
sec
GuiApp_UngrabTouchEvents_ret:
ret
; @end
; ***************************************************************************
; getters and setters
; ---------------------------------------------------------------------------
; @routine GuiApp_GetRootWindow @global
;
; @param Y address of object in SDRAM
; @param CFLAG set if response is not a NULL pointer
; @return r19:r18 root window
; @clobbers none
GuiApp_GetRootWindow:
ldd r18, Y+GUIAPP_OFFS_ROOTWINDOW_LO
ldd r19, Y+GUIAPP_OFFS_ROOTWINDOW_HI
sec
tst r18
brne GuiApp_GetRootWindow_ret
tst r19
brne GuiApp_GetRootWindow_ret
clc
GuiApp_GetRootWindow_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine GuiApp_SetRootWindow @global
;
; @param Y address of object in SDRAM
; @param X address of new window
GuiApp_SetRootWindow:
std Y+GUIAPP_OFFS_ROOTWINDOW_LO, xl
std Y+GUIAPP_OFFS_ROOTWINDOW_HI, xh
ret
; @end
; ---------------------------------------------------------------------------
; @routine GuiApp_GetCurrentWindow @global
;
; @param Y address of object in SDRAM
; @return CFLAG set if response is not a NULL pointer
; @return r19:r18 current window
; @clobbers none
GuiApp_GetCurrentWindow:
ldd r18, Y+GUIAPP_OFFS_CURRENTWINDOW_LO
ldd r19, Y+GUIAPP_OFFS_CURRENTWINDOW_HI
sec
tst r18
brne GuiApp_GetCurrentWindow_ret
tst r19
brne GuiApp_GetCurrentWindow_ret
clc
GuiApp_GetCurrentWindow_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine GuiApp_GetScreenSaver @global
;
; @param Y address of object in SDRAM
; @param CFLAG set if response is not a NULL pointer
GuiApp_GetScreenSaver:
ldd r18, Y+GUIAPP_OFFS_SCREENSAVER_LO
ldd r19, Y+GUIAPP_OFFS_SCREENSAVER_HI
sec
tst r18
brne GuiApp_GetScreenSaver_ret
tst r19
brne GuiApp_GetScreenSaver_ret
clc
GuiApp_GetScreenSaver_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine GuiApp_SetScreenSaver @global
;
; @param Y address of object in SDRAM
; @param X address of new window
GuiApp_SetScreenSaver:
std Y+GUIAPP_OFFS_SCREENSAVER_LO, xl
std Y+GUIAPP_OFFS_SCREENSAVER_HI, xh
ret
; @end
; ***************************************************************************
; signal handlers
; ---------------------------------------------------------------------------
; @routine GuiApp_OnDestroy @global
;
; @param Y address of object in SDRAM
; @return CFLAG set if signal handled
; @clobbers any, !Y
GuiApp_OnDestroy:
; TODO (destroy rootWindow)
; Clear CFLAG so that destroy handlers of base classes are called
; after this routine returns. This way the last routine called will be
; OBJ_OnDestroy which then frees the whole SDRAM object on heap.
clc
ret
; @end
; ---------------------------------------------------------------------------
; @routine GuiApp_OnTimer
;
; @param Y address of object in SDRAM
; @clobbers any, !Y
GuiApp_OnTimer:
rcall guiAppCheckTouch ; (any, !Y)
rcall guiAppSendTimerEvents ; (any, !Y)
rcall guiAppCheckSendGuiEvents ; (any, !Y)
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine GuiApp_OnMsgReceived @global
;
; @param Y address of object in SDRAM
; @param X pointer to message received in SDRAM
GuiApp_OnMsgReceived:
rcall guiAppSendRootMsgEvents
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine GuiApp_OnTouch
;
; @param Y address of object in SDRAM
; @param X pointer to touch object (see @ref WIDGET_TOUCH_OFFS_X_LO)
; @clobbers any, !Y
GuiApp_OnTouch:
rcall guiAppSendTouchEvents
ret
; @end
; ---------------------------------------------------------------------------
; @routine GuiApp_EnterWindow
;
; @param Y address of object in SDRAM
; @param X main window to enter
; @return CFLAG set if new window active
GuiApp_EnterWindow:
rcall GuiApp_GetCurrentWindow ; r19:r18=current window
brcc GuiApp_EnterWindow_l1 ; jmp if no current window
push xl
push xh
push yl
push yh
mov yl, r18
mov yh, r19
ldi r16, WIDGET_SIGNAL_HIDE
clr r17
bigcall OBJ_TreeHandleSignalChildenFirst
mov xl, yl
mov xh, yh
pop yh
pop yl
rcall guiAppPushMainWindow ; push current window onto stack
pop xh
pop xl
brcc GuiApp_EnterWindow_ret
GuiApp_EnterWindow_l1:
rcall guiAppSetCurrentWindow
push yl
push yh
mov yl, xl
mov yh, xh
ldi r16, WIDGET_SIGNAL_SHOW
clr r17
bigcall OBJ_TreeHandleSignal
pop yh
pop yl
sec
GuiApp_EnterWindow_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine GuiApp_LeaveWindow
;
; @param Y address of object in SDRAM
GuiApp_LeaveWindow:
rcall GuiApp_GetCurrentWindow ; r19:r18=current window
brcc GuiApp_LeaveWindow_ret ; jmp if no current window
push yl
push yh
mov yl, r18
mov yh, r19
ldi r16, WIDGET_SIGNAL_HIDE
clr r17
bigcall OBJ_TreeHandleSignalChildenFirst
pop yh
pop yl
GuiApp_LeaveWindow_l1:
rcall guiAppPopMainWindow ; X=popped window
brcc GuiApp_LeaveWindow_noPrevious
rcall guiAppSetCurrentWindow
push yl
push yh
mov yl, xl
mov yh, xh
ldi r16, WIDGET_SIGNAL_SHOW
clr r17
bigcall OBJ_TreeHandleSignal
pop yh
pop yl
rjmp GuiApp_LeaveWindow_ret
GuiApp_LeaveWindow_noPrevious:
clr xl
clr xh
rcall guiAppSetCurrentWindow
GuiApp_LeaveWindow_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine guiAppSetCurrentWindow
;
; @param Y address of object in SDRAM
; @param X address of new window
guiAppSetCurrentWindow:
std Y+GUIAPP_OFFS_CURRENTWINDOW_LO, xl
std Y+GUIAPP_OFFS_CURRENTWINDOW_HI, xh
ret
; @end
; ---------------------------------------------------------------------------
; @routine guiAppPushMainWindow
;
; @param Y address of object in SDRAM
; @param X window to push on stack and activate
; @return CFLAG set if pushed, cleared on error
guiAppPushMainWindow:
ldd r16, Y+GUIAPP_OFFS_WINDOWSTACK_POS
cpi r16, GUIAPP_WINDOWSTACK_ENTRIES
brcc GuiApp_PushMainWindow_ret
mov zl, yl
mov zh, yh
adiw zh:zl, GUIAPP_OFFS_WINDOWSTACK_BEGIN
clr r17
lsl r16
rol r17
add zl, r16
adc zh, r17
st Z+, xl
st Z, xh
ldd r16, Y+GUIAPP_OFFS_WINDOWSTACK_POS
inc r16
std Y+GUIAPP_OFFS_WINDOWSTACK_POS, r16
sec
GuiApp_PushMainWindow_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine guiAppPopMainWindow
;
; @param Y address of object in SDRAM
; @return CFLAG set if popped, cleared on error
; @return X window popped from stack
guiAppPopMainWindow:
ldd r16, Y+GUIAPP_OFFS_WINDOWSTACK_POS
tst r16
clc
breq guiAppPopMainWindow_ret
dec r16
std Y+GUIAPP_OFFS_WINDOWSTACK_POS, r16
mov zl, yl
mov zh, yh
adiw zh:zl, GUIAPP_OFFS_WINDOWSTACK_BEGIN
clr r17
lsl r16
rol r17
add zl, r16
adc zh, r17
ld xl, Z+
ld xh, Z
sec
guiAppPopMainWindow_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine guiAppSendTimerEvents
;
; @param Y ptr to GUIAPP
; @clobbers any, !Y
guiAppSendTimerEvents:
ldi r16, OBJECT_SIGNAL_TIMER
clr r17
ldi r20, (1<<OBJECT_OPTS_TIMER_BIT)
ldi r21, (1<<OBJECT_OPTS_TIMER_BIT)
rcall guiAppSendRootEventsIfOpts
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine guiAppCheckSendGuiEvents
;
; Send GUI events to current window if timer elapsed.
;
; @param Y ptr to GUIAPP
; @clobbers any, !Y
guiAppCheckSendGuiEvents:
push yl
push yh
rcall GuiApp_GetRootWindow
brcc guiAppCheckSendGuiEvents_done
ldd r16, Y+GUIAPP_OFFS_GUITIMER
tst r16
breq guiAppCheckSendGuiEvents_done
dec r16
std Y+GUIAPP_OFFS_GUITIMER, r16
brne guiAppCheckSendGuiEvents_done
; timer elapsed, send layout events, draw events
push yl
push yh
mov yl, r18
mov yh, r19
ldi r16, WIDGET_SIGNAL_LAYOUT
clr r17
ldi r20, (1<<WIDGET_FLAGS_VISIBLE_BIT) | (1<<WIDGET_FLAGS_LAYOUT_BIT)
bigcall OBJ_TreeHandleSignalIfFlagsSet ; (any, !Y)
ldi r16, WIDGET_SIGNAL_DRAW
clr r17
ldi r20, (1<<WIDGET_FLAGS_VISIBLE_BIT) | (1<<WIDGET_FLAGS_DIRTY_BIT)
bigcall OBJ_TreeHandleSignalIfFlagsSet ; (any, !Y)
pop yh
pop yl
ldi r16, GUIAPP_GUITIMER
std Y+GUIAPP_OFFS_GUITIMER, r16
guiAppCheckSendGuiEvents_done:
pop yh
pop yl
ret
; @end
; ---------------------------------------------------------------------------
; @routine guiAppSendTouchEvents
;
; Send touch events to current window or grabbing widget.
;
; @param Y ptr to GUIAPP
; @param X pointer to touch object (see @ref WIDGET_TOUCH_OFFS_X_LO)
; @clobbers any, !Y
guiAppSendTouchEvents:
push yl
push yh
ldd r18, Y+GUIAPP_OFFS_TOUCHWIDGET_LO
ldd r19, Y+GUIAPP_OFFS_TOUCHWIDGET_HI
mov r16, r18
or r16, r19
breq guiAppSendTouchEvents_sendToAll
mov yl, r18
mov yh, r19
ldi r16, WIDGET_SIGNAL_TOUCH
clr r17
bigcall OBJ_HandleSignal
rjmp guiAppSendTouchEvents_done
guiAppSendTouchEvents_sendToAll:
rcall GuiApp_GetCurrentWindow ; r19:r18=current window (none)
brcc guiAppSendTouchEvents_done
; send touch signal
mov yl, r18
mov yh, r19
ldi r16, WIDGET_SIGNAL_TOUCH
clr r17
ldi r20, (1<<WIDGET_OPTS_INPUT_BIT)
ldi r21, (1<<WIDGET_OPTS_INPUT_BIT)
bigcall OBJ_TreeHandleSignalIfMatchingOpts
guiAppSendTouchEvents_done:
pop yh
pop yl
; send keepAlive to screensaver
rcall GuiApp_PreventScreenSaver
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine guiAppSendRootMsgEvents
;
; Send touch events to root window.
;
; @param Y ptr to GUIAPP
; @param X pointer to message received in SDRAM
; @clobbers any, !Y
guiAppSendRootMsgEvents:
ldi r16, OBJECT_SIGNAL_RECVMSG
adiw xh:xl, NETMSG_OFFS_CMD
ld r17, X
sbiw xh:xl, NETMSG_OFFS_CMD
ldi r20, (1<<OBJECT_OPTS_MSGRECV_BIT)
ldi r21, (1<<OBJECT_OPTS_MSGRECV_BIT)
rcall guiAppSendRootEventsIfOpts
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine guiAppSendRootEventsIfOpts
;
; Send events to all widgets with matching OPTS_LO.
;
; @param Y ptr to GUIAPP
; @param R16 signal number
; @param R17 selector
; @param xl param1
; @param xh param2
; @param r20 mask for OBJECT_OFFS_OPTS
; @param r21 value for OBJECT_OFFS_OPTS to match
; @clobbers any, !Y
guiAppSendRootEventsIfOpts:
push yl
push yh
rcall GuiApp_GetRootWindow ; r19:r18=root window (none)
brcc guiAppSendRootEventsIfOpts_done
; send signal to root window and all below
mov yl, r18
mov yh, r19
bigcall OBJ_TreeHandleSignalIfMatchingOpts
guiAppSendRootEventsIfOpts_done:
pop yh
pop yl
ret
; @end
; ---------------------------------------------------------------------------
; @routine guiAppCheckTouch
;
; @param Y ptr to GUIAPP
; @clobbers any, !Y
guiAppCheckTouch:
bigcall Display_InputGetState ; r16=flags, r5:r4=x, r7:r6=y
mov r17, r16
andi r17, (1<<DISPLAY_IFLAGS_CHGCOORD_BIT) | (1<<DISPLAY_IFLAGS_CHGPRESS_BIT)
breq guiAppCheckTouch_ret
ldi xl, LOW(guiapp_touch_event)
ldi xh, HIGH(guiapp_touch_event)
st X+, r4 ; X
st X+, r5
st X+, r6 ; Y
st X+, r7
st X, r16 ; flags
sbiw xh:xl, 4 ; (4 times incremented)
; send touch signal
ldi r16, WIDGET_SIGNAL_TOUCH
clr r17
bigcall OBJ_HandleSignal
guiAppCheckTouch_ret:
ret
; @end
; ***************************************************************************
; data in FLASH
GuiApp_DefaultSignalmap:
; header
.dw Object_DefaultSignalmap*2 ; next table to use
; entries
.db 0, OBJECT_SIGNAL_TIMER, LOW(GuiApp_OnTimer), HIGH(GuiApp_OnTimer)
.db 0, OBJECT_SIGNAL_RECVMSG, LOW(GuiApp_OnMsgReceived), HIGH(GuiApp_OnMsgReceived)
.db 0, WIDGET_SIGNAL_TOUCH, LOW(GuiApp_OnTouch), HIGH(GuiApp_OnTouch)
.db 0, OBJECT_SIGNAL_DESTROY, LOW(GuiApp_OnDestroy), HIGH(GuiApp_OnDestroy)
.db 0, 0, 0, 0 ; end of table
#endif

View File

@@ -0,0 +1,387 @@
; ***************************************************************************
; 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_HLAYOUT_ASM
#define AQH_AVR_GUI2_HLAYOUT_ASM
; ***************************************************************************
; defines
.equ HLAYOUT_OFFS_BEGIN = WIDGET_SIZE
.equ HLAYOUT_OFFS_MODE = HLAYOUT_OFFS_BEGIN+0
.equ HLAYOUT_SIZE = HLAYOUT_OFFS_BEGIN+1
; values for HLAYOUT_OFFS_MODE
.equ HLAYOUT_MODE_EXPAND = 0
.equ HLAYOUT_MODE_SPREAD = 1
; ***************************************************************************
; code
.cseg
; ---------------------------------------------------------------------------
; @routine HLayout_new @global
;
; @return CFLAG set of okay, cleared otherwise
; @return Y address of newly created object
; @param X parent widget
; @param r16 value for OBJECT_OFFS_OPTS
; @param r17 value for WIDGET_OFFS_PACK
; @param r20 layout mode (HLAYOUT_MODE_EXPAND, HLAYOUT_MODE_SPREAD)
; @clobbers any
HLayout_new:
push r20
ldi r24, LOW(HLAYOUT_SIZE)
ldi r25, HIGH(HLAYOUT_SIZE)
bigcall Object_Alloc ; (!r16, !r17, !X)
pop r20
brcc HLayout_new_ret
rcall HLayout_Init ; (r16, r17, X)
sec
HLayout_new_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine HLayout_Init @global
;
; @param Y address of widget
; @param X parent widget (if any)
; @param r16 value for OBJECT_OFFS_OPTS
; @param r17 value for WIDGET_OFFS_PACK
; @param r20 layout mode (HLAYOUT_MODE_EXPAND, HLAYOUT_MODE_SPREAD)
; @clobbers r16, r17, X
HLayout_Init:
push r20
; call base class
bigcall Widget_Init ; (r16, r17, X)
pop r20
; set widget-specific data
std Y+HLAYOUT_OFFS_MODE, r20
; set default signal map
ldi r16, LOW(HLayout_DefaultSignalmap*2)
std Y+OBJECT_OFFS_SIGNALMAP_LO, r16
ldi r16, HIGH(HLayout_DefaultSignalmap*2)
std Y+OBJECT_OFFS_SIGNALMAP_HI, r16
ret
; @end
; ---------------------------------------------------------------------------
; @routine HLayout_OnLayout
;
; @param Y pointer to widget
; @clobbers any, !Y
HLayout_OnLayout:
; create and preset context
rcall LayoutCtx_CreateContextFor1D ; X=ctx, r16=num of children
brcc HLayout_OnLayout_ret
; do layout
mov r25, r16
rcall hLayoutHorizontally
rcall hLayoutVertically
; release layout context
bigcall LayoutCtx_free
; force re-drawing of this widget, clear layout bit
ldd r16, Y+OBJECT_OFFS_FLAGS
sbr r16, (1<<WIDGET_FLAGS_DIRTY_BIT)
cbr r16, (1<<WIDGET_FLAGS_LAYOUT_BIT)
std Y+OBJECT_OFFS_FLAGS, r16
HLayout_OnLayout_ret:
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine HLayout_OnGetDefaultHeight
;
; @param Y pointer to widget
; @return r19:r18 value
; @clobbers any, !Y
HLayout_OnGetDefaultHeight:
rcall Layout_SetDefaultHeights
rcall Layout_GetMaxTmp
bigcall Widget_AddOuterStyleBorders ; (r20, r21)
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine HLayout_OnGetDefaultWidth
;
; @param Y pointer to widget
; @return r19:r18 value
; @clobbers any, !Y
HLayout_OnGetDefaultWidth:
rcall Layout_SetDefaultWidths
rcall Layout_SumTmpValues ; r19:r18=default width
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine hLayoutVertically
;
; @param Y pointer to widget
; @param X layout context
; @param r25 number of children
; @clobbers any, !X, !Y
hLayoutVertically:
rcall hLayoutPrepareVertical ; (any, !R25, !X, !Y)
rcall hLayoutReadLayoutWriteVertical ; (r16-r24)
ret
; @end
; ---------------------------------------------------------------------------
; @routine hLayoutPrepareVertical
;
; @param Y pointer to widget
; @param X layout context
; @param r25 number of children
; @clobbers any, !R25, !X, !Y,
hLayoutPrepareVertical:
push xl
push xh
push yl
push yh
push r25
rcall Layout_SetDefaultHeights
pop r25
pop yh
pop yl
pop xh
pop xl
ldd r20, Y+WIDGET_OFFS_HEIGHT_LO
ldd r21, Y+WIDGET_OFFS_HEIGHT_HI
adiw xh:xl, LAYOUT_CTX_OFFS_TOTALSIZE_LO
st X+, r20
st X, r21
sbiw xh:xl, (LAYOUT_CTX_OFFS_TOTALSIZE_LO+1)
ret
; @end
; ---------------------------------------------------------------------------
; @routine hLayoutReadLayoutWriteVertical
;
; @param Y pointer to widget
; @param X layout context
; @param r25 number of children
; @clobbers r16-r24
hLayoutReadLayoutWriteVertical:
; read positions and flags into new layout context
bigcall LayoutCtx_ReadYDimsContiguous ; (R16, r18, r19, Z)
; layout
adiw xh:xl, LAYOUT_CTX_OFFS_BORDERS
ld r18, X
clr r19
sbiw xh:xl, LAYOUT_CTX_OFFS_BORDERS
bigcall LayoutCtx_SetFixedPos ; (r24)
mov r22, r18 ; save border
bigcall LayoutCtx_GetMaxSize ; r19:r18=max default size (r18, r19, r20, r21, r24)
ldd r16, Y+WIDGET_OFFS_PACK
andi r16, (1<<WIDGET_PACK_VSELF1_BIT) | (1<<WIDGET_PACK_VSELF0_BIT)
cpi r16, (WIDGET_PACK_FILLED<<WIDGET_PACK_VSELF0_BIT)
brne vLayoutReadLayoutWriteVertical_setSize
; use full possible width
adiw xh:xl, LAYOUT_CTX_OFFS_TOTALSIZE_LO
ld r18, X+
ld r19, X
sbiw xh:xl, (LAYOUT_CTX_OFFS_TOTALSIZE_LO+1)
clr r23
lsl r22
rol r23
sub r18, r22
sbc r19, r23
vLayoutReadLayoutWriteVertical_setSize:
bigcall LayoutCtx_SetFixedSize ; (r24)
; pack
bigcall LayoutCtx_PackYContiguous ; (R16, r18, r19, Z)
ret
; read positions and flags into new layout context
bigcall LayoutCtx_ReadYDimsContiguous ; (R16, r18, r19, Z)
; layout
bigcall LayoutCtx_GetMaxSize ; r19:r18=max default size (r18, r19, r20, r21, r24)
bigcall LayoutCtx_SetFixedSize ; (r24)
adiw xh:xl, LAYOUT_CTX_OFFS_BORDERS
ld r18, X
clr r19
sbiw xh:xl, LAYOUT_CTX_OFFS_BORDERS
bigcall LayoutCtx_SetFixedPos ; (r24)
; pack
bigcall LayoutCtx_PackYContiguous ; (R16, r18, r19, Z)
; write back dims
; bigcall LayoutCtx_WriteYDimsContiguous ; (R16, r18, r19, Z)
ret
; @end
; ---------------------------------------------------------------------------
; @routine hLayoutHorizontally
;
; @param Y pointer to widget
; @param X layout context
; @param r25 number of children
; @clobbers any, !Y
hLayoutHorizontally:
rcall hLayoutPrepareHorizontal ; (any, !R25, !X, !Y)
rcall hLayoutReadLayoutWriteHorizontal ; (r16-r24)
ret
; @end
; ---------------------------------------------------------------------------
; @routine hLayoutPrepareHorizontal
;
; @param Y pointer to widget
; @param X layout context
; @param r25 number of children
; @clobbers any, !R25, !X, !Y,
hLayoutPrepareHorizontal:
push xl
push xh
push yl
push yh
push r25
rcall Layout_SetDefaultWidths ; (any, !Y)
pop r25
pop yh
pop yl
pop xh
pop xl
; setup layout context for horizontal operations
ldd r20, Y+WIDGET_OFFS_WIDTH_LO
ldd r21, Y+WIDGET_OFFS_WIDTH_HI
adiw xh:xl, LAYOUT_CTX_OFFS_TOTALSIZE_LO
st X+, r20
st X, r21
sbiw xh:xl, (LAYOUT_CTX_OFFS_TOTALSIZE_LO+1)
ret
; @end
; ---------------------------------------------------------------------------
; @routine hLayoutReadLayoutWriteHorizontal
;
; @param Y pointer to widget
; @param X layout context
; @param r25 number of children
; @clobbers r16-r24
hLayoutReadLayoutWriteHorizontal:
; read X positions and flags into new layout context
bigcall LayoutCtx_ReadXDimsContiguous ; (R16, r18, r19, Z)
; layout
push r25
ldd r24, Y+HLAYOUT_OFFS_MODE
cpi r24, HLAYOUT_MODE_SPREAD
breq hLayoutReadLayoutWriteHorizontal_spread
bigcall LayoutCtx_LayoutExpand ; (r16-r25)
rjmp hLayoutReadLayoutWriteHorizontal_pack
hLayoutReadLayoutWriteHorizontal_spread:
bigcall LayoutCtx_LayoutSpread ; (r16-r25)
hLayoutReadLayoutWriteHorizontal_pack:
pop r25
; pack
push r25
bigcall LayoutCtx_PackXContiguous ; (r16-r21, r24, r25)
pop r25
; write back dims
; bigcall LayoutCtx_WriteXDimsContiguous ; (r16, r18, r19, r24)
ret
; @end
; ***************************************************************************
; data in FLASH
HLayout_DefaultSignalmap:
; header
.dw Widget_DefaultSignalmap*2 ; next table to use
; entries
.db 0, WIDGET_SIGNAL_LAYOUT, LOW(HLayout_OnLayout), HIGH(HLayout_OnLayout)
.db WIDGET_VALUE_DEFAULT_WIDTH, WIDGET_SIGNAL_GETVALUE, LOW(HLayout_OnGetDefaultWidth), HIGH(HLayout_OnGetDefaultWidth)
.db WIDGET_VALUE_DEFAULT_HEIGHT, WIDGET_SIGNAL_GETVALUE, LOW(HLayout_OnGetDefaultHeight), HIGH(HLayout_OnGetDefaultHeight)
.db 0, 0, 0, 0 ; end of table
#endif

View File

@@ -0,0 +1,354 @@
; ***************************************************************************
; 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_IMAGEVIEW_ASM
#define AQH_AVR_GUI2_IMAGEVIEW_ASM
; ***************************************************************************
; defines
.equ IMAGEVIEW_OFFS_BEGIN = WIDGET_SIZE
.equ IMAGEVIEW_OFFS_RESSOURCEID_LO = IMAGEVIEW_OFFS_BEGIN+0
.equ IMAGEVIEW_OFFS_RESSOURCEID_HI = IMAGEVIEW_OFFS_BEGIN+1
.equ IMAGEVIEW_OFFS_BGCOLOR_LO = IMAGEVIEW_OFFS_BEGIN+2
.equ IMAGEVIEW_OFFS_BGCOLOR_HI = IMAGEVIEW_OFFS_BEGIN+3
.equ IMAGEVIEW_SIZE = IMAGEVIEW_OFFS_BEGIN+4
.equ IMAGEVIEW_VALUE_BGCOL = WIDGET_VALUE_NEXTFREE+0
.equ IMAGEVIEW_VALUE_NEXTFREE = WIDGET_VALUE_NEXTFREE+1
; ***************************************************************************
; code
.cseg
; ---------------------------------------------------------------------------
; @routine ImageView_new @global
;
; @return CFLAG set of okay, cleared otherwise
; @return Y address of newly created object
; @param X parent widget
; @param r16 value for OBJECT_OFFS_OPTS
; @param r17 value for WIDGET_OFFS_PACK
; @param r21:r20 ressource id for image
; @clobbers any
ImageView_new:
ldi r24, LOW(IMAGEVIEW_SIZE)
ldi r25, HIGH(IMAGEVIEW_SIZE)
push r20
push r21
bigcall Object_Alloc ; (!r16, !r17, !X)
pop r21
pop r20
brcc ImageView_new_ret
rcall ImageView_Init ; (r16, r17, X)
sec
ImageView_new_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine ImageView_Init @global
;
; @param Y address of widget
; @param X parent widget (if any)
; @param r16 value for OBJECT_OFFS_OPTS
; @param r17 value for WIDGET_OFFS_PACK
; @param r21:r20 ressource id for image
; @clobbers r16, r17, X
ImageView_Init:
push r20
push r21
; call base class
bigcall Widget_Init ; (r16, r17, X)
pop r21
pop r20
; setup label data
std Y+IMAGEVIEW_OFFS_RESSOURCEID_LO, r20
std Y+IMAGEVIEW_OFFS_RESSOURCEID_HI, r21
; set default signal map
ldi r16, LOW(ImageView_DefaultSignalmap*2)
std Y+OBJECT_OFFS_SIGNALMAP_LO, r16
ldi r16, HIGH(ImageView_DefaultSignalmap*2)
std Y+OBJECT_OFFS_SIGNALMAP_HI, r16
ret
; @end
; ---------------------------------------------------------------------------
; @routine ImageView_SetRessourceId @global
;
; @param Y address of widget
; @param X id of text ressource
; @clobbers r16, r17, r18, r19
ImageView_SetRessourceId:
std Y+IMAGEVIEW_OFFS_RESSOURCEID_LO, xl
std Y+IMAGEVIEW_OFFS_RESSOURCEID_HI, xh
ldd r16, Y+OBJECT_OFFS_FLAGS
ori r16, (1<<WIDGET_FLAGS_DIRTY_BIT)
std Y+OBJECT_OFFS_FLAGS, r16
; force layout of this and all parent widgets
ldi r16, (1<<WIDGET_FLAGS_LAYOUT_BIT)
bigcall OBJ_AddFlagsUp ; (r17, r18, r19)
ret
; @end
; ---------------------------------------------------------------------------
; @routine ImageView_OnDraw @global
;
; @param Y address of widget
; @clobbers any, !Y
ImageView_OnDraw:
ldd r16, Y+OBJECT_OFFS_FLAGS
andi r16, (1<<WIDGET_FLAGS_DIRTY_BIT)
breq ImageView_OnDraw_ret
; bigcall Widget_Clear
rcall imageViewDraw
ldd r16, Y+OBJECT_OFFS_OPTS
andi r16, (1<<WIDGET_OPTS_BORDER_BIT)
breq ImageView_OnDraw_done
bigcall Widget_DrawBorder
ImageView_OnDraw_done:
ldd r16, Y+OBJECT_OFFS_FLAGS
cbr r16, (1<<WIDGET_FLAGS_DIRTY_BIT)
std Y+OBJECT_OFFS_FLAGS, r16
ImageView_OnDraw_ret:
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine ImageView_OnGetDefaultWidth @global
;
; @param Y address of widget
; @param r17 value requested
; @param xl param1
; @param xh param2
; @return CFLAG set if signal handled
; @return r19:r18 value
; @clobbers any, !Y
ImageView_OnGetDefaultWidth:
rcall imageViewGetRessource
brcs ImageView_OnGetDefaultWidth_getImageWidth
ldi r18, 1
clr r19
rjmp ImageView_OnGetDefaultWidth_addBorders
ImageView_OnGetDefaultWidth_getImageWidth:
rcall imageViewGetImageWidth
mov r18, r12
mov r19, r13
ImageView_OnGetDefaultWidth_addBorders:
bigcall Widget_AddOuterStyleBorders ; (r20, r21)
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine ImageView_OnGetDefaultHeight @global
;
; @param Y address of widget
; @param xl param1
; @param xh param2
; @return CFLAG set if signal handled
; @return r19:r18 value
; @clobbers any, !Y
ImageView_OnGetDefaultHeight:
rcall imageViewGetRessource
brcs ImageView_OnGetDefaultHeight_getImageHeight
ldi r18, 1
clr r19
rjmp ImageView_OnGetDefaultHeight_addBorders
ImageView_OnGetDefaultHeight_getImageHeight:
rcall imageViewGetImageHeight
mov r18, r12
mov r19, r13
ImageView_OnGetDefaultHeight_addBorders:
bigcall Widget_AddOuterStyleBorders ; (r20, r21)
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine ImageView_OnDraw @global
;
; @param Y address of widget
; @clobbers any, !Y
imageViewDraw:
rcall imageViewGetRessource
brcc imageViewDraw_ret
rcall imageViewAlignContentXY ; (r17, r18, r19, r20, r21, Z)
ldd r0, Y+IMAGEVIEW_OFFS_BGCOLOR_LO
ldd r1, Y+IMAGEVIEW_OFFS_BGCOLOR_HI
; select background color
mov r16, r0
or r16, r1
breq imageViewDraw_useStyleColors
ldd r16, Y+OBJECT_OFFS_FLAGS
sbrc r16, WIDGET_FLAGS_ACTIVATED_BIT
rjmp imageViewDraw_useStyleColors
rjmp imageViewDraw_draw
imageViewDraw_useStyleColors:
bigcall Widget_SelectColors ; (R16)
imageViewDraw_draw:
bigcall Widget_DrawImage
imageViewDraw_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine ImageView_OnSetBgCol @global
;
; @param Y address of widget
; @param X new background color
; @clobbers any, !Y
ImageView_OnSetBgCol:
std Y+IMAGEVIEW_OFFS_BGCOLOR_LO, xl
std Y+IMAGEVIEW_OFFS_BGCOLOR_HI, xh
ldd r16, Y+OBJECT_OFFS_FLAGS
ori r16, (1<<WIDGET_FLAGS_DIRTY_BIT)
std Y+OBJECT_OFFS_FLAGS, r16
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine imageViewGetRessource
;
; @param Y address of widget
; @return CFLAG set if ressource found, cleared on error
; @return Z pointer to ressource
imageViewGetRessource:
ldd r16, Y+IMAGEVIEW_OFFS_RESSOURCEID_LO
ldd r17, Y+IMAGEVIEW_OFFS_RESSOURCEID_HI
ldi zl, LOW(RESSOURCE_ADDR*2)
ldi zh, HIGH(RESSOURCE_ADDR*2)
bigcall RES_GetRessource ; (r16, r17, r18)
ret
; @end
; ---------------------------------------------------------------------------
; @routine imageViewAlignContentXY
;
; @param Y address of widget
; @param Z byte address pointer to image (for LPM!)
; @return R5:R4 X
; @return R7:R6 Y
; @clobbers r17, r18, r19, r20, r21, Z
imageViewAlignContentXY:
rcall imageViewGetImageWidth ; R13:R12=width (r16, r17, r18, Z)
bigcall Widget_PackContentX ; R5:R4=X (r17, r18, r19, r20, r21)
rcall imageViewGetImageHeight ; R13:R12=height (r16, r17, r18, Z)
bigcall Widget_PackContentY ; R7:R6=Y (r17, r18, r19, r20, r21)
ret
; @end
; ---------------------------------------------------------------------------
; @routine imageViewGetImageWidth
;
; @param Y address of widget
; @return Z byte address pointer to text in FLASH
; @return r13:r12 image width
; @clobbers r16, r17, r18, Z
imageViewGetImageWidth:
adiw zh:zl, RES_IMAGE_OFFS_WIDTH_LO
lpm r12, Z+
lpm r13, Z
sbiw zh:zl, (RES_IMAGE_OFFS_WIDTH_LO+1)
sec
imageViewGetImageWidth_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine imageViewGetImageHeight
;
; @param Y address of widget
; @param Z byte address pointer to image ressource
; @return r13:r12 image height
; @clobbers r16, r17, r18
imageViewGetImageHeight:
adiw zh:zl, RES_IMAGE_OFFS_HEIGHT_LO
lpm r12, Z+
lpm r13, Z
sbiw zh:zl, (RES_IMAGE_OFFS_HEIGHT_LO+1)
sec
imageViewGetImageHeight_ret:
ret
; @end
; ***************************************************************************
; data in FLASH
ImageView_DefaultSignalmap:
; header
.dw Widget_DefaultSignalmap*2 ; next table to use
; entries
.db 0, WIDGET_SIGNAL_DRAW, LOW(ImageView_OnDraw), HIGH(ImageView_OnDraw)
.db WIDGET_VALUE_DEFAULT_WIDTH, WIDGET_SIGNAL_GETVALUE, LOW(ImageView_OnGetDefaultWidth), HIGH(ImageView_OnGetDefaultWidth)
.db WIDGET_VALUE_DEFAULT_HEIGHT, WIDGET_SIGNAL_GETVALUE, LOW(ImageView_OnGetDefaultHeight), HIGH(ImageView_OnGetDefaultHeight)
.db IMAGEVIEW_VALUE_BGCOL, WIDGET_SIGNAL_SETVALUE, LOW(ImageView_OnSetBgCol), HIGH(ImageView_OnSetBgCol)
.db 0, 0, 0, 0 ; end of table
#endif

View File

@@ -0,0 +1,272 @@
; ***************************************************************************
; 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_LABEL_ASM
#define AQH_AVR_GUI2_LABEL_ASM
; ***************************************************************************
; defines
.equ LABEL_OFFS_BEGIN = WIDGET_SIZE
.equ LABEL_OFFS_TEXTRES_LO = LABEL_OFFS_BEGIN+0
.equ LABEL_OFFS_TEXTRES_HI = LABEL_OFFS_BEGIN+1
.equ LABEL_SIZE = LABEL_OFFS_BEGIN+2
; ***************************************************************************
; code
.cseg
; ---------------------------------------------------------------------------
; @routine Label_new @global
;
; @return CFLAG set of okay, cleared otherwise
; @return Y address of newly created object
; @param X parent widget
; @param r16 value for OBJECT_OFFS_OPTS
; @param r17 value for WIDGET_OFFS_PACK
; @param r21:r20 ressource id for label text
; @clobbers any
Label_new:
ldi r24, LOW(LABEL_SIZE)
ldi r25, HIGH(LABEL_SIZE)
push r20
push r21
bigcall Object_Alloc ; (!r16, !r17, !X)
pop r21
pop r20
brcc Label_new_ret
rcall Label_Init ; (r16, r17, X)
sec
Label_new_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine Label_Init @global
;
; @param Y address of widget
; @param X parent widget (if any)
; @param r16 value for OBJECT_OFFS_OPTS
; @param r17 value for WIDGET_OFFS_PACK
; @param r21:r20 ressource id for label text
; @clobbers r16, r17, X
Label_Init:
push r20
push r21
; call base class
bigcall Widget_Init ; (r16, r17, X)
pop r21
pop r20
; setup label data
std Y+LABEL_OFFS_TEXTRES_LO, r20
std Y+LABEL_OFFS_TEXTRES_HI, r21
; set default signal map
ldi r16, LOW(Label_DefaultSignalmap*2)
std Y+OBJECT_OFFS_SIGNALMAP_LO, r16
ldi r16, HIGH(Label_DefaultSignalmap*2)
std Y+OBJECT_OFFS_SIGNALMAP_HI, r16
ret
; @end
; ---------------------------------------------------------------------------
; @routine Label_SetTextRessourceId @global
;
; @param Y address of widget
; @param X id of text ressource
; @clobbers r16, r17, r18, r19
Label_SetTextRessourceId:
std Y+LABEL_OFFS_TEXTRES_LO, xl
std Y+LABEL_OFFS_TEXTRES_HI, xh
ldd r16, Y+OBJECT_OFFS_FLAGS
ori r16, (1<<WIDGET_FLAGS_DIRTY_BIT)
std Y+OBJECT_OFFS_FLAGS, r16
; force layout of this and all parent widgets
ldi r16, (1<<WIDGET_FLAGS_LAYOUT_BIT)
bigcall OBJ_AddFlagsUp ; (r17, r18, r19)
ret
; @end
; ---------------------------------------------------------------------------
; @routine Label_OnDraw @global
;
; @param Y address of widget
; @param xl param1
; @param xh param2
; @clobbers any, !Y
Label_OnDraw:
ldd r16, Y+OBJECT_OFFS_FLAGS
andi r16, (1<<WIDGET_FLAGS_DIRTY_BIT)
breq Label_OnDraw_ret
bigcall Widget_Clear
rcall labelWriteText
ldd r16, Y+OBJECT_OFFS_OPTS
andi r16, (1<<WIDGET_OPTS_BORDER_BIT)
breq Label_OnDraw_done
bigcall Widget_DrawBorder
Label_OnDraw_done:
ldd r16, Y+OBJECT_OFFS_FLAGS
cbr r16, (1<<WIDGET_FLAGS_DIRTY_BIT)
std Y+OBJECT_OFFS_FLAGS, r16
Label_OnDraw_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine Label_OnGetDefaultWidth @global
;
; @param Y address of widget
; @param r17 value requested
; @param xl param1
; @param xh param2
; @return CFLAG set if signal handled
; @return r19:r18 value
; @clobbers any, !Y
Label_OnGetDefaultWidth:
rcall labelCalcTextWidth
mov r18, r12
mov r19, r13
bigcall Widget_AddOuterStyleBorders ; (r20, r21)
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine Label_OnGetDefaultHeight @global
;
; @param Y address of widget
; @param xl param1
; @param xh param2
; @return CFLAG set if signal handled
; @return r19:r18 value
; @clobbers any, !Y
Label_OnGetDefaultHeight:
bigcall Widget_GetCharHeight ; R16=char height
mov r18, r16
clr r19
bigcall Widget_AddOuterStyleBorders ; (r20, r21)
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine Label_OnDraw @global
;
; @param Y address of widget
; @clobbers any, !Y
labelWriteText:
rcall labelAlignTextXY ; (r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19)
bigcall Widget_DrawTextFlash ; (any, !Y)
labelWriteText_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine labelAlignTextXY
;
; @param Y address of widget
; @param R13:R12 width of object to align
; @return R5:R4 X
; @return R7:R6 Y
; @return Z byte address pointer to text in FLASH
; @clobbers r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22, r23, r24, r25
labelAlignTextXY:
rcall labelCalcTextWidth ; Z=text, R13:R12=text width (r16, r17, r18)
bigcall Widget_PackContentX ; R5:R4=X (r17, r18, r19, r20, r21)
bigcall Widget_GetCharHeight ; R16=char height
mov r12, r16
clr r13
bigcall Widget_PackContentY ; R7:R6=Y (r17, r18, r19, r20, r21)
ret
; @end
; ---------------------------------------------------------------------------
; @routine labelCalcTextWidth
;
; @param Y address of widget
; @return Z byte address pointer to text in FLASH
; @return r13:r12 width of string
; @clobbers r16, r17, r18
labelCalcTextWidth:
; get text from ressource id
ldd r16, Y+LABEL_OFFS_TEXTRES_LO
ldd r17, Y+LABEL_OFFS_TEXTRES_HI
ldi zl, LOW(RESSOURCE_ADDR*2)
ldi zh, HIGH(RESSOURCE_ADDR*2)
bigcall RES_GetRessource ; (r16, r17, r18)
brcc labelCalcTextWidth_ret
bigcall Widget_GetCharWidth ; R16=char width
mov r18, r16
bigcall Widget_CalcStringWidthFLASH ; r13:r12=size (r16)
sec
labelCalcTextWidth_ret:
ret
; @end
; ***************************************************************************
; data in FLASH
Label_DefaultSignalmap:
; header
.dw Widget_DefaultSignalmap*2 ; next table to use
; entries
.db 0, WIDGET_SIGNAL_DRAW, LOW(Label_OnDraw), HIGH(Label_OnDraw)
.db WIDGET_VALUE_DEFAULT_WIDTH, WIDGET_SIGNAL_GETVALUE, LOW(Label_OnGetDefaultWidth), HIGH(Label_OnGetDefaultWidth)
.db WIDGET_VALUE_DEFAULT_HEIGHT, WIDGET_SIGNAL_GETVALUE, LOW(Label_OnGetDefaultHeight), HIGH(Label_OnGetDefaultHeight)
.db 0, 0, 0, 0 ; end of table
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,327 @@
; ***************************************************************************
; 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_MAINWINDOW_ASM
#define AQH_AVR_GUI2_MAINWINDOW_ASM
; ***************************************************************************
; defines
.equ MAINWINDOW_OFFS_BEGIN = VLAYOUT_SIZE
; no data for now
.equ MAINWINDOW_SIZE = MAINWINDOW_OFFS_BEGIN+0
; index of sub-windows
.equ MAINWINDOW_CHILDIDX_TITLE = 0
.equ MAINWINDOW_CHILDIDX_CONTENT = 1
; ***************************************************************************
; code
.cseg
; ---------------------------------------------------------------------------
; @routine MainWindow_new @global
;
; @return CFLAG set of okay, cleared otherwise
; @return Y address of newly created object
; @param X parent widget
; @param r16 value for OBJECT_OFFS_OPTS
; @param r17 value for WIDGET_OFFS_PACK
; @param r21:r20 ressource id for title
; @clobbers any
MainWindow_new:
push r20
push r21
ldi r24, LOW(MAINWINDOW_SIZE)
ldi r25, HIGH(MAINWINDOW_SIZE)
bigcall Object_Alloc ; (!r16, !r17, !X)
pop r21
pop r20
brcc MainWindow_new_ret
rcall MainWindow_Init ; (r16, r17, X)
sec
MainWindow_new_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine MainWindow_Init @global
;
; @param Y address of widget
; @param X parent widget (if any)
; @param r16 value for OBJECT_OFFS_OPTS
; @param r17 value for WIDGET_OFFS_PACK
; @param r21:r20 ressource id for title
; @clobbers r16, r17, X
MainWindow_Init:
push r20
push r21
; call base class
ldi r20, VLAYOUT_MODE_EXPAND
bigcall VLayout_Init ; (r16, r17, X)
pop r21
pop r20
; set default signal map
ldi r16, LOW(MainWindow_DefaultSignalmap*2)
std Y+OBJECT_OFFS_SIGNALMAP_LO, r16
ldi r16, HIGH(MainWindow_DefaultSignalmap*2)
std Y+OBJECT_OFFS_SIGNALMAP_HI, r16
; set style which has no spacing and no borders so needs no drawing because
; the children fill the screen completely
ldi r16, LOW(MainWindow_DefaultStyle*2)
std Y+WIDGET_OFFS_STYLE_LO, r16
ldi r16, HIGH(MainWindow_DefaultStyle*2)
std Y+WIDGET_OFFS_STYLE_HI, r16
bigcall Widget_SetFullScreen ; (R16)
; create sub widgets
rcall mainWindowCreateTitleWidget
rcall mainWindowCreateContentWidget
ret
; @end
; ---------------------------------------------------------------------------
; @routine MainWindow_GetContentWidget @global
;
; @param Y address of widget
; @param X parent widget (if any)
; @return CFLAG set, if found, cleared otherwise
; @return r19:r18 resulting object
; @clobbers r16
MainWindow_GetContentWidget:
ldi r16, MAINWINDOW_CHILDIDX_CONTENT
bigcall OBJ_GetChildAt
ret
; @end
; ---------------------------------------------------------------------------
; @routine MainWindow_GetContentWidget @global
;
; @param Y address of widget
; @param X parent widget (if any)
; @return CFLAG set, if found, cleared otherwise
; @return r19:r18 resulting object
; @clobbers r16
MainWindow_GetFirstChildOfContentWidget:
push yl
push yh
bigcall MainWindow_GetContentWidget ; r19:r18=content window (R16)
brcc MainWindow_GetFirstChildOfContentWidget_popRet
mov yl, r18
mov yh, r19
bigcall OBJ_GetFirstChild ; get first child
MainWindow_GetFirstChildOfContentWidget_popRet:
pop yh
pop yl
ret
; @end
; ***************************************************************************
; signal handlers
; ---------------------------------------------------------------------------
; @routine MainWindow_OnGetDefaultWidth @global
;
; @param Y address of widget
; @param r17 value requested
; @param xl param1
; @param xh param2
; @return CFLAG set if signal handled
; @return r19:r18 value
; @clobbers any, !Y
MainWindow_OnGetDefaultWidth:
ldi r18, LOW(DISPLAY_WIDTH)
ldi r19, HIGH(DISPLAY_WIDTH)
ret
; @end
; ---------------------------------------------------------------------------
; @routine MainWindow_OnGetDefaultHeight @global
;
; @param Y address of widget
; @param r17 value requested
; @param xl param1
; @param xh param2
; @return CFLAG set if signal handled
; @return r19:r18 value
; @clobbers any, !Y
MainWindow_OnGetDefaultHeight:
ldi r18, LOW(DISPLAY_HEIGHT)
ldi r19, HIGH(DISPLAY_HEIGHT)
ret
; @end
; ---------------------------------------------------------------------------
; @routine mainWindowCreateTitleWidget
;
; @param Y address of main window widget
; @param r21:r20 ressource id for title
; @return CFLAG set of okay, cleared otherwise
mainWindowCreateTitleWidget:
; create title widget
push yl
push yh
mov xl, yl
mov xh, yh
ldi r16, 0
ldi r17, (WIDGET_PACK_FILLED<<WIDGET_PACK_HSELF0_BIT) | (WIDGET_PACK_BEGIN<<WIDGET_PACK_VSELF0_BIT) | \
(WIDGET_PACK_BEGIN <<WIDGET_PACK_HCONTENT0_BIT) | (WIDGET_PACK_CENTER<<WIDGET_PACK_VCONTENT0_BIT)
bigcall Label_new
brcc mainWindowCreateTitleWidget_done
; set style for title widget
ldi r16, LOW(MainWindow_TitleStyle*2)
std Y+WIDGET_OFFS_STYLE_LO, r16
ldi r16, HIGH(MainWindow_TitleStyle*2)
std Y+WIDGET_OFFS_STYLE_HI, r16
sec
mainWindowCreateTitleWidget_done:
pop yh
pop yl
ret
; @end
; ---------------------------------------------------------------------------
; @routine mainWindowCreateContentWidget
;
; @param Y address of main window widget
; @param r21:r20 ressource id for title
; @return CFLAG set of okay, cleared otherwise
mainWindowCreateContentWidget:
; create content widget
push yl
push yh
mov xl, yl
mov xh, yh
ldi r16, 0 ; OPTS
ldi r17, (WIDGET_PACK_FILLED<<WIDGET_PACK_HSELF0_BIT) | (WIDGET_PACK_FILLED<<WIDGET_PACK_VSELF0_BIT) ; PACK
ldi r20, VLAYOUT_MODE_EXPAND
bigcall VLayout_new
brcc mainWindowCreateContentWidget_done
; set style for title widget
ldi r16, LOW(MainWindow_ContentStyle*2)
std Y+WIDGET_OFFS_STYLE_LO, r16
ldi r16, HIGH(MainWindow_ContentStyle*2)
std Y+WIDGET_OFFS_STYLE_HI, r16
mainWindowCreateContentWidget_done:
pop yh
pop yl
ret
; @end
; ***************************************************************************
; data in FLASH
MainWindow_DefaultSignalmap:
; header
.dw VLayout_DefaultSignalmap*2 ; next table to use
; entries
.db 0, WIDGET_SIGNAL_DRAW, LOW(Widget_OnDrawNop), HIGH(Widget_OnDrawNop)
.db WIDGET_VALUE_DEFAULT_WIDTH, WIDGET_SIGNAL_GETVALUE, LOW(MainWindow_OnGetDefaultWidth), HIGH(MainWindow_OnGetDefaultWidth)
.db WIDGET_VALUE_DEFAULT_HEIGHT, WIDGET_SIGNAL_GETVALUE, LOW(MainWindow_OnGetDefaultHeight), HIGH(MainWindow_OnGetDefaultHeight)
.db 0, 0, 0, 0 ; end of table
MainWindow_DefaultStyle:
.dw DISPLAY_COLOR_BLACK ; frontCol_norm
.dw DISPLAY_COLOR_LIGHTGREY ; backCol_norm
.dw DISPLAY_COLOR_BLACK ; borderCol_norm
.dw DISPLAY_COLOR_WHITE ; shadowCol_norm
.dw DISPLAY_COLOR_WHITE ; frontCol_activated
.dw DISPLAY_COLOR_NAVY ; backCol_activated
.dw DISPLAY_COLOR_BLACK ; borderCol_activated
.dw DISPLAY_COLOR_WHITE ; shadowCol_activated
.db 0, 0 ; outerBorderSize, innerBorderSize
.dw ili9341Font12x16_1*2 ; font
.db 12, 16 ; charWidth, charHeight
MainWindow_TitleStyle:
.dw STYLE_WIN_TITLE_FOREGROUND ; frontCol_norm
.dw STYLE_WIN_TITLE_BACKGROUND ; backCol_norm
.dw DISPLAY_COLOR_BLACK ; borderCol_norm
.dw DISPLAY_COLOR_WHITE ; shadowCol_norm
.dw DISPLAY_COLOR_WHITE ; frontCol_activated
.dw DISPLAY_COLOR_NAVY ; backCol_activated
.dw DISPLAY_COLOR_BLACK ; borderCol_activated
.dw DISPLAY_COLOR_WHITE ; shadowCol_activated
.db 2, 1 ; outerBorderSize, innerBorderSize
.dw ili9341Font12x16_1*2 ; font
.db 12, 16 ; charWidth, charHeight
; this is the defining style for most windows because normally
; the style of the parent will be propagated to newly created child widgets.
MainWindow_ContentStyle:
.dw DISPLAY_COLOR_BLACK ; frontCol_norm
.dw DISPLAY_COLOR_LIGHTGREY ; backCol_norm
.dw DISPLAY_COLOR_BLACK ; borderCol_norm
.dw DISPLAY_COLOR_WHITE ; shadowCol_norm
.dw DISPLAY_COLOR_WHITE ; frontCol_activated
.dw DISPLAY_COLOR_NAVY ; backCol_activated
.dw DISPLAY_COLOR_BLACK ; borderCol_activated
.dw DISPLAY_COLOR_WHITE ; shadowCol_activated
.db 2, 1 ; outerBorderSize, innerBorderSize
.dw ili9341Font12x16_1*2 ; font
.db 12, 16 ; charWidth, charHeight
#endif

View File

@@ -0,0 +1,278 @@
; ***************************************************************************
; 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_MCLAYOUT_ASM
#define AQH_AVR_GUI2_MCLAYOUT_ASM
; ***************************************************************************
; defines
.equ MCLAYOUT_OFFS_BEGIN = WIDGET_SIZE
.equ MCLAYOUT_OFFS_MODE = MCLAYOUT_OFFS_BEGIN+0
.equ MCLAYOUT_OFFS_COLUMNS = MCLAYOUT_OFFS_BEGIN+1
.equ MCLAYOUT_SIZE = MCLAYOUT_OFFS_BEGIN+2
; ***************************************************************************
; code
.cseg
; ---------------------------------------------------------------------------
; @routine MCLayout_new @global
;
; @return CFLAG set of okay, cleared otherwise
; @return Y address of newly created object
; @param X parent widget
; @param r16 value for OBJECT_OFFS_OPTS
; @param r17 value for WIDGET_OFFS_PACK
; @param r20 number of columns or rows (depending on mode in r20)
; @clobbers any
MCLayout_new:
push r20
ldi r24, LOW(MCLAYOUT_SIZE)
ldi r25, HIGH(MCLAYOUT_SIZE)
bigcall Object_Alloc ; (!r16, !r17, !X)
pop r20
brcc MCLayout_new_ret
rcall MCLayout_Init ; (r16, r17, X)
sec
MCLayout_new_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine MCLayout_Init @global
;
; @param Y address of widget
; @param X parent widget (if any)
; @param r16 value for OBJECT_OFFS_OPTS
; @param r17 value for WIDGET_OFFS_PACK
; @param r20 number of columns or rows (depending on mode in r20)
; @clobbers r16, r17, X
MCLayout_Init:
push r20
; call base class
bigcall Widget_Init ; (r16, r17, X)
pop r20
; set widget-specific data
std Y+MCLAYOUT_OFFS_COLUMNS, r20
; set default signal map
ldi r16, LOW(MCLayout_DefaultSignalmap*2)
std Y+OBJECT_OFFS_SIGNALMAP_LO, r16
ldi r16, HIGH(MCLayout_DefaultSignalmap*2)
std Y+OBJECT_OFFS_SIGNALMAP_HI, r16
ret
; @end
; ---------------------------------------------------------------------------
; @routine MCLayout_OnGetDefaultHeight
;
; @param Y pointer to widget
; @return r19:r18 value
; @clobbers any, !Y
MCLayout_OnGetDefaultHeight:
; rcall Layout_SetDefaultHeights
; rcall Layout_GetMaxTmp
; bigcall Widget_AddOuterStyleBorders ; (r20, r21)
ldi r18, 10
clr r19
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine MCLayout_OnGetDefaultWidth
;
; @param Y pointer to widget
; @return r19:r18 value
; @clobbers any, !Y
MCLayout_OnGetDefaultWidth:
; rcall Layout_SetDefaultWidths
; rcall Layout_SumTmpValues ; r19:r18=default width
ldi r18, 10
clr r19
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine MCLayout_OnLayout
;
; @param Y pointer to widget
; @clobbers any, !Y
MCLayout_OnLayout:
ldd r25, Y+MCLAYOUT_OFFS_COLUMNS
rcall Layout_CountChildrenSkipped ; r16=number of rows used (r18, r19)
mov r24, r16 ; store for later
ldd r17, Y+MCLAYOUT_OFFS_COLUMNS
cp r16, r17
brcc MCLayout_OnLayout_mkCtx
mov r16, r17
MCLayout_OnLayout_mkCtx:
; create and preset context
push r24 ; num of children
rcall LayoutCtx_CreateContextForN ; X=ctx (any, !R16, !Y)
pop r24
brcc MCLayout_OnLayout_ret
push r24 ; num of children
ldd r24, Y+MCLAYOUT_OFFS_COLUMNS
rcall mcLayoutHorizontally
pop r24
rcall mcLayoutVertically
; release layout context
bigcall LayoutCtx_free
; force re-drawing of this widget, clear layout bit
ldd r16, Y+OBJECT_OFFS_FLAGS
sbr r16, (1<<WIDGET_FLAGS_DIRTY_BIT)
cbr r16, (1<<WIDGET_FLAGS_LAYOUT_BIT)
std Y+OBJECT_OFFS_FLAGS, r16
MCLayout_OnLayout_ret:
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine mcLayoutVertically
;
; @param Y pointer to widget
; @param X layout context
; @param r24 number of rows
; @clobbers any, !X, !Y
mcLayoutVertically:
; prepare
push xl
push xh
push r24
rcall Layout_SetDefaultHeights ; (any, !Y)
pop r24
pop xh
pop xl
ldd r20, Y+WIDGET_OFFS_HEIGHT_LO
ldd r21, Y+WIDGET_OFFS_HEIGHT_HI
adiw xh:xl, LAYOUT_CTX_OFFS_TOTALSIZE_LO
st X+, r20
st X, r21
sbiw xh:xl, (LAYOUT_CTX_OFFS_TOTALSIZE_LO+1)
adiw xh:xl, LAYOUT_CTX_OFFS_NUMITEMS
st X, r24
sbiw xh:xl, LAYOUT_CTX_OFFS_NUMITEMS
; read positions and flags into new layout context
ldd r25, Y+MCLAYOUT_OFFS_COLUMNS
bigcall LayoutCtx_ReadYMaxDimsVertical ; (r16-r20, Z)
; layout
bigcall LayoutCtx_LayoutExpand ; (r16-r25)
; pack
ldd r25, Y+MCLAYOUT_OFFS_COLUMNS
rcall LayoutCtx_PackYVertical ; (r16, r18, r19, r24, Z)
ret
; @end
; ---------------------------------------------------------------------------
; @routine mcLayoutHorizontally
;
; @param Y pointer to widget
; @param X layout context
; @param r24 number of items to use
; @clobbers any, !Y
mcLayoutHorizontally:
; prepare
push xl
push xh
push r24
rcall Layout_SetDefaultWidths ; (any, !Y)
pop r24
pop xh
pop xl
; setup layout context for horizontal operations
ldd r20, Y+WIDGET_OFFS_WIDTH_LO
ldd r21, Y+WIDGET_OFFS_WIDTH_HI
adiw xh:xl, LAYOUT_CTX_OFFS_TOTALSIZE_LO
st X+, r20
st X, r21
sbiw xh:xl, (LAYOUT_CTX_OFFS_TOTALSIZE_LO+1)
adiw xh:xl, LAYOUT_CTX_OFFS_NUMITEMS
st X, r24
sbiw xh:xl, LAYOUT_CTX_OFFS_NUMITEMS
; read positions and flags into new layout context
ldd r25, Y+MCLAYOUT_OFFS_COLUMNS
bigcall LayoutCtx_ReadXMaxDimsHorizontal ; (r16-r20, Z)
; layout
bigcall LayoutCtx_LayoutExpand ; (r16-r25)
; pack
ldd r25, Y+MCLAYOUT_OFFS_COLUMNS
rcall LayoutCtx_PackXHorizontal ; (r16, r18, r19, r24, Z)
ret
; @end
; ***************************************************************************
; data in FLASH
MCLayout_DefaultSignalmap:
; header
.dw Widget_DefaultSignalmap*2 ; next table to use
; entries
.db 0, WIDGET_SIGNAL_LAYOUT, LOW(MCLayout_OnLayout), HIGH(MCLayout_OnLayout)
.db WIDGET_VALUE_DEFAULT_WIDTH, WIDGET_SIGNAL_GETVALUE, LOW(MCLayout_OnGetDefaultWidth), HIGH(MCLayout_OnGetDefaultWidth)
.db WIDGET_VALUE_DEFAULT_HEIGHT, WIDGET_SIGNAL_GETVALUE, LOW(MCLayout_OnGetDefaultHeight), HIGH(MCLayout_OnGetDefaultHeight)
.db 0, 0, 0, 0 ; end of table
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,181 @@
; ***************************************************************************
; 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_ROOTWINDOW_ASM
#define AQH_AVR_GUI2_ROOTWINDOW_ASM
; ***************************************************************************
; defines
.equ ROOTWINDOW_OFFS_BEGIN = WIDGET_SIZE
.equ ROOTWINDOW_OFFS_GUIAPP_LO = ROOTWINDOW_OFFS_BEGIN+0
.equ ROOTWINDOW_OFFS_GUIAPP_HI = ROOTWINDOW_OFFS_BEGIN+1
.equ ROOTWINDOW_SIZE = ROOTWINDOW_OFFS_BEGIN+2
; ***************************************************************************
; code
.cseg
; ---------------------------------------------------------------------------
; @routine RootWindow_new @global
;
; @return CFLAG set of okay, cleared otherwise
; @return Y address of newly created object
; @param r16 value for OBJECT_OFFS_OPTS
; @param r17 value for WIDGET_OFFS_PACK
; @param X pointer to GUIAPP
; @clobbers any
RootWindow_new:
ldi r24, LOW(ROOTWINDOW_SIZE)
ldi r25, HIGH(ROOTWINDOW_SIZE)
bigcall Object_Alloc ; (!r16, !r17, !X)
brcc RootWindow_new_ret
rcall RootWindow_Init ; (r16, r17, X)
sec
RootWindow_new_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine RootWindow_Init @global
;
; @return CFLAG set if okay, cleared otherwise
; @param Y address of widget
; @param r16 value for OBJECT_OFFS_OPTS
; @param r17 value for WIDGET_OFFS_PACK
; @param X pointer to GUIAPP
; @clobbers r16, r17, X
RootWindow_Init:
push xl
push xh
clr xl
clr xh
; call base class
bigcall Widget_Init ; (r16, r17, X)
pop xh
pop xl
std Y+ROOTWINDOW_OFFS_GUIAPP_LO, xl
std Y+ROOTWINDOW_OFFS_GUIAPP_HI, xh
bigcall Widget_SetFullScreen ; (R16)
; set default signal map
ldi r16, LOW(RootWindow_DefaultSignalmap*2)
std Y+OBJECT_OFFS_SIGNALMAP_LO, r16
ldi r16, HIGH(RootWindow_DefaultSignalmap*2)
std Y+OBJECT_OFFS_SIGNALMAP_HI, r16
; set default style
ldi r16, LOW(RootWindow_DefaultStyle*2)
std Y+WIDGET_OFFS_STYLE_LO, r16
ldi r16, HIGH(RootWindow_DefaultStyle*2)
std Y+WIDGET_OFFS_STYLE_HI, r16
ret
; @end
; ---------------------------------------------------------------------------
; @routine RootWindow_GetApp @global
;
; @param Y address of widget
; @return R19:R18 address pointer to GuiApp
; @clobbers none
RootWindow_GetApp:
ldd r18, Y+ROOTWINDOW_OFFS_GUIAPP_LO
ldd r19, Y+ROOTWINDOW_OFFS_GUIAPP_HI
ret
; @end
; ***************************************************************************
; signal handlers
; ---------------------------------------------------------------------------
; @routine RootWindow_OnLayout
;
; @param Y pointer to widget
; @clobbers any, !Y
RootWindow_OnLayout:
push yl
push yh
bigcall OBJ_GetFirstChild
brcc RootWindow_OnLayout_done
RootWindow_OnLayout_loop:
mov yl, r18
mov yh, r19
; all children are MainWindow, set to fullscreen
bigcall Widget_SetFullScreen ; (R16)
bigcall OBJ_GetNext
brcs RootWindow_OnLayout_loop
RootWindow_OnLayout_done:
pop yh
pop yl
ldd r17, Y+OBJECT_OFFS_FLAGS
cbr r17, (1<<WIDGET_FLAGS_LAYOUT_BIT)
std Y+OBJECT_OFFS_FLAGS, r17
sec
ret
; @end
; ***************************************************************************
; data in FLASH
RootWindow_DefaultSignalmap:
; header
.dw Widget_DefaultSignalmap*2 ; next table to use
; entries
.db 0, WIDGET_SIGNAL_DRAW, LOW(Widget_OnDrawNop), HIGH(Widget_OnDrawNop)
.db 0, WIDGET_SIGNAL_LAYOUT, LOW(RootWindow_OnLayout), HIGH(RootWindow_OnLayout)
.db 0, 0, 0, 0 ; end of table
RootWindow_DefaultStyle:
.dw DISPLAY_COLOR_BLACK ; frontCol_norm
.dw DISPLAY_COLOR_LIGHTGREY ; backCol_norm
.dw DISPLAY_COLOR_BLACK ; borderCol_norm
.dw DISPLAY_COLOR_WHITE ; shadowCol_norm
.dw DISPLAY_COLOR_WHITE ; frontCol_activated
.dw DISPLAY_COLOR_NAVY ; backCol_activated
.dw DISPLAY_COLOR_BLACK ; borderCol_activated
.dw DISPLAY_COLOR_WHITE ; shadowCol_activated
.db 0, 0 ; outerBorderSize, innerBorderSize
.dw ili9341Font12x16_1*2 ; font
.db 12, 16 ; charWidth, charHeight
#endif

View File

@@ -0,0 +1,281 @@
; ***************************************************************************
; 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_VALUELABEL_ASM
#define AQH_AVR_GUI2_VALUELABEL_ASM
; ***************************************************************************
; defines
.equ VLABEL_OFFS_BEGIN = WIDGET_SIZE
.equ VLABEL_OFFS_VALUE_LO = VLABEL_OFFS_BEGIN+0
.equ VLABEL_OFFS_VALUE_HI = VLABEL_OFFS_BEGIN+1
.equ VLABEL_OFFS_POSTKOMMADIGITS = VLABEL_OFFS_BEGIN+2
.equ VLABEL_SIZE = VLABEL_OFFS_BEGIN+3
.equ VLABEL_VALUE = WIDGET_VALUE_NEXTFREE+0
.equ VLABEL_VALUE_NEXTFREE = WIDGET_VALUE_NEXTFREE+1
; ***************************************************************************
; code
.cseg
; ---------------------------------------------------------------------------
; @routine ValueLabel_new @global
;
; @return CFLAG set of okay, cleared otherwise
; @return Y address of newly created object
; @param X parent widget
; @param r16 value for OBJECT_OFFS_OPTS
; @param r17 value for WIDGET_OFFS_PACK
; @param r20 number of postkomma digits
; @clobbers any
ValueLabel_new:
push r20
ldi r24, LOW(VLABEL_SIZE)
ldi r25, HIGH(VLABEL_SIZE)
bigcall Object_Alloc ; (!r16, !r17, !X)
pop r20
brcc ValueLabel_new_ret
rcall ValueLabel_Init ; (r16, r17, X)
sec
ValueLabel_new_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine ValueLabel_Init @global
;
; @param Y address of widget
; @param X parent widget (if any)
; @param r16 value for OBJECT_OFFS_OPTS
; @param r17 value for WIDGET_OFFS_PACK
; @param r20 number of postkomma digits
; @clobbers r16, r17, X
ValueLabel_Init:
push r20
; call base class
bigcall Widget_Init ; (r16, r17, X)
pop r20
; setup valueLabel data
std Y+VLABEL_OFFS_POSTKOMMADIGITS, r20
; set default signal map
ldi r16, LOW(ValueLabel_DefaultSignalmap*2)
std Y+OBJECT_OFFS_SIGNALMAP_LO, r16
ldi r16, HIGH(ValueLabel_DefaultSignalmap*2)
std Y+OBJECT_OFFS_SIGNALMAP_HI, r16
ret
; @end
; ---------------------------------------------------------------------------
; @routine ValueLabel_SetValue @global
;
; @param Y address of widget
; @param X new value
ValueLabel_SetValue:
ldi r17, VLABEL_VALUE
bigjmp Widget_SetValue ; (any, !Y)
; @end
; ---------------------------------------------------------------------------
; @routine ValueLabel_OnSetValue @global
;
; @param Y address of widget
; @param X new value
; @return CFLAG set if signal handled
; @clobbers r17
ValueLabel_OnSetValue:
std Y+VLABEL_OFFS_VALUE_LO, xl
std Y+VLABEL_OFFS_VALUE_HI, xh
ldd r17, Y+OBJECT_OFFS_FLAGS
ori r17, (1<<WIDGET_FLAGS_DIRTY_BIT)
std Y+OBJECT_OFFS_FLAGS, r17
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine ValueLabel_OnDraw @global
;
; @param Y address of widget
; @param xl param1
; @param xh param2
; @clobbers any, !Y
ValueLabel_OnDraw:
ldd r16, Y+OBJECT_OFFS_FLAGS
andi r16, (1<<WIDGET_FLAGS_DIRTY_BIT)
breq ValueLabel_OnDraw_ret
bigcall Widget_Clear
rcall valueLabelWriteValue
ldd r16, Y+OBJECT_OFFS_OPTS
andi r16, (1<<WIDGET_OPTS_BORDER_BIT)
breq ValueLabel_OnDraw_done
bigcall Widget_DrawBorder
ValueLabel_OnDraw_done:
ldd r16, Y+OBJECT_OFFS_FLAGS
cbr r16, (1<<WIDGET_FLAGS_DIRTY_BIT)
std Y+OBJECT_OFFS_FLAGS, r16
ValueLabel_OnDraw_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine ValueLabel_OnGetDefaultWidth @global
;
; @param Y address of widget
; @param r17 value requested
; @param xl param1
; @param xh param2
; @return CFLAG set if signal handled
; @return r19:r18 value
; @clobbers any, !Y
ValueLabel_OnGetDefaultWidth:
rcall valueLabelCalcTextWidth
mov r18, r12
mov r19, r13
bigcall Widget_AddOuterStyleBorders ; (r20, r21)
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine ValueLabel_OnGetDefaultHeight @global
;
; @param Y address of widget
; @param xl param1
; @param xh param2
; @return CFLAG set if signal handled
; @return r19:r18 value
; @clobbers any, !Y
ValueLabel_OnGetDefaultHeight:
bigcall Widget_GetCharHeight ; R16=char height
mov r18, r16
clr r19
bigcall Widget_AddOuterStyleBorders ; (r20, r21)
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine valueLabelWriteValue
;
; @param Y address of widget
; @clobbers any, !Y
valueLabelWriteValue:
rcall valueLabelAlignTextXY ; X=ptr to text (r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19)
bigcall Widget_DrawTextRam ; (any, !Y)
ret
; @end
; ---------------------------------------------------------------------------
; @routine valueLabelAlignTextXY
;
; @param Y address of widget
; @param R13:R12 width of object to align
; @return R5:R4 X
; @return R7:R6 Y
; @return X pointer to text in SDRAM
; @clobbers r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22, r23, r24, r25
valueLabelAlignTextXY:
rcall valueLabelCalcTextWidth ; X=ptr to text in SDRAM, R13:R12=text width (r16, r17, r18)
push xl
push xh
bigcall Widget_PackContentX ; R5:R4=X (r17, r18, r19, r20, r21)
bigcall Widget_GetCharHeight ; R16=char height
mov r12, r16
clr r13
bigcall Widget_PackContentY ; R7:R6=Y (r17, r18, r19, r20, r21)
pop xh
pop xl
ret
; @end
; ---------------------------------------------------------------------------
; @routine valueLabelCalcTextWidth
;
; @param Y address of widget
; @return X pointer to text in SDRAM
; @return r13:r12 width of string
; @clobbers r16, r17, r18
valueLabelCalcTextWidth:
ldd r20, Y+VLABEL_OFFS_VALUE_LO
ldd r21, Y+VLABEL_OFFS_VALUE_HI
ldd r24, Y+VLABEL_OFFS_POSTKOMMADIGITS
bigcall IntToAscii ; X=pointer to text
bigcall Widget_GetCharWidth ; R16=char width
mov r18, r16
bigcall Widget_CalcStringWidthSDRAM ; r13:r12=size (r16)
valueLabelCalcTextWidth_ret:
ret
; @end
; ***************************************************************************
; data in FLASH
ValueLabel_DefaultSignalmap:
; header
.dw Widget_DefaultSignalmap*2 ; next table to use
; entries
.db 0, WIDGET_SIGNAL_DRAW, LOW(ValueLabel_OnDraw), HIGH(ValueLabel_OnDraw)
.db VLABEL_VALUE, WIDGET_SIGNAL_SETVALUE, LOW(ValueLabel_OnSetValue), HIGH(ValueLabel_OnSetValue)
.db WIDGET_VALUE_DEFAULT_WIDTH, WIDGET_SIGNAL_GETVALUE, LOW(ValueLabel_OnGetDefaultWidth), HIGH(ValueLabel_OnGetDefaultWidth)
.db WIDGET_VALUE_DEFAULT_HEIGHT, WIDGET_SIGNAL_GETVALUE, LOW(ValueLabel_OnGetDefaultHeight), HIGH(ValueLabel_OnGetDefaultHeight)
.db 0, 0, 0, 0 ; end of table
#endif

View File

@@ -0,0 +1,355 @@
; ***************************************************************************
; 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_VLAYOUT_ASM
#define AQH_AVR_GUI2_VLAYOUT_ASM
; ***************************************************************************
; defines
.equ VLAYOUT_OFFS_BEGIN = WIDGET_SIZE
.equ VLAYOUT_OFFS_MODE = VLAYOUT_OFFS_BEGIN+0
.equ VLAYOUT_SIZE = VLAYOUT_OFFS_BEGIN+1
; values for VLAYOUT_OFFS_MODE
.equ VLAYOUT_MODE_EXPAND = 0
.equ VLAYOUT_MODE_SPREAD = 1
; ***************************************************************************
; code
.cseg
; ---------------------------------------------------------------------------
; @routine VLayout_new @global
;
; @return CFLAG set of okay, cleared otherwise
; @return Y address of newly created object
; @param X parent widget
; @param r16 value for OBJECT_OFFS_OPTS
; @param r17 value for WIDGET_OFFS_PACK
; @param r20 layout mode (VLAYOUT_MODE_EXPAND, VLAYOUT_MODE_SPREAD)
; @clobbers any
VLayout_new:
push r20
ldi r24, LOW(VLAYOUT_SIZE)
ldi r25, HIGH(VLAYOUT_SIZE)
bigcall Object_Alloc ; (!r16, !r17, !X)
pop r20
brcc VLayout_new_ret
rcall VLayout_Init ; (r16, r17, X)
sec
VLayout_new_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine VLayout_Init @global
;
; @param Y address of widget
; @param X parent widget (if any)
; @param r16 value for OBJECT_OFFS_OPTS
; @param r17 value for WIDGET_OFFS_PACK
; @param r20 layout mode (VLAYOUT_MODE_EXPAND, VLAYOUT_MODE_SPREAD)
; @clobbers r16, r17, X
VLayout_Init:
push r20
; call base class
bigcall Widget_Init ; (r16, r17, X)
pop r20
; set widget-specific data
std Y+VLAYOUT_OFFS_MODE, r20
; set default signal map
ldi r16, LOW(VLayout_DefaultSignalmap*2)
std Y+OBJECT_OFFS_SIGNALMAP_LO, r16
ldi r16, HIGH(VLayout_DefaultSignalmap*2)
std Y+OBJECT_OFFS_SIGNALMAP_HI, r16
ret
; @end
; ---------------------------------------------------------------------------
; @routine VLayout_OnLayout
;
; @param Y pointer to widget
; @clobbers any, !Y
VLayout_OnLayout:
; create and preset context
rcall LayoutCtx_CreateContextFor1D ; X=ctx, r16=num of children
brcc VLayout_OnLayout_ret
; do layout
mov r25, r16
rcall vLayoutHorizontally
rcall vLayoutVertically
; release layout context
bigcall LayoutCtx_free
; force re-drawing of this widget, clear layout bit
ldd r16, Y+OBJECT_OFFS_FLAGS
sbr r16, (1<<WIDGET_FLAGS_DIRTY_BIT)
cbr r16, (1<<WIDGET_FLAGS_LAYOUT_BIT)
std Y+OBJECT_OFFS_FLAGS, r16
VLayout_OnLayout_ret:
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine VLayout_OnGetDefaultHeight
;
; @param Y pointer to widget
; @return r19:r18 value
; @clobbers any, !Y
VLayout_OnGetDefaultHeight:
rcall Layout_SetDefaultHeights
rcall Layout_SumTmpValues ; r19:r18=default width
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine VLayout_OnGetDefaultWidth
;
; @param Y pointer to widget
; @return r19:r18 value
; @clobbers any, !Y
VLayout_OnGetDefaultWidth:
rcall Layout_SetDefaultWidths
rcall Layout_GetMaxTmp
bigcall Widget_AddOuterStyleBorders ; (r20, r21)
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine vLayoutHorizontally
;
; @param Y pointer to widget
; @param X layout context
; @param r25 number of children
; @clobbers any, !Y
vLayoutHorizontally:
rcall vLayoutPrepareHorizontal ; (any, !R25, !X, !Y)
rcall vLayoutReadLayoutWriteHorizontal ; (r16-r24)
ret
; @end
; ---------------------------------------------------------------------------
; @routine vLayoutPrepareHorizontal
;
; @param Y pointer to widget
; @param X layout context
; @param r25 number of children
; @clobbers any, !R25, !X, !Y,
vLayoutPrepareHorizontal:
push xl
push xh
push yl
push yh
push r25
rcall Layout_SetDefaultWidths
pop r25
pop yh
pop yl
pop xh
pop xl
ldd r20, Y+WIDGET_OFFS_WIDTH_LO
ldd r21, Y+WIDGET_OFFS_WIDTH_HI
adiw xh:xl, LAYOUT_CTX_OFFS_TOTALSIZE_LO
st X+, r20
st X, r21
sbiw xh:xl, (LAYOUT_CTX_OFFS_TOTALSIZE_LO+1)
ret
; @end
; ---------------------------------------------------------------------------
; @routine vLayoutReadLayoutWriteHorizontal
;
; @param Y pointer to widget
; @param X layout context
; @param r25 number of children
; @clobbers r16-r24
vLayoutReadLayoutWriteHorizontal:
; read positions and flags into new layout context
bigcall LayoutCtx_ReadXDimsContiguous ; (R16, r18, r19, Z)
; layout
adiw xh:xl, LAYOUT_CTX_OFFS_BORDERS
ld r18, X
clr r19
sbiw xh:xl, LAYOUT_CTX_OFFS_BORDERS
bigcall LayoutCtx_SetFixedPos ; (r24)
mov r22, r18 ; save border
bigcall LayoutCtx_GetMaxSize ; r19:r18=max default size (r18, r19, r20, r21, r24)
ldd r16, Y+WIDGET_OFFS_PACK
andi r16, (1<<WIDGET_PACK_HSELF1_BIT) | (1<<WIDGET_PACK_HSELF0_BIT)
cpi r16, WIDGET_PACK_FILLED
brne vLayoutReadLayoutWriteHorizontal_setSize
; use full possible width
adiw xh:xl, LAYOUT_CTX_OFFS_TOTALSIZE_LO
ld r18, X+
ld r19, X
sbiw xh:xl, (LAYOUT_CTX_OFFS_TOTALSIZE_LO+1)
clr r23
lsl r22
rol r23
sub r18, r22
sbc r19, r23
vLayoutReadLayoutWriteHorizontal_setSize:
bigcall LayoutCtx_SetFixedSize ; (r24)
; pack
bigcall LayoutCtx_PackXContiguous ; (R16, r18, r19, Z)
ret
; @end
; ---------------------------------------------------------------------------
; @routine vLayoutVertically
;
; @param Y pointer to widget
; @param X layout context
; @param r25 number of children
; @clobbers any, !X, !Y
vLayoutVertically:
rcall vLayoutPrepareVertical ; (any, !R25, !X, !Y)
rcall vLayoutReadLayoutWriteVertical ; (r16-r24)
ret
; @end
; ---------------------------------------------------------------------------
; @routine vLayoutPrepareVertical
;
; @param Y pointer to widget
; @param X layout context
; @param r25 number of children
; @clobbers any, !R25, !X, !Y,
vLayoutPrepareVertical:
push xl
push xh
push yl
push yh
push r25
rcall Layout_SetDefaultHeights ; (any, !Y)
pop r25
pop yh
pop yl
pop xh
pop xl
; setup layout context for horizontal operations
ldd r20, Y+WIDGET_OFFS_HEIGHT_LO
ldd r21, Y+WIDGET_OFFS_HEIGHT_HI
adiw xh:xl, LAYOUT_CTX_OFFS_TOTALSIZE_LO
st X+, r20
st X, r21
sbiw xh:xl, (LAYOUT_CTX_OFFS_TOTALSIZE_LO+1)
ret
; @end
; ---------------------------------------------------------------------------
; @routine vLayoutReadLayoutWriteVertical
;
; @param Y pointer to widget
; @param X layout context
; @param r25 number of children
; @clobbers r16-r24
vLayoutReadLayoutWriteVertical:
; read X positions and flags into new layout context
bigcall LayoutCtx_ReadYDimsContiguous ; (R16, r18, r19, Z)
; layout
push r25
ldd r24, Y+VLAYOUT_OFFS_MODE
cpi r24, VLAYOUT_MODE_SPREAD
breq vLayoutReadLayoutWriteVertical_spread
bigcall LayoutCtx_LayoutExpand ; (r16-r25)
rjmp vLayoutReadLayoutWriteVertical_pack
vLayoutReadLayoutWriteVertical_spread:
bigcall LayoutCtx_LayoutSpread ; (r16-r25)
vLayoutReadLayoutWriteVertical_pack:
pop r25
; pack
push r25
bigcall LayoutCtx_PackYContiguous ; (r16-r21, r24, r25)
pop r25
ret
; @end
; ***************************************************************************
; data in FLASH
VLayout_DefaultSignalmap:
; header
.dw Widget_DefaultSignalmap*2 ; next table to use
; entries
.db 0, WIDGET_SIGNAL_LAYOUT, LOW(VLayout_OnLayout), HIGH(VLayout_OnLayout)
.db WIDGET_VALUE_DEFAULT_WIDTH, WIDGET_SIGNAL_GETVALUE, LOW(VLayout_OnGetDefaultWidth), HIGH(VLayout_OnGetDefaultWidth)
.db WIDGET_VALUE_DEFAULT_HEIGHT, WIDGET_SIGNAL_GETVALUE, LOW(VLayout_OnGetDefaultHeight), HIGH(VLayout_OnGetDefaultHeight)
.db 0, 0, 0, 0 ; end of table
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,339 +0,0 @@
; ***************************************************************************
; 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_EEPROMDUMP_ASM
#define AQH_AVR_GUI2_EEPROMDUMP_ASM
; ***************************************************************************
; defines
.equ EEPROMDUMP_FONT = ili9341Font6x8_1
.equ EEPROMDUMP_FONT_WIDTH = 6
.equ EEPROMDUMP_FONT_HEIGHT = 8
.equ EEPROMDUMP_BYTESPERLINE = 8
.equ EEPROMDUMP_LINESPERPAGE = 18
; SDRAM data for EepromDump
.equ EEPROMDUMP_SD_OFFS_BEGIN = WIDGET_SD_SIZE
.equ EEPROMDUMP_SD_OFFS_STARTADDR_LO = EEPROMDUMP_SD_OFFS_BEGIN+0
.equ EEPROMDUMP_SD_OFFS_STARTADDR_HI = EEPROMDUMP_SD_OFFS_BEGIN+1
.equ EEPROMDUMP_SD_SIZE = EEPROMDUMP_SD_OFFS_BEGIN+2
; ***************************************************************************
; code
.cseg
; ---------------------------------------------------------------------------
; @routine SensorWatch_OnCreate @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
EepromDump_OnCreate:
bigcall OBJ_IsObject ; (none)
brcc EepromDump_OnCreate_ret
; preset SDRAM
bigcall Widget_GetSdramPtr ; (none)
clr r16
ldi r17, EEPROMDUMP_SD_SIZE
push yl
push yh
EepromDump_OnCreate_loop:
st Y+, r16
dec r17
brne EepromDump_OnCreate_loop
pop yh
pop yl
bigcall Widget_OnCreate
EepromDump_OnCreate_ret:
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine EepromDump_OnUp @global
;
; @param Z byte address of object (for LPM!)
EepromDump_OnUp:
bigcall Widget_GetSdramPtr ; (none)
ldd xl, Y+EEPROMDUMP_SD_OFFS_STARTADDR_LO
ldd xh, Y+EEPROMDUMP_SD_OFFS_STARTADDR_HI
ldi r16, LOW(EEPROMDUMP_BYTESPERLINE*EEPROMDUMP_LINESPERPAGE)
ldi r17, HIGH(EEPROMDUMP_BYTESPERLINE*EEPROMDUMP_LINESPERPAGE)
sub xl, r16
sbc xh, r17
brcc EepromDump_OnUp_set
clr xl
clr xh
EepromDump_OnUp_set:
std Y+EEPROMDUMP_SD_OFFS_STARTADDR_LO, xl
std Y+EEPROMDUMP_SD_OFFS_STARTADDR_HI, xh
ldd r17, Y+WIDGET_SD_OFFS_FLAGS
ori r17, (1<<WIDGET_FLAGS_DIRTY_BIT)
std Y+WIDGET_SD_OFFS_FLAGS, r17
sec
ret
; @end
EepromDump_OnDown:
bigcall Widget_GetSdramPtr ; (none)
ldd xl, Y+EEPROMDUMP_SD_OFFS_STARTADDR_LO
ldd xh, Y+EEPROMDUMP_SD_OFFS_STARTADDR_HI
ldi r16, LOW(EEPROMDUMP_BYTESPERLINE*EEPROMDUMP_LINESPERPAGE)
ldi r17, HIGH(EEPROMDUMP_BYTESPERLINE*EEPROMDUMP_LINESPERPAGE)
add xl, r16
adc xh, r17
brcs EepromDump_OnDown_tooHigh
ldi r16, LOW(EEPROMEND)
ldi r17, HIGH(EEPROMEND)
cp xl, r16
cpc xh, r17
brcs EepromDump_OnDown_set
EepromDump_OnDown_tooHigh:
ldi xl, LOW(EEPROMEND-EEPROMDUMP_BYTESPERLINE)
ldi xh, HIGH(EEPROMEND-EEPROMDUMP_BYTESPERLINE)
EepromDump_OnDown_set:
std Y+EEPROMDUMP_SD_OFFS_STARTADDR_LO, xl
std Y+EEPROMDUMP_SD_OFFS_STARTADDR_HI, xh
ldd r17, Y+WIDGET_SD_OFFS_FLAGS
ori r17, (1<<WIDGET_FLAGS_DIRTY_BIT)
std Y+WIDGET_SD_OFFS_FLAGS, r17
sec
ret
; @end
EepromDump_OnResetTlv:
bigcall Widget_GetSdramPtr ; (none)
ldi xl, LOW(EEPROM_OFFS_TLV)
ldi xh, HIGH(EEPROM_OFFS_TLV)
EepromDump_OnResetTlv_loop:
bigcall Eeprom_CheckAddr
brcc EepromDump_OnResetTlv_loopEnd
ldi r16, 0xff
bigcall Eeprom_WriteByte
adiw xh:xl, 1
rjmp EepromDump_OnResetTlv_loop
EepromDump_OnResetTlv_loopEnd:
ldd r17, Y+WIDGET_SD_OFFS_FLAGS
ori r17, (1<<WIDGET_FLAGS_DIRTY_BIT)
std Y+WIDGET_SD_OFFS_FLAGS, r17
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine EepromDump_OnDraw @global
;
; @param Z byte address of object (for LPM!)
; @param xl param1
; @param xh param2
; @clobbers any, !Z
EepromDump_OnDraw:
bigcall Widget_GetSdramPtr ; (none)
ldd r16, Y+WIDGET_SD_OFFS_FLAGS
andi r16, (1<<WIDGET_FLAGS_DIRTY_BIT)
breq EepromDump_OnDraw_ret
rcall Widget_Clear
bigcall Widget_GetSdramPtr ; (none)
ldd xl, Y+EEPROMDUMP_SD_OFFS_STARTADDR_LO
ldd xh, Y+EEPROMDUMP_SD_OFFS_STARTADDR_HI
ldi r16, 2
mov r4, r16
clr r5
mov r6, r16
clr r7
rcall eepromDumpDrawBlock
bigcall Widget_GetSdramPtr ; (none)
ldd r16, Y+WIDGET_SD_OFFS_FLAGS
cbr r16, (1<<WIDGET_FLAGS_DIRTY_BIT)
std Y+WIDGET_SD_OFFS_FLAGS, r16
EepromDump_OnDraw_ret:
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine eepromDumpDrawBlock
;
; @param Z byte address of widget object (for LPM!)
; @param R5:R4 X relative to widget
; @param R7:R6 Y relative to widget
; @param X current start address
; @param R18 number of bytes to print as hex bytes
eepromDumpDrawBlock:
ldi r18, EEPROMDUMP_LINESPERPAGE
eepromDumpDrawBlock_loop:
push r18
push r4
push r5
rcall eepromDumpDrawLine
pop r5
pop r4
ldi r16, LOW(EEPROMDUMP_FONT_HEIGHT)
ldi r17, HIGH(EEPROMDUMP_FONT_HEIGHT)
add r6, r16
adc r7, r17
pop r18
dec r18
brne eepromDumpDrawBlock_loop
ret
; @end
; ---------------------------------------------------------------------------
; @routine eepromDumpDrawLine
;
; @param Z byte address of widget object (for LPM!)
; @param R5:R4 X relative to widget
; @param R7:R6 Y relative to widget
; @param X current start address
; @param R18 number of bytes to print as hex bytes
; @return X pointer to next byte to write
; @clobbers any, !Z, !R6, !R7
eepromDumpDrawLine:
push xl
push xh
mov r20, xl
mov r21, xh
bigcall HexWordToAscii ; X=ptr to addr (R16, R17)
rcall eepromDumpDrawText
ldi r16, LOW(EEPROMDUMP_FONT_WIDTH*4)
ldi r17, HIGH(EEPROMDUMP_FONT_WIDTH*4)
add r4, r16
adc r5, r17
ldi r16, ':'
rcall eepromDumpDrawChar
ldi r16, ' '
rcall eepromDumpDrawChar
pop xh
pop xl
ldi r18, EEPROMDUMP_BYTESPERLINE
eepromDumpDrawLine_loop:
bigcall Eeprom_ReadByte ; R16=byte read
brcc eepromDumpDrawLine_ret
adiw xh:xl, 1
push r18
push xl
push xh
bigcall HexByteToAscii ; X=ptr to addr (R16, R17)
rcall eepromDumpDrawText
ldi r16, LOW(EEPROMDUMP_FONT_WIDTH*2)
ldi r17, HIGH(EEPROMDUMP_FONT_WIDTH*2)
add r4, r16
adc r5, r17
ldi r16, ' '
rcall eepromDumpDrawChar
pop xh
pop xl
pop r18
dec r18
brne eepromDumpDrawLine_loop
eepromDumpDrawLine_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine eepromDumpDrawLine
;
; @param Z byte address of widget object (for LPM!)
; @param R5:R4 X relative to widget
; @param R7:R6 Y relative to widget
; @param X address of text to write
; @clobbers any, !Z, !(r4-r7)
eepromDumpDrawText:
push r4
push r5
push r6
push r7
bigcall Widget_DrawTextSDRAM ; (any, !Z)
pop r7
pop r6
pop r5
pop r4
ret
; @end
; ---------------------------------------------------------------------------
; @routine eepromDumpDrawChar
;
; @param Z byte address of widget object (for LPM!)
; @param R5:R4 X relative to widget
; @param R7:R6 Y relative to widget
; @param R16 byte to write
; @clobbers any, !Z, !(r4-r7)
eepromDumpDrawChar:
push r4
push r5
push r6
push r7
bigcall Widget_DrawCharAt ; (any, !Z)
pop r7
pop r6
pop r5
pop r4
ldi r16, LOW(EEPROMDUMP_FONT_WIDTH)
ldi r17, HIGH(EEPROMDUMP_FONT_WIDTH)
add r4, r16
adc r5, r17
ret
; @end
#endif

View File

@@ -1,95 +0,0 @@
; ***************************************************************************
; 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_BUTTON_ASM
#define AQH_AVR_GUI2_BUTTON_ASM
; ***************************************************************************
; code
.cseg
; ---------------------------------------------------------------------------
; @routine Button_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
Button_OnTouch:
rcall Widget_GetSdramPtr ; Y:=SDRAM data for widget
; read touch signal data from X
ld r18, X+ ; WIDGET_DATA_TOUCH_OFFS_X_LO
ld r19, X+ ; WIDGET_DATA_TOUCH_OFFS_X_HI
ld r20, X+ ; WIDGET_DATA_TOUCH_OFFS_Y_LO
ld r21, X+ ; WIDGET_DATA_TOUCH_OFFS_Z_HI
ld r22, X ; WIDGET_DATA_TOUCH_OFFS_STATE
sbiw xh:xl, 4
sbrs r22, DISPLAY_IFLAGS_PRESSED_BIT
rjmp Button_OnTouch_up
; down (active touch)
ldd r16, Y+WIDGET_SD_OFFS_FLAGS
sbrc r16, WIDGET_FLAGS_PRESSED_BIT
rjmp Button_OnTouch_ret ; already pressed, jmp
; newly pressed
rcall widgetLoadCoordsForFullWidget ; get X, Y, W, H (none)
rcall Widget_MakeAbsPos ; (R16, R17)
rcall Widget_IsPointInRect ; (R16, R17)
brcc Button_OnTouch_ret ; touch not inside this widget, jmp
; touch down inside this widget, handle
bigcall Widget_GrabTouchEvents ; (r16, r17, r18, r19, X)
brcc Button_OnTouch_ret
ldi r16, (1<<WIDGET_FLAGS_PRESSED_BIT) | (1<<WIDGET_FLAGS_DIRTY_BIT)
push yl
push yh
bigcall Widget_AddFlagsDown ; (R17, R18, R19, R22, R23, Y)
pop yh
pop yl
rjmp Button_OnTouch_ret
Button_OnTouch_up:
ldd r16, Y+WIDGET_SD_OFFS_FLAGS
sbrs r16, WIDGET_FLAGS_PRESSED_BIT
rjmp Button_OnTouch_ret
; was pressed, not any more
bigcall Widget_UngrabTouchEvents ; (r16, r17, r18, r19, X)
push yl
push yh
ldi r16, (1<<WIDGET_FLAGS_PRESSED_BIT)
bigcall Widget_SubFlagsDown ; (R17, R18, R19, R22, R23, Y)
ldi r16, (1<<WIDGET_FLAGS_DIRTY_BIT)
bigcall Widget_AddFlagsDown ; (R17, R18, R19, R22, R23, Y)
ldi r16, WIDGET_SIGNAL_CLICKED ; emit "CLICKED" signal
bigcall OBJ_EmitSignal
pop yh
pop yl
Button_OnTouch_ret:
sec
ret
; @end
Button_DefaultSignalmap:
.db 0, WIDGET_SIGNAL_TOUCH, LOW(Button_OnTouch), HIGH(Button_OnTouch)
.db 0, WIDGET_SIGNAL_DRAW, LOW(ImageView_OnDraw), HIGH(ImageView_OnDraw)
.db 0, IMGVIEW_SIGNAL_SETBGCOL, LOW(ImageView_OnSetBgCol), HIGH(ImageView_OnSetBgCol)
.db 0, OBJECT_SIGNAL_CREATE, LOW(ImageView_OnCreate), HIGH(ImageView_OnCreate)
.db 0, 0, 0, 0 ; end of table
#endif

View File

@@ -1,593 +0,0 @@
; ***************************************************************************
; 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_GUIAPP_ASM
#define AQH_AVR_GUI2_GUIAPP_ASM
; ***************************************************************************
; defines
; GuiApp in flash
.equ GUIAPP_OFFS_GUIAPP = OBJECT_SIZE
.equ GUIAPP_OFFS_SDRAM_LO = GUIAPP_OFFS_GUIAPP+0
.equ GUIAPP_OFFS_SDRAM_HI = GUIAPP_OFFS_GUIAPP+1
.equ GUIAPP_OFFS_ROOTWIDGET_LO = GUIAPP_OFFS_GUIAPP+2
.equ GUIAPP_OFFS_ROOTWIDGET_HI = GUIAPP_OFFS_GUIAPP+3
.equ GUIAPP_OFFS_SCREENSAVER_LO = GUIAPP_OFFS_GUIAPP+4
.equ GUIAPP_OFFS_SCREENSAVER_HI = GUIAPP_OFFS_GUIAPP+5
.equ GUIAPP_SIZE = GUIAPP_OFFS_GUIAPP+6
; signals
.equ GUIAPP_SIGNAL_RAISE = OBJECT_SIGNAL_NEXTFREE+0 ; app->cntrl: X=WIDGET to raise
.equ GUIAPP_SIGNAL_SHOW = OBJECT_SIGNAL_NEXTFREE+1 ; cntrl->app
.equ GUIAPP_SIGNAL_HIDE = OBJECT_SIGNAL_NEXTFREE+2 ; cntrl->app
.equ GUIAPP_SIGNAL_DEBUG = OBJECT_SIGNAL_NEXTFREE+3
.equ GUIAPP_SIGNAL_NEXTFREE = OBJECT_SIGNAL_NEXTFREE+4
; SDRAM data for guiapp
.equ GUIAPP_SD_OFFS_FLAGS = 0
.equ GUIAPP_SD_OFFS_DRAWTIMER = 1
.equ GUIAPP_SD_OFFS_CURRENTWIDGET_LO = 2
.equ GUIAPP_SD_OFFS_CURRENTWIDGET_HI = 3
.equ GUIAPP_SD_OFFS_TOUCHWIDGET_LO = 4
.equ GUIAPP_SD_OFFS_TOUCHWIDGET_HI = 5
.equ GUIAPP_SD_SIZE = 6
.equ GUIAPP_DRAWTIMER = 2
; ***************************************************************************
; data
.dseg
guiapp_touch_event:
.byte WIDGET_DATA_TOUCH_SIZE
; ***************************************************************************
; code
.cseg
; ---------------------------------------------------------------------------
; @routine GuiApp_Init
;
; @param Z byte address of guiapp object (for LPM!)
GuiApp_Init:
ldi r16, OBJECT_SIGNAL_CREATE
clr r17
bigcall OBJ_HandleSignal
rcall GuiApp_ShowFirstView
ret
; @end
; ---------------------------------------------------------------------------
; @routine GuiApp_Every100ms @global
;
; @param Z byte address of guiapp object (for LPM!)
GuiApp_Every100ms:
ldi r16, OBJECT_SIGNAL_TIMER
clr r17
bigcall OBJ_HandleSignal
ret
; @end
; ---------------------------------------------------------------------------
; @routine GuiApp_MsgReceived @global
;
; @param Z byte address of guiapp object (for LPM!)
GuiApp_MsgReceived:
ldi r16, OBJECT_SIGNAL_RECVMSG
clr r17
bigcall OBJ_HandleSignal
ret
; @end
; ---------------------------------------------------------------------------
; @routine GuiApp_OnTimer
;
; @param Z byte address of guiapp object (for LPM!)
GuiApp_OnTimer:
; check for touch event
rcall guiAppCheckTouch
; send timer signal to all accepting widgets
push zl
push zh
adiw zh:zl, GUIAPP_OFFS_ROOTWIDGET_LO
lpm r16, Z+
lpm zh, Z
mov zl, r16
or r17, zh
breq GuiApp_OnTimer_l1
bigcall Widget_Tree_SendTimerSignal
GuiApp_OnTimer_l1:
pop zh
pop zl
; possibly draw widgets
rcall GuiApp_GetSdramPtr
ldd r16, Y+GUIAPP_SD_OFFS_DRAWTIMER
tst r16
breq GuiApp_OnTimer_ret
dec r16
brne GuiApp_OnTimer_writeDrawTimer
push yl
push yh
rcall guiAppDrawWidgets
pop yh
pop yl
ldi r16, GUIAPP_DRAWTIMER
GuiApp_OnTimer_writeDrawTimer:
std Y+GUIAPP_SD_OFFS_DRAWTIMER, r16
GuiApp_OnTimer_ret:
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine GuiApp_OnTouch
;
; @param Z byte address of guiapp object (for LPM!)
; @param X pointer to touch event in SDRAM
GuiApp_OnTouch:
push zl
push zh
rcall GuiApp_GetSdramPtr
ldd r18, Y+GUIAPP_SD_OFFS_TOUCHWIDGET_LO
ldd r19, Y+GUIAPP_SD_OFFS_TOUCHWIDGET_HI
mov r16, r18
or r16, r19
breq GuiApp_OnTouch_sendToAll
mov zl, r18
mov zh, r19
ldi r16, WIDGET_SIGNAL_TOUCH
clr r17
bigcall OBJ_HandleSignal
rjmp GuiApp_OnTouch_done
GuiApp_OnTouch_sendToAll:
rcall GuiApp_GetRootWidgetToZ
brcc GuiApp_OnTouch_done
; send touch signal
bigcall Widget_Tree_SendTouchSignal
GuiApp_OnTouch_done:
pop zh
pop zl
; send keepAlive to screensaver (if not active!)
rcall guiAppSendKeepAliveIfScreenSaverInactive
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine guiAppSendKeepAliveIfScreenSaverInactive
;
; @param Z byte address of guiapp object (for LPM!)
; @clobbers any
guiAppSendKeepAliveIfScreenSaverInactive:
push zl
push zh
rcall GuiApp_GetSdramPtr
adiw zh:zl, GUIAPP_OFFS_SCREENSAVER_LO
lpm r20, Z+
lpm r21, Z
sbiw zh:zl, GUIAPP_OFFS_SCREENSAVER_LO+1
ldd r16, Y+GUIAPP_SD_OFFS_CURRENTWIDGET_LO
cp r16, r20
brne guiAppSendKeepAliveIfScreenSaverInactive_send
ldd r16, Y+GUIAPP_SD_OFFS_CURRENTWIDGET_HI
cp r16, r21
breq guiAppSendKeepAliveIfScreenSaverInactive_end
guiAppSendKeepAliveIfScreenSaverInactive_send:
mov zl, r20
mov zh, r21
bigcall ScreenSaver_KeepAlive
guiAppSendKeepAliveIfScreenSaverInactive_end:
pop zh
pop zl
ret
; @end
; ---------------------------------------------------------------------------
; @routine GuiApp_OnMsgReceived @global
;
; @param Z byte address of guiapp object (for LPM!)
; @param X pointer to message received in SDRAM
GuiApp_OnMsgReceived:
push zl
push zh
rcall GuiApp_GetRootWidgetToZ
brcc GuiApp_OnMsgReceived_done
bigcall Widget_Tree_SendMsgRecvSignal
GuiApp_OnMsgReceived_done:
pop zh
pop zl
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine GuiApp_OnCreate @global
;
; @param Z byte address of object (for LPM!)
; @return CFLAG set if signal handled
; @clobbers any, !Z
GuiApp_OnCreate:
; init sdram data
rcall GuiApp_GetSdramPtr
ldi r17, GUIAPP_SD_SIZE
clr r16
push yl
push yh
GuiApp_OnCreate_loop:
st Y+, r16
dec r17
brne GuiApp_OnCreate_loop
pop yh
pop yl
clr r16
std Y+GUIAPP_SD_OFFS_FLAGS, r16
ldi r16, GUIAPP_DRAWTIMER
std Y+GUIAPP_SD_OFFS_DRAWTIMER, r16
rcall guiAppInitWidgets
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine GuiApp_GetSdramPtr @global
;
; @param Z byte address of object (for LPM!)
; @return Y pointer to SDRAM data for widget
; @clobbers none
GuiApp_GetSdramPtr:
adiw zh:zl, GUIAPP_OFFS_SDRAM_LO
lpm yl, Z+
lpm yh, Z
sbiw zh:zl, GUIAPP_OFFS_SDRAM_LO+1
ret
; @end
; ---------------------------------------------------------------------------
; @routine GuiApp_GetRootWidgetToZ @global
;
; @param Z byte address of object (for LPM!)
; @return CFLAG set if there is a root widget, cleared otherwise
; @return Z byte address pointer to root widget (for LPM!), if CFLAG set, garbage otherwise
; @clobbers none
GuiApp_GetRootWidgetToZ:
rcall OBJ_IsObject
brcc GuiApp_GetRootWidgetToZ_ret
adiw zh:zl, GUIAPP_OFFS_ROOTWIDGET_LO
lpm r16, Z+
lpm zh, Z
mov zl, r16
rcall OBJ_IsObject
GuiApp_GetRootWidgetToZ_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine GuiApp_ShowFirstView @global
;
; @param Z byte address of guiapp object (for LPM!)
GuiApp_ShowFirstView:
push zl
push zh
rcall GuiApp_GetRootWidgetToZ
brcc GuiApp_ShowFirstView_error
bigcall OBJ_GetFirstChild
brcc GuiApp_ShowFirstView_error
mov xl, r18
mov xh, r19
pop zh
pop zl
rcall GuiApp_ShowView
rjmp GuiApp_ShowFirstView_ret
GuiApp_ShowFirstView_error:
pop zh
pop zl
GuiApp_ShowFirstView_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine GuiApp_ShowView @global
;
; @param Z byte address of object (for LPM!)
; @param X byte address of object to show (for LPM!)
; @return CFLAG set if signal handled
; @clobbers any, !Z
GuiApp_ShowView:
rcall GuiApp_GetSdramPtr ; Y=SDRAM
ldd r18, Y+GUIAPP_SD_OFFS_CURRENTWIDGET_LO
ldd r19, Y+GUIAPP_SD_OFFS_CURRENTWIDGET_HI
eor r18, xl ; 0 if same
eor r19, xh ; 0 if same
or r18, r19 ; 0 if r19:r18==X
breq GuiApp_ShowView_ret ; same, no change
push yl
push yh
rcall guiAppHideCurrent ; (any, !X, !Z)
pop yh
pop yl
; store new view
std Y+GUIAPP_SD_OFFS_CURRENTWIDGET_LO, xl
std Y+GUIAPP_SD_OFFS_CURRENTWIDGET_HI, xh
; show new (if any)
rcall guiAppShowCurrent
GuiApp_ShowView_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine GuiApp_GetCurrentView @global
;
; @param Z byte address of object (for LPM!)
; @return X byte address of current view object (for LPM!)
; @clobbers Y
GuiApp_GetCurrentView:
rcall GuiApp_GetSdramPtr ; Y=SDRAM
ldd xl, Y+GUIAPP_SD_OFFS_CURRENTWIDGET_LO
ldd xh, Y+GUIAPP_SD_OFFS_CURRENTWIDGET_HI
ret
; @end
; ---------------------------------------------------------------------------
; @routine GuiApp_GrabTouchEvents
;
; @param Z byte address of gui app object (for LPM!)
; @param X byte address of widget grabbing touch events
; @return CFLAG set if grabbed, cleared otherwise
; @clobbers R16, R17, Y
GuiApp_GrabTouchEvents:
rcall OBJ_IsObject ; (none)
brcc GuiApp_GrabTouchEvents_ret
rcall GuiApp_GetSdramPtr ; (none)
ldd r16, Y+GUIAPP_SD_OFFS_TOUCHWIDGET_LO
ldd r17, Y+GUIAPP_SD_OFFS_TOUCHWIDGET_HI
or r16, r17
clc
brne GuiApp_GrabTouchEvents_ret ; only grab if not already grabbed!
std Y+GUIAPP_SD_OFFS_TOUCHWIDGET_LO, xl
std Y+GUIAPP_SD_OFFS_TOUCHWIDGET_HI, xh
sec
GuiApp_GrabTouchEvents_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine GuiApp_UngrabTouchEvents
;
; @param Z byte address of gui app object (for LPM!)
; @param X byte address of widget ungrabbing touch events
; @return CFLAG set if ungrabbed, cleared otherwise
; @clobbers R16, R17
GuiApp_UngrabTouchEvents:
rcall OBJ_IsObject ; (none)
brcc GuiApp_UngrabTouchEvents_ret
rcall GuiApp_GetSdramPtr ; (none)
ldd r16, Y+GUIAPP_SD_OFFS_TOUCHWIDGET_LO
ldd r17, Y+GUIAPP_SD_OFFS_TOUCHWIDGET_HI
eor r16, xl
eor r17, xh
or r16, r17
clc
brne GuiApp_UngrabTouchEvents_ret ; only ungrab same widget!
clr r16
std Y+GUIAPP_SD_OFFS_TOUCHWIDGET_LO, r16
std Y+GUIAPP_SD_OFFS_TOUCHWIDGET_HI, r16
sec
GuiApp_UngrabTouchEvents_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine guiAppHideCurrent
;
; @param Z byte address of gui app object (for LPM!)
; @clobbers any, !X, !Z
guiAppHideCurrent:
push zl
push zh
rcall GuiApp_GetSdramPtr ; Y=SDRAM
ldd zl, Y+GUIAPP_SD_OFFS_CURRENTWIDGET_LO
ldd zh, Y+GUIAPP_SD_OFFS_CURRENTWIDGET_HI
mov r16, zl
or r16, zh
breq guiAppHideCurrent_done
ldi r16, WIDGET_SIGNAL_HIDE
clr r17
bigcall OBJ_HandleSignal ; (any, !X, !Y. !Z)
ldi r16, (1<<WIDGET_FLAGS_ACTIVE_BIT)
bigcall Widget_SubFlagsDown ; (R17, R18, R19, R22, R23)
guiAppHideCurrent_done:
pop zh
pop zl
ret
; @end
; ---------------------------------------------------------------------------
; @routine guiAppShowCurrent
;
; @param Z byte address of gui app object (for LPM!)
; @clobbers any, !X, !Z
guiAppShowCurrent:
push zl
push zh
rcall GuiApp_GetSdramPtr ; Y=SDRAM
ldd zl, Y+GUIAPP_SD_OFFS_CURRENTWIDGET_LO
ldd zh, Y+GUIAPP_SD_OFFS_CURRENTWIDGET_HI
mov r16, zl
or r16, zh
breq guiAppShowCurrent_done
ldi r16, (1<<WIDGET_FLAGS_ACTIVE_BIT) | (1<<WIDGET_FLAGS_DIRTY_BIT)
bigcall Widget_AddFlagsDown
ldi r16, WIDGET_SIGNAL_SHOW
clr r17
bigcall OBJ_HandleSignal ; (any, !X, !Y. !Z)
guiAppShowCurrent_done:
pop zh
pop zl
rcall guiAppDrawWidgets ; (any, !Z)
ret
; @end
; ---------------------------------------------------------------------------
; @routine guiAppInitWidgets
;
; @param Z byte address of guiapp object (for LPM!)
guiAppInitWidgets:
; init widgets
push zl
push zh
rcall GuiApp_GetRootWidgetToZ
brcc guiAppInitWidgets_done
ldi r16, OBJECT_SIGNAL_CREATE
clr r17
bigcall OBJ_TreeAllHandleSignal
ldi r16, (1<<WIDGET_FLAGS_ACTIVE_BIT) | (1<<WIDGET_FLAGS_DIRTY_BIT) ; root window is always active
rcall Widget_AddFlags
guiAppInitWidgets_done:
pop zh
pop zl
ret
; @end
; ---------------------------------------------------------------------------
; @routine guiAppDrawWidgets
;
; @param Z byte address of guiapp object (for LPM!)
guiAppDrawWidgets:
push zl
push zh
rcall GuiApp_GetRootWidgetToZ
brcc guiAppDrawWidgets_done
bigcall Widget_Tree_SendDrawSignal
guiAppDrawWidgets_done:
pop zh
pop zl
guiAppDrawWidgets_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine guiAppCheckTouch
;
; @param Z byte address of guiapp object (for LPM!)
guiAppCheckTouch:
bigcall Display_InputGetState ; r16=flags, r5:r4=x, r7:r6=y
mov r17, r16
andi r17, (1<<DISPLAY_IFLAGS_CHGCOORD_BIT) | (1<<DISPLAY_IFLAGS_CHGPRESS_BIT)
breq guiAppCheckTouch_ret
ldi xl, LOW(guiapp_touch_event)
ldi xh, HIGH(guiapp_touch_event)
st X+, r4 ; X
st X+, r5
st X+, r6 ; Y
st X+, r7
st X, r16 ; flags
sbiw xh:xl, 4 ; (4 times incremented)
; send touch signal
ldi r16, WIDGET_SIGNAL_TOUCH
clr r17
bigcall OBJ_HandleSignal
guiAppCheckTouch_ret:
ret
; @end
guiAbortIfNotObject:
bigcall OBJ_IsObject
brcs guiAbortIfNotObject_ret
rcall DEBUG2
guiAbortIfNotObject_ret:
ret
; @end
#endif

View File

@@ -1,187 +0,0 @@
; ***************************************************************************
; 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_IMAGEVIEW_ASM
#define AQH_AVR_GUI2_IMAGEVIEW_ASM
; ***************************************************************************
; defines
; IMGVIEW in flash
.equ IMGVIEW_OFFS_IMGVIEW = WIDGET_SIZE
.equ IMGVIEW_OFFS_RESSOURCEID_LO = IMGVIEW_OFFS_IMGVIEW+0
.equ IMGVIEW_OFFS_RESSOURCEID_HI = IMGVIEW_OFFS_IMGVIEW+1
.equ IMGVIEW_SIZE = IMGVIEW_OFFS_IMGVIEW+2
; SDRAM data for IMGVIEW
.equ IMGVIEW_SD_OFFS_IMGVIEW = WIDGET_SD_SIZE
.equ IMGVIEW_SD_OFFS_BGCOL_LO = IMGVIEW_SD_OFFS_IMGVIEW+0
.equ IMGVIEW_SD_OFFS_BGCOL_HI = IMGVIEW_SD_OFFS_IMGVIEW+1
.equ IMGVIEW_SD_SIZE = IMGVIEW_SD_OFFS_IMGVIEW+2
; signals
.equ IMGVIEW_SIGNAL_SETBGCOL = WIDGET_SIGNAL_NEXTFREE+0
.equ IMGVIEW_SIGNAL_NEXTFREE = WIDGET_SIGNAL_NEXTFREE+1
; ***************************************************************************
; code
.cseg
; ---------------------------------------------------------------------------
; @routine ImageView_OnCreate @global
;
; @param Z byte address of widget object (for LPM!)
; @return CFLAG set if signal handled
; @clobbers any, !Z
ImageView_OnCreate:
bigcall Widget_OnCreate
bigcall Widget_GetSdramPtr ; (none)
adiw zh:zl, WIDGET_OFFS_BACKCOL_LO
lpm r16, Z+
lpm r17, Z
sbiw zh:zl, WIDGET_OFFS_BACKCOL_LO+1
std Y+IMGVIEW_SD_OFFS_BGCOL_LO, r16
std Y+IMGVIEW_SD_OFFS_BGCOL_HI, r17
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine ImageView_OnSetBgCol @global
;
; @param Z byte address of widget object (for LPM!)
; @param X new value for background color
; @return CFLAG set if signal handled
; @clobbers r17
ImageView_OnSetBgCol:
bigcall OBJ_IsObject ; (none)
brcc ImageView_OnSetBgCol_ret
push zl
push zh
rcall Widget_GetSdramPtr ; (none)
std Y+IMGVIEW_SD_OFFS_BGCOL_LO, xl
std Y+IMGVIEW_SD_OFFS_BGCOL_HI, xh
ldd r17, Y+WIDGET_SD_OFFS_FLAGS
ori r17, (1<<WIDGET_FLAGS_DIRTY_BIT)
std Y+WIDGET_SD_OFFS_FLAGS, r17
pop zh
pop zl
ImageView_OnSetBgCol_ret:
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine Widget_OnDraw @global
;
; @param Z byte address of widget object (for LPM!)
; @return CFLAG set if signal handled
; @clobbers any, !Z
ImageView_OnDraw:
bigcall Widget_GetSdramPtr ; (none)
ldd r16, Y+WIDGET_SD_OFFS_FLAGS
andi r16, (1<<WIDGET_FLAGS_DIRTY_BIT)
breq ImageView_OnDraw_ret
; rcall Widget_Clear
adiw zh:zl, WIDGET_OFFS_OPTS_LO
lpm r14, Z
sbiw zh:zl, WIDGET_OFFS_OPTS_LO
push zl
push zh
; get ressource id
adiw zh:zl, IMGVIEW_OFFS_RESSOURCEID_LO
lpm r16, Z+
lpm r17, Z
sbiw zh:zl, IMGVIEW_OFFS_RESSOURCEID_LO+1
; get ressource
ldi zl, LOW(RESSOURCE_ADDR*2)
ldi zh, HIGH(RESSOURCE_ADDR*2)
bigcall RES_GetRessource
mov r12, zl
mov r13, zh
pop zh
pop zl
brcc ImageView_OnDraw_done
; get background color
ldd r16, Y+WIDGET_SD_OFFS_FLAGS
andi r16, (1<<WIDGET_FLAGS_PRESSED_BIT)
breq ImageView_OnDraw_useStoredBgCol
ldi r16, LOW(STYLE_BUTTON_COL_BG_PRESSED)
mov r0, r16
ldi r16, HIGH(STYLE_BUTTON_COL_BG_PRESSED)
mov r1, r16
rjmp ImageView_OnDraw_getPos
ImageView_OnDraw_useStoredBgCol:
ldd r0, Y+IMGVIEW_SD_OFFS_BGCOL_LO
ldd r1, Y+IMGVIEW_SD_OFFS_BGCOL_HI
ImageView_OnDraw_getPos:
; draw at 0/0
clr r4 ; X
clr r5
clr r6 ; Y
clr r7
sbrs r14, WIDGET_OPTSLO_BORDER_BIT
rjmp ImageView_OnDraw_draw
ldi r16, 2
clr r17
add r4, r16
adc r5, r17
add r6, r16
adc r7, r17
ImageView_OnDraw_draw:
bigcall Widget_DrawImage
sbrs r14, WIDGET_OPTSLO_BORDER_BIT
rjmp ImageView_OnDraw_done
bigcall Widget_DrawBorder
ImageView_OnDraw_done:
bigcall Widget_GetSdramPtr ; (none)
ldd r16, Y+WIDGET_SD_OFFS_FLAGS
cbr r16, (1<<WIDGET_FLAGS_DIRTY_BIT)
std Y+WIDGET_SD_OFFS_FLAGS, r16
ImageView_OnDraw_ret:
sec
ret
; @end
ImageView_DefaultSignalmap:
.db 0, WIDGET_SIGNAL_DRAW, LOW(ImageView_OnDraw), HIGH(ImageView_OnDraw)
.db 0, IMGVIEW_SIGNAL_SETBGCOL, LOW(ImageView_OnSetBgCol), HIGH(ImageView_OnSetBgCol)
.db 0, OBJECT_SIGNAL_CREATE, LOW(ImageView_OnCreate), HIGH(ImageView_OnCreate)
.db 0, 0, 0, 0 ; end of table
#endif

View File

@@ -1,118 +0,0 @@
; ***************************************************************************
; 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_LABEL_ASM
#define AQH_AVR_GUI2_LABEL_ASM
; ***************************************************************************
; defines
; Label in flash
.equ LABEL_OFFS_LABEL = WIDGET_SIZE
.equ LABEL_OFFS_TEXT_LO = LABEL_OFFS_LABEL+0
.equ LABEL_OFFS_TEXT_HI = LABEL_OFFS_LABEL+1
.equ LABEL_SIZE = LABEL_OFFS_LABEL+2
; ***************************************************************************
; code
.cseg
; ---------------------------------------------------------------------------
; @routine Label_OnDraw @global
;
; @param Z byte address of object (for LPM!)
; @param xl param1
; @param xh param2
; @clobbers any, !Z
Label_OnDraw:
bigcall Widget_GetSdramPtr ; (none)
ldd r16, Y+WIDGET_SD_OFFS_FLAGS
andi r16, (1<<WIDGET_FLAGS_DIRTY_BIT)
breq Label_OnDraw_ret
adiw zh:zl, WIDGET_OFFS_OPTS_LO ; get OPTS low
lpm r14, Z
sbiw zh:zl, WIDGET_OFFS_OPTS_LO
rcall Widget_Clear
rcall labelWriteText
mov r16, r14
andi r16, (1<<WIDGET_OPTSLO_BORDER_BIT)
breq Label_OnDraw_done
ldi r16, LOW(STYLE_BUTTON_COL_BORDER)
mov r2, r16
ldi r16, HIGH(STYLE_BUTTON_COL_BORDER)
mov r3, r16
bigcall Widget_DrawBorder
Label_OnDraw_done:
bigcall Widget_GetSdramPtr ; (none)
ldd r16, Y+WIDGET_SD_OFFS_FLAGS
cbr r16, (1<<WIDGET_FLAGS_DIRTY_BIT)
std Y+WIDGET_SD_OFFS_FLAGS, r16
Label_OnDraw_ret:
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine labelWriteText
;
; @param Z byte address of object (for LPM!)
; @param R14 opts low
; @clobbers any, !Z
labelWriteText:
push zl
push zh
adiw zh:zl, LABEL_OFFS_TEXT_LO
lpm r16, Z+
lpm zh, Z
mov zl, r16
or r16, zh
breq labelWriteText_noText
ldi r18, STYLE_WIN_FONT_WIDTH
rcall Widget_CalcStringWidthFLASH ; r13:r12=string width
pop zh
pop zl
rcall Widget_AlignPosXY ; (r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19)
adiw zh:zl, LABEL_OFFS_TEXT_LO
lpm r12, Z+
lpm r13, Z
sbiw zh:zl, LABEL_OFFS_TEXT_LO+1
bigcall Widget_DrawTextFlash
ret
labelWriteText_noText:
pop zh
pop zl
ret
; @end
Label_DefaultSignalmap:
.db 0, OBJECT_SIGNAL_CREATE, LOW(Widget_OnCreate), HIGH(Widget_OnCreate)
.db 0, WIDGET_SIGNAL_DRAW, LOW(Label_OnDraw), HIGH(Label_OnDraw)
.db 0, 0, 0, 0 ; end of table
#endif

View File

@@ -1,530 +0,0 @@
; ***************************************************************************
; 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_OBJECT_ASM
#define AQH_AVR_GUI2_OBJECT_ASM
; ***************************************************************************
; defines
; Object in flash
.equ OBJECT_OFFS_MAGIC_LO = 0
.equ OBJECT_OFFS_MAGIC_HI = 1
.equ OBJECT_OFFS_NEXT_LO = 2 ; byte address (for LPM!)
.equ OBJECT_OFFS_NEXT_HI = 3
.equ OBJECT_OFFS_PARENT_LO = 4 ; byte address (for LPM!)
.equ OBJECT_OFFS_PARENT_HI = 5
.equ OBJECT_OFFS_CHILD_LO = 6 ; byte address (for LPM!)
.equ OBJECT_OFFS_CHILD_HI = 7
.equ OBJECT_OFFS_TARGET_LO = 8 ; byte address (for LPM!)
.equ OBJECT_OFFS_TARGET_HI = 9
.equ OBJECT_OFFS_SELECTOR = 10
.equ OBJECT_OFFS_UNUSED = 11
.equ OBJECT_OFFS_SIGNALMAP_LO = 12 ; byte address (for LPM!)
.equ OBJECT_OFFS_SIGNALMAP_HI = 13
.equ OBJECT_SIZE = 14
; SignalMap entries
.equ OBJECT_SIGNALMAP_OFFS_SELECTOR = 0
.equ OBJECT_SIGNALMAP_OFFS_SIGNAL = 1 ; end if 0
.equ OBJECT_SIGNALMAP_OFFS_HANDLER_LO = 2
.equ OBJECT_SIGNALMAP_OFFS_HANDLER_HI = 3
; signals
.equ OBJECT_SIGNAL_NONE = 0
.equ OBJECT_SIGNAL_CREATE = 1
.equ OBJECT_SIGNAL_DESTROY = 2
.equ OBJECT_SIGNAL_TIMER = 3
.equ OBJECT_SIGNAL_RECVMSG = 4 ; X=msg
.equ OBJECT_SIGNAL_NEXTFREE = 5
; ***************************************************************************
; code
.cseg
; ---------------------------------------------------------------------------
; @routine OBJ_IsObject @global
;
; @param Z byte address of object (for LPM!)
; @return CFLAG set if is widget, cleared otherwise
; @clobbers none
OBJ_IsObject:
push r22
push r23
mov r22, zl
or r22, zh
clc
breq OBJ_IsObject_ret
lpm r22, Z+
lpm r23, Z
sbiw zh:zl, 1
cpi r22, 0x55
clc
brne OBJ_IsObject_ret
cpi r23, 0xaa
clc
brne OBJ_IsObject_ret
sec
OBJ_IsObject_ret:
pop r23
pop r22
ret
; @end
; ---------------------------------------------------------------------------
; @routine OBJ_GetParent @global
;
; @param Z byte address of object (for LPM!)
; @return CFLAG set, if found, cleared otherwise
; @return r19:r18 resulting object (byte address for LPM!), NULL otherwise
; @clobbers none
OBJ_GetParent:
rcall OBJ_IsObject
brcc OBJ_GetParent_ret
adiw zh:zl, OBJECT_OFFS_PARENT_LO
lpm r18, Z+
lpm r19, Z
sbiw zh:zl, OBJECT_OFFS_PARENT_LO+1
tst r18
brne OBJ_GetParent_secRet
tst r19
clc
breq OBJ_GetParent_ret
OBJ_GetParent_secRet:
sec
OBJ_GetParent_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine OBJ_GetFirstChild @global
;
; @param Z byte address of object (for LPM!)
; @return CFLAG set, if found, cleared otherwise
; @return r19:r18 resulting object (byte address for LPM!), NULL otherwise
; @clobbers none
OBJ_GetFirstChild:
rcall OBJ_IsObject
brcc OBJ_GetFirstChild_ret
adiw zh:zl, OBJECT_OFFS_CHILD_LO
lpm r18, Z+
lpm r19, Z
sbiw zh:zl, OBJECT_OFFS_CHILD_LO+1
tst r18
brne OBJ_GetFirstChild_secRet
tst r19
clc
breq OBJ_GetFirstChild_ret
OBJ_GetFirstChild_secRet:
sec
OBJ_GetFirstChild_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine OBJ_GetNext @global
;
; @param Z byte address of object (for LPM!)
; @return CFLAG set, if found, cleared otherwise
; @return r19:r18 resulting object (byte address for LPM!), NULL otherwise
; @clobbers none
OBJ_GetNext:
rcall OBJ_IsObject
brcc OBJ_GetNext_ret
adiw zh:zl, OBJECT_OFFS_NEXT_LO
lpm r18, Z+
lpm r19, Z
sbiw zh:zl, OBJECT_OFFS_NEXT_LO+1
tst r18
brne OBJ_GetNext_secRet
tst r19
clc
breq OBJ_GetNext_ret
OBJ_GetNext_secRet:
sec
OBJ_GetNext_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine OBJ_GetBelow @global
;
; @param Z byte address of object (for LPM!)
; @return CFLAG set, if found, cleared otherwise
; @return r19:r18 resulting object (byte address for LPM!), NULL otherwise
; @clobbers r16
OBJ_GetBelow:
push zl
push zh
rcall OBJ_IsObject
brcc OBJ_GetBelow_ret
OBJ_GetBelow_get:
rcall OBJ_GetFirstChild
brcs OBJ_GetBelow_ret ; jmp if found
rcall OBJ_GetNext
brcs OBJ_GetBelow_ret ; jmp if found
OBJ_GetBelow_loop:
rcall OBJ_GetParent
brcc OBJ_GetBelow_ret ; jmp if no parent
; use parent
mov zl, r18
mov zh, r19
; don't check for first child here, we came from there!
rcall OBJ_GetNext
brcs OBJ_GetBelow_ret
rjmp OBJ_GetBelow_loop
OBJ_GetBelow_ret:
pop zh
pop zl
ret
; @end
; ---------------------------------------------------------------------------
; @routine OBJ_GetBelowParent @global
;
; @param Z byte address of object (for LPM!)
; @param r21:20 stay below this object
; @return CFLAG set, if found, cleared otherwise
; @return r19:r18 resulting object (byte address for LPM!), NULL otherwise
; @clobbers r16
OBJ_GetBelowParent:
push zl
push zh
rcall OBJ_IsObject
brcc OBJ_GetBelowParent_ret
OBJ_GetBelowParent_get:
rcall OBJ_GetFirstChild
brcs OBJ_GetBelowParent_ret ; jmp if found
rcall OBJ_GetNext
brcs OBJ_GetBelowParent_ret ; jmp if found
OBJ_GetBelowParent_loop:
rcall OBJ_GetParent
brcc OBJ_GetBelowParent_ret ; jmp if no parent
mov zl, r18
mov zh, r19
rcall objZIsNotR21R20
brcc OBJ_GetBelowParent_ret ; Z is avoidable parent
; don't check for first child here, we came from there!
rcall OBJ_GetNext
brcs OBJ_GetBelowParent_ret
rjmp OBJ_GetBelowParent_loop
OBJ_GetBelowParent_ret:
pop zh
pop zl
ret
; @end
objZIsNotR21R20:
cp zl, r20
brne objZIsNotR21R20_secRet
cp zh, r21
brne objZIsNotR21R20_secRet
clc
rjmp objZIsNotR21R20_ret
objZIsNotR21R20_secRet:
sec
objZIsNotR21R20_ret:
ret
; ---------------------------------------------------------------------------
; @routine OBJ_GetBelowSkipChildren @global
;
; Same as @ref OBJ_GetBelow but skips children of given object.
;
; @param Z byte address of object (for LPM!)
; @return CFLAG set, if found, cleared otherwise
; @return r19:r18 resulting object (byte address for LPM!), NULL otherwise
; @clobbers r16
OBJ_GetBelowSkipChildren:
push zl
push zh
tst zh
brne OBJ_GetBelowSkipChildren_get
tst zl
clc
breq OBJ_GetBelowSkipChildren_ret
OBJ_GetBelowSkipChildren_get:
rcall OBJ_GetNext
brcs OBJ_GetBelowSkipChildren_ret ; jmp if found
OBJ_GetBelowSkipChildren_loop:
rcall OBJ_GetParent
brcc OBJ_GetBelowSkipChildren_ret ; jmp if no parent
; use parent
mov zl, r18
mov zh, r19
; don't check for first child here, we came from there!
rcall OBJ_GetNext
brcs OBJ_GetBelowSkipChildren_ret
rjmp OBJ_GetBelowSkipChildren_loop
OBJ_GetBelowSkipChildren_ret:
pop zh
pop zl
ret
; @end
; ---------------------------------------------------------------------------
; @routine OBJ_EmitSignal @global
;
; @param Z byte address of object (for LPM!)
; @param R16 signal number
; @param xl param1
; @param xh param2
; @clobbers any, !X, !Y, !Z
OBJ_EmitSignal:
rcall OBJ_IsObject ; (none)
brcc OBJ_EmitSignal_ret
push zl
push zh
adiw zh:zl, OBJECT_OFFS_SELECTOR
lpm r17, Z
sbiw zh:zl, OBJECT_OFFS_SELECTOR
adiw zh:zl, OBJECT_OFFS_TARGET_LO
lpm r23, Z+
lpm zh, Z
mov zl, r23
rcall OBJ_HandleSignal ; (any, !X, !Y, !Z)
pop zh
pop zl
OBJ_EmitSignal_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine OBJ_TreeHandleSignal @global
;
; @param Z byte address of object (for LPM!)
; @param R16 signal number
; @param R17 selector
; @param xl param1
; @param xh param2
; @return CFLAG set if handled, cleared otherwise
; @clobbers any, !R16, !R17, !X, !Z
OBJ_TreeHandleSignal:
rcall OBJ_IsObject ; (none)
brcc OBJ_TreeHandleSignal_ret
push zl
push zh
mov r18, zl
or r18, zh
clc
breq OBJ_TreeHandleSignal_done
rcall OBJ_HandleSignalSaveInRegs
brcs OBJ_TreeHandleSignal_done
rcall OBJ_GetFirstChild
OBJ_TreeHandleSignal_loop:
brcc OBJ_TreeHandleSignal_done
mov zl, r18
mov zh, r19
rcall OBJ_TreeHandleSignal ; recursion
brcs OBJ_TreeHandleSignal_done
rcall OBJ_GetNext
rjmp OBJ_TreeHandleSignal_loop
OBJ_TreeHandleSignal_done:
pop zh
pop zl
OBJ_TreeHandleSignal_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine OBJ_TreeAllHandleSignal @global
;
; @param Z byte address of object (for LPM!)
; @param R16 signal number
; @param R17 selector
; @param xl param1
; @param xh param2
; @clobbers any, !R16, !R17, !X, !Z
OBJ_TreeAllHandleSignal:
rcall OBJ_IsObject ; (none)
brcc OBJ_TreeAllHandleSignal_ret
push zl
push zh
OBJ_TreeAllHandleSignal_loop:
rcall OBJ_HandleSignalSaveInRegs ; (any, !R16, !R17, !X, !Z)
push r16
rcall OBJ_GetBelow ; (R16)
pop r16
brcc OBJ_TreeAllHandleSignal_done
mov zl, r18
mov zh, r19
rjmp OBJ_TreeAllHandleSignal_loop
OBJ_TreeAllHandleSignal_done:
pop zh
pop zl
OBJ_TreeAllHandleSignal_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine OBJ_HandleSignalSaveInRegs
;
; @param Z byte address of object (for LPM!)
; @param R16 signal number
; @param R17 selector
; @param xl param1
; @param xh param2
; @return CFLAG set if handled, cleared otherwise
; @clobbers any, !R16, !R17, !X, !Z
OBJ_HandleSignalSaveInRegs:
push r16
push r17
rcall OBJ_HandleSignal ; (any, !X, !Y, !Z)
pop r17
pop r16
ret
; @end
; ---------------------------------------------------------------------------
; @routine OBJ_HandleSignal
;
; @param Z byte address of object (for LPM!)
; @param R16 signal number
; @param R17 selector
; @param xl param1
; @param xh param2
; @return CFLAG set if handled, cleared otherwise
; @clobbers any, !X, !Y, !Z
OBJ_HandleSignal:
rcall OBJ_IsObject ; (none)
brcc OBJ_HandleSignal_ret
push zl
push zh
rcall objGetHandlerFromSignalMap ; CF set: R19:R18=handler (r22, r23)
brcc OBJ_HandleSignal_done
push xl
push xh
push yl
push yh
rcall OBJ_HandleSignal_jmpR19R18
pop yh
pop yl
pop xh
pop xl
OBJ_HandleSignal_done:
pop zh
pop zl
OBJ_HandleSignal_ret:
ret
OBJ_HandleSignal_jmpR19R18:
; jmp to r19:r18 via stack
push r18
push r19
ret
; @end
; ---------------------------------------------------------------------------
; @routine objGetHandlerFromSignalMap
;
; @param Z byte address of object (for LPM!)
; @param R16 signal number
; @param R17 selector
; @param xl param1
; @param xh param2
; @return CFLAG set if found, cleared otherwise
; @return R19:R18 handler found
; @clobbers r22, r23
objGetHandlerFromSignalMap:
push zl
push zh
; z:=signal map
adiw zh:zl, OBJECT_OFFS_SIGNALMAP_LO
lpm r23, Z+
lpm zh, Z
mov zl, r23
or r23, zh
clc
breq objGetHandlerFromSignalMap_done ; no signal map
objGetHandlerFromSignalMap_loop:
lpm r22, Z+ ; selector
lpm r23, Z+ ; signal (0=end of table)
lpm r18, Z+ ; handler LOW
lpm r19, Z+ ; handler HIGH
tst r23 ; end of table?
clc
breq objGetHandlerFromSignalMap_done ; yes, jmp
cp r16, r23 ; signal match?
brne objGetHandlerFromSignalMap_next ; no, next
tst r22
breq objGetHandlerFromSignalMap_checkHandler ; accept any selector if it is 0 in table
cp r17, r22 ; selector match?
brne objGetHandlerFromSignalMap_next ; no, next
objGetHandlerFromSignalMap_checkHandler:
mov r23, r18 ; handler==NULL?
or r23, r19
clc
breq objGetHandlerFromSignalMap_done ; yes, done
sec ; found handler, return in r19:r18
rjmp objGetHandlerFromSignalMap_done
objGetHandlerFromSignalMap_next:
rjmp objGetHandlerFromSignalMap_loop
objGetHandlerFromSignalMap_done:
pop zh
pop zl
ret
; @end
#endif

View File

@@ -1,56 +0,0 @@
; ***************************************************************************
; 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_ROOTWIDGET_ASM
#define AQH_AVR_GUI2_ROOTWIDGET_ASM
; ***************************************************************************
; defines
; RootWidget in flash
.equ ROOTWIDGET_OFFS_BEGIN = WIDGET_SIZE
.equ ROOTWIDGET_OFFS_APP_LO = ROOTWIDGET_OFFS_BEGIN+0
.equ ROOTWIDGET_OFFS_APP_HI = ROOTWIDGET_OFFS_BEGIN+1
.equ ROOTWIDGET_SIZE = ROOTWIDGET_OFFS_BEGIN+2
; ***************************************************************************
; code
.cseg
; ---------------------------------------------------------------------------
; @routine RootWidget_GetApp @global
;
; @param Z byte address of object (for LPM!)
; @return R19:R18 byte address pointer to GuiApp
; @clobbers none
RootWidget_GetApp:
bigcall OBJ_IsObject ; (none)
brcc RootWidget_GetApp_ret
adiw zh:zl, ROOTWIDGET_OFFS_APP_LO
lpm r18, Z+
lpm r19, Z
sbiw zh:zl, ROOTWIDGET_OFFS_APP_LO+1
sec
RootWidget_GetApp_ret:
ret
; @end
#endif

View File

@@ -1,471 +0,0 @@
; ***************************************************************************
; 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

View File

@@ -1,177 +0,0 @@
; ***************************************************************************
; 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_VALUELABEL_ASM
#define AQH_AVR_GUI2_VALUELABEL_ASM
; ***************************************************************************
; defines
; IMGVIEW in flash
.equ VLABEL_OFFS_VLABEL = WIDGET_SIZE
.equ VLABEL_OFFS_POSTKOMMADIGITS = VLABEL_OFFS_VLABEL+0
.equ VLABEL_OFFS_RESERVED = VLABEL_OFFS_VLABEL+1
.equ VLABEL_SIZE = VLABEL_OFFS_VLABEL+2
; SDRAM data for IMGVIEW
.equ VLABEL_SD_OFFS_VLABEL = WIDGET_SD_SIZE
.equ VLABEL_SD_OFFS_VALUE_LO = VLABEL_SD_OFFS_VLABEL+0
.equ VLABEL_SD_OFFS_VALUE_HI = VLABEL_SD_OFFS_VLABEL+1
.equ VLABEL_SD_SIZE = VLABEL_SD_OFFS_VLABEL+2
; signals
.equ VLABEL_SIGNAL_SETVALUE = WIDGET_SIGNAL_NEXTFREE+0
.equ VLABEL_SIGNAL_NEXTFREE = WIDGET_SIGNAL_NEXTFREE+1
; ***************************************************************************
; code
.cseg
; ---------------------------------------------------------------------------
; @routine ImageView_OnCreate @global
;
; @param Z byte address of widget object (for LPM!)
; @return CFLAG set if signal handled
; @clobbers any, !Z
ValueLabel_OnCreate:
bigcall Widget_OnCreate
bigcall Widget_GetSdramPtr ; (none)
clr r16
std Y+VLABEL_SD_OFFS_VALUE_LO, r16
std Y+VLABEL_SD_OFFS_VALUE_HI, r16
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine ValueLabel_OnSetValue @global
;
; @param Z byte address of widget object (for LPM!)
; @param X new value for background color
; @return CFLAG set if signal handled
; @clobbers r17
ValueLabel_OnSetValue:
bigcall OBJ_IsObject ; (none)
brcc ValueLabel_OnSetValue_ret
push zl
push zh
rcall Widget_GetSdramPtr ; (none)
std Y+VLABEL_SD_OFFS_VALUE_LO, xl
std Y+VLABEL_SD_OFFS_VALUE_HI, xh
ldd r17, Y+WIDGET_SD_OFFS_FLAGS
ori r17, (1<<WIDGET_FLAGS_DIRTY_BIT)
std Y+WIDGET_SD_OFFS_FLAGS, r17
pop zh
pop zl
ValueLabel_OnSetValue_ret:
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine ValueLabel_OnDraw @global
;
; @param Z byte address of widget object (for LPM!)
; @return CFLAG set if signal handled
; @clobbers any, !Z
ValueLabel_OnDraw:
bigcall Widget_GetSdramPtr ; (none)
ldd r16, Y+WIDGET_SD_OFFS_FLAGS
andi r16, (1<<WIDGET_FLAGS_DIRTY_BIT)
breq ValueLabel_OnDraw_ret
bigcall Widget_Clear
adiw zh:zl, WIDGET_OFFS_OPTS_LO ; get OPTS low
lpm r14, Z
sbiw zh:zl, WIDGET_OFFS_OPTS_LO
push r14
rcall valueLabelWriteValue
pop r14
sbrs r14, WIDGET_OPTSLO_BORDER_BIT
rjmp ValueLabel_OnDraw_done
ldi r16, LOW(STYLE_BUTTON_COL_BORDER)
mov r2, r16
ldi r16, HIGH(STYLE_BUTTON_COL_BORDER)
mov r3, r16
bigcall Widget_DrawBorder
ValueLabel_OnDraw_done:
bigcall Widget_GetSdramPtr ; (none)
ldd r16, Y+WIDGET_SD_OFFS_FLAGS
cbr r16, (1<<WIDGET_FLAGS_DIRTY_BIT)
std Y+WIDGET_SD_OFFS_FLAGS, r16
ValueLabel_OnDraw_ret:
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine valueLabelWriteValue
;
; @param Z byte address of object (for LPM!)
; @param R14 opts low
; @clobbers any, !Z
valueLabelWriteValue:
push zl
push zh
bigcall Widget_GetSdramPtr ; (none)
; convert value to string
ldd r20, Y+VLABEL_SD_OFFS_VALUE_LO
ldd r21, Y+VLABEL_SD_OFFS_VALUE_HI
adiw zh:zl, VLABEL_OFFS_POSTKOMMADIGITS
lpm r24, Z
sbiw zh:zl, VLABEL_OFFS_POSTKOMMADIGITS
rcall IntToAscii ; X=pointer to text
; align according to string size
ldi r18, STYLE_WIN_FONT_WIDTH
rcall Widget_CalcStringWidthSDRAM ; r13:r12=string width
rcall Widget_AlignPosXY ; (r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19)
bigcall Widget_DrawTextSDRAM
pop zh
pop zl
ret
; @end
ValueLabel_DefaultSignalmap:
.db 0, OBJECT_SIGNAL_CREATE, LOW(ValueLabel_OnCreate), HIGH(ValueLabel_OnCreate)
.db 0, WIDGET_SIGNAL_DRAW, LOW(ValueLabel_OnDraw), HIGH(ValueLabel_OnDraw)
.db 0, VLABEL_SIGNAL_SETVALUE, LOW(ValueLabel_OnSetValue), HIGH(ValueLabel_OnSetValue)
.db 0, 0, 0, 0 ; end of table
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,11 @@
<?xml?>
<gwbuild>
<extradist>
simple.asm
</extradist>
</gwbuild>

View File

@@ -0,0 +1,490 @@
; ***************************************************************************
; 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_GUI_SCREENSAVER_SIMPLE_ASM
#define AQH_AVR_GUI_SCREENSAVER_SIMPLE_ASM
; ***************************************************************************
; defines
.equ SIMPLESAVER_TIMER100ms = 6000 ; 10mins
;.equ SIMPLESAVER_TIMER100ms = 100 ; 10secs
; widget data
.equ SIMPLESAVER_OFFS_BEGIN = MAINWINDOW_SIZE
.equ SIMPLESAVER_OFFS_TIMER_LO = SIMPLESAVER_OFFS_BEGIN+0
.equ SIMPLESAVER_OFFS_TIMER_HI = SIMPLESAVER_OFFS_BEGIN+1
.equ SIMPLESAVER_OFFS_RELOAD_LO = SIMPLESAVER_OFFS_BEGIN+2
.equ SIMPLESAVER_OFFS_RELOAD_HI = SIMPLESAVER_OFFS_BEGIN+3
.equ SIMPLESAVER_OFFS_NODEADDR1 = SIMPLESAVER_OFFS_BEGIN+4
.equ SIMPLESAVER_OFFS_VALUEID1 = SIMPLESAVER_OFFS_BEGIN+5
.equ SIMPLESAVER_OFFS_NODEADDR2 = SIMPLESAVER_OFFS_BEGIN+6
.equ SIMPLESAVER_OFFS_VALUEID2 = SIMPLESAVER_OFFS_BEGIN+7
.equ SIMPLESAVER_SIZE = SIMPLESAVER_OFFS_BEGIN+8
; EEPROM data
.equ SIMPLESAVER_EE_OFFS_NODEADDR1 = 0
.equ SIMPLESAVER_EE_OFFS_VALUEID1 = 1
.equ SIMPLESAVER_EE_OFFS_NODEADDR2 = 2
.equ SIMPLESAVER_EE_OFFS_VALUEID2 = 3
.equ SIMPLESAVER_EE_SIZE = 4
; ***************************************************************************
; code
.cseg
; ---------------------------------------------------------------------------
; @routine SimpleSaver_new @global
;
; @return CFLAG set of okay, cleared otherwise
; @return Y address of newly created object
; @param X parent widget
; @param r16 value for OBJECT_OFFS_OPTS
; @param r17 value for WIDGET_OFFS_PACK
; @clobbers any
SimpleSaver_new:
ldi r24, LOW(SIMPLESAVER_SIZE)
ldi r25, HIGH(SIMPLESAVER_SIZE)
bigcall Object_Alloc ; (!r16, !r17, !X)
brcc SimpleSaver_new_ret
rcall SimpleSaver_Init ; (r16, r17, X)
sec
SimpleSaver_new_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine SimpleSaver_Init @global
;
; @return CFLAG set of okay, cleared otherwise
; @return Y address of newly created object
; @param X parent widget
; @param r16 value for OBJECT_OFFS_OPTS
; @param r17 value for WIDGET_OFFS_PACK
; @clobbers any
SimpleSaver_Init:
; call base class
bigcall MainWindow_Init
; set default signal map
ldi r16, LOW(SimpleSaver_DefaultSignalmap*2)
std Y+OBJECT_OFFS_SIGNALMAP_LO, r16
ldi r16, HIGH(SimpleSaver_DefaultSignalmap*2)
std Y+OBJECT_OFFS_SIGNALMAP_HI, r16
; set style which has no spacing and no borders
ldi r16, LOW(SimpleSaver_DefaultStyle*2)
std Y+WIDGET_OFFS_STYLE_LO, r16
ldi r16, HIGH(SimpleSaver_DefaultStyle*2)
std Y+WIDGET_OFFS_STYLE_HI, r16
; read config from eeprom
rcall simpleSaverReadFromEeprom
; preset and start timer
ldi r16, LOW(SIMPLESAVER_TIMER100ms)
ldi r17, HIGH(SIMPLESAVER_TIMER100ms)
std Y+SIMPLESAVER_OFFS_RELOAD_LO, r16
std Y+SIMPLESAVER_OFFS_RELOAD_HI, r17
std Y+SIMPLESAVER_OFFS_TIMER_LO, r16
std Y+SIMPLESAVER_OFFS_TIMER_HI, r17
ret
; @end
SimpleSaver_Enter:
bigcall Widget_GetApp
push yl
push yh
mov xl, yl
mov xh, yh
mov yl, r18
mov yh, r19
bigcall GuiApp_EnterWindow
pop yh
pop yl
ret
; @end
SimpleSaver_Leave:
ldd r16, Y+OBJECT_OFFS_FLAGS
andi r16, (1<<WIDGET_FLAGS_VISIBLE_BIT)
breq SimpleSaver_Leave_ret ; jump if not active
bigcall Widget_GetApp
push yl
push yh
mov yl, r18
mov yh, r19
bigcall GuiApp_LeaveWindow
pop yh
pop yl
SimpleSaver_Leave_ret:
ret
; @end
SimpleSaver_KeepAlive:
; restart timer
ldd r16, Y+SIMPLESAVER_OFFS_RELOAD_LO
ldd r17, Y+SIMPLESAVER_OFFS_RELOAD_HI
std Y+SIMPLESAVER_OFFS_TIMER_LO, r16
std Y+SIMPLESAVER_OFFS_TIMER_HI, r17
; screen saver active?
ldd r16, Y+OBJECT_OFFS_FLAGS
andi r16, (1<<WIDGET_FLAGS_VISIBLE_BIT)
breq SimpleSaver_KeepAlive_ret ; jump if not active
rcall SimpleSaver_Leave
SimpleSaver_KeepAlive_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine simpleSaverWriteToEeprom
;
; @param Y widget
; @return CFLAG set if data found and read, cleared on error
; @clobbers R16, R17, R18, R20, R21, X
simpleSaverWriteToEeprom:
ldi r16, EEID_SCREENSAVER
bigcall EepromTlv_FindFirst ; (R18)
brcs simpleSaverWriteToEeprom_write
ldi r16, EEID_SCREENSAVER
ldi r17, SIMPLESAVER_EE_SIZE
bigcall EepromTlv_AddTlv ; X=pointer to EEPROM data (R16, R18, R20, R21)
brcc simpleSaverWriteToEeprom_ret
simpleSaverWriteToEeprom_write:
push yl
push yh
adiw yh:yl, SIMPLESAVER_OFFS_NODEADDR1
ldi r18, SIMPLESAVER_EE_SIZE
simpleSaverWriteToEeprom_loop:
ld r16, Y+
bigcall Eeprom_WriteByteIfChanged ; (R17)
brcc simpleSaverWriteToEeprom_ret
adiw xh:xl, 1
dec r18
brne simpleSaverWriteToEeprom_loop
pop yh
pop yl
sec
simpleSaverWriteToEeprom_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine simpleSaverReadFromEeprom
;
; @param Y widget
; @return CFLAG set if data found and read, cleared on error
; @clobbers R16, R18, X
simpleSaverReadFromEeprom:
ldi r16, EEID_SCREENSAVER
bigcall EepromTlv_FindFirst ; (R18)
brcc simpleSaverReadFromEeprom_ret
push yl
push yh
adiw yh:yl, SIMPLESAVER_OFFS_NODEADDR1
ldi r18, SIMPLESAVER_EE_SIZE
simpleSaverReadFromEeprom_loop:
bigcall Eeprom_ReadByte ; R16=byte (none)
brcc simpleSaverReadFromEeprom_ret
st Y+, r16
adiw xh:xl, 1
dec r18
brne simpleSaverReadFromEeprom_loop
pop yh
pop yl
sec
simpleSaverReadFromEeprom_ret:
ret
; @end
; ***************************************************************************
; signal handlers
SimpleSaver_OnTimer:
ldd r16, Y+OBJECT_OFFS_FLAGS
andi r16, (1<<WIDGET_FLAGS_VISIBLE_BIT)
brne SimpleSaver_OnTimer_ret ; jump if active
; check timer
ldd r24, Y+SIMPLESAVER_OFFS_TIMER_LO
ldd r25, Y+SIMPLESAVER_OFFS_TIMER_HI
mov r16, r24
or r16, r25
breq SimpleSaver_OnTimer_ret
sbiw r25:r24, 1
std Y+SIMPLESAVER_OFFS_TIMER_LO, r24
std Y+SIMPLESAVER_OFFS_TIMER_HI, r25
brne SimpleSaver_OnTimer_ret
; timer elapsed, enter screensaver
rcall SimpleSaver_Enter
SimpleSaver_OnTimer_ret:
sec
ret
; @end
SimpleSaver_OnTouch:
; read touch signal data from X
adiw xh:xl, WIDGET_TOUCH_OFFS_STATE
ld r22, X ; WIDGET_DATA_TOUCH_OFFS_STATE
sbiw xh:xl, WIDGET_TOUCH_OFFS_STATE
sbrs r22, DISPLAY_IFLAGS_PRESSED_BIT
rjmp SimpleSaver_OnTouch_up
; down (active touch), switch display on
ldi r16, 0xff
bigcall Display_SetBacklight
rjmp SimpleSaver_OnTouch_ret
SimpleSaver_OnTouch_up:
rcall SimpleSaver_KeepAlive
SimpleSaver_OnTouch_ret:
sec
ret
; @end
SimpleSaver_OnMsgReceived:
push zl
push zh
ldi zl, LOW(SimpleSaver_MsgTable*2)
ldi zh, HIGH(SimpleSaver_MsgTable*2)
bigcall Main_HandleValueMsg ; (any)
pop zh
pop zl
clc
ret
; @end
SimpleSaver_OnShow:
; stop timer
clr r16
std Y+SIMPLESAVER_OFFS_TIMER_LO, r16
std Y+SIMPLESAVER_OFFS_TIMER_HI, r16
; force redraw (black background)
ldd r16, Y+OBJECT_OFFS_FLAGS
sbr r16, (1<<WIDGET_FLAGS_DIRTY_BIT) | (1<<WIDGET_FLAGS_VISIBLE_BIT)
std Y+OBJECT_OFFS_FLAGS, r16
; turn off backlight
clr r16
bigcall Display_SetBacklight
sec
ret
; @end
SimpleSaver_OnHide:
ldd r16, Y+OBJECT_OFFS_FLAGS
cbr r16, (1<<WIDGET_FLAGS_VISIBLE_BIT)
std Y+OBJECT_OFFS_FLAGS, r16
; restart timer
ldd r16, Y+SIMPLESAVER_OFFS_RELOAD_LO
ldd r17, Y+SIMPLESAVER_OFFS_RELOAD_HI
std Y+SIMPLESAVER_OFFS_TIMER_LO, r16
std Y+SIMPLESAVER_OFFS_TIMER_HI, r17
; turn backlight on
ldi r16, 0xff
bigcall Display_SetBacklight
sec
ret
; @end
SimpleSaver_OnKeepAlive:
rcall SimpleSaver_KeepAlive
sec
ret
; @end
; ***************************************************************************
; message handlers
; ---------------------------------------------------------------------------
; @routine simpleSaverHandleSetSource1
;
; @param Y widget
; @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
simpleSaverHandleSetSource1:
std Y+SIMPLESAVER_OFFS_NODEADDR1, r18
std Y+SIMPLESAVER_OFFS_VALUEID1, r19
rcall simpleSaverWriteToEeprom ; (R16, R17, R18, R20, R21, X, Y)
ldi r23, NETMSG_CMD_VALUE_SET_ACK
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine simpleSaverHandleSetSource2
;
; @param Y widget
; @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
simpleSaverHandleSetSource2:
std Y+SIMPLESAVER_OFFS_NODEADDR1, r18
std Y+SIMPLESAVER_OFFS_VALUEID1, r19
rcall simpleSaverWriteToEeprom ; (R16, R17, R18, R20, R21, X, Y)
ldi r23, NETMSG_CMD_VALUE_SET_ACK
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine simpleSaverHandleReport
;
; @param Y widget
; @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
simpleSaverHandleReport:
mov r16, r18 ; check for non-zero value
or r16, r19
breq simpleSaverHandleReport_end
ldd r16, Y+SIMPLESAVER_OFFS_NODEADDR1
cp r16, r22
brne simpleSaverHandleReport_l1
ldd r16, Y+SIMPLESAVER_OFFS_VALUEID1
cp r16, r17
breq simpleSaverHandleReport_matches
simpleSaverHandleReport_l1:
ldd r16, Y+SIMPLESAVER_OFFS_NODEADDR2
cp r16, r22
brne simpleSaverHandleReport_end
ldd r16, Y+SIMPLESAVER_OFFS_VALUEID2
cp r16, r17
brne simpleSaverHandleReport_end
simpleSaverHandleReport_matches:
rcall SimpleSaver_KeepAlive
simpleSaverHandleReport_end:
clc ; no ACK needed
ret
; @end
; ***************************************************************************
; data in FLASH
SimpleSaver_DefaultStyle:
.dw DISPLAY_COLOR_LIGHTGREY ; frontCol_norm
.dw DISPLAY_COLOR_BLACK ; backCol_norm
.dw DISPLAY_COLOR_BLACK ; borderCol_norm
.dw DISPLAY_COLOR_WHITE ; shadowCol_norm
.dw DISPLAY_COLOR_WHITE ; frontCol_activated
.dw DISPLAY_COLOR_NAVY ; backCol_activated
.dw DISPLAY_COLOR_BLACK ; borderCol_activated
.dw DISPLAY_COLOR_WHITE ; shadowCol_activated
.db 0, 1 ; outerBorderSize, innerBorderSize
.dw ili9341Font12x16_1*2 ; font
.db 12, 16 ; charWidth, charHeight
SimpleSaver_MsgTable:
.dw NETMSG_CMD_VALUE_SET | (VALUE_ID_SCREENSAVER_SETSOURCE1<<8), simpleSaverHandleSetSource1
.dw NETMSG_CMD_VALUE_SET | (VALUE_ID_SCREENSAVER_SETSOURCE2<<8), simpleSaverHandleSetSource2
.dw NETMSG_CMD_VALUE_REPORT, simpleSaverHandleReport
.dw 0, 0
SimpleSaver_DefaultSignalmap:
; header
.dw MainWindow_DefaultSignalmap*2 ; next table to use
; entries
.db 0, OBJECT_SIGNAL_TIMER, LOW(SimpleSaver_OnTimer), HIGH(SimpleSaver_OnTimer)
.db 0, WIDGET_SIGNAL_KEEPALIVE, LOW(SimpleSaver_OnKeepAlive), HIGH(SimpleSaver_OnKeepAlive)
.db 0, WIDGET_SIGNAL_SHOW, LOW(SimpleSaver_OnShow), HIGH(SimpleSaver_OnShow)
.db 0, WIDGET_SIGNAL_HIDE, LOW(SimpleSaver_OnHide), HIGH(SimpleSaver_OnHide)
.db 0, WIDGET_SIGNAL_TOUCH, LOW(SimpleSaver_OnTouch), HIGH(SimpleSaver_OnTouch)
.db 0, OBJECT_SIGNAL_RECVMSG, LOW(SimpleSaver_OnMsgReceived), HIGH(SimpleSaver_OnMsgReceived)
.db 0, WIDGET_SIGNAL_DRAW, LOW(Widget_OnDraw), HIGH(Widget_OnDraw)
.db 0, 0, 0, 0 ; end of table
#endif

View File

@@ -1,608 +0,0 @@
; ***************************************************************************
; 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_SENSORWATCH_ASM
#define AQH_AVR_GUI2_SENSORWATCH_ASM
; ***************************************************************************
; SensorWatch
;
; This widget has three subwidgets:
; - Title (Label)
; - Image (ImageView)
; - Value (Label)
;
; It watches received messages and reacts on those matching the stored
; combination of NodeAddr and ValueId by colouring the image according to
; the value received and also shows the value beloe the image.
;
; Please note that this widget needs to have the option bit
; "WIDGET_OPTSLO_MSGRECV_BIT" set in order to receive MsgReceived signals.
;
; ***************************************************************************
; ***************************************************************************
; defines
; SensorWatch in flash
.equ SENSORWATCH_OFFS_BEGIN = WIDGET_SIZE
.equ SENSORWATCH_OFFS_BASEVALUEID = SENSORWATCH_OFFS_BEGIN+0
.equ SENSORWATCH_OFFS_EEPROMID = SENSORWATCH_OFFS_BEGIN+1
.equ SENSORWATCH_SIZE = SENSORWATCH_OFFS_BEGIN+2
; SDRAM data for SensorWatch
.equ SENSORWATCH_SD_OFFS_SENSORWATCH = WIDGET_SD_SIZE
.equ SENSORWATCH_SD_OFFS_NODEADDR = SENSORWATCH_SD_OFFS_SENSORWATCH+0
.equ SENSORWATCH_SD_OFFS_VALUEID = SENSORWATCH_SD_OFFS_SENSORWATCH+1
.equ SENSORWATCH_SD_OFFS_UPPER_LIMIT_WARN_LO = SENSORWATCH_SD_OFFS_SENSORWATCH+2
.equ SENSORWATCH_SD_OFFS_UPPER_LIMIT_WARN_HI = SENSORWATCH_SD_OFFS_SENSORWATCH+3
.equ SENSORWATCH_SD_OFFS_LOWER_LIMIT_WARN_LO = SENSORWATCH_SD_OFFS_SENSORWATCH+4
.equ SENSORWATCH_SD_OFFS_LOWER_LIMIT_WARN_HI = SENSORWATCH_SD_OFFS_SENSORWATCH+5
.equ SENSORWATCH_SD_OFFS_UPPER_LIMIT_CRIT_LO = SENSORWATCH_SD_OFFS_SENSORWATCH+6
.equ SENSORWATCH_SD_OFFS_UPPER_LIMIT_CRIT_HI = SENSORWATCH_SD_OFFS_SENSORWATCH+7
.equ SENSORWATCH_SD_OFFS_LOWER_LIMIT_CRIT_LO = SENSORWATCH_SD_OFFS_SENSORWATCH+8
.equ SENSORWATCH_SD_OFFS_LOWER_LIMIT_CRIT_HI = SENSORWATCH_SD_OFFS_SENSORWATCH+9
.equ SENSORWATCH_SD_OFFS_VALUE_LO = SENSORWATCH_SD_OFFS_SENSORWATCH+10
.equ SENSORWATCH_SD_OFFS_VALUE_HI = SENSORWATCH_SD_OFFS_SENSORWATCH+11
.equ SENSORWATCH_SD_SIZE = SENSORWATCH_SD_OFFS_SENSORWATCH+12
; EEPROM data for SensorWatch
.equ SENSORWATCH_EE_OFFS_NODEADDR = 0
.equ SENSORWATCH_EE_OFFS_VALUEID = 1
.equ SENSORWATCH_EE_OFFS_UPPER_LIMIT_WARN_LO = 2
.equ SENSORWATCH_EE_OFFS_UPPER_LIMIT_WARN_HI = 3
.equ SENSORWATCH_EE_OFFS_LOWER_LIMIT_WARN_LO = 4
.equ SENSORWATCH_EE_OFFS_LOWER_LIMIT_WARN_HI = 5
.equ SENSORWATCH_EE_OFFS_UPPER_LIMIT_CRIT_LO = 6
.equ SENSORWATCH_EE_OFFS_UPPER_LIMIT_CRIT_HI = 7
.equ SENSORWATCH_EE_OFFS_LOWER_LIMIT_CRIT_LO = 8
.equ SENSORWATCH_EE_OFFS_LOWER_LIMIT_CRIT_HI = 9
.equ SENSORWATCH_EE_SIZE = 10
; signals
.equ SENSORWATCH_SIGNAL_SETSOURCE = WIDGET_SIGNAL_NEXTFREE+0
.equ SENSORWATCH_SIGNAL_SETUPPERLIMWARN = WIDGET_SIGNAL_NEXTFREE+1
.equ SENSORWATCH_SIGNAL_SETLOWERLIMWARN = WIDGET_SIGNAL_NEXTFREE+2
.equ SENSORWATCH_SIGNAL_SETUPPERLIMCRIT = WIDGET_SIGNAL_NEXTFREE+3
.equ SENSORWATCH_SIGNAL_SETLOWERLIMCRIT = WIDGET_SIGNAL_NEXTFREE+4
.equ SENSORWATCH_SIGNAL_NEXTFREE = WIDGET_SIGNAL_NEXTFREE+5
; ***************************************************************************
; code
.cseg
; ---------------------------------------------------------------------------
; @routine SensorWatch_OnCreate @global
;
; @param Z byte address of widget object (for LPM!)
; @return CFLAG set if signal handled
; @clobbers any, !Z
SensorWatch_OnCreate:
bigcall OBJ_IsObject ; (none)
brcc SensorWatch_OnCreate_ret
; preset SDRAM
bigcall Widget_GetSdramPtr ; (none)
clr r16
ldi r17, SENSORWATCH_SD_SIZE
push yl
push yh
SensorWatch_OnCreate_loop:
st Y+, r16
dec r17
brne SensorWatch_OnCreate_loop
pop yh
pop yl
bigcall Widget_OnCreate
rcall sensorWatchReadFromEeprom ; (R16, R18, X, Y)
SensorWatch_OnCreate_ret:
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine SensorWatch_OnSetSource @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
SensorWatch_OnSetSource:
bigcall OBJ_IsObject ; (none)
brcc SensorWatch_OnSetSource_ret
push zl
push zh
bigcall Widget_GetSdramPtr ; (none)
std Y+SENSORWATCH_SD_OFFS_NODEADDR, xl
std Y+SENSORWATCH_SD_OFFS_VALUEID, xh
pop zh
pop zl
SensorWatch_OnSetSource_ret:
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine SensorWatch_OnSetLowerLimitWarn @global
;
; @param Z byte address of widget object (for LPM!)
; @param X value
; @return CFLAG set if signal handled
; @clobbers any, !Z
SensorWatch_OnSetLowerLimitWarn:
bigcall OBJ_IsObject ; (none)
brcc SensorWatch_OnSetLowerLimitWarn_ret
bigcall Widget_GetSdramPtr ; (none)
std Y+SENSORWATCH_SD_OFFS_LOWER_LIMIT_WARN_LO, xl
std Y+SENSORWATCH_SD_OFFS_LOWER_LIMIT_WARN_HI, xh
rcall sensorWatchSetColor
SensorWatch_OnSetLowerLimitWarn_ret:
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine SensorWatch_OnSetUpperLimitWarn @global
;
; @param Z byte address of widget object (for LPM!)
; @param X value
; @return CFLAG set if signal handled
; @clobbers any, !Z
SensorWatch_OnSetUpperLimitWarn:
bigcall OBJ_IsObject ; (none)
brcc SensorWatch_OnSetUpperLimitWarn_ret
bigcall Widget_GetSdramPtr ; (none)
std Y+SENSORWATCH_SD_OFFS_UPPER_LIMIT_WARN_LO, xl
std Y+SENSORWATCH_SD_OFFS_UPPER_LIMIT_WARN_HI, xh
rcall sensorWatchSetColor
SensorWatch_OnSetUpperLimitWarn_ret:
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine SensorWatch_OnSetLimitCrit @global
;
; @param Z byte address of widget object (for LPM!)
; @param X value
; @return CFLAG set if signal handled
; @clobbers any, !Z
SensorWatch_OnSetLowerLimitCrit:
bigcall OBJ_IsObject ; (none)
brcc SensorWatch_OnSetLowerLimitCrit_ret
rcall Widget_GetSdramPtr ; (none)
std Y+SENSORWATCH_SD_OFFS_LOWER_LIMIT_CRIT_LO, xl
std Y+SENSORWATCH_SD_OFFS_LOWER_LIMIT_CRIT_HI, xh
rcall sensorWatchSetColor
SensorWatch_OnSetLowerLimitCrit_ret:
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine SensorWatch_OnSetUpperLimitCrit @global
;
; @param Z byte address of widget object (for LPM!)
; @param X value
; @return CFLAG set if signal handled
; @clobbers any, !Z
SensorWatch_OnSetUpperLimitCrit:
bigcall OBJ_IsObject ; (none)
brcc SensorWatch_OnSetUpperLimitCrit_ret
rcall Widget_GetSdramPtr ; (none)
std Y+SENSORWATCH_SD_OFFS_UPPER_LIMIT_CRIT_LO, xl
std Y+SENSORWATCH_SD_OFFS_UPPER_LIMIT_CRIT_HI, xh
rcall sensorWatchSetColor
SensorWatch_OnSetUpperLimitCrit_ret:
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine SensorWatch_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
SensorWatch_OnMsgReceived:
adiw xh:xl, 2 ; command
ld r16, X
sbiw xh:xl, 2
cpi r16, NETMSG_CMD_VALUE_REPORT
breq SensorWatch_OnMsgReceived_report
cpi r16, NETMSG_CMD_VALUE_SET
breq SensorWatch_OnMsgReceived_set
rjmp SensorWatch_OnMsgReceived_ret
SensorWatch_OnMsgReceived_report:
bigcall Widget_GetSdramPtr ; (none)
bigcall NETMSG_ValueRead ; R17=valueId, R22=nodeAddr R19:R18=value (none)
; check node addr
ldd r16, Y+SENSORWATCH_SD_OFFS_NODEADDR
cp r16, r22
brne SensorWatch_OnMsgReceived_ret
; check value id
ldd r16, Y+SENSORWATCH_SD_OFFS_VALUEID
cp r16, r17
brne SensorWatch_OnMsgReceived_ret
; store value
std Y+SENSORWATCH_SD_OFFS_VALUE_LO, r18
std Y+SENSORWATCH_SD_OFFS_VALUE_HI, r19
; setup background color
rcall sensorWatchSetColor ; (any, !Y, !Z)
rcall sensorWatchSetValueLabel ; (any, !Y, !Z)
rjmp SensorWatch_OnMsgReceived_ret
SensorWatch_OnMsgReceived_set:
bigcall Widget_GetSdramPtr ; (none)
bigcall NETMSG_ValueRead ; R17=valueId, R22=nodeAddr R19:R18=value (none)
adiw zh:zl, SENSORWATCH_OFFS_BASEVALUEID
lpm r16, Z
sbiw zh:zl, SENSORWATCH_OFFS_BASEVALUEID
sub r17, r16
brcs SensorWatch_OnMsgReceived_ret ; not my value
cpi r17, 3
brcc SensorWatch_OnMsgReceived_ret ; not my value
cpi r17, 0
breq SensorWatch_OnMsgReceived_setSource
cpi r17, 1
breq SensorWatch_OnMsgReceived_setLimWarn
cpi r17, 2
breq SensorWatch_OnMsgReceived_setLimCrit
rjmp SensorWatch_OnMsgReceived_ret
SensorWatch_OnMsgReceived_setSource:
std Y+SENSORWATCH_SD_OFFS_NODEADDR, r18
std Y+SENSORWATCH_SD_OFFS_VALUEID, r19
rjmp SensorWatch_OnMsgReceived_sendACK
SensorWatch_OnMsgReceived_setLimWarn:
std Y+SENSORWATCH_SD_OFFS_LOWER_LIMIT_WARN_LO, r18
std Y+SENSORWATCH_SD_OFFS_LOWER_LIMIT_WARN_HI, r19
std Y+SENSORWATCH_SD_OFFS_UPPER_LIMIT_WARN_LO, r20
std Y+SENSORWATCH_SD_OFFS_UPPER_LIMIT_WARN_HI, r21
rjmp SensorWatch_OnMsgReceived_sendACK
SensorWatch_OnMsgReceived_setLimCrit:
std Y+SENSORWATCH_SD_OFFS_LOWER_LIMIT_CRIT_LO, r18
std Y+SENSORWATCH_SD_OFFS_LOWER_LIMIT_CRIT_HI, r19
std Y+SENSORWATCH_SD_OFFS_UPPER_LIMIT_CRIT_LO, r20
std Y+SENSORWATCH_SD_OFFS_UPPER_LIMIT_CRIT_HI, r21
SensorWatch_OnMsgReceived_sendACK:
add r17, r16 ; restore valueId
push xl
push xh
push yl
push yh
ldi r23, NETMSG_CMD_VALUE_SET_ACK
bigcall Main_SendValueResponse ; (clobbers all except Z)
pop yh
pop yl
rcall sensorWatchSetColor ; (any, !Y, !Z)
rcall sensorWatchWriteToEeprom ; (R16, R17, R18, R20, R21, X, Y)
pop xh
pop xl
SensorWatch_OnMsgReceived_ret:
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine SensorWatch_GetImageView @global
;
; @param Z byte address of widget object (for LPM!)
; @return CFLAG set if widget found, cleared otherwise
; @return R19:R18 byte address pointer to image view (for LPM!)
; @clobbers none
SensorWatch_GetImageView:
bigcall OBJ_IsObject ; (none)
brcc SensorWatch_GetImageView_ret
push zl
push zh
bigcall OBJ_GetFirstChild ; (none)
brcc SensorWatch_GetImageView_done
mov zl, r18
mov zh, r19
bigcall OBJ_GetNext ; 2nd child
SensorWatch_GetImageView_done:
pop zh
pop zl
SensorWatch_GetImageView_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine SensorWatch_GetValueLabel @global
;
; @param Z byte address of widget object (for LPM!)
; @return CFLAG set if widget found, cleared otherwise
; @return R19:R18 byte address pointer to image view (for LPM!)
; @clobbers none
SensorWatch_GetValueLabel:
bigcall OBJ_IsObject ; (none)
brcc SensorWatch_GetValueLabel_ret
push zl
push zh
bigcall OBJ_GetFirstChild ; (none)
brcc SensorWatch_GetValueLabel_done
mov zl, r18
mov zh, r19
bigcall OBJ_GetNext ; 2nd child
brcc SensorWatch_GetValueLabel_done
mov zl, r18
mov zh, r19
bigcall OBJ_GetNext ; 3nd child
SensorWatch_GetValueLabel_done:
pop zh
pop zl
SensorWatch_GetValueLabel_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine sensorWatchSetColor
;
; @param Z byte address of widget object (for LPM!)
; @param Y pointer to SDRAM data
; @clobbers any, !Y, !Z
sensorWatchSetColor:
push yl
push yh
; default color is green
ldi xl, LOW(DISPLAY_COLOR_DARKGREEN)
ldi xh, HIGH(DISPLAY_COLOR_DARKGREEN)
ldd r20, Y+SENSORWATCH_SD_OFFS_VALUE_LO
ldd r21, Y+SENSORWATCH_SD_OFFS_VALUE_HI
mov r16, r20
or r16, r21
breq sensorWatchSetColor_ret ; do nothing
; check against critical limits
adiw yh:yl, SENSORWATCH_SD_OFFS_UPPER_LIMIT_CRIT_LO
rcall sensorWatchCheckAgainstLimit ; (r16, r17, r22, r23)
brcs sensorWatchSetColor_setRed
sbiw yh:yl, SENSORWATCH_SD_OFFS_UPPER_LIMIT_CRIT_LO
; check against warning limits
adiw yh:yl, SENSORWATCH_SD_OFFS_UPPER_LIMIT_WARN_LO
rcall sensorWatchCheckAgainstLimit ; (r16, r17, r22, r23)
brcs sensorWatchSetColor_setYellow
sbiw yh:yl, SENSORWATCH_SD_OFFS_UPPER_LIMIT_WARN_LO
; set green background
rjmp sensorWatchSetColor_setColor
sensorWatchSetColor_setRed:
ldi xl, LOW(DISPLAY_COLOR_RED)
ldi xh, HIGH(DISPLAY_COLOR_RED)
rjmp sensorWatchSetColor_setColor
sensorWatchSetColor_setYellow:
ldi xl, LOW(DISPLAY_COLOR_YELLOW)
ldi xh, HIGH(DISPLAY_COLOR_YELLOW)
sensorWatchSetColor_setColor:
rcall SensorWatch_GetImageView ; (none)
brcc sensorWatchSetColor_ret
push zl
push zh
mov zl, r18
mov zh, r19
ldi r16, IMGVIEW_SIGNAL_SETBGCOL
clr r17
bigcall OBJ_HandleSignal ; (any, !X, !Y, !Z)
pop zh
pop zl
sensorWatchSetColor_ret:
pop yh
pop yl
ret
; @end
; ---------------------------------------------------------------------------
; @routine sensorWatchCheckAgainstLimit
;
; @param R21:R20 value to check against limit
; @param Y points to upper limit (lo/hi), followed by lower limit (lo/hi)
; @return CFLAG set if limit triggered, cleared if between upper and lower limit
; @clobbers r16, r17, r22, r23
sensorWatchCheckAgainstLimit:
; check against upper limit (if any)
ldd r22, Y+0
ldd r23, Y+1
mov r16, r22
or r16, r23 ; zero?
clc
breq sensorWatchCheckAgainstLimit_ret ; yes, jmp
cp r20, r22
cpc r21, r23
brcc sensorWatchCheckAgainstLimit_secRet
; check against lower limit (if any)
ldd r22, Y+2
ldd r23, Y+3
mov r16, r22
or r16, r23 ; zero?
clc
breq sensorWatchCheckAgainstLimit_ret ; yes, jmp
cp r22, r20
cpc r23, r21
brcc sensorWatchCheckAgainstLimit_secRet
clc
rjmp sensorWatchCheckAgainstLimit_ret
sensorWatchCheckAgainstLimit_secRet:
sec
sensorWatchCheckAgainstLimit_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine sensorWatchSetValueLabel
;
; @param Z byte address of widget object (for LPM!)
; @param Y pointer to SDRAM data
; @clobbers any, !Y, !Z
sensorWatchSetValueLabel:
rcall SensorWatch_GetValueLabel ; (none)
brcc sensorWatchSetValueLabel_ret
push zl
push zh
mov zl, r18
mov zh, r19
ldd xl, Y+SENSORWATCH_SD_OFFS_VALUE_LO
ldd xh, Y+SENSORWATCH_SD_OFFS_VALUE_HI
ldi r16, VLABEL_SIGNAL_SETVALUE
clr r17
bigcall OBJ_HandleSignal ; (any, !X, !Y, !Z)
pop zh
pop zl
sensorWatchSetValueLabel_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine sensorWatchWriteToEeprom
;
; @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
sensorWatchWriteToEeprom:
adiw zh:zl, SENSORWATCH_OFFS_EEPROMID
lpm r16, Z
sbiw zh:zl, SENSORWATCH_OFFS_EEPROMID
tst r16
clc
breq sensorWatchWriteToEeprom_ret
push r16
bigcall EepromTlv_FindFirst ; (R18)
pop r16
brcs sensorWatchWriteToEeprom_write
ldi r17, SENSORWATCH_EE_SIZE
bigcall EepromTlv_AddTlv ; X=pointer to EEPROM data (R16, R18, R20, R21)
brcc sensorWatchWriteToEeprom_ret
sensorWatchWriteToEeprom_write:
bigcall Widget_GetSdramPtr ; (none)
adiw yh:yl, SENSORWATCH_SD_OFFS_NODEADDR
ldi r18, SENSORWATCH_EE_SIZE
sensorWatchWriteToEeprom_loop:
ld r16, Y+
bigcall Eeprom_WriteByteIfChanged ; (R17)
brcc sensorWatchWriteToEeprom_ret
adiw xh:xl, 1
dec r18
brne sensorWatchWriteToEeprom_loop
sec
sensorWatchWriteToEeprom_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine sensorWatchReadFromEeprom
;
; @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
sensorWatchReadFromEeprom:
adiw zh:zl, SENSORWATCH_OFFS_EEPROMID
lpm r16, Z
sbiw zh:zl, SENSORWATCH_OFFS_EEPROMID
bigcall EepromTlv_FindFirst ; (R18)
brcc sensorWatchReadFromEeprom_ret
bigcall Widget_GetSdramPtr ; (none)
adiw yh:yl, SENSORWATCH_SD_OFFS_NODEADDR
ldi r18, SENSORWATCH_EE_SIZE
sensorWatchReadFromEeprom_loop:
bigcall Eeprom_ReadByte ; R16=byte (none)
brcc sensorWatchReadFromEeprom_ret
st Y+, r16
adiw xh:xl, 1
dec r18
brne sensorWatchReadFromEeprom_loop
sec
sensorWatchReadFromEeprom_ret:
ret
; @end
SensorWatch_DefaultSignalmap:
.db 0, OBJECT_SIGNAL_CREATE, LOW(SensorWatch_OnCreate), HIGH(SensorWatch_OnCreate)
.db 0, WIDGET_SIGNAL_DRAW, LOW(Widget_OnDraw), HIGH(Widget_OnDraw)
.db 0, OBJECT_SIGNAL_RECVMSG, LOW(SensorWatch_OnMsgReceived), HIGH(SensorWatch_OnMsgReceived)
.db 0, SENSORWATCH_SIGNAL_SETSOURCE, LOW(SensorWatch_OnSetSource), HIGH(SensorWatch_OnSetSource)
.db 0, SENSORWATCH_SIGNAL_SETUPPERLIMWARN, LOW(SensorWatch_OnSetUpperLimitWarn), HIGH(SensorWatch_OnSetUpperLimitWarn)
.db 0, SENSORWATCH_SIGNAL_SETLOWERLIMWARN, LOW(SensorWatch_OnSetLowerLimitWarn), HIGH(SensorWatch_OnSetLowerLimitWarn)
.db 0, SENSORWATCH_SIGNAL_SETUPPERLIMCRIT, LOW(SensorWatch_OnSetUpperLimitCrit), HIGH(SensorWatch_OnSetUpperLimitCrit)
.db 0, SENSORWATCH_SIGNAL_SETLOWERLIMCRIT, LOW(SensorWatch_OnSetLowerLimitCrit), HIGH(SensorWatch_OnSetLowerLimitCrit)
.db 0, 0, 0, 0 ; end of table
#endif