; *************************************************************************** ; 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< 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