Files
aqhomecontrol/avr/modules/uart_hw/net_uart.asm
2025-05-20 00:31:12 +02:00

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