.nolist
.include "include/tn84def.inc" ; Define device ATtiny84
.list



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

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

.equ clock=1000000 ; Define the clock frequency



; ---------------------------------------------------------------------------
; COM module

.equ COM_BIT_LENGTH      = 52000 ; 104000=9600, 52000=19200, 26000=38400

.equ COM_RINGBUFFER_SIZE = 32    ; 32 bytes for now

.equ COM_DDR_DATA        = DDRA
.equ COM_PORT_DATA       = PORTA
.equ COM_PIN_DATA        = PINA
.equ COM_PINNUM_DATA     = PORTA1

.equ COM_DDR_ATTN        = DDRA
.equ COM_PORT_ATTN       = PORTA
.equ COM_PIN_ATTN        = PINA
.equ COM_PINNUM_ATTN     = PORTA7

.equ COM_IRQ_ADDR_ATTN   = PCMSK0
.equ COM_IRQ_BIT_ATTN    = 7              ; bit 7 in PCMSK0
.equ COM_IRQ_GIFR_ATTN   = PCIF0
.equ COM_IRQ_GIMSK_ATTN  = PCIE0




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

.cseg
.org 000000



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

	rjmp main ; Reset vector
	reti ; EXT_INT0
	reti ; PCI0
	reti ; PCI1
	reti ; WATCHDOG
	reti ; ICP1
	reti ; OC1A
	reti ; OC1B
	reti ; OVF1
        rjmp timerIrqOC0A ; OC0A
	reti ; OC0B
	reti ; OVF0
	reti ; ACI
	reti ; ADCC
	reti ; ERDY
	reti ; USI_STR
	reti ; USI_OVF



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

.include "utils.asm"
.include "ringbuffer.asm"
.include "timer.asm"
.include "led.asm"
.include "com.asm"



; ***************************************************************************
; data in SRAM

.dseg

ledA3Sram:   .byte LED_SRAM_SIZE




; ***************************************************************************
; data in EEPROM

.eseg




; ***************************************************************************
; data in FLASH

.cseg

ledA3Flash:    .db DDRA+0x20, PORTA+0x20, PINA+0x20, (1<<PORTA3)
blinkPattern:  .db 5, 5, 5, 5, 5, 10, 0xff, 0xff   ; 3 short blinks, 1s pause, restart
blinkPattern2:  .db 10, 20, 0xff, 0xff   ; 1 long blink, 2s pause, restart





main:
  ; 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 initModules
  sei ; Enable interrupts

  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

main_loop:
    rcall runModulesUntilIdle
;    sbi DDRA, PORTA2 ; debug
;    sbi PINA, PORTA2 ; debug (toggle)
;    cbi PORTA, PORTA2 ; debug (on)
;    sbi PORTA, PORTA2 ; debug (off)
  
    ; only modify SE, SM1 and SM0
    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
    sleep                      ; sleep, wait for interrupt
  rjmp main_loop




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

initModules:
  rcall Timer_Init

  ldi zl, LOW(ledA3Flash)
  ldi zh, HIGH(ledA3Flash)
  ldi yl, LOW(ledA3Sram)
  ldi yh, HIGH(ledA3Sram)
  rcall Led_Init
  
  rcall Com_Init
  ret



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

runModulesUntilIdle:

  ; TIMER module
  rcall Timer_Run

  ; COM module (call until carry flag cleared but at most 10 times to not starve other modules)
  ldi r16, 10
runModulesUntilIdle_Com:
    push r16
      rcall Com_Run
    pop r16
    brcc runModulesUntilIdle_ComEnd
    dec r16
  brne runModulesUntilIdle_Com
runModulesUntilIdle_ComEnd:

  ; add more modules here
  ret



; ---------------------------------------------------------------------------
; onEvery100ms
;
; Called every 100ms. Add your routine calls here.
;
; IN:
; - nothing
; OUT:
; - nothing
; USED: depending on called routines

onEvery100ms:
  ; ticker for LED module
  ldi zl, LOW(ledA3Flash)
  ldi zh, HIGH(ledA3Flash)
  ldi yl, LOW(ledA3Sram)
  ldi yh, HIGH(ledA3Sram)
  rcall Led_Tick

  ; add more calls here
  
  ret



; ---------------------------------------------------------------------------
; onEverySecond
;
; Called every second. Add your routine calls here.
;
; IN:
; - nothing
; OUT:
; - nothing
; USED: depending on called routines

onEverySecond:
  ret



; ---------------------------------------------------------------------------
; onEvery10s
;
; Called every 10 seconds. Add your routine calls here.
;
; IN:
; - nothing
; OUT:
; - nothing
; USED: depending on called routines

onEvery10s:
  in r15, SREG ; debug
  cli
  push r15
    ldi r17, 219
    rcall COM_EnqueuePing
;    rcall comHandleNextPacketInRingbuffer
  pop r15
  out SREG, r15
  ret



; ---------------------------------------------------------------------------
; onEveryMinute
;
; Called every minute. Add your routine calls here.
;
; IN:
; - nothing
; OUT:
; - nothing
; USED: depending on called routines

onEveryMinute:
    sbi DDRA, PORTA2 ; debug
    sbi PINA, PORTA2 ; debug (toggle)
  ret



; ---------------------------------------------------------------------------
; onPacketReceived:
;
; Called after a packet was received via COM module. Add your routine calls here.
;
; The packet will be removed from buffer in any case after return from this call.
; IN:
; - R18: pos of packet in ringbuffer
; - Y  : pointer to ringbuffer
; OUT:
; - CFLAG: set if handled, cleared otherwise
; USED: depending on called routines

onPacketReceived:
  clc               ; not handled
  ret







debugSendByte:
  in r15, SREG ; debug
  cli

  ldi r17, 8
  sbi DDRA, PORTA2 ; debug

  cbi PORTA, PORTA2 ; debug (on)
  Utils_WaitNanoSecs 200000, 0, r22 ; start with 2t low

debugSendByte_loop:
  lsr r16
  brcs debugSendByte_sendLow
  cbi PORTA, PORTA2 ; debug (on)
  rjmp debugSendByte_wait
debugSendByte_sendLow:
  sbi PORTA, PORTA2 ; debug (off)

debugSendByte_wait:
  Utils_WaitNanoSecs 100000, 0, r22
  dec r17
  brne debugSendByte_loop

  cbi PORTA, PORTA2 ; debug (on)
  Utils_WaitNanoSecs 200000, 0, r22 ; end with 2t low
  sbi PORTA, PORTA2 ; debug (off)


  out SREG, r15
  ret

