; *************************************************************************** ; 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_noAddMsg: rcall NET_Buffer_ReleaseByNum ; (R16, X) ldi r16, NET_IFACE_OFFS_ERR_MISSED_LOW rjmp netUartRecvPacket_incCounterRet 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: cpi r16, UART_ERROR_IO breq netUartRecvPacketIntoX_ioError cpi r16, UART_ERROR_CONTENT breq netUartRecvPacketIntoX_contentError rjmp netUartRecvPacketIntoX_retNc netUartRecvPacketIntoX_ioError: ldi r16, NET_IFACE_OFFS_ERR_IO_LOW rjmp netUartRecvPacketIntoX_incCounterRetNc 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