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

;.equ clock=1000000 ; Define the clock frequency
.equ clock=8000000 ; Define the clock frequency



.nolist
.include "include/m644Pdef.inc" ; Define device ATmega644P
.list

.include "version.asm"
.include "../defs.asm"

.include "devices/all/defs.asm"
.include "common/calls.asm"
.include "common/utils_wait.asm"
.include "common/utils_io.asm"



; ***************************************************************************
; defines

; ---------------------------------------------------------------------------
; generic

.equ STACK_SIZE                   = 256

.equ NET_BUFFERS_NUM              =  5
.equ NET_MSGNUMINBUF_SIZE         =  8 ; max buffer nums in ringbuffer (global incoming)
.equ NET_IFACE_OUTMSGBUF_SIZE     =  8 ; max buffer nums in ringbuffer (per interface outbound)



; ---------------------------------------------------------------------------
; firmware settings including list of modules used

; #define MODULES_TIMER
#define MODULES_CLOCK
;#define MODULES_XRAM
#define MODULES_HEAP
#define MODULES_BEEPER_SIMPLE
#define MODULES_LED1
#define MODULES_NETWORK
;#define MODULES_COMONUART0
;#define MODULES_UART_HW
;#define MODULES_UART_BITBANG
#define MODULES_COM2W
#define MODULES_SPI_HW
#define MODULES_ILI9341
#define MODULES_XPT2046
#define MODULES_FONT
;#define MODULES_GUI
;#define MODULES_TWI_MASTER
;#define MODULES_LCD
;#define LCD_MINIMAL_FONT
;#define MODULES_SI7021
;#define MODULES_STATS
;#define MODULES_OWI_MASTER
;#define MODULES_MOTION
#define MODULES_BRIGHTNESS

#define APPS_NETWORK
;#define APPS_MOTION
#define APPS_REPORTSENSORS
#define APPS_STATS



; ---------------------------------------------------------------------------
; defines for values

.equ VALUE_ID_ADC              = 0x03

.equ VALUE_ID_BRIGHTNESS       = 0x0b

.equ VALUE_ID_DEBUG            = 0x7f

.equ VALUE_ID_SENSOR_CO2_BASE        = 0x90
.equ   VALUE_ID_SENSOR_CO2_SOURCE    = 0x90
.equ   VALUE_ID_SENSOR_CO2_LIMWARN   = 0x91
.equ   VALUE_ID_SENSOR_CO2_LIMCRIT   = 0x92

.equ VALUE_ID_SENSOR_TEMP_BASE       = 0x93
.equ   VALUE_ID_SENSOR_TEMP_SOURCE   = 0x93
.equ   VALUE_ID_SENSOR_TEMP_LIMWARN  = 0x94
.equ   VALUE_ID_SENSOR_TEMP_LIMCRIT  = 0x95

.equ VALUE_ID_SENSOR_HUM_BASE        = 0x96
.equ   VALUE_ID_SENSOR_HUM_SOURCE    = 0x96
.equ   VALUE_ID_SENSOR_HUM_LIMWARN   = 0x97
.equ   VALUE_ID_SENSOR_HUM_LIMCRIT   = 0x98

.equ VALUE_ID_SCREENSAVER_SETSOURCE1 = 0x9a
.equ VALUE_ID_SCREENSAVER_SETSOURCE2 = 0x9b



; ***************************************************************************
; code segment

.cseg
.org 000000



; ---------------------------------------------------------------------------
; Reset and interrupt vectors
  jmp BOOTLOADER_ADDR           ;  1: Reset vector   RESET
  jmp irqNotSet                 ;  2: INT0           External Interrupt Request 0
  jmp irqNotSet                 ;  3: INT1           External Interrupt Request 1
  jmp irqNotSet                 ;  4: INT2           External Interrupt Request 2
  jmp com2wPcintIsr             ;  5: PCINT0         Pin Change Interrupt Request 0
  jmp irqNotSet                 ;  6: PCINT1         Pin Change Interrupt Request 1
  jmp irqNotSet                 ;  7: PCINT2         Pin Change Interrupt Request 2
  jmp irqNotSet                 ;  8: PCINT3         Pin Change Interrupt Request 3
  jmp irqNotSet                 ;  9: WDT            Watchdog Time-out Interrupt
  jmp irqNotSet                 ; 10: TIMER2_COMPA   Timer/Counter2 Compare Match A
  jmp irqNotSet                 ; 11: TIMER2_COMPB   Timer/Counter2 Compare Match B
  jmp irqNotSet                 ; 12: TIMER2_OVF     Timer/Counter2 Overflow
  jmp irqNotSet                 ; 13: TIMER1_CAPT    Timer/Counter1 Capture Event
  jmp irqNotSet                 ; 14: TIMER1_COMPA   Timer/Counter1 Compare Match A
  jmp irqNotSet                 ; 15: TIMER1_COMPB   Timer/Counter1 Compare Match B
  jmp irqNotSet                 ; 16: TIMER1_OVF     Timer/Counter1 Overflow
  jmp baseTimerIrqOC0A          ; 17: TIMER0_COMPA   Timer/Counter0 Compare Match A
  jmp irqNotSet                 ; 18: TIMER0_COMPB   Timer/Counter0 Compare Match B
  jmp irqNotSet                 ; 19: TIMER0_OVF     Timer/Counter0 Overflow
  jmp irqNotSet                 ; 20: SPI_STC        Serial Transfer Complete
  jmp irqNotSet                 ; 21: USART0_RXC     USART0 Rx Complete
  jmp irqNotSet                 ; 22: USART0_UDRE    USART0 Data Register Empty
  jmp irqNotSet                 ; 23: USART0_TXC     USART0 Tx Complete
  jmp irqNotSet                 ; 24: ANA_COMP       Analog Comparator
  jmp irqNotSet                 ; 25: ADC            ADC Conversion Complete
  jmp irqNotSet                 ; 26: EE_RDY         EEPROM Ready
  jmp irqNotSet                 ; 27: TWI            2-Wire Interface
  jmp irqNotSet                 ; 28: SPM_RDY        Store Program Memory Ready



devInfoBlock:        ; 12 bytes
devInfoManufacturer: .db 'A', 'Q', 'U', 'A'
devInfoId:           .db DEVICEINFO_ID, 0
devInfoVersion:      .db DEVICEINFO_VERSION, DEVICEINFO_REVISION             ; version, revision
firmwareVersion:     .db FIRMWARE_VARIANT_TEMP_WINDOW, FIRMWARE_VERSION_MAJOR
                     .db FIRMWARE_VERSION_MINOR, FIRMWARE_VERSION_PATCHLEVEL



; ---------------------------------------------------------------------------
; @routine firmwareStart @global

firmwareStart:
  rjmp main
; @end


irqNotSet:
  reti



; ---------------------------------------------------------------------------
; @routine onSystemStart

onSystemStart:
  bigcall test
  ret
; @end



; ---------------------------------------------------------------------------
; @routine onMessageReceived
;
; Called on every message received

onMessageReceived:
  lds yl, guiApp
  lds yh, guiApp+1
  bigcall GuiApp_MsgReceived
  clc
  ret
; @end



; ---------------------------------------------------------------------------
; @routine onEvery100ms
;
; Called every 100ms. Add your routine calls here. No arguments, no results.

onEvery100ms:
  lds yl, guiApp
  lds yh, guiApp+1
  bigcall GuiApp_Every100ms
  ret

onEveryMinute:
onEveryHour:
onEveryDay:
  ret
; @end


onEverySecond:
  ret



; ---------------------------------------------------------------------------
; @routine onEveryLoop
;
; Called on every loop (i.e. after awakening from sleep).
;
onEveryLoop:
  ret
; @end



test:
  bigcall C03App_new
  sts guiApp, yl
  sts guiApp+1, yh
  
  ret


;  ; debug
;  ldi r16, LOW(Debug_Style*2)
;  std Y+WIDGET_OFFS_STYLE_LO, r16
;  ldi r16, HIGH(Debug_Style*2)
;  std Y+WIDGET_OFFS_STYLE_HI, r16

DEBUG_STOP:
  bigjmp DEBUG1


DEBUG_STOP2:
  bigjmp DEBUG2

DEBUG_STOP3:
  bigjmp DEBUG3



DEBUG_DUMPCTX:
  lds yl, guiApp
  lds yh, guiApp+1
  bigcall GuiApp_GetRootWindow
  mov yl, r18
  mov yh, r19

  bigcall Widget_Clear

  clr r4
  clr r5
  clr r6
  clr r7
  
  adiw xh:xl, LAYOUT_CTX_OFFS_NUMITEMS
  ld r24, X+

DEBUG_DUMPCTX_loop:
    clr r4
    clr r5
    rcall DEBUG_DUMPCTXITEM
    ldi r16, 20
    clr r17
    add r6, r16
    adc r7, r17
    dec r24
  brne DEBUG_DUMPCTX_loop
  bigjmp DEBUG3


DEBUG_DUMPONEITEM:
  lds yl, guiApp
  lds yh, guiApp+1
  bigcall GuiApp_GetRootWindow
  mov yl, r18
  mov yh, r19
  bigcall Widget_Clear

  clr r4
  clr r5
  clr r6
  clr r7
  rjmp DEBUG_DUMPCTXITEM

DEBUG_DUMPCTXITEM:
  adiw xh:xl, LAYOUT_CTX_ITEM_OFFS_POS_LO
  ld r20, X+             ; pos
  ld r21, X+
  rcall DEBUG_WRITE_INT
  ldi r16, 65
  clr r17
  add r4, r16
  adc r5, r17

  ld r20, X+             ; size
  ld r21, X+
  rcall DEBUG_WRITE_INT
  ldi r16, 65
  clr r17
  add r4, r16
  adc r5, r17

  ld r20, X+             ; flags
  clr r21
  rcall DEBUG_WRITE_INT
  ldi r16, 65
  clr r17
  add r4, r16
  adc r5, r17
  ret



DEBUG_DUMPWDG:
  lds yl, guiApp
  lds yh, guiApp+1
  bigcall GuiApp_GetRootWindow
  mov yl, r18
  mov yh, r19

  push zl
    push zh
      bigcall Widget_Clear
    pop zh
  pop zl

  clr r4
  clr r5
  clr r6
  clr r7

  ldi r16, 3
  add r4, r16
  adc r5, r17
  rcall DEBUG_DUMPCWDG
  ldi r16, 20
  clr r17
  add r6, r16
  adc r7, r17
  
  push yl
    push yh
      mov yl, zl
      mov yh, zh
      bigcall OBJ_GetFirstChild
    pop yh
  pop yl
  mov zl, r18
  mov zh, r19
  ldi r24, 11
DEBUG_DUMPWDG_loop:
    rcall DEBUG_DUMPCWDG

    ldi r16, 20
    clr r17
    add r6, r16
    adc r7, r17
    dec r24
    breq DEBUG_DUMPWDG_end
    push yl
      push yh
        mov yl, zl
        mov yh, zh
        bigcall OBJ_GetNext
      pop yh
    pop yl
    mov zl, r18
    mov zh, r19
    brcc DEBUG_DUMPWDG_end
  rjmp DEBUG_DUMPWDG_loop

DEBUG_DUMPWDG_end:
  bigjmp DEBUG3


DEBUG_DUMPCWDG:
  clr r4
  clr r5

  ldd r20, Z+WIDGET_OFFS_X_LO
  ldd r21, Z+WIDGET_OFFS_X_HI
  rcall DEBUG_WRITE_INT
  ldi r16, 65
  clr r17
  add r4, r16
  adc r5, r17

  ldd r20, Z+WIDGET_OFFS_Y_LO
  ldd r21, Z+WIDGET_OFFS_Y_HI
  rcall DEBUG_WRITE_INT
  ldi r16, 65
  clr r17
  add r4, r16
  adc r5, r17

  ldd r20, Z+WIDGET_OFFS_WIDTH_LO
  ldd r21, Z+WIDGET_OFFS_WIDTH_HI
  rcall DEBUG_WRITE_INT
  ldi r16, 65
  clr r17
  add r4, r16
  adc r5, r17

  ldd r20, Z+WIDGET_OFFS_HEIGHT_LO
  ldd r21, Z+WIDGET_OFFS_HEIGHT_HI
  rcall DEBUG_WRITE_INT
  ldi r16, 65
  clr r17
  add r4, r16
  adc r5, r17

  ldd r20, Z+WIDGET_OFFS_TMP_LO
  ldd r21, Z+WIDGET_OFFS_TMP_HI
  rcall DEBUG_WRITE_INT
  ldi r16, 65
  clr r17
  add r4, r16
  adc r5, r17
  ret




; @param r21:r20: number
DEBUG_WRITE_INT:
  push r24
    push zl
      push zh
        ldi r24, 0
        push xl
          push xh
            bigcall IntToAscii                        ; X=pointer to text
            push r4
              push r5
                bigcall Widget_DrawTextRam   ; (any, !Y)
              pop r5
            pop r4
          pop xh
        pop xl
      pop zh
    pop zl
  pop r24
  ret
; @end






Debug_Style:
  .dw DISPLAY_COLOR_BLACK      ; frontCol_norm
  .dw DISPLAY_COLOR_GREEN      ; 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



; ***************************************************************************
; includes

.include "devices/all/hw_m644p.asm"
.include "devices/all/includes.asm"

.include "devices/all/handlevaluemsg.asm"

.include "common/debug.asm"

.include "modules/lcd2/ili9341/font12x16.asm"
.include "modules/lcd2/ili9341/font12x16_1.asm"

.include "modules/lcd2/ili9341/font6x8.asm"
.include "modules/lcd2/ili9341/font6x8_1.asm"

;.include "modules/lcd2/ili9341/font12x20.asm"
;.include "modules/lcd2/ili9341/font12x20_1.asm"
;.include "common/list_t.asm"
;.include "common/tree_t.asm"

.include "common/eeprom_tlv.asm"

.include "common/divide.asm"
.include "common/multiply.asm"
.include "common/multiply8.asm"
.include "common/itoa.asm"
.include "common/ressource.asm"
.include "common/list.asm"

.include "style.asm"


GUI_MODULE_BEGIN:
.include "modules/lcd2/gui/base/object.asm"
.include "modules/lcd2/gui/base/widget.asm"
.include "modules/lcd2/gui/base/guiapp.asm"
.include "modules/lcd2/gui/base/rootwindow.asm"
.include "modules/lcd2/gui/base/label.asm"
.include "modules/lcd2/gui/base/button.asm"
.include "modules/lcd2/gui/base/imageview.asm"
.include "modules/lcd2/gui/base/imagebutton.asm"
.include "modules/lcd2/gui/base/textbutton.asm"
.include "modules/lcd2/gui/base/valuelabel.asm"
.include "modules/lcd2/gui/base/imagelabel.asm"
.include "modules/lcd2/gui/base/checkbox.asm"
.include "modules/lcd2/gui/base/checkbutton.asm"
.include "modules/lcd2/gui/base/tile.asm"
.include "modules/lcd2/gui/base/layout.asm"
.include "modules/lcd2/gui/base/hlayout.asm"
.include "modules/lcd2/gui/base/vlayout.asm"
.include "modules/lcd2/gui/base/mclayout.asm"
.include "modules/lcd2/gui/composite/hspinner.asm"
.include "modules/lcd2/gui/composite/mainwindow.asm"
.include "modules/lcd2/gui/base/keypad.asm"
.include "modules/lcd2/gui/base/keypad_num.asm"
.include "modules/lcd2/gui/composite/d_numinput.asm"
.include "modules/lcd2/gui/base/cwidget.asm"
.include "modules/lcd2/gui/composite/dialog.asm"
.include "modules/lcd2/gui/composite/cdialog.asm"
.include "modules/lcd2/gui/aqhome/sensorwatch.asm"
.include "modules/lcd2/gui/aqhome/lightsettings.asm"
.include "modules/lcd2/gui/aqhome/d_light_conns.asm"
.include "modules/lcd2/gui/aqhome/d_nodevalueid.asm"
.include "modules/lcd2/gui/composite/textsel.asm"
.include "modules/lcd2/gui/screensavers/simple.asm"
GUI_MODULE_END:
.equ MODULE_SIZE_GUI = GUI_MODULE_END-GUI_MODULE_BEGIN

.include "a_c03.asm"
.include "w_menu.asm"
.include "w_climate.asm"
.include "w_netstats.asm"
.include "w_lightsettings.asm"

.include "ressources.inc"


; ---------------------------------------------------------------------------
; defines for network interface

;.equ netInterfaceData = netUartIface
;.equ netInterfaceData = uart_bitbang_iface
.equ netInterfaceData = com2w_iface



deviceCodeEnd:
  .if deviceCodeEnd >= RESSOURCE_ADDR
    .warning "Code reaches into ressources!"
  .endif




.dseg

guiApp:     .byte 2



heapStart:

.equ HEAP_START = heapStart
;.equ HEAP_SIZE  = (SRAM_SIZE-STACK_SIZE)-HEAP_START
.equ HEAP_END   = (RAMEND-STACK_SIZE)
.equ HEAP_SIZE  = (HEAP_END-HEAP_START)


