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






.equ CPRO_PACKET_FLASH_START_OFFS_MSGNUM = COM_MSG_OFFS_PAYLOAD+0 ; 2 bytes
.equ CPRO_PACKET_FLASH_START_OFFS_ADDR   = COM_MSG_OFFS_PAYLOAD+2 ; 2 bytes

.equ CPRO_PACKET_FLASH_ADDR_OFFS_MSGNUM  = COM_MSG_OFFS_PAYLOAD+0 ; 2 bytes
.equ CPRO_PACKET_FLASH_ADDR_OFFS_ADDR    = COM_MSG_OFFS_PAYLOAD+2 ; 2 bytes

.equ CPRO_PACKET_FLASH_DATA_OFFS_MSGNUM  = COM_MSG_OFFS_PAYLOAD+0 ; 2 bytes
.equ CPRO_PACKET_FLASH_DATA_OFFS_DATA    = COM_MSG_OFFS_PAYLOAD+2 ; 2 bytes

.equ CPRO_FLASH_ERROR_NONE       = 0
.equ CPRO_FLASH_ERROR_BAD_MSGNUM = 1
.equ CPRO_FLASH_ERROR_BAD_ADDR   = 2



; ***************************************************************************
; data


.dseg

flashDataBegin:
  flashCurrentAddress:     .byte 2
  flashLastReceivedMsg:    .byte 2
flashDataEnd:




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


.cseg




; ---------------------------------------------------------------------------
; Enqueue a FLASHDATA_ACK packet.
;
; IN:
; - R16: destination address
; - R17: response code (0 if ok, error code otherwise)
; - R19:R18: msg num
; OUT:
; - CFLAG: set if okay, clear otherwise
; MODIFIED REGS: R6, R7, R8, R9, R10, R11, R12, R16, R17, X, Y (R3, R4, R15, R16, R17, R18, R19, R20, R21)

CPRO_EnqueueFlashRsp:
  mov r6, r16
  mov r7, r17
  mov r8, r18
  mov r9, r19

  rcall COM_AllocBufferAndGetXY ; (r16, r17, r21)
  brcc CPRO_EnqueueFlashRsp_error

  push xh
    push xl
      mov r16, r6
      ldi r17, CPRO_PAYLOAD_FLAGS_SECONDS | (3<<CPRO_PAYLOAD_FLAGS_SHIFT_NUM)
      ldi r18, CPRO_CMD_FLASH_RSP
      rcall cproBeginMsgWithVariablePayload  ; (R3, R4, R16, R17, R18, R19, R20, R21, X)
      st X+, r8                              ; 4: msg num (low)
      st X+, r9                              ; 5: msg num (high)
      st X+, r7                              ; 6: ACK or NAK
    pop xl
  pop xh
  rcall comCalcAndAddChecksumByte

  ; mark buffer as enqueued with PRIO "important" (higher number of retries)
  ldi r20, COM_BUFFER_PRIO_IMPORTANT
  rcall COM_EnqueuePacket      ; (R15, R16)
  brcc CPRO_EnqueueFlashRsp_error
  sec
  ret
CPRO_EnqueueFlashRsp_error:
  clc
  ret



; ---------------------------------------------------------------------------
; Handle "FLASH_START" packet.
;
; IN:
; - Y  : pointer to received buffer
; OUT:
; - CFLAG: set if handled, cleared otherwise
;

CPRO_HandleFlashStart:
  ldd r21, y+(COM_BUFFER_OFFS_DATA+COM_MSG_OFFS_SRCADDR)  ; source address for later
  
  ; check message number
  ldi r20, CPRO_FLASH_ERROR_BAD_MSGNUM          ; preset error code
  ldd r16, y+(COM_BUFFER_OFFS_DATA+CPRO_PACKET_FLASH_START_OFFS_MSGNUM)
  ldd r17, y+(COM_BUFFER_OFFS_DATA+CPRO_PACKET_FLASH_START_OFFS_MSGNUM)+1
  tst r17
  brne CPRO_HandleFlashStart_respond            ; high byte of first message number should be 0
  cpi r16, 1
  brne CPRO_HandleFlashStart_respond            ; low byte of first message number should be 1
  
  lds r16, flashLastReceivedMsg
  lds r17, flashLastReceivedMsg+1
  or r16, r17
  brne CPRO_HandleFlashStart_respond            ; should be 0, otherwise operation already in progress
  
  sts flashLastReceivedMsg+1, r16               ; high byte: 0
  ldi r16, 1
  sts flashLastReceivedMsg, r16                 ; low byte: 1

  ; check address
  ldi r20, CPRO_FLASH_ERROR_BAD_ADDR            ; preset error code
  ldd r16, y+(COM_BUFFER_OFFS_DATA+CPRO_PACKET_FLASH_START_OFFS_ADDR)
  ldd r17, y+(COM_BUFFER_OFFS_DATA+CPRO_PACKET_FLASH_START_OFFS_ADDR)+1
  mov r18, r16
  mov r19, r17
  subi r18, LOW(AQHOME_FW_START_ADDRESS_MAIN)   ; below start of main firmware?
  sbci r19, HIGH(AQHOME_FW_START_ADDRESS_MAIN)
  brcs CPRO_HandleFlashStart_respond

  ; store address
  sts flashCurrentAddress, r16
  sts flashCurrentAddress+1, r17
  clr r20                                       ; set response code to 0
  ; fall through
CPRO_HandleFlashStart_respond:
  mov r16, r21 ; dest addr
  mov r17, r20 ; response
  lds r18, flashLastReceivedMsg
  lds r19, flashLastReceivedMsg+1
  rcall CPRO_EnqueueFlashRsp
  sec ; message handled
  ret






