From 41843cbab90620a35159563f0c3fb8c4287ac054 Mon Sep 17 00:00:00 2001 From: Martin Preuss Date: Mon, 25 Aug 2025 14:12:39 +0200 Subject: [PATCH] avr: added forwarder app. simpler than router app, just for forwarding messages between interfaces. mainly used by t03. --- avr/apps/0BUILD | 1 + avr/apps/forwarder/0BUILD | 15 ++ avr/apps/forwarder/main.asm | 359 +++++++++++++++++++++++++++++++++++ avr/devices/all/apps.asm | 16 +- avr/devices/all/includes.asm | 8 + avr/devices/all/main.asm | 4 + 6 files changed, 402 insertions(+), 1 deletion(-) create mode 100644 avr/apps/forwarder/0BUILD create mode 100644 avr/apps/forwarder/main.asm diff --git a/avr/apps/0BUILD b/avr/apps/0BUILD index 29dc20d..3db3ca4 100644 --- a/avr/apps/0BUILD +++ b/avr/apps/0BUILD @@ -11,6 +11,7 @@ stats router hub + forwarder diff --git a/avr/apps/forwarder/0BUILD b/avr/apps/forwarder/0BUILD new file mode 100644 index 0000000..593fe80 --- /dev/null +++ b/avr/apps/forwarder/0BUILD @@ -0,0 +1,15 @@ + + + + + + + + + main.asm + + + + + + diff --git a/avr/apps/forwarder/main.asm b/avr/apps/forwarder/main.asm new file mode 100644 index 0000000..c7a5696 --- /dev/null +++ b/avr/apps/forwarder/main.asm @@ -0,0 +1,359 @@ +; *************************************************************************** +; 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 + +; --------------------------------------------------------------------------- +; network interfaces + +.equ NETDEV0_IFACENUM = 1 +.equ NETDEV1_IFACENUM = 2 + + + +; *************************************************************************** +; data + +.dseg + +; nothing so far + + + +; *************************************************************************** +; code + +.cseg + +; --------------------------------------------------------------------------- +; @routine AppForwarder_Init @global + +AppForwarder_Init: + ; set interface number for NETDEV0 + ldi r16, NETDEV0_IFACENUM + sts netInterfaceData+NET_IFACE_OFFS_IFACENUM, r16 + ; set interface number for NETDEV1 + ldi r16, NETDEV1_IFACENUM + sts netInterfaceData2+NET_IFACE_OFFS_IFACENUM, r16 + sec + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine AppForwarder_EveryDay @global +; +; @clobbers R16, R17, X + +AppForwarder_EveryDay: + ldi yl, LOW(netInterfaceData) + ldi yh, HIGH(netInterfaceData) + bigcall NET_Interface_ResetStats ; (R16, R17, X) + + ldi yl, LOW(netInterfaceData2) + ldi yh, HIGH(netInterfaceData2) + bigcall NET_Interface_ResetStats ; (R16, R17, X) + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine AppForwarder_Run @global +; +; Read messages from either interface and forward to the other one. + +AppForwarder_Run: + rjmp appForwarderCheckRecvdMsg +; @end + + + +; --------------------------------------------------------------------------- +; @routine appForwarderCheckRecvdMsg +; +; Read messages from either interface and forward to the other one. +; @return CFLAG set if something done, cleared otherwise +; @clobbers any + +appForwarderCheckRecvdMsg: + rcall NET_PeekNextIncomingMsgNum ; check read queue (bufNum->r16) + brcc appForwarderCheckRecvdMsg_ret ; no msg, jmp + rcall NET_Buffer_Locate ; (R17) + push r16 + ld r16, X ; read buffer header + andi r16, 0x0f ; keep interface number (in low nibble) + rcall appForwarderGetDeviceByIfaceNum ; Y=src interface (R17) + pop r16 + brcc appForwarderCheckRecvdMsg_ret ; interface not found + adiw xh:xl, 1 ; point to message begin + + push r16 + rcall appForwarderHandleMsgAnyDev ; check for message we should handle (ping etc) + pop r16 + + ; let system handle incoming messages + push r16 + rcall appForwarderLetSysHandleMsg + pop r16 + + ; forward to other interface + ldd r17, Y+NET_IFACE_OFFS_IFACENUM + rcall appForwarderSendToOtherDev + brcc appForwarderCheckRecvdMsg_ret ; could not add, jmp + rcall NET_GetNextIncomingMsgNum ; take off the queue + sec +appForwarderCheckRecvdMsg_ret: + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine appForwarderHandleMsgAnyDev @global +; +; @param Y pointer to source interface for the message +; @param X pointer to received message +; @return CFLAG set if msg handled, cleared otherwise +; @clobbers any, !X + +appForwarderHandleMsgAnyDev: + push xl + push xh + rcall appForwarderHandleMsgAnyDev_savedX + pop xh + pop xl + rjmp appForwarderHandleMsgAnyDev_end +appForwarderHandleMsgAnyDev_savedX: + adiw xh:xl, NETMSG_OFFS_CMD ; maybe move ping/reboot handling to all/main.asm? + ld r16, X + sbiw xh:xl, NETMSG_OFFS_CMD + cpi r16, NETMSG_CMD_REBOOT_REQUEST + breq appForwarderHandleMsgAnyDev_handleRebootMsg + cpi r16, NETMSG_CMD_PING + breq appForwarderHandleMsgAnyDev_handlePingMsg + cpi r16, NETMSG_CMD_CLAIM_ADDRESS + breq appForwarderHandleMsgAnyDev_handleClaimAddr + rjmp appForwarderHandleMsgAnyDev_clcRet +appForwarderHandleMsgAnyDev_handleRebootMsg: + rcall appForwarderHandleRebootRequest + ret +appForwarderHandleMsgAnyDev_handlePingMsg: + rcall appForwarderHandlePingRequest + clc + ret +appForwarderHandleMsgAnyDev_handleClaimAddr: + rcall appForwarderHandleClaimAddrRequest + clc + ret +appForwarderHandleMsgAnyDev_clcRet: + clc +appForwarderHandleMsgAnyDev_end: + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine appForwarderHandleClaimAddrRequest +; +; @param X pointer to received message +; @param Y pointer to source interface for the message +; @clobbers + +appForwarderHandleClaimAddrRequest: + rcall NETMSG_Address_Read ; R18=cmd, R19=addr(R18, R19) + lds r16, netInterfaceData+NET_IFACE_OFFS_ADDRESS + cp r19, r16 + brne appForwarderHandleClaimAddrRequest_ret + ldi r18, NETMSG_CMD_DENY_ADDRESS ; deny addr + rcall appForwarderSendAddrMsg ; (R16, R17, R18, R19, R20, R21, X, Y) +appForwarderHandleClaimAddrRequest_ret: + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine appForwarderSendAddrMsg +; +; @param R18 command +; @param R19 address to send +; @param Y pointer to interface to send to +; @clobbers R16 (R17, R18, R19, R20, R21, X, Y) + +appForwarderSendAddrMsg: + bigcall NET_Buffer_Alloc ; (R16, R17, X) + brcc appForwarderSendAddrMsg_end + push r16 + adiw xh:xl, 1 + bigcall NETMSG_Address_Write ; (R16, R17, R18, R19, R20, R21) + sbiw xh:xl, 1 + pop r16 + bigcall NET_Interface_AddOrReleaseOutMsg ; (R16, R17, R18, X) +appForwarderSendAddrMsg_end: + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine appForwarderHandleRebootRequest +; +; Doesn't return if reboot msg is valid. +; +; @param X pointer to received message + +appForwarderHandleRebootRequest: + rcall NETMSG_RebootRequestRead + brcc appForwarderHandleRebootRequest_end + ; reboot + cli + bigjmp BOOTLOADER_ADDR +appForwarderHandleRebootRequest_end: + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine appForwarderHandlePingRequest +; +; @param X pointer to received message +; @param Y pointer to source interface for the message + +appForwarderHandlePingRequest: + ld r17, X + lds r16, (netInterfaceData+NET_IFACE_OFFS_ADDRESS) + cp r16, r17 + breq appForwarderHandlePingRequest_forMe + cpi r17, 0xff + breq appForwarderHandlePingRequest_forMe + clc + rjmp appForwarderHandlePingRequest_end +appForwarderHandlePingRequest_forMe: + adiw xh:xl, NETMSG_OFFS_SRCADDR + ld r17, X + sbiw xh:xl, NETMSG_OFFS_SRCADDR + push r17 + bigcall NET_Buffer_Alloc ; (R16, R17, X) + pop r17 + brcc appForwarderHandlePingRequest_end ; jmp on error + push r16 ; buffer num + mov r16, r17 ; DEST addr + adiw xh:xl, 1 + bigcall NETMSG_Pong_Write ; (R16, R17, R18, R19, R20, X) + sbiw xh:xl, 1 + pop r16 ; buffer num + bigcall NET_Interface_AddOrReleaseOutMsg ; (R16, R17, R18, X) +appForwarderHandlePingRequest_end: + ret + + + + + +; --------------------------------------------------------------------------- +; @routine appForwarderLetSysHandleMsg +; +; @param X pointer to msg to handle (point behind the buffer header!) +; @param Y pointer to source interface for the message +; @clobbers any, !X + +appForwarderLetSysHandleMsg: + ld r16, X + cpi r16, 0xff + breq appForwarderLetSysHandleMsg_forMe + lds r17, netInterfaceData+NET_IFACE_OFFS_ADDRESS + cp r16, r17 + brne appForwarderLetSysHandleMsg_end +appForwarderLetSysHandleMsg_forMe: + push xl + push xh + rcall onMessageReceived + pop xh + pop xl + push xl + push xh + rcall mainModulesOnPacketReceived + pop xh + pop xl + push xl + push xh + rcall mainAppsOnPacketReceived + pop xh + pop xl +appForwarderLetSysHandleMsg_end: + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine appForwarderSendToOtherDev +; @param r16 buffer num +; @param r17 src interface num + +appForwarderSendToOtherDev: + ldi yl, LOW(netInterfaceData) + ldi yh, HIGH(netInterfaceData) + ldd r18, Y+NET_IFACE_OFFS_IFACENUM + andi r18, 0x0f + cp r18, r17 + breq appForwarderSendToAllDevsBut_check2 + bigcall NET_Interface_AddOutgoingMsgNum ; (R17, R18, X) + rjmp appForwarderSendToOtherDev_ret +appForwarderSendToAllDevsBut_check2: + ldi yl, LOW(netInterfaceData2) + ldi yh, HIGH(netInterfaceData2) + ldd r18, Y+NET_IFACE_OFFS_IFACENUM + andi r18, 0x0f + cp r18, r17 + breq appForwarderSendToOtherDev_ret + bigcall NET_Interface_AddOutgoingMsgNum ; (R17, R18, X) +appForwarderSendToOtherDev_ret: + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine appForwarderGetDeviceByIfaceNum +; +; @param r16 interface number +; @return CFLAG set if interface found (cleared otherwise) +; @return Y pointer to interface with given number +; @clobbers r17 + +appForwarderGetDeviceByIfaceNum: + ldi yl, LOW(netInterfaceData) + ldi yh, HIGH(netInterfaceData) + ldd r17, Y+NET_IFACE_OFFS_IFACENUM + cp r16, r17 + breq appForwarderGetDeviceByIfaceNum_secRet + ldi yl, LOW(netInterfaceData2) + ldi yh, HIGH(netInterfaceData2) + ldd r17, Y+NET_IFACE_OFFS_IFACENUM + cp r16, r17 + breq appForwarderGetDeviceByIfaceNum_secRet + clc + rjmp appForwarderGetDeviceByIfaceNum_ret +appForwarderGetDeviceByIfaceNum_secRet: + sec +appForwarderGetDeviceByIfaceNum_ret: + ret +; @end + + + + diff --git a/avr/devices/all/apps.asm b/avr/devices/all/apps.asm index 1cc7ebe..ca63ec3 100644 --- a/avr/devices/all/apps.asm +++ b/avr/devices/all/apps.asm @@ -37,6 +37,10 @@ initApps: bigcall AppHub_Init #endif +#ifdef APPS_FORWARDER + bigcall AppForwarder_Init +#endif + #ifdef APPS_MOTION bigcall AppMotion_Init #endif @@ -79,7 +83,17 @@ runApps: #endif #ifdef APPS_HUB - bigcall AppHub_Run + push r16 + bigcall AppHub_Run + pop r16 + sbci r16, 0 ; decrease r16 only if CFLAG set +#endif + +#ifdef APPS_FORWARDER + push r16 + bigcall AppForwarder_Run + pop r16 + sbci r16, 0 ; decrease r16 only if CFLAG set #endif ; add more modules here diff --git a/avr/devices/all/includes.asm b/avr/devices/all/includes.asm index bbbf16e..e765f78 100644 --- a/avr/devices/all/includes.asm +++ b/avr/devices/all/includes.asm @@ -336,6 +336,14 @@ #endif +#ifdef APPS_FORWARDER +.include "apps/forwarder/main.asm" +.include "modules/network/msg/reboot-r.asm" +.include "modules/network/msg/reboot-d.asm" +.include "modules/network/msg/pong-w.asm" +#endif + + #ifdef APPS_REPORTSENSORS .include "apps/reportsensors/data.asm" .include "apps/reportsensors/main.asm" diff --git a/avr/devices/all/main.asm b/avr/devices/all/main.asm index b31182b..0e5d96e 100644 --- a/avr/devices/all/main.asm +++ b/avr/devices/all/main.asm @@ -250,6 +250,10 @@ sysOnEveryDay: bigcall AppRouter_EveryDay #endif +#ifdef APPS_FORWARDER + bigcall AppForwarder_EveryDay +#endif + bigjmp onEveryDay ; @end