; ***************************************************************************
; copyright   : (C) 2025 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.   *
; ***************************************************************************



; ***************************************************************************
; code


.cseg



; ---------------------------------------------------------------------------
; @routine main @global

main:
  cli
  ; setup stack
  .ifdef SPH               ; if SPH is defined
    ldi r16, High(RAMEND)
    out SPH, r16           ; init MSB stack pointer
  .endif
  ldi r16, Low(RAMEND)
  out SPL, r16             ; init LSB stack pointer

;  rcall watchdogOff        ; turn off watchdog timer (sometimes it stays on after reboot)

  bigcall systemSetSpeed
  bigcall systemInitHardware
  bigcall RAND_SetupSeed
  bigcall DevUid_Setup
  bigcall modulesInit
  bigcall appsInit
  bigcall Utils_InitialWait
  sei ; Enable interrupts       TODO: move below!

  bigcall onSystemStart

main_loop:
    bigcall systemSleep   ; system-dependant

    ; run loop as long as some run function returns with CFLAG set
    clr r17
main_runLoop:
    push r17
      clr r16
      push r16
        bigcall modulesRun
      pop r16
      sbci r16, 0
      
      push r16
        bigcall appsRun
      pop r16
      sbci r16, 0
    
      push r16
        bigcall onEveryLoop   ; call into main app
      pop r16
    pop r17

    tst r16
    breq main_endRunLoop
    inc r17
    cpi r17, 10
    brcc main_endRunLoop
  brne main_runLoop
main_endRunLoop:

#ifdef MODULES_NETWORK
  #ifndef MAIN_WITHOUT_MSG_HANDLING
    rcall mainHandleMessages
  #endif
#endif

  rjmp main_loop

main_loop_reboot:
  cli
  bigjmp BOOTLOADER_ADDR
; @end



onSystemTimerTick:
  bigcall onEvery100ms
  bigcall modulesOnEvery100ms
  bigcall appsOnEvery100ms
  ret
; @end


#ifdef MODULES_CLOCK

sysOnEverySecond:
  bigcall modulesOnEverySecond
  bigcall appsOnEverySecond
  bigjmp onEverySecond
; @end


sysOnEveryMinute:
  bigcall modulesOnEveryMinute
  bigcall appsOnEveryMinute
  bigjmp onEveryMinute
; @end


sysOnEveryHour:
  bigcall modulesOnEveryHour
  bigcall appsOnEveryHour
  bigjmp onEveryHour
; @end


sysOnEveryDay:
  bigcall modulesOnEveryDay
  bigcall appsOnEveryDay
  bigjmp onEveryDay
; @end

#endif



#ifdef MODULES_NETWORK
; ---------------------------------------------------------------------------
; @routine mainHandleMessages

mainHandleMessages:
  bigcall NET_GetNextIncomingMsgNum           ; R16=msg num
  brcc mainHandleMessages_end
  bigcall NET_Buffer_Locate                   ; X=buffer addr (R17)
  adiw xh:xl, 1

  push r16
    bigcall onMessageReceived
    bigcall modulesOnPacketReceived
    bigcall appsOnPacketReceived
  pop r16
  bigcall NET_Buffer_ReleaseByNum
  sec
mainHandleMessages_end:
  ret
; @end
#endif





