274 lines
7.1 KiB
NASM
274 lines
7.1 KiB
NASM
; ***************************************************************************
|
|
; 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. *
|
|
; ***************************************************************************
|
|
|
|
|
|
; ***************************************************************************
|
|
; defines
|
|
|
|
|
|
|
|
|
|
; ***************************************************************************
|
|
; data
|
|
|
|
.dseg
|
|
|
|
|
|
netUartIface: .byte UART_HW_IFACE_SIZE
|
|
|
|
|
|
|
|
; ***************************************************************************
|
|
; code
|
|
|
|
.cseg
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine ComOnUart0_Init @global
|
|
;
|
|
|
|
NET_Uart_Init:
|
|
ldi yl, LOW(netUartIface)
|
|
ldi yh, HIGH(netUartIface)
|
|
rcall UART_HW_Interface_Init
|
|
rcall UART_Init
|
|
rcall ATTN_Init
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine NET_Uart_Periodically
|
|
;
|
|
; @clobbers all, !Y
|
|
|
|
NET_Uart_Every100ms:
|
|
ldi yl, LOW(netUartIface)
|
|
ldi yh, HIGH(netUartIface)
|
|
push r15
|
|
in r15, SREG
|
|
cli
|
|
rcall NET_Interface_Periodically ; (R16)
|
|
rcall netUartSendNextPkg
|
|
out SREG, r15
|
|
pop r15
|
|
ret
|
|
rjmp NET_Interface_Periodically
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine netUartSendNextPkg
|
|
;
|
|
; Check whether there is an outgoing message in interface data
|
|
; and send it if possible.
|
|
;
|
|
; @return CFLAG set if okay, clear on error
|
|
; @param Y pointer to start of interface data
|
|
; @clobbers R16, R17, R18, R21, R21, R24, R25, X
|
|
|
|
netUartSendNextPkg:
|
|
rcall NET_Interface_PeekNextOutgoingMsgNum ; (R17, R18, X)
|
|
brcc netUartSendNextPkg_end
|
|
rcall NET_Buffer_Locate ; get pointer to buffer (R17)
|
|
brcc netUartSendNextPkg_end
|
|
adiw xh:xl, 1 ; skip buffer header
|
|
rcall netUartSendPacketWithAttn ; (R16, R17, R21, R22, X)
|
|
brcc netUartSendNextPkg_error
|
|
rcall NET_Interface_GetNextOutgoingMsgNum ; remove from stack (R17, R18, X)
|
|
rcall NET_Buffer_ReleaseByNum ; release buffer (R16, X)
|
|
ldi r16, NET_IFACE_OFFS_PACKETSOUT_LOW
|
|
rcall NET_Interface_IncCounter16 ; (R24, R25)
|
|
sec
|
|
rjmp netUartSendNextPkg_end
|
|
netUartSendNextPkg_error:
|
|
rcall NET_Interface_IncCounter16 ; (R24, R25)
|
|
clc
|
|
netUartSendNextPkg_end:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine netUartSendPacket
|
|
;
|
|
; @param X buffer to send
|
|
; @return CFLAG set if okay, cleared on error
|
|
; @return R16 error code (if CFLAG cleared)
|
|
; @clobbers R16, R17, R22, X
|
|
|
|
netUartSendPacketWithAttn:
|
|
rcall ATTN_IsHigh
|
|
ldi r16, NET_IFACE_OFFS_ERR_BUSY_LOW
|
|
brcc netUartSendPacketWithAttn_end ; ATTN low, jmp
|
|
|
|
rcall ATTN_SetLowDisableIrq ; reserve bus (R16)
|
|
Utils_WaitNanoSecs COM_BIT_LENGTH, 0, r22 ; wait for one bit duration
|
|
Utils_WaitNanoSecs COM_BIT_LENGTH, 0, r22 ; wait for one bit duration
|
|
rcall netUartSendPacket
|
|
rcall ATTN_SetHighEnableIrq ; release bus
|
|
sec
|
|
netUartSendPacketWithAttn_end:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine netUartSendPacket
|
|
;
|
|
; @param X buffer to send
|
|
; @clobbers R17 (R16, X)
|
|
|
|
netUartSendPacket:
|
|
adiw xh:xl, NETMSG_OFFS_MSGLEN
|
|
ld r17, X
|
|
inc r17
|
|
inc r17
|
|
inc r17
|
|
sbiw xh:xl, NETMSG_OFFS_MSGLEN
|
|
rjmp UART_SendBytes ; (R16, R17, X)
|
|
; @end
|
|
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine netUartRecvPacket
|
|
;
|
|
; alloc a buffer, receive message, add message to global list
|
|
; @param Y pointer to start of interface data
|
|
; @return CFLAG set if okay, cleared on error
|
|
; @clobbers R16, R17, R18, R19, R20, R24, R25, X
|
|
|
|
netUartRecvPacket:
|
|
rcall UART_StartRx ; (R16)
|
|
rcall NET_Buffer_Alloc ; (R16, R17, X)
|
|
brcs netUartRecvPacket_haveBuf
|
|
rcall UART_StopRx ; (R16)
|
|
ldi r16, NET_IFACE_OFFS_ERR_NOBUF_LOW
|
|
rjmp netUartRecvPacket_incCounterRet
|
|
netUartRecvPacket_haveBuf:
|
|
push r16
|
|
adiw xh:xl, 1
|
|
ldd r18, Y+NET_IFACE_OFFS_ADDRESS
|
|
ldi r17, NET_BUFFERS_SIZE-1
|
|
rcall netUartRecvPacketIntoX ; (R16, R17, R18, R19, R20, R24, R25)
|
|
pop r16
|
|
brcc netUartRecvPacket_releaseBufRet
|
|
rcall NET_AddIncomingMsgNum ; (R17, R18, X)
|
|
brcc netUartRecvPacket_releaseBufRet
|
|
rcall UART_StopRx ; (R16)
|
|
sec
|
|
ret
|
|
netUartRecvPacket_releaseBufRet:
|
|
rcall NET_Buffer_ReleaseByNum ; (R16, X)
|
|
ldi r16, NET_IFACE_OFFS_ERR_NOBUF_LOW
|
|
netUartRecvPacket_incCounterRet:
|
|
rcall NET_Interface_IncCounter16 ; (R24, R25)
|
|
rcall UART_StopRx ; (R16)
|
|
netUartRecvPacket_retNc:
|
|
clc
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine netUartRecvPacketIntoX
|
|
;
|
|
; @param Y pointer to start of interface data
|
|
; @param X pointer buffer (in RAM)
|
|
; @param r17 maximum number of bytes to receive
|
|
; @param r18 network address to listen to
|
|
; @return CFLAG set if okay, cleared on error
|
|
; @clobbers R16, R17, R18, R19, R20, R24, R25
|
|
|
|
netUartRecvPacketIntoX:
|
|
push xh
|
|
push xl
|
|
rcall UART_RecvPacket ; (r16, r17, X)
|
|
pop xl
|
|
pop xh
|
|
brcc netUartRecvPacketIntoX_handleError
|
|
push xl
|
|
push xh
|
|
rcall NETMSG_CheckMessageInBuffer ; (R16, R17, R18, R19, R20, X)
|
|
pop xh
|
|
pop xl
|
|
brcc netUartRecvPacketIntoX_contentError
|
|
ldi r16, NET_IFACE_OFFS_PACKETSIN_LOW
|
|
rcall NET_Interface_IncCounter16 ; (R24, R25)
|
|
sec
|
|
ret
|
|
netUartRecvPacketIntoX_handleError:
|
|
mov r17, r16
|
|
cpi r17, UART_ERROR_IO
|
|
ldi r16, NET_IFACE_OFFS_ERR_IO_LOW
|
|
breq netUartRecvPacketIntoX_incCounterRetNc
|
|
cpi r17, UART_ERROR_CONTENT
|
|
breq netUartRecvPacketIntoX_contentError
|
|
rjmp netUartRecvPacketIntoX_retNc
|
|
netUartRecvPacketIntoX_contentError:
|
|
ldi r16, NET_IFACE_OFFS_ERR_CONTENT_LOW
|
|
netUartRecvPacketIntoX_incCounterRetNc:
|
|
rcall NET_Interface_IncCounter16 ; (R24, R25)
|
|
netUartRecvPacketIntoX_retNc:
|
|
clc
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine NetUart_AttnChangeIsr @global @isr
|
|
;
|
|
; @clobbers none
|
|
|
|
NetUart_AttnChangeIsr:
|
|
push r15
|
|
in r15, SREG
|
|
push r16
|
|
push r17
|
|
push r18
|
|
push r19
|
|
push r20
|
|
push r24
|
|
push r25
|
|
push xl
|
|
push xh
|
|
push yl
|
|
push yh
|
|
ldi yl, LOW(netUartIface)
|
|
ldi yh, HIGH(netUartIface)
|
|
rcall netUartRecvPacket ; (R16, R17, R18, R19, R20, R24, R25, X)
|
|
pop yh
|
|
pop yl
|
|
pop xh
|
|
pop xl
|
|
pop r25
|
|
pop r24
|
|
pop r20
|
|
pop r19
|
|
pop r18
|
|
pop r17
|
|
pop r16
|
|
out SREG, r15
|
|
pop r15
|
|
reti
|
|
; @end
|
|
|
|
|
|
|