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




; ***************************************************************************
; Source file for temperature sensor node on AtTiny 84
;
; This is for the full system (i.e. not the boot loader).
;
; All definitions and changes should go into this file.
;
;
; ***************************************************************************


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


.nolist
.include "include/tn841def.inc" ; Define device ATtiny841
.list

.include "../defs.asm"
.include "version.asm"
;.include "defs_all.asm"

.include "devices/all/defs.asm"

.include "common/calls.asm"
.include "common/utils_wait.asm"
.include "common/utils_io.asm"



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

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

.equ COMONUART0_IFACENUM = 1
.equ TTYONUART1_IFACENUM = 2


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


#define MAIN_WITHOUT_MSG_HANDLING ; we do message handling ourselfes
#define APP_STATS_NETDEV2
#define COM_ACCEPT_ALL_DEST       ; accept all messages!

#define MODULES_CLOCK
;#define MODULES_COM
;#define MODULES_COM_WITH_ADDR_PROTO
;#define MODULES_LED
#define MODULES_LED1
;#define MODULES_TWI_MASTER
;#define MODULES_LCD
;#define LCD_MINIMAL_FONT
;#define MODULES_SI7021
;#define MODULES_STATS
;#define MODULES_CNY70
;#define MODULES_REED
;#define MODULES_OWI_MASTER
;#define MODULES_DS18B20
;#define MODULES_MOTION
#define MODULES_NETWORK
#define MODULES_COM2W
;#define MODULES_COMONUART0
#define MODULES_TTYONUART1
#define APPS_STATS
#define APPS_NETWORK



.equ NET_BUFFERS_NUM           = 10
.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)




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

.equ VALUE_ID_DS18B20_TEMP     = 0x06

.equ VALUE_ID_LEDSIMPLE_TIMING = 0x88


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

.cseg
.org 000000



; ---------------------------------------------------------------------------
; Reset and interrupt vectors

        rjmp BOOTLOADER_ADDR          ;  1: RESET             Reset vector  use this for flashed system
	reti                          ;  2: INT0              External Interrupt Request 0
        rjmp com2wPcintIsr            ;  3: PCINT0            Pin Change Interrupt 0
	reti                          ;  4: PCINT1            Pin Change Interrupt 1
	reti                          ;  5: WDT               Watchdog Time-out
	reti                          ;  6: TIM1_CAPT         Timer/Counter1 Capture Event
	reti                          ;  7: TIM1_COMPA (OC1A) Timer/Counter1 Compare Match A
	reti                          ;  8: TIM1_COMPB (OC1B) Timer/Counter1 Compare Match B
	reti                          ;  9: TIM1_OVF (OVF1)   Timer/Counter1 Overflow
        rjmp baseTimerIrqOC0A         ; 10: TIM0_COMPA (OC0A) Timer/Counter0 Compare Match A
	reti                          ; 11: TIM0_COMPB (OC0B) Timer/Counter0 Compare Match B
	reti                          ; 12: TIM0_OVF (OVF0)   Timer/Counter0 Overflow
	reti                          ; 13: ANA_COMP0         Analog Comparator 0
        reti                          ; 14: ADC_READY         ADC Conversion Complete
        reti                          ; 15: EE_RDY (ERDY)     EEPROM Ready
        reti                          ; 16: ANA_COMP1         Analog Comparator 1
        reti                          ; 17: TIM2_CAPT         Timer/Counter2 Capture Event
        reti                          ; 18: TIM2_COMPA (OC2A) Timer/Counter2 Compare Match A
        reti                          ; 19: TIM2_COMPB (OC2B) Timer/Counter2 Compare Match B
        reti                          ; 20: TIM2_OVF (OVF2)   Timer/Counter2 Overflow
        reti                          ; 21: SPI               SPI Serial Transfer Complete
        reti                          ; 22: USART0_RXS        USART0 Rx Start
        reti                          ; 23: USART0_RXC        USART0 Rx Complete
        reti                          ; 24: USART0_DRE        USART0 Data Register Empty
        reti                          ; 25: USART0_TXC        USART0 Tx Complete
        reti                          ; 26: USART1_RXS        USART1 Rx Start
        rjmp TtyOnUart1_RxCharIsr     ; 27: USART1_RXC        USART1 Rx Complete
        rjmp TtyOnUart1_TxUdreIsr     ; 28: USART1_DRE        USART1 Data Register Empty
        rjmp TtyOnUart1_TxCharIsr     ; 29: USART1_TXC        USART1 Tx Complete
        reti                          ; 30: TWI               Two-Wire-Interface
        reti                          ; 31: RESERVED          reserved



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



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

onSystemStart:
  ; set interface number for UART0
  ldi r16, COMONUART0_IFACENUM
  sts netInterfaceData2+NET_IFACE_OFFS_IFACENUM, r16
  ; set interface number for UART1
  ldi r16, TTYONUART1_IFACENUM
  sts ttyOnUart1_iface+NET_IFACE_OFFS_IFACENUM, r16
  
  ret
; @end



onEvery100ms:
onEverySecond:
onEveryMinute:
onEveryHour:
onEveryDay:
  ret



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

onEveryLoop:
  rcall checkRecvdMsg
  ret
; @end



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

onMessageReceived:
  clc
  ret
; @end



; ---------------------------------------------------------------------------
; @routine checkRecvdMsg
;
; Read messages from either interface and forward to the other one.

checkRecvdMsg:
    rcall NET_PeekNextIncomingMsgNum          ; check read queue (bufNum->r16)
    brcc checkRecvdMsg_end                    ; no msg, jmp
    rcall NET_Buffer_Locate                   ; (R17)
    ; let system handle incoming messages
    push r16
      push xl
        push xh
          adiw xh:xl, 1
          rcall letSysHandleMsg
        pop xh
      pop xl
    pop r16

    ; forward to other interface
    ld r17, X
    andi r17, (1<<NET_IFACE_BUFFER_IFACENUM1_BIT) | (1<<NET_IFACE_BUFFER_IFACENUM0_BIT)
    rcall reverseInterfaceNum                 ; (R17)
;    ldi r17, TTYONUART1_IFACENUM ; DEBUG: send everything to uart1 to test that code first
    rcall addMsgToInterface
    brcc checkRecvdMsg_end                    ; could not add, jmp
    rcall NET_GetNextIncomingMsgNum           ; take off the queue
  rjmp checkRecvdMsg
checkRecvdMsg_end:
  ret
; @end



letSysHandleMsg:
  ld r16, X
  cpi r16, 0xff
  breq letSysHandleMsg_forMe
  lds r17, netInterfaceData2+NET_IFACE_OFFS_ADDRESS
  cp r16, r17
  brne letSysHandleMsg_end
letSysHandleMsg_forMe:
  push xl
    push xh
      rcall onMessageReceived
    pop xh
  pop xl
  push xl
    push xh
      rcall modulesOnPacketReceived
    pop xh
  pop xl
  push xl
    push xh
      rcall appsOnPacketReceived
    pop xh
  pop xl
letSysHandleMsg_end:
  ret
; @end



; ---------------------------------------------------------------------------
; @routine reverseInterfaceNum
;
; @param r17 buffer num
; @return r17 reversed interface number
; @clobbers r17

reverseInterfaceNum:
  andi r17, (1<<NET_IFACE_BUFFER_IFACENUM1_BIT) | (1<<NET_IFACE_BUFFER_IFACENUM0_BIT)
  cpi r17, COMONUART0_IFACENUM
  brne reverseInterfaceNum_notUart0
  ldi r17, TTYONUART1_IFACENUM
  ret
reverseInterfaceNum_notUart0:
  ldi r17, COMONUART0_IFACENUM
  ret
; @end



; ---------------------------------------------------------------------------
; @routine addMsgToInterface
; @param r16 buffer num
; @param r17 interface num

addMsgToInterface:
  cpi r17, COMONUART0_IFACENUM
  breq addMsgToInterface_toUart0
  cpi r17, TTYONUART1_IFACENUM
  breq addMsgToInterface_toUart1
  clc
  ret
addMsgToInterface_toUart0:
  ldi yl, LOW(netInterfaceData2)
  ldi yh, HIGH(netInterfaceData2)
  rjmp NET_Interface_AddOutgoingMsgNum     ; try to add msg to interface
addMsgToInterface_toUart1:
  ldi yl, LOW(ttyOnUart1_iface)
  ldi yh, HIGH(ttyOnUart1_iface)
  rjmp NET_Interface_AddOutgoingMsgNum     ; try to add msg to interface
; @end






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

.include "devices/all/hw_tn841.asm"
.include "devices/all/includes.asm"
.include "common/debug.asm"




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

.equ netInterfaceData  = ttyOnUart1_iface
.equ netInterfaceData2 = com2w_iface

