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

#ifndef AVR_MODULES_COM2W_COM2WN_SEND_H
#define AVR_MODULES_COM2W_COM2WN_SEND_H


; WORK IN PROGRESS



.cseg



; ---------------------------------------------------------------------------
; @routine com2wnSendMsg
;
; @param X pointer to bytes to send
; @param Y pointer to interface data in SRAM
; @return CFLAG set if message sent, cleared otherwise
; @clobbers R16, R18 (R20, R22, R24, R25, X)

com2wnSendMsg:
  ldi r20, 6                             ; wait for about 60us for clock low
  rcall com2wWaitForClockLowMulti10Us    ; (R16, R20, R22)
  brcs com2wnSendMsg_busy                ; CLK got low while waiting, so line is busy
  push r15
    in r15, SREG
    cli                                  ; atomic disable irq and set CLK low
    rcall com2wnDisableClkIrq            ; (none)
    rcall com2wnClkSetLow                ; reserve bus (none)
    out SREG, r15
  pop r15
  adiw xh:xl, NETMSG_OFFS_MSGLEN
  ld r18, X
  sbiw xh:xl, NETMSG_OFFS_MSGLEN
  inc r18                                ; adjust for DESTADDR
  inc r18                                ; adjust for MSGLEN
  inc r18                                ; adjust for CRCBYTE
  rcall com2wnWaitTime1                   ; longer wait period (R22)
  rcall com2wnSendBytes                   ; (r16, r17, r18, r22, X)
  rcall com2wClkSetHigh                  ; make sure bus is released
  rcall com2wnDataSetHigh

  rcall com2wnEnableClkIrq               ; (none)
  ldi r16, NET_IFACE_OFFS_PACKETSOUT_LOW
  rcall NET_Interface_IncCounter16       ; (R24, R25)
  sec
  ret
com2wnSendMsg_busy:
  ldi r16, NET_IFACE_OFFS_ERR_BUSY_LOW
  rcall NET_Interface_IncCounter16       ; (R24, R25)
  clc
  ret
; @end



; ---------------------------------------------------------------------------
; @routine com2wnSendBytes
;
; @param  R18 number of bytes to send
; @param X pointer to bytes to send
; @param Y pointer to interface data in SRAM
; @clobbers: r16, r18, X (r17, r22)

com2wnSendBytes:
com2wnSendBytes_loop:
    rcall com2wnClkSetLow                      ; (none)
    rcall com2wnWaitTime1                      ; longer wait period (R22)
    ld r16, X+
    rcall com2wnSendByte                       ; (R16, R17, R22)
    dec r18
  brne com2wnSendBytes_loop
  ret
; @end



; ---------------------------------------------------------------------------
; @routine com2wnSendByte
;
; @param R16 byte to send
; @param Y pointer to interface data in SRAM
; @clobbers r16, r17 (r22)

com2wnSendByte:
  ldi r17, 8
com2wnSendByte_loop:
    rcall com2wnClkSetLow
    rcall com2wnWaitTime1                       ; longer wait period (R22)
    lsr r16
    brcs com2wnSendByte_send1
    rcall com2wnDataSetLow
    rjmp com2wnSendByte_sent
com2wnSendByte_send1:
    rcall com2wnDataSetHigh
com2wnSendByte_sent:
    rcall com2wnWaitTime2                       ; shorter wait period (R22)
    push r15
      in r15, SREG
      cli                                       ; ensure time period by disabling irqs
      rcall com2wClkSetHigh
      rcall com2wnWaitTime1                     ; longer wait period (R22)
      out SREG, r15
    pop r15
    dec r17
  brne com2wnSendByte_loop
  ret
; @end



; ---------------------------------------------------------------------------
; @routine com2wnWaitTime1
;
; waits for longer period (e.g. 30ns)
;
; @clobbers R22

com2wnWaitTime1:
  Utils_WaitNanoSecs COM2W_WAITTIME1, 7, r22            ; wait for longer time (minus RCALL and RET)
  ret
; @end



; ---------------------------------------------------------------------------
; @routine com2wnWaitTime2
;
; waits for shorter period (e.g. 10ns)
;
; @clobbers R22

com2wnWaitTime2:
  Utils_WaitNanoSecs COM2W_WAITTIME2, 7, r22            ; wait for shorter time (minus RCALL and RET)
  ret
; @end







#endif ; AVR_MODULES_COM2W_COM2WN_SEND_H

