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



; ---------------------------------------------------------------------------
; main
;

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)

  rcall systemSetSpeed
  rcall Utils_Init
  rcall Utils_SetupUid
  rcall initModules
  rcall Utils_InitialWait
  sei ; Enable interrupts

  rcall onSystemStart

#ifdef MODULES_LED
  ldi xl, LOW(blinkPattern)  ; debug: set blink pattern
  ldi xh, HIGH(blinkPattern)
  ldi zl, LOW(ledA3Flash)
  ldi zh, HIGH(ledA3Flash)
  ldi yl, LOW(ledA3Sram)
  ldi yh, HIGH(ledA3Sram)
  rcall Led_SetPattern
#endif

main_loop:
    rcall runModules

#ifdef MODULES_NETWORK
    rcall handleMessages
#endif

    ; only modify SE, SM1 and SM0
    cli
    in r16, MCUCR
    ldi r17, (1<<SE) | (1<<SM1) | (1<<SM0)
    neg r17
    and r16, r17
    ori r16, (1<<SE)           ; sleep mode "idle", enable
    out MCUCR, r16
    sei                        ; make sure interrupts really are enabled
    sleep                      ; sleep, wait for interrupt
  rjmp main_loop




; ---------------------------------------------------------------------------
; @routine initModules
;
; Call init functions of the used modules. Add your routine calls here.

initModules:
  rcall BaseTimer_Init ; unconditionally call this

#ifdef MODULES_CLOCK
  rcall Clock_Init
#endif

#ifdef MODULES_TIMER
  rcall Timer_Init
#endif

#ifdef MODULES_LED
  ldi zl, LOW(ledA3Flash)
  ldi zh, HIGH(ledA3Flash)
  ldi yl, LOW(ledA3Sram)
  ldi yh, HIGH(ledA3Sram)
  rcall Led_Init
#endif

#ifdef MODULES_LED_SIMPLE
  rcall LedSimple_Init
#endif
  
#ifdef MODULES_COM
  rcall Com2_Init   ; init COM module
  rcall CPRO_Init   ; init COM protocol module
#endif

#ifdef MODULES_NETWORK
  rcall NET_Init
#endif

#ifdef MODULES_UART_BITBANG
  rcall UART_BitBang_Init
#endif

#ifdef MODULES_MOTION
  rcall Motion_Init
#endif

#ifdef MODULES_TWI_MASTER
  rcall TWI_Master_Init
#endif

#ifdef MODULES_OWI_MASTER
  rcall OwiMaster_Init
#endif
#ifdef MODULES_LCD
  rcall LCD_Init
#endif
#ifdef MODULES_BMP280
  rcall BMP280_Init
#endif

#ifdef MODULES_SI7021
  rcall SI7021_Init
#endif

#ifdef MODULES_DS18B20
  rcall Ds18b20_Init
#endif

#ifdef MODULES_STATS
  rcall Stats_Init
#endif

#ifdef MODULES_CNY70
  rcall CNY70_Init
#endif

#ifdef MODULES_REED
  rcall REED_Init
#endif

#ifdef MODULES_SK6812
  rcall SK6812_Init
#endif

#ifdef MODULES_MOTION_LIGHT
  rcall MotionLight_Init
#endif

#ifdef MODULES_TCRT1000
  rcall TCRT1K_Init
#endif

#ifdef MODULES_CCS811
  rcall CCS811_Init
#endif

  ; done
  ret
; @end



; ---------------------------------------------------------------------------
; runModules
;
; Call run functions of the used modules. Add your routine calls here.
;
; IN:
; - nothing
; OUT:
; - nothing
; USED: depending on called routines

runModules:
  rcall BaseTimer_Run
  
#ifdef MODULES_COM
; COM module (call until carry flag cleared but at most 10 times to not starve other modules)
  ldi r16, 10
runModules_Com:
    push r16
      rcall Com2_Run
    pop r16
    brcc runModules_ComEnd
    dec r16
  brne runModules_Com
runModules_ComEnd:  
  
#endif

#ifdef MODULES_STATS
  rcall Stats_Run
#endif

#ifdef MODULES_REED
  rcall REED_Run
#endif

#ifdef MODULES_CNY70
  rcall CNY70_Run
#endif

#ifdef MODULES_DS18B20
  rcall Ds18b20_Run
#endif

#ifdef MODULES_MOTION_LIGHT
;  rcall MotionLight_Run
#endif


#ifdef MODULES_TCRT1000
  rcall TCRT1K_Run
#endif

  ; add more modules here
  ret




#ifdef MODULES_NETWORK
; ---------------------------------------------------------------------------
; @routine handleMessages

handleMessages:
  rcall NET_GetNextIncomingMsgNum           ; R16=msg num
  brcc handleMessages_end
  rcall NET_Buffer_Locate                   ; X=buffer addr (R17)
  push r16
    ; handle messages
    ldi yl, LOW(uart_bitbang_iface)
    ldi yh, HIGH(uart_bitbang_iface)
    rcall AppNetwork_HandleMsg
    ; add more here
  pop r16
  rcall NET_Buffer_ReleaseByNum
  sec
handleMessages_end:
  ret
; @end
#endif




