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



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


.cseg




; ---------------------------------------------------------------------------
; wait for a specific message to arrive within given time, flashing LED
;
; IN:
; - R16: message type to receive
; - R17: wait time in 100ms (1=100ms, 2=200ms etc.)
; OUT:
; - CFLAG: set if msg received (either expected msg or FLASH_END), cleared otherwise
; - R16: message type received (if CFLAG set)
; REGS: R2, R16, R17 (R1, R24, R25, X)

flashWaitForSpecificMessageWithLed:
  mov r2, r16
  sbi PORTA, PORTA3                          ; LED off

flashWaitForSpecificMessageWithLed_loop:
    sbi PINA, PORTA3                         ; toggle LED
    mov r16, r2
    push r17
      ldi r17, 100                           ; wait up to 100ms
      rcall flashWaitForSpecificMessage      ; (R1, R16, R17, R24, R25, X)
    pop r17
    brcs flashWaitForSpecificMessageWithLed_received
    dec r17
  brne flashWaitForSpecificMessageWithLed_loop
  sbi PORTA, PORTA3 ; off
  rjmp flash_recv_clc_ret                    ; timeout
flashWaitForSpecificMessageWithLed_received:
  sbi PORTA, PORTA3 ; off
  sec
  ret



; ---------------------------------------------------------------------------
; wait for a specific message to arrive within given time.
;
; IN:
; - R16: msg command to wait for
; - R17: time to wait for packet (in milliseconds)
; OUT:
; - CFLAG: set if msg received, cleared on timeout
; - R16  : message type received
; REGS: R1, R16, R17, X (R24, R25)

flashWaitForSpecificMessage:
  mov r1, r16                               ; expected message type
flashWaitForSpecificMessage_loop0:
    ; wait for ATTN to go low
flashWaitForSpecificMessage_loop1:
    ldi r16, 0                              ; wait for low
    rcall flashWaitForAttnState1ms          ; (R22, R24)
    brcs flashWaitForSpecificMessage_isLow
    dec r17
  brne flashWaitForSpecificMessage_loop1
  rjmp flash_recv_clc_ret                   ; timeout
  ; receive message
flashWaitForSpecificMessage_isLow:          ; is low, receive message, check for msg type
  push r17
    ldi r16, COM2_MAINTENANCE_ADDR
    ldi r17, FLASH_RECVBUFFER_MAXLEN-3
    ldi xl, LOW(flashRecvBuffer)
    ldi xh, HIGH(flashRecvBuffer)
    rcall com2ReceivePacketRaw
  pop r17
  brcc flashWaitForSpecificMessage_waitAttnHigh
  ldi xl, LOW(flashRecvBuffer)
  ldi xh, HIGH(flashRecvBuffer)
  adiw xh:xl, COM2_MSG_OFFS_CMD
  ld r16, X
  sbiw xh:xl, COM2_MSG_OFFS_CMD
  cp r16, r1
  breq flashWaitForSpecificMessage_received
  cpi r16, CPRO_CMD_FLASH_END
  breq flashWaitForSpecificMessage_received

flashWaitForSpecificMessage_waitAttnHigh:
  dec r17
  breq flash_recv_clc_ret
  ; wait for ATTN to go high
flashWaitForSpecificMessage_loop2:
    ldi r16, 0xff                           ; wait for high
    rcall flashWaitForAttnState1ms          ; (R22, R24)
    brcs flashWaitForSpecificMessage_isHigh
    dec r17
  brne flashWaitForSpecificMessage_loop2
  rjmp flash_recv_clc_ret                   ; timeout

flashWaitForSpecificMessage_isHigh:
  rjmp flashWaitForSpecificMessage_loop0
flashWaitForSpecificMessage_received:       ; R16 contains message type
  sec
  ret



; ---------------------------------------------------------------------------
; Wait for up to 1ms for ATTN line to reach the given state
;
; IN:
; - R16: expected state (0xff for high, 0 for low)
; OUT:
; - CFLAG: set if state reached, cleared otherwise
; REGS: R24 (R22)

flashWaitForAttnState1ms:
  ldi r24, 100
flashWaitForAttnState1ms_loop:
    push r17
      in r17, COM_PIN_ATTN
      eor r17, r16
      andi r17, (1<<COM_PINNUM_ATTN)
    pop r17
    breq flashWaitForAttnState1ms_stateReached

    Utils_WaitNanoSecs 10000, 0, r22              ; wait for 10us
    dec r24
  brne flashWaitForAttnState1ms_loop
  rjmp flash_recv_clc_ret
flashWaitForAttnState1ms_stateReached:
  sec
  ret


flash_recv_clc_ret:
  clc
flash_recv_ret:
  ret


