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


; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; This file contains timer handlers for the address protocol
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;


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

.cseg



CPRO_Address_OnTimer:
  lds r16, cproMode
  ldi r17, CPRO_MODE_NEXT_FREE
  ldi zl, LOW(cproAddressOnTimerTable)
  ldi zh, HIGH(cproAddressOnTimerTable)
  rjmp Utils_TableJump


cproAddressOnTimerTable:
  .dw CPRO_StartReclaimAddrProcedure     ; CPRO_MODE_NOADDRESS
  .dw 0                                  ; CPRO_MODE_NORMAL
  .dw cproHandle1sNeedAddr               ; CPRO_MODE_SEND_NEED_ADDR
  .dw cproHandle1sGetAddrStarted         ; CPRO_MODE_GETADDRSTARTED
  .dw cproHandle1sSendClaimAddr1         ; CPRO_MODE_SEND_CLAIM_ADDR1
  .dw cproHandle1sClaimingAddr12         ; CPRO_MODE_CLAIMING_ADDR1
  .dw cproHandle1sClaimingAddr12         ; CPRO_MODE_CLAIMING_ADDR2
  .dw cproHandle1sClaimingAddr3          ; CPRO_MODE_CLAIMING_ADDR3
  .dw cproHandle1sSendingHaveAddress     ; CPRO_MODE_SENDING_HAVE_ADDR
  .dw cproHandle1sSendReclaimAddr        ; CPRO_MODE_SEND_RECLAIM_ADDR
  .dw cproHandle1sReclaimingAddr         ; CPRO_MODE_RECLAIMING_ADDR
  .dw cproHandle1sSendDenyAddr           ; CPRO_MODE_SEND_DENY_ADDR


cproHandle1sSendingHaveAddress:
  lds r19, com2Address
  rcall CPRO_SendHaveAddress
  brcs cproHandle1sSendingHaveAddress_okay
  rcall cproAddressSetTimer1s              ; could not send, restart timer 1s and retry later
  ret
cproHandle1sSendingHaveAddress_okay:
  ldi r16, CPRO_MODE_NORMAL
  sts cproMode, r16
  ret



cproHandle1sNeedAddr:
  rcall CPRO_SendNeedAddress
  brcs cproHandle1sNeedAddr_okay
  rjmp cproAddressSetTimer1s               ; could not send, restart timer 1s and retry later
cproHandle1sNeedAddr_okay:
  ldi r16, CPRO_MODE_GETADDRSTARTED        ; wait for incoming messages
  sts cproMode, r16
  ldi r18, LOW(CPRO_WAITTIME_GETADDR)      ; set timeout
  ldi r19, HIGH(CPRO_WAITTIME_GETADDR)     ; set timeout
  rjmp cproAddressSetTimer



cproHandle1sSendDenyAddr:
  rcall CPRO_SendDenyAddress
  brcs cproHandle1sSendDenyAddr_okay
  rjmp cproAddressSetTimer1s               ; could not send, restart timer 1s and retry later
cproHandle1sSendDenyAddr_okay:
  ldi r16, CPRO_MODE_NORMAL                ; DENY_ADDR sent, back to normal
  sts cproMode, r16
  ret



cproHandle1sSendReclaimAddr:
  lds r19, cproAddrRangeBegin
  rcall CPRO_SendClaimAddress
  brcs cproHandle1sSendReclaimAddr_okay
  rjmp cproAddressSetTimer1s              ; could not send, restart timer 1s and retry later
cproHandle1sSendReclaimAddr_okay:
  ldi r16, CPRO_MODE_RECLAIMING_ADDR
  sts cproMode, r16
  ldi r18, LOW(CPRO_WAITTIME_RECLAIMADDR)
  ldi r19, HIGH(CPRO_WAITTIME_RECLAIMADDR)
  rjmp cproAddressSetTimer                ; prepare time for next stage



cproHandle1sGetAddrStarted:
  rcall cproGetFirstFreeAddr
  brcs cproHandle1sGetAddrStarted_gotAddr
  ; no free address, abort  TODO: send an error message to bus ("bus full")
  ldi r16, CPRO_MODE_NOADDRESS
  sts cproMode, r16
  ret
cproHandle1sGetAddrStarted_gotAddr:
  ldi r16, CPRO_MODE_SEND_CLAIM_ADDR1
  sts cproMode, r16
  rjmp cproAddressSetTimer1s           ; start



cproHandle1sSendClaimAddr1:
  lds r19, cproAddrRangeBegin
  rcall CPRO_SendClaimAddress
  brcs cproHandle1sClaimSend_okay
  rjmp cproAddressSetTimer1s              ; could not send, restart timer 1s and retry later
cproHandle1sClaimSend_okay:               ; goto nex stage
  ldi r16, CPRO_MODE_CLAIMING_ADDR1
  sts cproMode, r16
  ldi r18, LOW(CPRO_WAITTIME_CLAIMADDR)
  ldi r19, HIGH(CPRO_WAITTIME_CLAIMADDR)
  rjmp cproAddressSetTimer                ; prepare timer for next stage



cproHandle1sClaimingAddr12:
  lds r19, cproAddrRangeBegin            ; currently claimed address
  rcall CPRO_SendClaimAddress
  brcs cproHandle1sClaimingAddr12_okay
  rjmp cproAddressSetTimer1s             ; could not send, restart timer 1s and retry later
cproHandle1sClaimingAddr12_okay:
  lds r16, cproMode
  inc r16
  sts cproMode, r16
  ldi r18, LOW(CPRO_WAITTIME_CLAIMADDR)
  ldi r19, HIGH(CPRO_WAITTIME_CLAIMADDR)
  rjmp cproAddressSetTimer                ; prepare time for next stage



cproHandle1sClaimingAddr3:
cproHandle1sReclaimingAddr:
  ; claimed given address 3rd time or addr reclaimed, set address and enter "normal" mode
  lds r19, cproAddrRangeBegin           ; currently claimed address
  sts com2Address, r19
  rcall CPRO_SendHaveAddress
  brcs cproHandle1sClaimingAddr3_okay
  rjmp cproAddressSetTimer1s            ; could not send, restart timer 1s and retry later
cproHandle1sClaimingAddr3_okay:
  in r15, SREG
  push r15
    cli
    lds r16, com2Address                ; currently sent address is in cproAddrRangeBegin
    ldi xl, LOW(EEPROM_OFFS_COMADDR)    ; write address into eeprom
    ldi xh, HIGH(EEPROM_OFFS_COMADDR)
    rcall Utils_WriteEepromIncr         ; write address to EEPROM
  pop r15
  out SREG, r15
  ldi r16, CPRO_MODE_NORMAL             ; set mode to "normal"
  sts cproMode, r16
  ret





