41 Commits

Author SHA1 Message Date
Martin Preuss
ae1e4c3e37 avr: bootloader works with new com2w code. 2025-07-20 00:05:53 +02:00
Martin Preuss
78cbbf334e com2w: alloc buffer after receiving message. receiving works now. 2025-07-19 17:47:52 +02:00
Martin Preuss
c8c12bb892 t03: use router app. 2025-07-19 17:08:39 +02:00
Martin Preuss
ae1853ba62 enable sending messages. 2025-07-19 17:08:19 +02:00
Martin Preuss
e8423ae97f check dest address for ping requests. 2025-07-19 17:07:52 +02:00
Martin Preuss
597504fb08 t03: added test firmware. 2025-07-19 15:02:46 +02:00
Martin Preuss
59a0962420 added com2w0 2025-07-19 15:02:31 +02:00
Martin Preuss
323a5b76be sync test. 2025-07-19 09:48:56 +02:00
Martin Preuss
b7234a6da2 start using new COM module in n27, r05 and t03. 2025-07-19 09:47:23 +02:00
Martin Preuss
4a5ba97b85 increase buffer size. 2025-07-19 09:46:06 +02:00
Martin Preuss
bdd710fc5c avr: started working on new SPI-like COM protocol.
use a clock and a data line to introduce synchronisation into the
protocol to be able to work with the wide range of mcu speeds (no need for
exact timing, no need for exact calibration).
2025-07-19 09:42:02 +02:00
Martin Preuss
535a695c50 limit number of loops inside main_runLoop. 2025-07-12 20:16:34 +02:00
Martin Preuss
357ffe4e17 comonuartX: handle multiple messages in one run.
still there are NOBUF errors...
2025-07-12 20:09:40 +02:00
Martin Preuss
349b4a929a use in instead of inr (SREG is always inside normal io space). 2025-07-12 20:08:54 +02:00
Martin Preuss
a06d245345 r05: disable OWI and ds18b20 modules (no time to handle those), increase buffers 2025-07-12 20:08:30 +02:00
Martin Preuss
83225c453d Use uid to determine initial wait time after re-enum request. 2025-07-12 20:07:33 +02:00
Martin Preuss
fa94190345 fixed message description for FLASH_DATA. 2025-07-12 00:22:18 +02:00
Martin Preuss
68aa3beab8 incremented firmware version. 2025-07-12 00:21:59 +02:00
Martin Preuss
3cd23d5f60 reduce size of net buffers from 32 to 28.
allows us to use 10 buffers in R05.
2025-07-12 00:21:47 +02:00
Martin Preuss
003f53b0b7 added READMEs 2025-07-11 23:25:19 +02:00
Martin Preuss
c1ea4212f2 Moved NET_BUFFERS_SIZE to network/defs.asm
- Changing this value requires changing the routine NET_Buffer_Locate
  so its best to keep both in one module.
- Redefining it in the individual devices doesn't change the code in
  NET_Buffer_Locate
2025-07-11 23:25:10 +02:00
Martin Preuss
3283a38981 Release 0.9.12. 2025-07-11 23:22:09 +02:00
Martin Preuss
3054274da5 Fixed stats value list. 2025-07-11 23:21:50 +02:00
Martin Preuss
2d84198e54 incremented version. 2025-07-07 21:53:59 +02:00
Martin Preuss
f3544f5e93 fixed apidoc. 2025-07-07 21:53:48 +02:00
Martin Preuss
04c02b5e33 fixed a bug. 2025-07-07 21:53:35 +02:00
Martin Preuss
b709b7e624 updated node doc. 2025-07-07 21:45:36 +02:00
Martin Preuss
8c397dd6b2 added missing includes. 2025-07-07 21:45:19 +02:00
Martin Preuss
6e923ce075 improved apidoc. 2025-07-07 21:44:54 +02:00
Martin Preuss
245d44c05d improved "run" code. 2025-07-07 21:44:40 +02:00
Martin Preuss
4f497fc41a removed unneeded code. 2025-07-07 21:43:41 +02:00
Martin Preuss
e32e8e7c13 use Eeprom_WriteByteIfChanged 2025-07-07 21:43:28 +02:00
Martin Preuss
f3020562bf incremented firmware version. 2025-07-07 16:06:31 +02:00
Martin Preuss
fbb710a4e3 added TLV code for EEPROM (not used for now). 2025-07-07 16:06:18 +02:00
Martin Preuss
cbd498150f avr: fully implemented router functionality in network and router app. 2025-07-07 16:05:53 +02:00
Martin Preuss
691ee3c71b incremented firmware version. 2025-07-06 20:22:38 +02:00
Martin Preuss
280d5828bf fixed a possible problem.
don't reboot on broadcast request.
2025-07-06 20:22:19 +02:00
Martin Preuss
6ecc1721b0 r05: no longer use APPS_NETWORK.
Implemented some of those features in APP_ROUTER like PING, REBOOT.
2025-07-06 20:21:51 +02:00
Martin Preuss
1824e8ccdf Increment packets-out counter. 2025-07-06 20:01:35 +02:00
Martin Preuss
0a45e38939 make router functionality of r05 an app. 2025-07-06 18:21:48 +02:00
Martin Preuss
81b008af0c r05, comOnUart0 and comOnUart1 work! 2025-07-06 17:19:59 +02:00
83 changed files with 5169 additions and 947 deletions

2
0BUILD
View File

@@ -2,7 +2,7 @@
<gwbuild>
<project name="aqhome" version="0.0.11" so_current="0" so_age="0" so_revision="11" write_config_h="TRUE">
<project name="aqhome" version="0.0.12" so_current="0" so_age="0" so_revision="12" write_config_h="TRUE">
<setVar name="package">$(project_name)</setVar>
<setVar name="version">
$(project_vmajor).$(project_vminor).$(project_vpatchlevel)

View File

@@ -62,6 +62,7 @@
m_flashend.h
m_flashready.h
m_flashresponse.h
m_range.h
</headers>
@@ -89,6 +90,7 @@
m_flashend.c
m_flashready.c
m_flashresponse.c
m_range.c
</sources>

View File

@@ -28,6 +28,7 @@
#include "aqhome/msg/node/m_flashend.h"
#include "aqhome/msg/node/m_flashready.h"
#include "aqhome/msg/node/m_flashresponse.h"
#include "aqhome/msg/node/m_range.h"
#include <gwenhywfar/text.h>
@@ -212,6 +213,7 @@ const char *AQH_NodeMessage_MsgTypeToChar(uint8_t i)
case AQH_MSG_TYPE_CLAIM_ADDRESS: return "ClaimAddress";
case AQH_MSG_TYPE_DENY_ADDRESS: return "DenyAddress";
case AQH_MSG_TYPE_ADDRESS_RANGE: return "Range";
case AQH_MSG_TYPE_REENUM: return "Reenum";
case AQH_MSG_TYPE_FLASH_START: return "FlashStart";
case AQH_MSG_TYPE_FLASH_END: return "FlashEnd";
@@ -246,6 +248,8 @@ void AQH_NodeMessage_DumpSpecificToBuffer(const AQH_MESSAGE *msg, GWEN_BUFFER *d
case AQH_MSG_TYPE_HAVE_ADDRESS: AQH_AddrMessage_DumpToBuffer(msg, dbuf, sText); break;
case AQH_MSG_TYPE_CLAIM_ADDRESS: AQH_AddrMessage_DumpToBuffer(msg, dbuf, sText); break;
case AQH_MSG_TYPE_DENY_ADDRESS: AQH_AddrMessage_DumpToBuffer(msg, dbuf, sText); break;
case AQH_MSG_TYPE_ADDRESS_RANGE: AQH_RangeMessage_DumpToBuffer(msg, dbuf, sText); break;
case AQH_MSG_TYPE_REENUM: AQH_RangeMessage_DumpToBuffer(msg, dbuf, sText); break;
case AQH_MSG_TYPE_FLASH_START: AQH_FlashStartMessage_DumpToBuffer(msg, dbuf, sText); break;
case AQH_MSG_TYPE_FLASH_END: AQH_FlashEndMessage_DumpToBuffer(msg, dbuf, sText); break;
@@ -266,7 +270,6 @@ void AQH_NodeMessage_DumpSpecificToBuffer(const AQH_MESSAGE *msg, GWEN_BUFFER *d
case AQH_MSG_TYPE_DEBUG:
case AQH_MSG_TYPE_TWIBUSMEMBER:
case AQH_MSG_TYPE_ADDRESS_RANGE:
default: AQH_NodeMessage_DumpToBuffer(msg, dbuf, sText); break;
}
}

View File

@@ -40,6 +40,7 @@
#define AQH_MSG_TYPE_CLAIM_ADDRESS 62
#define AQH_MSG_TYPE_DENY_ADDRESS 63
#define AQH_MSG_TYPE_ADDRESS_RANGE 64
#define AQH_MSG_TYPE_REENUM 65
#define AQH_MSG_TYPE_FLASH_START 70
#define AQH_MSG_TYPE_FLASH_END 71

61
aqhome/msg/node/m_range.c Normal file
View File

@@ -0,0 +1,61 @@
/****************************************************************************
* This file is part of the project AqHome.
* AqHome (c) by 2025 Martin Preuss, all rights reserved.
*
* The license for this file can be found in the file COPYING which you
* should have received along with this file.
****************************************************************************/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "aqhome/msg/node/m_range.h"
#include "aqhome/msg/node/m_node.h"
#include <gwenhywfar/debug.h>
#define AQH_MSG_OFFS_RANGE_UID 0 /* 4 bytes */
#define AQH_MSG_OFFS_RANGE_BEGIN 4 /* 1 bytes */
#define AQH_MSG_OFFS_RANGE_END 5 /* 1 bytes */
uint32_t AQH_RangeMessage_GetUid(const AQH_MESSAGE *msg)
{
return AQH_Message_ReadUint32At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_RANGE_UID, 0);
}
uint8_t AQH_RangeMessage_GetRangeBegin(const AQH_MESSAGE *msg)
{
return AQH_Message_ReadUint8At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_RANGE_BEGIN, 0);
}
uint8_t AQH_RangeMessage_GetRangeEnd(const AQH_MESSAGE *msg)
{
return AQH_Message_ReadUint8At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_RANGE_END, 0);
}
void AQH_RangeMessage_DumpToBuffer(const AQH_MESSAGE *msg, GWEN_BUFFER *dbuf, const char *sText)
{
GWEN_Buffer_AppendArgs(dbuf,
"0x%02x->0x%02x: RANGE(%s) %s (uid=0x%08x, begin=0x%x, end=0x%x)\n",
AQH_NodeMessage_GetSourceAddress(msg),
AQH_NodeMessage_GetDestAddress(msg),
AQH_NodeMessage_MsgTypeToChar(AQH_NodeMessage_GetMsgType(msg)),
sText,
(unsigned int) AQH_RangeMessage_GetUid(msg),
AQH_RangeMessage_GetRangeBegin(msg),
AQH_RangeMessage_GetRangeEnd(msg));
}

30
aqhome/msg/node/m_range.h Normal file
View File

@@ -0,0 +1,30 @@
/****************************************************************************
* This file is part of the project AqHome.
* AqHome (c) by 2025 Martin Preuss, all rights reserved.
*
* The license for this file can be found in the file COPYING which you
* should have received along with this file.
****************************************************************************/
#ifndef AQH_M_RANGE_H
#define AQH_M_RANGE_H
#include <aqhome/api.h>
#include <aqhome/ipc2/message.h>
#include <gwenhywfar/debug.h>
/* This message is used for message types ClaimAddr, DenyAddr, HaveAddr */
AQHOME_API uint32_t AQH_RangeMessage_GetUid(const AQH_MESSAGE *msg);
AQHOME_API uint8_t AQH_RangeMessage_GetAddr(const AQH_MESSAGE *msg);
AQHOME_API uint8_t AQH_RangeMessage_GetRangeBegin(const AQH_MESSAGE *msg);
AQHOME_API uint8_t AQH_RangeMessage_GetRangeEnd(const AQH_MESSAGE *msg);
AQHOME_API void AQH_RangeMessage_DumpToBuffer(const AQH_MESSAGE *msg, GWEN_BUFFER *dbuf, const char *sText);
#endif

View File

@@ -9,6 +9,7 @@
network
reportsensors
stats
router
</subdirs>
<extradist>

View File

@@ -101,7 +101,7 @@ AppNetwork_Every100ms_jump:
; ---------------------------------------------------------------------------
; @routine AppNetwork_Every100ms @global
; @routine AppNetwork_EveryDay @global
;
; @clobbers R16, R17, X
@@ -117,6 +117,13 @@ AppNetwork_EveryDay:
; @param X pointer to received message
AppNetwork_HandleMsg:
push xl
push xh
rcall AppNetwork_HandleMsg_savedX
pop xh
pop xl
rjmp AppNetwork_HandleMsg_end
AppNetwork_HandleMsg_savedX:
adiw xh:xl, NETMSG_OFFS_CMD
ld r16, X
sbiw xh:xl, NETMSG_OFFS_CMD
@@ -124,14 +131,21 @@ AppNetwork_HandleMsg:
breq AppNetwork_HandleMsg_handleRebootMsg
cpi r16, NETMSG_CMD_PING
breq AppNetwork_HandleMsg_handlePingMsg
cpi r16, NETMSG_CMD_REENUM
breq AppNetwork_HandleMsg_handleReenumMsg
cpi r16, NETMSG_CMD_NEED_ADDRESS
brcs AppNetwork_HandleMsg_clcRet ; lower than "HAVE_NEED"
cpi r16, NETMSG_CMD_ADDRESS_RANGE
breq AppNetwork_HandleMsg_handleRangeMsg
brcc AppNetwork_HandleMsg_clcRet ; higher or equal to "ADDR_RANGE"
rjmp AppNetwork_HandleMsg_handleAddrMsg
AppNetwork_HandleMsg_handleReenumMsg:
rjmp appNetworkHandleReeunumRequest
AppNetwork_HandleMsg_handleRangeMsg:
; TODO
bigcall NETMSG_Range_Read
std Y+NET_IFACE_OFFS_RANGE_BEGIN, r20
std Y+NET_IFACE_OFFS_RANGE_END, r21
std Y+NET_IFACE_OFFS_ADDRESS, r20
rjmp AppNetwork_HandleMsg_clcRet
AppNetwork_HandleMsg_handleAddrMsg:
@@ -145,21 +159,13 @@ AppNetwork_HandleMsg_handleAddrMsg:
sub zh, r16
ijmp
AppNetwork_HandleMsg_handleRebootMsg:
push xl
push xh
rcall appNetworkHandleRebootRequest
pop xh
pop xl
rcall appNetworkHandleRebootRequest
ret
AppNetwork_HandleMsg_handlePingMsg:
push xl
push xh
rcall appNetworkHandlePingRequest
pop xh
pop xl
ret
rjmp appNetworkHandlePingRequest
AppNetwork_HandleMsg_clcRet:
clc
AppNetwork_HandleMsg_end:
ret
; @end
@@ -172,7 +178,7 @@ AppNetwork_HandleMsg_clcRet:
appNetworkHandleRebootRequest:
rcall NETMSG_RebootRequestRead
brcc appNetworkHandleRebootRequest_end
brcc appNetworkHandleRebootRequest_end ; uid doesn't match
; reboot
cli
bigjmp BOOTLOADER_ADDR
@@ -203,6 +209,27 @@ appNetworkHandlePingRequest_end:
appNetworkHandleReeunumRequest:
push xl
push xh
rcall Utils_ReadUid ; r21:r20:r19:r18=uid (r16, X)
pop xh
pop xl
rcall NETMSG_Range_Read ; r20=range begin, r21=range end (none)
ldi r16, APP_NETWORK_STATE_INITIALWAIT
std Y+NET_IFACE_OFFS_STATUS, r16
cpi r18, 20
brcc appNetworkHandleReeunumRequest_setWait
subi r18, -20 ; minimum 2s
appNetworkHandleReeunumRequest_setWait:
std Y+NET_IFACE_OFFS_STATETIMER, r18 ; use lowest byte of uid as wat time
std Y+NET_IFACE_OFFS_RANGE_BEGIN, r20
std Y+NET_IFACE_OFFS_RANGE_END, r21
ret
; @end
appNetworkTimerTable:
rjmp appNetworkHandleStateInitialWait
rjmp appNetworkHandleStateNeedAddress
@@ -249,20 +276,11 @@ appNetworkHandleStateHaveAddress2:
std Y+NET_IFACE_OFFS_STATUS, r16
ldi r16, APP_NETWORK_TIMER_100MS
std Y+NET_IFACE_OFFS_STATETIMER, r16
ldd r16, Y+NET_IFACE_OFFS_RANGE_BEGIN ; set interface address
ldd r17, Y+NET_IFACE_OFFS_ADDRESS
cp r16, r17
breq appNetworkHandleStateHaveAddress2_end
; store new address in IFACE and in EEPROM
std Y+NET_IFACE_OFFS_ADDRESS, r16
push r15
in r15, SREG
cli
ldi xl, LOW(EEPROM_OFFS_COMADDR)
ldi xh, HIGH(EEPROM_OFFS_COMADDR)
bigcall Utils_WriteEepromIncr ; write address to EEPROM
out SREG, r15
pop r15
ldd r16, Y+NET_IFACE_OFFS_ADDRESS
ldi xl, LOW(EEPROM_OFFS_COMADDR)
ldi xh, HIGH(EEPROM_OFFS_COMADDR)
bigcall Eeprom_WriteByteIfChanged ; write address to EEPROM (R17)
appNetworkHandleStateHaveAddress2_end:
ret
@@ -280,7 +298,7 @@ appNetworkHandleStateUp:
; @clobbers R16, R19 (R17, R18, R20, R21, X)
appNetworkSendMsgNextState:
ldd r19, Y+NET_IFACE_OFFS_RANGE_BEGIN
ldd r19, Y+NET_IFACE_OFFS_ADDRESS
rcall appNetworkSendAddrMsg ; (R16, R17, R18, R19, R20, R21, X)
brcc appNetworkSendMsgNextState_retry
ldd r16, Y+NET_IFACE_OFFS_STATUS
@@ -345,9 +363,9 @@ appNetworkHandleMsgClaimAddr:
cp r19, r16
brne appNetworkHandleMsgClaimAddr_end ; not our address
ldd r16, Y+NET_IFACE_OFFS_STATUS
cpi r16, APP_NETWORK_STATE_UP ; up?
brne appNetworkHandleMsgClaimAddr_end ; nope, ignore
; network is up, someone claimed our address, deny it
cpi r16, APP_NETWORK_STATE_CLAIMADDRESS1
brcs appNetworkHandleMsgClaimAddr_end ; nope, ignore
; network is somewhat up, someone claimed our address, deny it
ldi r18, NETMSG_CMD_DENY_ADDRESS ; deny our addr
ldd r19, Y+NET_IFACE_OFFS_ADDRESS
rjmp appNetworkSendAddrMsg
@@ -369,12 +387,12 @@ appNetworkHandleMsgDenyAddr:
cpi r16, APP_NETWORK_STATE_UP
breq appNetworkHandleMsgDenyAddr_end ; ignore (our network stack is up)
; still setting up address, check whether the last one is denied now
ldd r16, Y+NET_IFACE_OFFS_RANGE_BEGIN
ldd r16, Y+NET_IFACE_OFFS_ADDRESS
cp r19, r16 ; our claimed address?
brne appNetworkHandleMsgDenyAddr_end ; nope, jump
; try next address (if any left)
ldd r17, Y+NET_IFACE_OFFS_RANGE_END
inc r16 ; RANGE_BEGIN+1
inc r16 ; next address
cp r17, r16 ; smaller than or equal to RANGE_END?
brcc appNetworkHandleMsgDenyAddr_claimNext
; out of addresses, start completely new after some waiting time
@@ -384,7 +402,7 @@ appNetworkHandleMsgDenyAddr:
rjmp appNetworkHandleMsgDenyAddr_end
appNetworkHandleMsgDenyAddr_claimNext:
; send CLAIM_ADDR for next address (new state: APP_NETWORK_STATE_NEEDADDRESS+1)
std Y+NET_IFACE_OFFS_RANGE_BEGIN, r16
std Y+NET_IFACE_OFFS_ADDRESS, r16
ldi r16, APP_NETWORK_STATE_NEEDADDRESS
std Y+NET_IFACE_OFFS_STATUS, r16
ldi r18, NETMSG_CMD_CLAIM_ADDRESS
@@ -435,6 +453,7 @@ appNetworkResetState:
std Y+NET_IFACE_OFFS_STATETIMER, r16
ldi r16, APP_NETWORK_ADDRESS_RANGE_BEGIN
std Y+NET_IFACE_OFFS_RANGE_BEGIN, r16
std Y+NET_IFACE_OFFS_ADDRESS, r16
rcall appNetworkGetAddressFromEeprom ; R16=addr (R15, X)
tst r16
breq appNetworkResetState_setRangeEnd

15
avr/apps/router/0BUILD Normal file
View File

@@ -0,0 +1,15 @@
<?xml?>
<gwbuild>
<subdirs>
</subdirs>
<extradist>
main.asm
</extradist>
</gwbuild>

579
avr/apps/router/main.asm Normal file
View File

@@ -0,0 +1,579 @@
; ***************************************************************************
; 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
appRouterDataBegin:
appRouterRangeBegin: .byte 1
appRouterRangeEnd: .byte 1
appRouterDataEnd:
; ***************************************************************************
; code
.cseg
; ---------------------------------------------------------------------------
; @routine AppRouter_Init @global
AppRouter_Init:
ldi xh, HIGH(appRouterDataBegin)
ldi xl, LOW(appRouterDataBegin)
clr r16
ldi r17, (appRouterDataEnd-appRouterDataBegin)
rcall Utils_FillSram
#ifndef APP_ROUTER_NO_ADDR_MGR
ldi r16, 0xe0 ; default range from 0xe0-0xef (will be changed later)
sts netInterfaceData+NET_IFACE_OFFS_ADDRESS, r16 ; use first address for router itself
sts netInterfaceData2+NET_IFACE_OFFS_ADDRESS, r16 ; use same address for both interfaces to save on addresses
inc r16
sts appRouterRangeBegin, r16 ; range from router+1
ldi r16, 0xef
sts appRouterRangeEnd, r16
rcall appRouterReadConfFromEeprom ; try to read config from EEPROM
#endif
; 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
#ifndef APP_ROUTER_NO_ADDR_MGR
ldi r18, NETMSG_CMD_ADDRESS_RANGE
rcall appRouterSendRangeMsgToDev1
#endif
ret
; @end
; ---------------------------------------------------------------------------
; @routine AppRouter_EveryDay @global
;
; @clobbers R16, R17, X
AppRouter_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 AppRouter_Run @global
;
; Read messages from either interface and forward to the other one.
AppRouter_Run:
rjmp appRouterCheckRecvdMsg
; @end
; ---------------------------------------------------------------------------
; @routine appRouterHandleMsgAnyDev @global
;
; @param X pointer to received message
; @return CFLAG set if msg handled, cleared otherwise
; @clobbers any, !X
appRouterHandleMsgAnyDev:
push xl
push xh
rcall appRouterHandleMsgAnyDev_savedX
pop xh
pop xl
rjmp appRouterHandleMsgAnyDev_end
appRouterHandleMsgAnyDev_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 appRouterHandleMsgAnyDev_handleRebootMsg
cpi r16, NETMSG_CMD_PING
breq appRouterHandleMsgAnyDev_handlePingMsg
cpi r16, NETMSG_CMD_VALUE_SET
breq appRouterHandleMsgAnyDev_handleSetValue
rjmp appRouterHandleMsgAnyDev_clcRet
appRouterHandleMsgAnyDev_handleRebootMsg:
rcall appRouterHandleRebootRequest
ret
appRouterHandleMsgAnyDev_handlePingMsg:
rcall appRouterHandlePingRequest
clc
ret
appRouterHandleMsgAnyDev_handleSetValue:
rcall NETMSG_ValueRead ; (none)
cpi r17, VALUE_ID_ROUTER_SETRANGE
breq appRouterHandleMsgAnyDev_handleSetRange
rjmp appRouterHandleMsgAnyDev_clcRet
appRouterHandleMsgAnyDev_handleSetRange:
#ifndef APP_ROUTER_NO_ADDR_MGR
sts netInterfaceData+NET_IFACE_OFFS_ADDRESS, r18 ; use first address for router itself
sts netInterfaceData2+NET_IFACE_OFFS_ADDRESS, r18 ; use same address for both interfaces to save on addresses
inc r18 ; start range after router
sts appRouterRangeBegin, r18
sts appRouterRangeEnd, r19
; send ACK
ldi r23, NETMSG_CMD_VALUE_SET_ACK
rcall Main_SendValueResponse ; (clobbers all, including Y)
; let subnodes re-eunumerate
ldi r18, NETMSG_CMD_REENUM
rcall appRouterSendRangeMsgToDev1 ; (R16, R17, R18, R19, R20, R21, X, Y)
rcall appRouterWriteConfToEeprom ; (r16, r17, X)
#endif
sec
ret
appRouterHandleMsgAnyDev_clcRet:
clc
appRouterHandleMsgAnyDev_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine appRouterHandleDev1Msg @global
;
; Handle messages from controlled subnet.
;
; @param X pointer to received message
; @return CFLAG set if msg handled, cleared otherwise
; @clobbers any, !X
appRouterHandleDev1Msg:
#ifndef APP_ROUTER_NO_ADDR_MGR
push xl
push xh
rcall appRouterHandleDev1Msg_savedX
pop xh
pop xl
rjmp appRouterHandleDev1Msg_end
appRouterHandleDev1Msg_savedX:
adiw xh:xl, NETMSG_OFFS_CMD
ld r16, X
sbiw xh:xl, NETMSG_OFFS_CMD
cpi r16, NETMSG_CMD_NEED_ADDRESS
breq appRouterHandleDev1Msg_handleNeedAddr
cpi r16, NETMSG_CMD_CLAIM_ADDRESS
breq appRouterHandleDev1Msg_handleClaimAddr
; add more here
ldi r16, 0
rjmp appRouterHandleDev1Msg_clcRet
appRouterHandleDev1Msg_handleNeedAddr:
ldi r18, NETMSG_CMD_ADDRESS_RANGE
rcall appRouterSendRangeMsgToDev1 ; (R16, R17, R18, R19, R20, R21, X, Y)
sec
rjmp appRouterHandleDev1Msg_end
appRouterHandleDev1Msg_handleClaimAddr:
rcall NETMSG_Address_Read ; R18=cmd, R19=addr(R18, R19)
rcall appRouterIsR19InRange
brcs appRouterHandleDev1Msg_end
; is not in subnet range, deny
rcall appRouterSendDenyAddrR19ToDev1 ; (R16, R17, R18, R19, R20, R21, X, Y)
sec
rjmp appRouterHandleDev1Msg_end
#endif
appRouterHandleDev1Msg_clcRet:
clc
appRouterHandleDev1Msg_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine appRouterIsR19InRange
;
; @param R19 address to check against range
; @clobbers R16
appRouterIsR19InRange:
lds r16, appRouterRangeBegin
cp r19, r16
brcs appRouterIsR19InRangeClcRet
lds r16, appRouterRangeEnd
cp r16, r19
brcs appRouterIsR19InRangeClcRet
sec
rjmp appRouterIsR19InRange_end
appRouterIsR19InRangeClcRet:
clc
appRouterIsR19InRange_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine appRouterSendDenyAddrR19ToDev1
;
; @param R19 address to send
; @clobbers R16, R17, R18, R19, R20, R21, X, Y
appRouterSendDenyAddrR19ToDev1:
ldi r18, NETMSG_CMD_DENY_ADDRESS ; deny addr
rjmp appRouterSendAddrMsgToDev1 ; (R16, R17, R18, R19, R20, R21, X, Y)
; @end
; ---------------------------------------------------------------------------
; @routine appRouterSendAddrMsgToDev1
;
; @param R18 command
; @param R19 address to send
; @clobbers R16 (R17, R18, R19, R20, R21, X, Y)
appRouterSendAddrMsgToDev1:
bigcall NET_Buffer_Alloc ; (R16, R17, X)
brcc appRouterSendAddrMsgToDev1_end
push r16
adiw xh:xl, 1
bigcall NETMSG_Address_Write ; (R16, R17, R18, R19, R20, R21)
sbiw xh:xl, 1
pop r16
rcall appRouterSendMsgToDev1 ; (R16, R17, R18, R24, R25, X, Y)
appRouterSendAddrMsgToDev1_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine appRouterSendRangeMsgToDev1
;
; @param R18 msg code
; @return CFLAG set if message enqueued, cleared on error
; @clobbers (R16, R17, R18, R19, R20, R21, R24, R25, X, Y)
appRouterSendRangeMsgToDev1:
bigcall NET_Buffer_Alloc ; (R16, R17, X)
brcc appRouterSendRangeMsgToDev1_end
push r16
lds r20, appRouterRangeBegin
lds r21, appRouterRangeEnd
adiw xh:xl, 1
bigcall NETMSG_Range_Write ; (R16, R17, R18, R19, R20, R21)
sbiw xh:xl, 1
pop r16
rcall appRouterSendMsgToDev1 ; (R16, R17, R18, R24, R25, X, Y)
appRouterSendRangeMsgToDev1_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine appRouterSendMsgToDev1
;
; @param R16 num of allocated buffer
; @param X msg to send (points to start of allocated buffer, e.g. buffer header)
; @return CFLAG set if message enqueued, cleared on error
; @clobbers Y (R16, R17, R18, R24, R25, X)
appRouterSendMsgToDev1:
ldi yl, LOW(netInterfaceData2)
ldi yh, HIGH(netInterfaceData2)
bigcall NET_Interface_AddOutgoingMsgNum ; (R17, R18, X)
brcs appRouterSendMsgToDev1_end
bigcall NET_Buffer_ReleaseByNum ; (R16, X)
ldi r16, NET_IFACE_OFFS_ERR_NOBUF_LOW
rcall NET_Interface_IncCounter16 ; (R24, R25)
clc
appRouterSendMsgToDev1_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine appRouterHandleRebootRequest
;
; Doesn't return if reboot msg is valid.
;
; @param X pointer to received message
appRouterHandleRebootRequest:
rcall NETMSG_RebootRequestRead
brcc appRouterHandleRebootRequest_end
; reboot
cli
bigjmp BOOTLOADER_ADDR
appRouterHandleRebootRequest_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine appRouterHandlePingRequest
;
; @param X pointer to received message
appRouterHandlePingRequest:
ld r17, X
lds r16, (netInterfaceData+NET_IFACE_OFFS_ADDRESS)
cp r16, r17
breq appRouterHandlePingRequest_forMe
cpi r17, 0xff
breq appRouterHandlePingRequest_forMe
clc
rjmp appRouterHandlePingRequest_end
appRouterHandlePingRequest_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 appRouterHandlePingRequest_end ; jmp on error
push r16 ; buffer num
mov r16, r17 ; DEST addr
adiw xh:xl, 1
ldi yl, LOW(netInterfaceData)
ldi yh, HIGH(netInterfaceData)
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)
appRouterHandlePingRequest_end:
ret
; ---------------------------------------------------------------------------
; @routine appRouterCheckRecvdMsg
;
; Read messages from either interface and forward to the other one.
;
; @return CFLAG set if something done, cleared otherwise
appRouterCheckRecvdMsg:
rcall NET_PeekNextIncomingMsgNum ; check read queue (bufNum->r16)
brcc appRouterCheckRecvdMsg_end ; no msg, jmp
rcall NET_Buffer_Locate ; (R17)
rcall appRouterHandleRouterMsgWithHdr ; filter out router msgs
brcs appRouterCheckRecvdMsg_removeMsg ; handled by router code, don't forward
; let system handle incoming messages
adiw xh:xl, 1
rcall appRouterLetSysHandleMsg
sbiw xh:xl, 1
; forward to other interface
ld r17, X
andi r17, (1<<NET_IFACE_BUFFER_IFACENUM1_BIT) | (1<<NET_IFACE_BUFFER_IFACENUM0_BIT)
rcall appRouterReverseInterfaceNum ; (R16, R17)
rcall appRouterAddMsgToInterface
brcc appRouterCheckRecvdMsg_end ; could not add, jmp
rcall NET_GetNextIncomingMsgNum ; take off the queue
sec
ret
appRouterCheckRecvdMsg_removeMsg:
rcall NET_GetNextIncomingMsgNum ; take off the queue
rcall NET_Buffer_ReleaseByNum ; (R16, X)
sec
appRouterCheckRecvdMsg_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine appRouterHandleRouterMsgWithHdr
;
; @param X pointer to msg
; @return CFLAG set if msg handled, cleared otherwise
appRouterHandleRouterMsgWithHdr:
ld r17, X
adiw xh:xl, 1
andi r17, (1<<NET_IFACE_BUFFER_IFACENUM1_BIT) | (1<<NET_IFACE_BUFFER_IFACENUM0_BIT)
cpi r17, NETDEV1_IFACENUM
brne appRouterHandleRouterMsgWithHdr_any
#ifndef APP_ROUTER_NO_ADDR_MGR
rcall appRouterHandleDev1Msg ; handle messages from controlled subnet
brcs appRouterHandleRouterMsgWithHdr_msgHandled
#endif
appRouterHandleRouterMsgWithHdr_any:
rcall appRouterHandleMsgAnyDev ; handle any msg
brcs appRouterHandleRouterMsgWithHdr_msgHandled
sbiw xh:xl, 1 ; CFLAG cleared
rjmp appRouterHandleRouterMsgWithHdr_end
appRouterHandleRouterMsgWithHdr_msgHandled:
sbiw xh:xl, 1
sec
appRouterHandleRouterMsgWithHdr_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine appRouterLetSysHandleMsg
;
; @param X pointer to msg to handle (point behind the buffer header!)
; @clobbers any, !X
appRouterLetSysHandleMsg:
ld r16, X
cpi r16, 0xff
breq appRouterLetSysHandleMsg_forMe
lds r17, netInterfaceData+NET_IFACE_OFFS_ADDRESS
cp r16, r17
brne appRouterLetSysHandleMsg_end
appRouterLetSysHandleMsg_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
appRouterLetSysHandleMsg_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine appRouterReverseInterfaceNum
;
; @param r17 buffer num
; @return r17 reversed interface number
; @clobbers r16, r17
appRouterReverseInterfaceNum:
ldi r16, (1<<NET_IFACE_BUFFER_IFACENUM1_BIT) | (1<<NET_IFACE_BUFFER_IFACENUM0_BIT)
eor r17, r16
and r17, r16
ret
; @end
; ---------------------------------------------------------------------------
; @routine appRouterAddMsgToInterface
; @param r16 buffer num
; @param r17 interface num
appRouterAddMsgToInterface:
cpi r17, NETDEV0_IFACENUM
brne appRouterAddMsgToInterface_notNetDev0
ldi yl, LOW(netInterfaceData)
ldi yh, HIGH(netInterfaceData)
rjmp NET_Interface_AddOutgoingMsgNum ; try to add msg to interface
appRouterAddMsgToInterface_notNetDev0:
ldi yl, LOW(netInterfaceData2)
ldi yh, HIGH(netInterfaceData2)
rjmp NET_Interface_AddOutgoingMsgNum ; try to add msg to interface
appRouterAddMsgToInterface_end:
clc
ret
; @end
; ---------------------------------------------------------------------------
; @routine appRouterWriteConfToEeprom
;
; @clobbers R16, X (R17)
appRouterWriteConfToEeprom:
; write range begin
ldi xl, LOW(EEPROM_OFFS_ROUTER_RANGE_BEGIN)
ldi xh, HIGH(EEPROM_OFFS_ROUTER_RANGE_BEGIN)
lds r16, appRouterRangeBegin
rcall Eeprom_WriteByteIfChanged ; (R17)
brcc appRouterWriteConfToEeprom_end
; write range end
ldi xl, LOW(EEPROM_OFFS_ROUTER_RANGE_END)
ldi xh, HIGH(EEPROM_OFFS_ROUTER_RANGE_END)
lds r16, appRouterRangeEnd
rcall Eeprom_WriteByteIfChanged ; (R17)
appRouterWriteConfToEeprom_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine appRouterReadConfFromEeprom
;
; @clobbers R16, X (R17)
appRouterReadConfFromEeprom:
; read range begin
ldi xl, LOW(EEPROM_OFFS_ROUTER_RANGE_BEGIN)
ldi xh, HIGH(EEPROM_OFFS_ROUTER_RANGE_BEGIN)
rcall Eeprom_ReadByte
brcc appRouterReadConfFromEeprom_end
cpi r16, 0xff
breq appRouterReadConfFromEeprom_okay ; not set, jmp
cpi r16, 2 ; range should at least start at 2 to assign 1 to router
brcs appRouterReadConfFromEeprom_okay
sts appRouterRangeBegin, r16
dec r16
sts netInterfaceData+NET_IFACE_OFFS_ADDRESS, r16 ; use addr rangeBegin-1 for router itself
sts netInterfaceData2+NET_IFACE_OFFS_ADDRESS, r16 ; use same address for both interfaces to save on addresses
; read range end
ldi xl, LOW(EEPROM_OFFS_ROUTER_RANGE_END)
ldi xh, HIGH(EEPROM_OFFS_ROUTER_RANGE_END)
rcall Eeprom_ReadByte
brcc appRouterReadConfFromEeprom_end
cpi r16, 0xff
breq appRouterReadConfFromEeprom_okay
sts appRouterRangeEnd, r16
appRouterReadConfFromEeprom_okay:
sec
appRouterReadConfFromEeprom_end:
ret
; @end

View File

@@ -139,8 +139,19 @@ AppStats_OnEveryMinute_store:
ret
AppStats_OnEveryMinute_sendDevice:
rjmp AppNetwork_SendDevice
push yl
push yh
ldi yl, LOW(netInterfaceData)
ldi yh, HIGH(netInterfaceData)
rcall AppNetwork_SendDevice
#ifdef APP_STATS_NETDEV2
ldi yl, LOW(netInterfaceData2)
ldi yh, HIGH(netInterfaceData2)
rcall AppNetwork_SendDevice
#endif
pop yh
pop yl
ret
AppStats_OnEveryMinute_sendPacketsIn:
ldi r16, 0
rjmp appStatsSendDeviceStat

View File

@@ -30,6 +30,8 @@
list_t.asm
tree.asm
tree_t.asm
eeprom-r.asm
eeprom-w.asm
</extradist>
</gwbuild>

80
avr/common/eeprom-r.asm Normal file
View File

@@ -0,0 +1,80 @@
; ***************************************************************************
; 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 AQH_AVR_COMMON_EEPROM_R_H
#define AQH_AVR_COMMON_EEPROM_R_H
; ---------------------------------------------------------------------------
; @routine Eeprom_ReadByte
;
; Read a byte from EEPROM (see example in ATtiny24/44/84 manual p.19).
;
; @param X EEPROM Address to read from
; @return CFLAG set if address okay, cleared if out of range
; @return R16 byte read
; @return X EEPROM Address incremented
; @clobbers none
Eeprom_ReadByte:
rcall Eeprom_CheckAddr
brcs Eeprom_ReadByte_addrOk
ret
Eeprom_ReadByte_addrOk:
; call routine with IRQs disabled
push r15
inr r15, SREG
cli
rcall Eeprom_ReadByte_noirq
outr SREG, r15
pop r15
sec
ret
Eeprom_ReadByte_noirq:
; wait until EEPROM ready
Eeprom_ReadByte_waitLoop:
.ifdef EEPE
sbic EECR, EEPE ; wait for previous write to complete (if any)
.else
sbic EECR, EEWE ; wait for previous write to complete (if any)
.endif
rjmp Eeprom_ReadByte_waitLoop
; read from EEPROM
out EEARH, xh ; set EEPROM address
out EEARL, xl
sbi EECR, EERE ; start EEPROM read by writing EERE
in r16, EEDR ; read data from data register
ret
; @end
; ---------------------------------------------------------------------------
; @routine Eeprom_CheckAddr
;
;
; @param X EEPROM Address to validate
; @return CFLAG set if address okay, cleared if out of range
; @clobbers r16
Eeprom_CheckAddr:
mov r16, xl
subi r16, LOW(EEPROMEND)
mov r16, xh
sbci r16, HIGH(EEPROMEND)
ret
; @end
#endif ; AQH_AVR_COMMON_EEPROM_R_H

100
avr/common/eeprom-w.asm Normal file
View File

@@ -0,0 +1,100 @@
; ***************************************************************************
; 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 AQH_AVR_COMMON_EEPROM_W_H
#define AQH_AVR_COMMON_EEPROM_W_H
; ---------------------------------------------------------------------------
; Utils_WriteEepromIncr
;
; Write a byte to EEPROM (see example in ATtiny24/44/84 manual p.18).
;
; @param R16 byte to write
; @param X EEPROM Address to write to
; @return CFLAG set if data written, cleared on error
; @clobbers R17
Eeprom_WriteByte:
mov r17, r16
rcall Eeprom_CheckAddr ; (r16)
mov r16, r17
brcs Eeprom_WriteByte_addrOk
ret
Eeprom_WriteByte_addrOk:
; call routine with IRQs disabled
push r15
inr r15, SREG
cli
rcall Eeprom_WriteByte_noirq
outr SREG, r15
pop r15
sec
ret
Eeprom_WriteByte_noirq:
; wait for EEPROM to be ready
Eeprom_WriteByte_waitLoop:
.ifdef EEPE
sbic EECR, EEPE ; wait for previous write to complete (if any)
.else
sbic EECR, EEWE ; wait for previous write to complete (if any)
.endif
rjmp Eeprom_WriteByte_waitLoop
; write data
.ifdef EEPM1
ldi r17, (0<<EEPM1) | (0<<EEPM0) ; set programming mode
.endif
out EECR, r17
out EEARH, xh ; set EEPROM address
out EEARL, xl
out EEDR, r16 ; write data to data register
.ifdef EEMPE
sbi EECR, EEMPE ; write logical one to EEMPE
.else
sbi EECR, EEMWE ; write logical one to EEMWE
.endif
.ifdef EEPE
sbi EECR, EEPE ; start EEPROM write by setting EEPE
.else
sbi EECR, EEWE ; start EEPROM write by setting EEWE
.endif
ret
; @end
; ---------------------------------------------------------------------------
; @routine Eeprom_WriteByteIfChanged @global
;
; Only write EEPROM byte if changed from current value (save on write cycles)
;
; @param r16 byte to write
; @param X eeprom address to write to
; @clobbers r17
Eeprom_WriteByteIfChanged:
mov r17, r16
rcall Eeprom_ReadByte
brcc Eeprom_WriteByteIfChanged_end
cp r16, r17
sec
breq Eeprom_WriteByteIfChanged_end
mov r16, r17
rcall Eeprom_WriteByte ; (R17)
Eeprom_WriteByteIfChanged_end:
ret
; @end
#endif ; AQH_AVR_COMMON_EEPROM_W_H

135
avr/common/eeprom_tlv.asm Normal file
View File

@@ -0,0 +1,135 @@
; ***************************************************************************
; 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 AQH_AVR_COMMON_EEPROM_TLV_H
#define AQH_AVR_COMMON_EEPROM_TLV_H
; ---------------------------------------------------------------------------
; @routine EepromTlv_AddTlv @global
;
; @param r16 type (must not be 0xff!)
; @param r17 length
; @return CFLAG set if free bytes found, cleared on error
; @return X EEPROM address of data for TLV (behind TLV header)
; @clobbers R16, R20, R21, X (R18)
EepromTlv_AddTlv:
mov r20, r16
mov r21, r17
ldi r16, 0xff
rcall EepromTlv_FindFirst ; (R18)
brcc EepromTlv_AddTlv_end
cpi r17, 0xff
brne EepromTlv_AddTlv_clcEnd
add xl, r21 ; wanted size
adc xh, r21
sub xh, r21
rcall Eeprom_CheckAddr ; check end address
brcc EepromTlv_AddTlv_end
sub xl, r21
sbc xh, r21
add xh, r21
sbiw xh:xl, 2
mov r16, r20 ; type
rcall Eeprom_WriteByte
adiw xh:xl, 1
mov r16, r21 ; length
rcall Eeprom_WriteByte
adiw xh:xl, 1
sec
rjmp EepromTlv_AddTlv_end
EepromTlv_AddTlv_clcEnd:
clc
EepromTlv_AddTlv_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine EepromTlv_FindFirst @global
;
; Find first matching TLV
;
; @param r16 TLV type to find
; @return CFLAG set if TLV found, cleared otherwise
; @return r16 type
; @return r17 length
; @return X points to begin of TLV data
; @clobbers r18
EepromTlv_FindFirst:
ldi xl, LOW(EEPROM_OFFS_TLV)
ldi xh, HIGH(EEPROM_OFFS_TLV)
rjmp EepromTlv_Find
; @end
; ---------------------------------------------------------------------------
; @routine EepromTlv_Find @global
;
; @param r16 TLV type to find
; @param X EEPROM address to start search
; @return CFLAG set if TLV found, cleared otherwise
; @return r16 type
; @return r17 length
; @return X points to begin of TLV data
; @clobbers r18
EepromTlv_Find:
mov r18, r16
EepromTlv_Find_loop:
rcall EepromTlv_ReadHeader
brcc EepromTlv_Find_notFound
cpi r16, r18 ; the one we wanted?
breq EepromTlv_Find_found
add xl, r17 ; skip TLV data
adc xh, r17
sub xh, r17
rjmp EepromTlv_Find_loop
EepromTlv_Find_notFound:
clc
rjmp EepromTlv_Find_end
EepromTlv_Find_found:
sec
EepromTlv_Find_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine EepromTlv_ReadHeader
;
; @param X EEPROM address
; @return CFLAG set if address okay, cleared if out of range
; @return r16 type
; @return r17 length (only data length, can be 0)
; @return X EEPROM address behind TLV header
; @clobbers none
EepromTlv_ReadHeader:
rcall Eeprom_ReadByteIncr ; read type
brcc EepromTlv_ReadHeader
adiw xh:xl, 1
push r16
rcall Eeprom_ReadByteIncr ; read length
mov r17, r16
pop r16
brcc EepromTlv_ReadHeader
adiw xh:xl, 1
sec
EepromTlv_ReadHeader:
ret
; @end

View File

@@ -7,29 +7,6 @@
; * Please see toplevel file COPYING of that project for license details. *
; ***************************************************************************
#if 0
; M_IO_READ DEST, SRC
.macro M_IO_READ
.if @1 < 64
in @0, @1
.else
lds @0, @1
.endif
.endmacro
; M_IO_WRITE DEST, SRC
.macro M_IO_WRITE
.if @0 < 64
out @0, @1
.else
sts @0, @1
.endif
.endmacro
#endif
; inr DEST, SRC
.macro inr

View File

@@ -29,6 +29,10 @@ initApps:
bigcall AppNetwork_Init
#endif
#ifdef APPS_ROUTER
bigcall AppRouter_Init
#endif
#ifdef APPS_MOTION
bigcall AppMotion_Init
#endif
@@ -62,9 +66,23 @@ initApps:
;
runApps:
clr r16
#ifdef APPS_ROUTER
push r16
bigcall AppRouter_Run
pop r16
sbci r16, 0 ; decrease r16 only if CFLAG set
#endif
; add more modules here
tst r16
clc
breq runApps_end
sec
runApps_end:
ret
; @end

View File

@@ -57,6 +57,12 @@
.equ TLV_OFFS_LEN = 0
.equ TLV_OFFS_TYPE = 1
.equ TLV_OFFS_VALUE = 2
; ---------------------------------------------------------------------------
; EEPROM positions
@@ -76,5 +82,18 @@
.equ EEPROM_OFFS_MAL_CONF_SRC2_VALUEID = 19 ; 1 byte
.equ EEPROM_OFFS_MAL_CONF_RGBWVALUE = 20 ; 4 bytes
; next is 24
.equ EEPROM_OFFS_ROUTER_RANGE_BEGIN = 24 ; 1 byte
.equ EEPROM_OFFS_ROUTER_RANGE_END = 25 ; 1 byte
; next is 26
.equ EEPROM_OFFS_TLV = 32 ; begin TLV area here
.equ EEPROM_TLV_ROUTER_RANGE = 0x10 ; 2 bytes (range begin, range end)

View File

@@ -96,6 +96,29 @@
#endif
#ifdef MODULES_COM2W
.include "modules/com2w/defs.asm"
.include "modules/com2w/com2w.asm"
#endif
#ifdef MODULES_COM2W0
.include "modules/com2w/defs.asm"
.include "modules/com2w/common.asm"
.include "modules/com2w/com2w0.asm"
#endif
#ifdef MODULES_COM2W1
.include "modules/com2w/defs.asm"
.include "modules/com2w/common.asm"
.include "modules/com2w/com2w1.asm"
#endif
#ifdef MODULES_CLOCK
.include "modules/clock/main.asm"
#endif
@@ -239,6 +262,23 @@
.include "modules/network/msg/reboot-d.asm"
.include "modules/network/msg/reboot-r.asm"
.include "modules/network/msg/pong-w.asm"
.include "modules/network/msg/range-d.asm"
.include "modules/network/msg/range-r.asm"
.include "common/eeprom-r.asm"
.include "common/eeprom-w.asm"
#endif
#ifdef APPS_ROUTER
.include "apps/router/main.asm"
.include "modules/network/msg/reboot-d.asm"
.include "modules/network/msg/reboot-r.asm"
.include "modules/network/msg/pong-w.asm"
.include "modules/network/msg/range-d.asm"
.include "modules/network/msg/range-r.asm"
.include "modules/network/msg/range-w.asm"
.include "common/eeprom-r.asm"
.include "common/eeprom-w.asm"
#endif

View File

@@ -55,11 +55,35 @@ main:
main_loop:
bigcall systemSleep ; system-dependant
bigcall runModules
bigcall runApps
bigcall onEveryLoop ; call into main app
; run loop as long as some run function returns with CFLAG set
clr r17
main_runLoop:
push r17
clr r16
push r16
bigcall runModules
pop r16
sbci r16, 0
push r16
bigcall runApps
pop r16
sbci r16, 0
push r16
bigcall onEveryLoop ; call into main app
pop r16
pop r17
tst r16
breq main_endRunLoop
inc r17
cpi r17, 2
brcc main_endRunLoop
brne main_runLoop
main_endRunLoop:
#ifdef MODULES_NETWORK
#ifndef MAIN_WITHOUT_MSG_HANDLING
rcall mainHandleMessages
@@ -111,6 +135,19 @@ onSystemTimerTick:
bigcall ComOnUart1_Periodically
#endif
#ifdef MODULES_COM2W
bigcall COM2W_Every100ms
#endif
#ifdef MODULES_COM2W0
bigcall COM2W0_Periodically
#endif
#ifdef MODULES_COM2W1
bigcall COM2W1_Periodically
#endif
#ifdef MODULES_TCRT1000
bigcall TCRT1K_Every100ms
#endif
@@ -186,6 +223,10 @@ sysOnEveryDay:
bigcall AppNetwork_EveryDay
#endif
#ifdef APPS_ROUTER
bigcall AppRouter_EveryDay
#endif
bigjmp onEveryDay
; @end

View File

@@ -81,6 +81,18 @@ initModules:
bigcall ComOnUart1_Init
#endif
#ifdef MODULES_COM2W
bigcall COM2W_Init
#endif
#ifdef MODULES_COM2W0
bigcall COM2W0_Init
#endif
#ifdef MODULES_COM2W1
bigcall COM2W1_Init
#endif
#ifdef MODULES_MOTION
bigcall Motion_Init
#endif
@@ -175,56 +187,83 @@ initModules:
; USED: depending on called routines
runModules:
bigcall BaseTimer_Run
clr r16
push r16
bigcall BaseTimer_Run
pop r16
#ifdef MODULES_COM
; COM module (call until carry flag cleared but at most 10 times to not starve other modules)
ldi r16, 10
runModules_Com:
push r16
bigcall Com2_Run
pop r16
brcc runModules_ComEnd
dec r16
brne runModules_Com
runModules_ComEnd:
#endif
#ifdef MODULES_TTYONUART1
bigcall TtyOnUart1_Run
push r16
bigcall TtyOnUart1_Run
pop r16
#endif
push r16
rcall runComModules
pop r16
sbci r16, 0
; add more modules here
; check for repeat request
tst r16
clc
breq runModules_end
sec
runModules_end:
ret
; run until every module idle
runComModules:
clr r17
runComModules_loop:
push r17
clr r16
#ifdef MODULES_COMONUART0
bigcall ComOnUart0_Run
push r16
bigcall ComOnUart0_Run
pop r16
sbci r16, 0
#endif
#ifdef MODULES_COMONUART1
bigcall ComOnUart1_Run
push r16
bigcall ComOnUart1_Run
pop r16
sbci r16, 0
#endif
#ifdef MODULES_STATS
bigcall Stats_Run
#ifdef MODULES_COM2W0
push r16
bigcall COM2W0_Run
pop r16
sbci r16, 0
#endif
#ifdef MODULES_REED
bigcall REED_Run
#ifdef MODULES_COM2W1
push r16
bigcall COM2W1_Run
pop r16
sbci r16, 0
#endif
#ifdef MODULES_CNY70
bigcall CNY70_Run
#endif
#ifdef MODULES_MOTION_LIGHT
; rcall MotionLight_Run
#endif
#ifdef MODULES_TCRT1000
; rcall TCRT1K_Run
#endif
; add more modules here
pop r17
; check for repeat request
tst r16
clc
breq runComModules_loopEnd
inc r17
cpi r17, 2
brne runComModules_loop
runComModules_loopEnd:
tst r17
clc
breq runComModules_end
sec
runComModules_end:
ret

View File

@@ -23,6 +23,7 @@
; @param R19:R18 value
; @param R21:R20 denom (e.g. 100, meaning value must be divided by 100)
; @param R22 value type
; @return CFLAG on success, cleared on error
Main_SendValueReport:
push r17
@@ -52,6 +53,7 @@ Main_SendValueReport_end:
; @param R21:R20 denom (e.g. 100, meaning value must be divided by 100)
; @param R23 command
; @param R25:R24 ref msg id
; @return CFLAG on success, cleared on error
Main_SendValueResponse:
push r17

View File

@@ -29,6 +29,7 @@
.include "devices/all/defs.asm"
.include "common/calls.asm"
.include "common/utils_io.asm"
.include "common/utils_wait.asm"
@@ -40,7 +41,6 @@
; generic
.equ NET_BUFFERS_NUM = 6
.equ NET_BUFFERS_SIZE = 32

View File

@@ -36,6 +36,7 @@
.include "devices/all/defs.asm"
.include "common/calls.asm"
.include "common/utils_io.asm"
.include "common/utils_wait.asm"
@@ -47,7 +48,6 @@
; generic
.equ NET_BUFFERS_NUM = 6
.equ NET_BUFFERS_SIZE = 32

View File

@@ -25,6 +25,7 @@
.include "../defs.asm"
.include "devices/all/defs.asm"
.include "common/calls.asm"
.include "common/utils_io.asm"
.include "common/utils_wait.asm" ; wait macro
@@ -34,7 +35,6 @@
.equ NET_BUFFERS_NUM = 6
.equ NET_BUFFERS_SIZE = 32
; ---------------------------------------------------------------------------

View File

@@ -35,6 +35,7 @@
.include "devices/all/defs.asm"
.include "common/calls.asm"
.include "common/utils_io.asm"
.include "common/utils_wait.asm"
@@ -46,7 +47,6 @@
; generic
.equ NET_BUFFERS_NUM = 4
.equ NET_BUFFERS_SIZE = 32

View File

@@ -36,6 +36,7 @@
.include "devices/all/defs.asm"
.include "common/calls.asm"
.include "common/utils_io.asm"
.include "common/utils_wait.asm"
@@ -47,7 +48,6 @@
; generic
.equ NET_BUFFERS_NUM = 6
.equ NET_BUFFERS_SIZE = 32

View File

@@ -29,6 +29,7 @@
.include "devices/all/defs.asm"
.include "common/calls.asm"
.include "common/utils_io.asm"
.include "common/utils_wait.asm"
@@ -40,7 +41,6 @@
; generic
.equ NET_BUFFERS_NUM = 6
.equ NET_BUFFERS_SIZE = 32

View File

@@ -5,12 +5,12 @@
<deviceversion>23</deviceversion>
<values>
<value name="SI7021_TEMP" id="0x01" type="sensor" dataType="rational" modality="temperature" units="C" denom="100" />
<value name="SI7021_HUM" id="0x02" type="sensor" dataType="rational" modality="humidity" units="%" denom="1" />
<value name="MOTION" id="0x07" type="sensor" dataType="rational" modality="motion" denom="1" />
<value name="SGP40_VALUE" id="0x08" type="sensor" dataType="rational" modality="tvoc" denom="1" />
<value name="SGP30_TVOC" id="0x09" type="sensor" dataType="rational" modality="tvoc" denom="1" />
<value name="SGP30_CO2" id="0x0a" type="sensor" dataType="rational" modality="co2" denom="1" />
<value name="SI7021_TEMP" id="0x01" type="sensor" dataType="rational" modality="temperature" units="C" denom="100" />
<value name="SI7021_HUM" id="0x02" type="sensor" dataType="rational" modality="humidity" units="%" denom="1" />
<value name="MOTION" id="0x07" type="sensor" dataType="rational" modality="motion" denom="1" />
<value name="SGP40_VALUE" id="0x08" type="sensor" dataType="rational" modality="tvoc" denom="1" />
<value name="SGP30_TVOC" id="0x09" type="sensor" dataType="rational" modality="tvoc" denom="1" />
<value name="SGP30_CO2" id="0x0a" type="sensor" dataType="rational" modality="co2" denom="1" />
<value name="stats_packets_in" id="0xe0" type="sensor" dataType="uint16" denom="1" />
<value name="stats_packets_out" id="0xe1" type="sensor" dataType="uint16" denom="1" />
@@ -19,8 +19,10 @@
<value name="stats_nobuf_errors" id="0xe4" type="sensor" dataType="uint16" denom="1" />
<value name="stats_collision_errors" id="0xe5" type="sensor" dataType="uint16" denom="1" />
<value name="stats_busy_errors" id="0xe6" type="sensor" dataType="uint16" denom="1" />
<value name="stats_msgsize_errors" id="0xe7" type="sensor" dataType="uint16" denom="1" />
<value name="stats_missed_errors" id="0xe8" type="sensor" dataType="uint16" denom="1" />
<value name="LEDTIMING" id="0x88" type="actor" dataType="uint16" />
<value name="LEDTIMING" id="0x88" type="actor" dataType="uint16" />
</values>
</device>

View File

@@ -36,6 +36,7 @@
.include "devices/all/defs.asm"
.include "common/calls.asm"
.include "common/utils_io.asm"
.include "common/utils_wait.asm"
@@ -47,7 +48,6 @@
; generic
.equ NET_BUFFERS_NUM = 6
.equ NET_BUFFERS_SIZE = 32
.equ PROGRAM_SENSOR_INTERVAL_SECS = 60
.equ PROGRAM_STATS_INTERVAL_MINS = 10

View File

@@ -5,13 +5,13 @@
<deviceversion>24</deviceversion>
<values>
<value name="SI7021_TEMP" id="0x01" type="sensor" dataType="rational" modality="temperature" units="C" denom="100" />
<value name="SI7021_HUM" id="0x02" type="sensor" dataType="rational" modality="humidity" units="%" denom="1" />
<value name="MOTION" id="0x07" type="sensor" dataType="rational" modality="motion" denom="1" />
<value name="SGP40_VALUE" id="0x08" type="sensor" dataType="rational" modality="tvoc" denom="1" />
<value name="SGP30_TVOC" id="0x09" type="sensor" dataType="rational" modality="tvoc" denom="1" />
<value name="SGP30_CO2" id="0x0a" type="sensor" dataType="rational" modality="co2" denom="1" />
<value name="LIGHT" id="0x0b" type="sensor" dataType="rational" modality="light" denom="1" />
<value name="SI7021_TEMP" id="0x01" type="sensor" dataType="rational" modality="temperature" units="C" denom="100" />
<value name="SI7021_HUM" id="0x02" type="sensor" dataType="rational" modality="humidity" units="%" denom="1" />
<value name="MOTION" id="0x07" type="sensor" dataType="rational" modality="motion" denom="1" />
<value name="SGP40_VALUE" id="0x08" type="sensor" dataType="rational" modality="tvoc" denom="1" />
<value name="SGP30_TVOC" id="0x09" type="sensor" dataType="rational" modality="tvoc" denom="1" />
<value name="SGP30_CO2" id="0x0a" type="sensor" dataType="rational" modality="co2" denom="1" />
<value name="LIGHT" id="0x0b" type="sensor" dataType="rational" modality="light" denom="1" />
<value name="stats_packets_in" id="0xe0" type="sensor" dataType="uint16" denom="1" />
<value name="stats_packets_out" id="0xe1" type="sensor" dataType="uint16" denom="1" />
@@ -20,8 +20,10 @@
<value name="stats_nobuf_errors" id="0xe4" type="sensor" dataType="uint16" denom="1" />
<value name="stats_collision_errors" id="0xe5" type="sensor" dataType="uint16" denom="1" />
<value name="stats_busy_errors" id="0xe6" type="sensor" dataType="uint16" denom="1" />
<value name="stats_msgsize_errors" id="0xe7" type="sensor" dataType="uint16" denom="1" />
<value name="stats_missed_errors" id="0xe8" type="sensor" dataType="uint16" denom="1" />
<value name="LEDTIMING" id="0x88" type="actor" dataType="uint16" />
<value name="LEDTIMING" id="0x88" type="actor" dataType="uint16" />
</values>
</device>

View File

@@ -36,6 +36,7 @@
.include "version.asm"
.include "devices/all/defs.asm"
.include "common/calls.asm"
.include "common/utils_io.asm"
.include "common/utils_wait.asm"
@@ -47,7 +48,6 @@
; generic
.equ NET_BUFFERS_NUM = 6
.equ NET_BUFFERS_SIZE = 32
.equ PROGRAM_SENSOR_INTERVAL_SECS = 60
.equ PROGRAM_STATS_INTERVAL_MINS = 10

View File

@@ -5,15 +5,15 @@
<deviceversion>25</deviceversion>
<values>
<value name="DS18B20_TEMP" id="0x06" type="sensor" dataType="rational" modality="temperature" units="C" denom="16" />
<value name="DS18B20_TEMP" id="0x06" type="sensor" dataType="rational" modality="temperature" units="C" denom="16" />
<value name="NUMLEDS" id="0x82" type="actor" dataType="int" />
<value name="RGBWVALUE" id="0x83" type="actor" dataType="dword" />
<value name="NUMLEDS" id="0x82" type="actor" dataType="int" />
<value name="RGBWVALUE" id="0x83" type="actor" dataType="dword" />
<value name="MALRGBWVALUE" id="0x84" type="actor" dataType="dword" />
<value name="MALONTIME" id="0x85" type="actor" dataType="uint16" />
<value name="MALSOURCE1" id="0x86" type="actor" dataType="uint16" />
<value name="MALSOURCE2" id="0x87" type="actor" dataType="uint16" />
<value name="MALRGBWVALUE" id="0x84" type="actor" dataType="dword" />
<value name="MALONTIME" id="0x85" type="actor" dataType="uint16" />
<value name="MALSOURCE1" id="0x86" type="actor" dataType="uint16" />
<value name="MALSOURCE2" id="0x87" type="actor" dataType="uint16" />
<value name="stats_packets_in" id="0xe0" type="sensor" dataType="uint16" denom="1" />
<value name="stats_packets_out" id="0xe1" type="sensor" dataType="uint16" denom="1" />
@@ -22,8 +22,10 @@
<value name="stats_nobuf_errors" id="0xe4" type="sensor" dataType="uint16" denom="1" />
<value name="stats_collision_errors" id="0xe5" type="sensor" dataType="uint16" denom="1" />
<value name="stats_busy_errors" id="0xe6" type="sensor" dataType="uint16" denom="1" />
<value name="stats_msgsize_errors" id="0xe7" type="sensor" dataType="uint16" denom="1" />
<value name="stats_missed_errors" id="0xe8" type="sensor" dataType="uint16" denom="1" />
<value name="LEDTIMING" id="0x88" type="actor" dataType="uint16" />
<value name="LEDTIMING" id="0x88" type="actor" dataType="uint16" />
</values>
</device>

View File

@@ -29,6 +29,7 @@
.include "devices/all/defs.asm"
.include "common/calls.asm"
.include "common/utils_io.asm"
.include "common/utils_wait.asm"
@@ -40,7 +41,6 @@
; generic
.equ NET_BUFFERS_NUM = 6
.equ NET_BUFFERS_SIZE = 32

View File

@@ -5,8 +5,8 @@
<deviceversion>26</deviceversion>
<values>
<value name="SGP30_TVOC" id="0x09" type="sensor" dataType="rational" modality="tvoc" denom="1" />
<value name="SGP30_CO2" id="0x0a" type="sensor" dataType="rational" modality="co2" denom="1" />
<value name="SGP30_TVOC" id="0x09" type="sensor" dataType="rational" modality="tvoc" denom="1" />
<value name="SGP30_CO2" id="0x0a" type="sensor" dataType="rational" modality="co2" denom="1" />
<value name="stats_packets_in" id="0xe0" type="sensor" dataType="uint16" denom="1" />
<value name="stats_packets_out" id="0xe1" type="sensor" dataType="uint16" denom="1" />
@@ -15,6 +15,8 @@
<value name="stats_nobuf_errors" id="0xe4" type="sensor" dataType="uint16" denom="1" />
<value name="stats_collision_errors" id="0xe5" type="sensor" dataType="uint16" denom="1" />
<value name="stats_busy_errors" id="0xe6" type="sensor" dataType="uint16" denom="1" />
<value name="stats_msgsize_errors" id="0xe7" type="sensor" dataType="uint16" denom="1" />
<value name="stats_missed_errors" id="0xe8" type="sensor" dataType="uint16" denom="1" />
<value name="LEDTIMING" id="0x88" type="actor" dataType="uint16" />
</values>

View File

@@ -36,6 +36,7 @@
.include "version.asm"
.include "devices/all/defs.asm"
.include "common/calls.asm"
.include "common/utils_io.asm"
.include "common/utils_wait.asm"
@@ -47,7 +48,6 @@
; generic
.equ NET_BUFFERS_NUM = 6
.equ NET_BUFFERS_SIZE = 32
.equ PROGRAM_SENSOR_INTERVAL_SECS = 60
.equ PROGRAM_STATS_INTERVAL_MINS = 10

View File

@@ -2,7 +2,7 @@
N27
===
- Role: Air quality and climate sensors
- Role: Climate sensors
- MCU: AtTiny84
- Connection: RJ45
- Predecessor: N24, N23, N19
@@ -10,6 +10,4 @@ N27
- PIR sensor (AMN31112)
- TWI interface
- SI7021 temperature and humidity sensor
or
- SGP-30/40 air quality sensor

View File

@@ -5,13 +5,13 @@
<deviceversion>27</deviceversion>
<values>
<value name="SI7021_TEMP" id="0x01" type="sensor" dataType="rational" modality="temperature" units="C" denom="100" />
<value name="SI7021_HUM" id="0x02" type="sensor" dataType="rational" modality="humidity" units="%" denom="1" />
<value name="MOTION" id="0x07" type="sensor" dataType="rational" modality="motion" denom="1" />
<value name="SGP40_VALUE" id="0x08" type="sensor" dataType="rational" modality="tvoc" denom="1" />
<value name="SGP30_TVOC" id="0x09" type="sensor" dataType="rational" modality="tvoc" denom="1" />
<value name="SGP30_CO2" id="0x0a" type="sensor" dataType="rational" modality="co2" denom="1" />
<value name="LIGHT" id="0x0b" type="sensor" dataType="rational" modality="light" denom="1" />
<value name="SI7021_TEMP" id="0x01" type="sensor" dataType="rational" modality="temperature" units="C" denom="100" />
<value name="SI7021_HUM" id="0x02" type="sensor" dataType="rational" modality="humidity" units="%" denom="1" />
<value name="MOTION" id="0x07" type="sensor" dataType="rational" modality="motion" denom="1" />
<value name="SGP40_VALUE" id="0x08" type="sensor" dataType="rational" modality="tvoc" denom="1" />
<value name="SGP30_TVOC" id="0x09" type="sensor" dataType="rational" modality="tvoc" denom="1" />
<value name="SGP30_CO2" id="0x0a" type="sensor" dataType="rational" modality="co2" denom="1" />
<value name="LIGHT" id="0x0b" type="sensor" dataType="rational" modality="light" denom="1" />
<value name="stats_packets_in" id="0xe0" type="sensor" dataType="uint16" denom="1" />
<value name="stats_packets_out" id="0xe1" type="sensor" dataType="uint16" denom="1" />
@@ -20,8 +20,10 @@
<value name="stats_nobuf_errors" id="0xe4" type="sensor" dataType="uint16" denom="1" />
<value name="stats_collision_errors" id="0xe5" type="sensor" dataType="uint16" denom="1" />
<value name="stats_busy_errors" id="0xe6" type="sensor" dataType="uint16" denom="1" />
<value name="stats_msgsize_errors" id="0xe7" type="sensor" dataType="uint16" denom="1" />
<value name="stats_missed_errors" id="0xe8" type="sensor" dataType="uint16" denom="1" />
<value name="LEDTIMING" id="0x88" type="actor" dataType="uint16" />
<value name="LEDTIMING" id="0x88" type="actor" dataType="uint16" />
</values>
</device>

View File

@@ -26,6 +26,7 @@
.include "../defs.asm"
.include "common/calls.asm"
.include "common/utils_io.asm"
.include "devices/all/defs.asm"
@@ -122,8 +123,7 @@ main:
.include "modules/flash/defs.asm"
.include "modules/flash/eeprom.asm"
.include "modules/flash/io.asm"
.include "modules/flash/io_attn.asm"
.include "modules/flash/io_bitbang.asm"
.include "modules/flash/io_com2w.asm"
.include "modules/flash/flash1p.asm"
.include "modules/flash/flashxp.asm"
.include "modules/flash/flashprocess.asm"

View File

@@ -70,6 +70,17 @@
.equ COM_IRQ_GIMSK_ATTN = PCIE0
.equ COM_CLK_DDR = DDRA
.equ COM_CLK_INPUT = PINA
.equ COM_CLK_OUTPUT = PORTA
.equ COM_CLK_PIN = PORTA7
.equ COM_IRQ_ADDR_CLK = PCMSK0
.equ COM_IRQ_BIT_CLK = PCINT7 ; bit 7 in PCMSK0
.equ COM_IRQ_GIFR_CLK = PCIF0
.equ COM_IRQ_GIMSK_CLK = PCIE0
; ---------------------------------------------------------------------------
; TWI master module

View File

@@ -36,6 +36,7 @@
.include "version.asm"
.include "devices/all/defs.asm"
.include "common/calls.asm"
.include "common/utils_io.asm"
.include "common/utils_wait.asm"
@@ -47,7 +48,6 @@
; generic
.equ NET_BUFFERS_NUM = 6
.equ NET_BUFFERS_SIZE = 32
.equ PROGRAM_SENSOR_INTERVAL_SECS = 60
.equ PROGRAM_STATS_INTERVAL_MINS = 10
@@ -61,7 +61,8 @@
#define MODULES_CLOCK
#define MODULES_LED_SIMPLE
#define MODULES_NETWORK
#define MODULES_UART_BITBANG
;#define MODULES_UART_BITBANG
#define MODULES_COM2W
#define MODULES_TWI_MASTER
;#define MODULES_LCD
;#define LCD_MINIMAL_FONT
@@ -123,7 +124,8 @@
; rjmp main ; Reset vector
rjmp BOOTLOADER_ADDR ; Reset vector ; use this for flashed system
reti ; EXT_INT0
rjmp UART_BitBang_PcintIsr ; PCI0
; rjmp UART_BitBang_PcintIsr ; PCI0
rjmp com2wPcintIsr ; PCI0
reti ; PCI1
reti ; WATCHDOG
reti ; ICP1
@@ -218,7 +220,8 @@ onEveryLoop:
; ---------------------------------------------------------------------------
; defines for network interface
.equ netInterfaceData = uart_bitbang_iface
;.equ netInterfaceData = uart_bitbang_iface
.equ netInterfaceData = com2w_iface

View File

@@ -0,0 +1,13 @@
R04
===
- Role: Router
- MCU: AtTiny841
- Connection: RJ45
- Predecessor: none
- UART: comonuart0 (uart_hw2), comonuart1 (uart_hw2)
- Periphery:
- OWI interface
- DS18B20 temperature sensor

View File

@@ -27,7 +27,8 @@
<value name="stats_msgsize_errors2" id="0xf0" type="sensor" dataType="uint16" denom="1" />
<value name="stats_missed_errors2" id="0xf1" type="sensor" dataType="uint16" denom="1" />
<value name="LEDTIMING" id="0x88" type="actor" dataType="uint16" />
<value name="LEDTIMING" id="0x88" type="actor" dataType="uint16" />
<value name="addressRange" id="0x89" type="actor" dataType="uint16" />
</values>
</device>

View File

@@ -85,7 +85,6 @@
.equ NET_BUFFERS_NUM = 9
.equ NET_BUFFERS_SIZE = 32
.equ UART_HW_MSGNUMINBUF_SIZE = 8
.equ UART_HW_MSGNUMOUTBUF_SIZE = 8

View File

@@ -85,7 +85,6 @@
.equ NET_BUFFERS_NUM = 8
.equ NET_BUFFERS_SIZE = 32
.equ UART_HW_MSGNUMINBUF_SIZE = 8
.equ UART_HW_MSGNUMOUTBUF_SIZE = 8

View File

@@ -0,0 +1,13 @@
R05
===
- Role: Router
- MCU: AtTiny841
- Connection: RJ45
- Predecessor: R04
- UART: comonuart0 (uart_hw2), comonuart1 (uart_hw2)
- Periphery:
- OWI interface
- DS18B20 temperature sensor

View File

@@ -7,18 +7,28 @@
<values>
<value name="DS18B20_TEMP" id="0x06" type="sensor" dataType="rational" modality="temperature" units="C" denom="16" />
<value name="stats_packets_in" id="0xe0" type="sensor" dataType="uint16" denom="1" />
<value name="stats_packets_out" id="0xe1" type="sensor" dataType="uint16" denom="1" />
<value name="stats_content_errors" id="0xe2" type="sensor" dataType="uint16" denom="1" />
<value name="stats_io_errors" id="0xe3" type="sensor" dataType="uint16" denom="1" />
<value name="stats_nobuf_errors" id="0xe4" type="sensor" dataType="uint16" denom="1" />
<value name="stats_collision_errors" id="0xe5" type="sensor" dataType="uint16" denom="1" />
<value name="stats_busy_errors" id="0xe6" type="sensor" dataType="uint16" denom="1" />
<value name="stats_packets_in" id="0xe0" type="sensor" dataType="uint16" denom="1" />
<value name="stats_packets_out" id="0xe1" type="sensor" dataType="uint16" denom="1" />
<value name="stats_content_errors" id="0xe2" type="sensor" dataType="uint16" denom="1" />
<value name="stats_io_errors" id="0xe3" type="sensor" dataType="uint16" denom="1" />
<value name="stats_nobuf_errors" id="0xe4" type="sensor" dataType="uint16" denom="1" />
<value name="stats_collision_errors" id="0xe5" type="sensor" dataType="uint16" denom="1" />
<value name="stats_busy_errors" id="0xe6" type="sensor" dataType="uint16" denom="1" />
<value name="stats_msgsize_errors" id="0xe7" type="sensor" dataType="uint16" denom="1" />
<value name="stats_missed_errors" id="0xe8" type="sensor" dataType="uint16" denom="1" />
<value name="stats_packets2_in" id="0xe9" type="sensor" dataType="uint16" denom="1" />
<value name="stats_packets2_out" id="0xe9" type="sensor" dataType="uint16" denom="1" />
<value name="stats_packets_in2" id="0xe9" type="sensor" dataType="uint16" denom="1" />
<value name="stats_packets_out2" id="0xea" type="sensor" dataType="uint16" denom="1" />
<value name="stats_content_errors2" id="0xeb" type="sensor" dataType="uint16" denom="1" />
<value name="stats_io_errors2" id="0xec" type="sensor" dataType="uint16" denom="1" />
<value name="stats_nobuf_errors2" id="0xed" type="sensor" dataType="uint16" denom="1" />
<value name="stats_collision_errors2" id="0xee" type="sensor" dataType="uint16" denom="1" />
<value name="stats_busy_errors2" id="0xef" type="sensor" dataType="uint16" denom="1" />
<value name="stats_msgsize_errors2" id="0xf0" type="sensor" dataType="uint16" denom="1" />
<value name="stats_missed_errors2" id="0xf1" type="sensor" dataType="uint16" denom="1" />
<value name="LEDTIMING" id="0x88" type="actor" dataType="uint16" />
<value name="LEDTIMING" id="0x88" type="actor" dataType="uint16" />
<value name="addressRange" id="0x89" type="actor" dataType="uint16" />
</values>
</device>

View File

@@ -56,11 +56,11 @@
.equ COM_HALFBIT_LENGTH = 26000 ; see https://de.wikipedia.org/wiki/Universal_Asynchronous_Receiver_Transmitter
; settings for comOnUart0
;.equ COM_DATA_DDR = DDRA
;.equ COM_DATA_INPUT = PINA
;.equ COM_DATA_OUTPUT = PORTA
;.equ COM_DATA_PUE = PUEA
;.equ COM_DATA_PIN = PORTA2
.equ COM_DATA0_DDR = DDRA
.equ COM_DATA0_INPUT = PINA
.equ COM_DATA0_OUTPUT = PORTA
.equ COM_DATA0_PUE = PUEA
.equ COM_DATA0_PIN = PORTA2
.equ COM_ATTN0_DDR = DDRA
.equ COM_ATTN0_INPUT = PINA
@@ -87,6 +87,25 @@
.equ COM_IRQ_GIMSK_ATTN1 = PCIE1
; settings for comOnUart1
.equ COM_DATA1_DDR = DDRA
.equ COM_DATA1_INPUT = PINA
.equ COM_DATA1_OUTPUT = PORTA
.equ COM_DATA1_PUE = PUEA
.equ COM_DATA1_PIN = PORTA4
.equ COM_CLK1_DDR = DDRB
.equ COM_CLK1_INPUT = PINB
.equ COM_CLK1_OUTPUT = PORTB
.equ COM_CLK1_PUE = PUEB
.equ COM_CLK1_PIN = PORTB1
.equ COM_IRQ_ADDR_CLK1 = PCMSK1
.equ COM_IRQ_BIT_CLK1 = PCINT9 ; bit PCINT9 in PCMSK1
.equ COM_IRQ_GIFR_CLK1 = PCIF1
.equ COM_IRQ_GIMSK_CLK1 = PCIE1
; ---------------------------------------------------------------------------
; TWI master module

View File

@@ -48,18 +48,14 @@
; ---------------------------------------------------------------------------
; generic
; ---------------------------------------------------------------------------
; network interfaces
.equ COMONUART0_IFACENUM = 1
.equ COMONUART1_IFACENUM = 2
; ---------------------------------------------------------------------------
; firmware settings including list of modules used
#define MAIN_WITHOUT_MSG_HANDLING ; we do message handling ourselfes
#define MAIN_WITHOUT_MSG_HANDLING ; message handling in AppRouter!
#define APP_STATS_NETDEV2 ; send stats for 2nd device
#define MODULES_CLOCK
#define MODULES_LED_SIMPLE
@@ -68,22 +64,19 @@
#define MODULES_LCD
#define LCD_MINIMAL_FONT
#else ; decrease code when using display
#define MODULES_OWI_MASTER
#define MODULES_DS18B20
; #define MODULES_OWI_MASTER
; #define MODULES_DS18B20
#define APPS_STATS
#endif
#define MODULES_NETWORK
#define MODULES_COMONUART0
#define MODULES_COMONUART1
#define APPS_NETWORK
;#define MODULES_COMONUART1
#define MODULES_COM2W1
;#define APPS_NETWORK
#define APPS_ROUTER
.equ NET_BUFFERS_NUM = 8
.equ NET_BUFFERS_SIZE = 32
.equ UART_HW_MSGNUMINBUF_SIZE = 8
.equ UART_HW_MSGNUMOUTBUF_SIZE = 8
.equ NET_BUFFERS_NUM = 10
@@ -93,6 +86,7 @@
.equ VALUE_ID_DS18B20_TEMP = 0x06
.equ VALUE_ID_LEDSIMPLE_TIMING = 0x88
.equ VALUE_ID_ROUTER_SETRANGE = 0x89
; ***************************************************************************
@@ -109,7 +103,7 @@
rjmp BOOTLOADER_ADDR ; 1: RESET Reset vector use this for flashed system
reti ; 2: INT0 External Interrupt Request 0
rjmp ComOnUart0_AttnChangeIsr ; 3: PCINT0 Pin Change Interrupt 0
rjmp ComOnUart1_AttnChangeIsr ; 4: PCINT1 Pin Change Interrupt 1
rjmp COM2W1_ClkChangeIsr ; 4: PCINT1 Pin Change Interrupt 1
reti ; 5: WDT Watchdog Time-out
reti ; 6: TIM1_CAPT Timer/Counter1 Capture Event
reti ; 7: TIM1_COMPA (OC1A) Timer/Counter1 Compare Match A
@@ -129,12 +123,12 @@
reti ; 21: SPI SPI Serial Transfer Complete
reti ; 22: USART0_RXS USART0 Rx Start
rjmp ComOnUart0_RxCharIsr ; 23: USART0_RXC USART0 Rx Complete
rjmp ComOnUart0_TxUdreIsr ; 24: USART0_DRE USART0 Data Register Empty
rjmp ComOnUart0_TxCharIsr ; 25: USART0_TXC USART0 Tx Complete
reti ; 24: USART0_DRE USART0 Data Register Empty
reti ; 25: USART0_TXC USART0 Tx Complete
reti ; 26: USART1_RXS USART1 Rx Start
rjmp ComOnUart1_RxCharIsr ; 27: USART1_RXC USART1 Rx Complete
rjmp ComOnUart1_TxUdreIsr ; 28: USART1_DRE USART1 Data Register Empty
rjmp ComOnUart1_TxCharIsr ; 29: USART1_TXC USART1 Tx Complete
reti ; 27: USART1_RXC USART1 Rx Complete
reti ; 28: USART1_DRE USART1 Data Register Empty
reti ; 29: USART1_TXC USART1 Tx Complete
reti ; 30: TWI Two-Wire-Interface
reti ; 31: RESERVED reserved
@@ -173,28 +167,19 @@ onSystemStart:
onEvery100ms:
onEverySecond:
onEveryMinute:
onEveryHour:
onEveryDay:
ret
onEveryMinute:
#ifdef APPS_STATS
rcall sendPacketsIface2In
#endif
ret
; @end
; ---------------------------------------------------------------------------
; @routine onEveryLoop
;
; Called on every loop (i.e. after awakening from sleep).
onEveryLoop:
rcall checkRecvdMsg
ret
; @end
@@ -212,122 +197,6 @@ onMessageReceived:
; ---------------------------------------------------------------------------
; @routine checkRecvdMsg
;
; Read messages from either interface and forward to the other one.
checkRecvdMsg:
rcall NET_PeekNextIncomingMsgNum ; check read queue (bufNum->r16)
brcc checkRecvdMsg_end ; no msg, jmp
rcall NET_Buffer_Locate ; (R17)
; let system handle incoming messages
push r16
adiw xh:xl, 1
rcall letSysHandleMsg
sbiw xh:xl, 1
pop r16
; forward to other interface
ld r17, X
andi r17, (NET_IFACE_BUFFER_IFACENUM1_BIT | NET_IFACE_BUFFER_IFACENUM0_BIT)
rcall reverseInterfaceNum ; (R16, R17)
; ldi r17, COMONUART0_IFACENUM ; DEBUG: send everything to uart0 to test that code first
rcall addMsgToInterface
brcc checkRecvdMsg_end ; could not add, jmp
rcall NET_GetNextIncomingMsgNum ; take off the queue
rjmp checkRecvdMsg
checkRecvdMsg_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine letSysHandleMsg
;
; @param X pointer to msg to handle (point behind the buffer header!)
; @clobbers any, !X
letSysHandleMsg:
ld r16, X
cpi r16, 0xff
breq letSysHandleMsg_forMe
lds r17, comOnUart0_iface+NET_IFACE_OFFS_ADDRESS
cp r16, r17
brne letSysHandleMsg_end
letSysHandleMsg_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
letSysHandleMsg_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine reverseInterfaceNum
;
; @param r17 buffer num
; @return r17 reversed interface number
; @clobbers r16, r17
reverseInterfaceNum:
ldi r16, (1<<NET_IFACE_BUFFER_IFACENUM1_BIT) | (1<<NET_IFACE_BUFFER_IFACENUM0_BIT)
eor r17, r16
ret
; @end
; ---------------------------------------------------------------------------
; @routine addMsgToInterface
; @param r16 buffer num
; @param r17 interface num
addMsgToInterface:
cpi r17, COMONUART0_IFACENUM
brne addMsgToInterface_notUart0
ldi yl, LOW(comOnUart0_iface)
ldi yh, HIGH(comOnUart0_iface)
rjmp NET_Interface_AddOutgoingMsgNum ; try to add msg to interface
addMsgToInterface_notUart0:
ldi yl, LOW(comOnUart1_iface)
ldi yh, HIGH(comOnUart1_iface)
rjmp NET_Interface_AddOutgoingMsgNum ; try to add msg to interface
addMsgToInterface_end:
clc
ret
; @end
#ifdef APPS_STATS
sendPacketsIface2In:
ldi yl, LOW(netInterfaceData)
ldi yh, HIGH(netInterfaceData)
ldi r17, AQHOME_VALUEID_STATS_PACKETS_IN2
lds r18, comOnUart1_iface+NET_IFACE_OFFS_PACKETSIN_LOW
lds r19, comOnUart1_iface+NET_IFACE_OFFS_PACKETSIN_HIGH
rjmp appStatsSend16BitValue
#endif
; ***************************************************************************
; includes
@@ -342,6 +211,7 @@ sendPacketsIface2In:
; defines for network interface
.equ netInterfaceData = comOnUart0_iface
.equ netInterfaceData2 = com2w1_iface

View File

@@ -75,8 +75,8 @@
;#define MODULES_MOTION
#define MODULES_NETWORK
;#define MODULES_TTYONUART1
;#define MODULES_COMONUART0
#define MODULES_COMONUART1
#define MODULES_COMONUART0
;#define MODULES_COMONUART1
#define APPS_STATS
#define APPS_NETWORK
@@ -85,7 +85,6 @@
.equ NET_BUFFERS_NUM = 8
.equ NET_BUFFERS_SIZE = 32
.equ UART_HW_MSGNUMINBUF_SIZE = 8
.equ UART_HW_MSGNUMOUTBUF_SIZE = 8
@@ -113,9 +112,10 @@
rjmp BOOTLOADER_ADDR ; 1: RESET Reset vector use this for flashed system
reti ; 2: INT0 External Interrupt Request 0
; rjmp ComOnUart0_AttnChangeIsr ; 3: PCINT0 Pin Change Interrupt 0
reti ; 3: PCINT0 Pin Change Interrupt 0
rjmp ComOnUart1_AttnChangeIsr ; 4: PCINT1 Pin Change Interrupt 1
rjmp ComOnUart0_AttnChangeIsr ; 3: PCINT0 Pin Change Interrupt 0
; reti ; 3: PCINT0 Pin Change Interrupt 0
; rjmp ComOnUart1_AttnChangeIsr ; 4: PCINT1 Pin Change Interrupt 1
reti ; 4: PCINT1 Pin Change Interrupt 1
reti ; 5: WDT Watchdog Time-out
reti ; 6: TIM1_CAPT Timer/Counter1 Capture Event
reti ; 7: TIM1_COMPA (OC1A) Timer/Counter1 Compare Match A
@@ -134,19 +134,17 @@
reti ; 20: TIM2_OVF (OVF2) Timer/Counter2 Overflow
reti ; 21: SPI SPI Serial Transfer Complete
reti ; 22: USART0_RXS USART0 Rx Start
; rjmp ComOnUart0_RxCharIsr ; 23: USART0_RXC USART0 Rx Complete
reti ; 23: USART0_RXC USART0 Rx Complete
rjmp ComOnUart0_RxCharIsr ; 23: USART0_RXC USART0 Rx Complete
; reti ; 23: USART0_RXC USART0 Rx Complete
; rjmp ComOnUart0_TxUdreIsr ; 24: USART0_DRE USART0 Data Register Empty
reti ; 24: USART0_DRE USART0 Data Register Empty
; rjmp ComOnUart0_TxCharIsr ; 25: USART0_TXC USART0 Tx Complete
reti ; 25: USART0_TXC USART0 Tx Complete
reti ; 26: USART1_RXS USART1 Rx Start
rjmp ComOnUart1_RxCharIsr ; 27: USART1_RXC USART1 Rx Complete
; reti ; 27: USART1_RXC USART1 Rx Complete
rjmp ComOnUart1_TxUdreIsr ; 28: USART1_DRE USART1 Data Register Empty
; reti ; 28: USART1_DRE USART1 Data Register Empty
rjmp ComOnUart1_TxCharIsr ; 29: USART1_TXC USART1 Tx Complete
; reti ; 29: USART1_TXC USART1 Tx Complete
; rjmp ComOnUart1_RxCharIsr ; 27: USART1_RXC USART1 Rx Complete
reti ; 27: USART1_RXC USART1 Rx Complete
reti ; 28: USART1_DRE USART1 Data Register Empty
reti ; 29: USART1_TXC USART1 Tx Complete
reti ; 30: TWI Two-Wire-Interface
reti ; 31: RESERVED reserved
@@ -175,11 +173,11 @@ firmwareStart:
onSystemStart:
; set interface number for UART0
; ldi r16, COMONUART0_IFACENUM
; sts comOnUart0_iface+NET_IFACE_OFFS_IFACENUM, r16
ldi r16, COMONUART0_IFACENUM
sts comOnUart0_iface+NET_IFACE_OFFS_IFACENUM, r16
; set interface number for UART1
ldi r16, COMONUART1_IFACENUM
sts comOnUart1_iface+NET_IFACE_OFFS_IFACENUM, r16
; ldi r16, COMONUART1_IFACENUM
; sts comOnUart1_iface+NET_IFACE_OFFS_IFACENUM, r16
ret
; @end
@@ -236,7 +234,7 @@ onMessageReceived:
; ---------------------------------------------------------------------------
; defines for network interface
.equ netInterfaceData = comOnUart1_iface
.equ netInterfaceData = comOnUart0_iface
;.equ netInterfaceData2 = comOnUart1_iface

View File

@@ -5,6 +5,7 @@
<subdirs>
boot
main
test
</subdirs>
<extradist>

View File

@@ -0,0 +1,13 @@
T03
===
- Role: COM-PC-Interface
- MCU: AtTiny841
- Connection: RJ45
- Predecessor: none
- UART: comonuart0 (uart_hw2), ttyonuart1 (uart_hw)
- Periphery:
- OWI interface
- DS18B20 temperature sensor

View File

@@ -79,6 +79,25 @@
.equ COM_DATA_DDR = DDRA
.equ COM_DATA_INPUT = PINA
.equ COM_DATA_OUTPUT = PORTA
.equ COM_DATA_PUE = PUEA
.equ COM_DATA_PIN = PORTA2
.equ COM_CLK_DDR = DDRA
.equ COM_CLK_INPUT = PINA
.equ COM_CLK_OUTPUT = PORTA
.equ COM_CLK_PUE = PUEA
.equ COM_CLK_PIN = PORTA0
.equ COM_IRQ_ADDR_CLK = PCMSK0
.equ COM_IRQ_BIT_CLK = PCINT0 ; bit 0 in PCMSK0
.equ COM_IRQ_GIFR_CLK = PCIF0
.equ COM_IRQ_GIMSK_CLK = PCIE0
; ---------------------------------------------------------------------------
; 1-Wire Master
;

View File

@@ -74,7 +74,8 @@
;#define MODULES_DS18B20
;#define MODULES_MOTION
#define MODULES_NETWORK
#define MODULES_COMONUART0
#define MODULES_COM2W
;#define MODULES_COMONUART0
#define MODULES_TTYONUART1
#define APPS_STATS
#define APPS_NETWORK
@@ -82,7 +83,6 @@
.equ NET_BUFFERS_NUM = 10
.equ NET_BUFFERS_SIZE = 32
.equ UART_HW_MSGNUMINBUF_SIZE = 8
.equ UART_HW_MSGNUMOUTBUF_SIZE = 8
@@ -110,7 +110,8 @@
rjmp BOOTLOADER_ADDR ; 1: RESET Reset vector use this for flashed system
reti ; 2: INT0 External Interrupt Request 0
rjmp ComOnUart0AttnChangeIsr ; 3: PCINT0 Pin Change Interrupt 0
; rjmp COM2W1_ClkChangeIsr ; 3: PCINT0 Pin Change Interrupt 0
rjmp com2wPcintIsr ; 3: PCINT0 Pin Change Interrupt 0
reti ; 4: PCINT1 Pin Change Interrupt 1
reti ; 5: WDT Watchdog Time-out
reti ; 6: TIM1_CAPT Timer/Counter1 Capture Event
@@ -130,9 +131,10 @@
reti ; 20: TIM2_OVF (OVF2) Timer/Counter2 Overflow
reti ; 21: SPI SPI Serial Transfer Complete
reti ; 22: USART0_RXS USART0 Rx Start
rjmp ComOnUart0_RxCharIsr ; 23: USART0_RXC USART0 Rx Complete
rjmp ComOnUart0_TxUdreIsr ; 24: USART0_DRE USART0 Data Register Empty
rjmp ComOnUart0_TxCharIsr ; 25: USART0_TXC USART0 Tx Complete
; rjmp ComOnUart0_RxCharIsr ; 23: USART0_RXC USART0 Rx Complete
reti ; 23: USART0_RXC USART0 Rx Complete
reti ; 24: USART0_DRE USART0 Data Register Empty
reti ; 25: USART0_TXC USART0 Tx Complete
reti ; 26: USART1_RXS USART1 Rx Start
rjmp TtyOnUart1_RxCharIsr ; 27: USART1_RXC USART1 Rx Complete
rjmp TtyOnUart1_TxUdreIsr ; 28: USART1_DRE USART1 Data Register Empty
@@ -166,7 +168,7 @@ firmwareStart:
onSystemStart:
; set interface number for UART0
ldi r16, COMONUART0_IFACENUM
sts comOnUart0_iface+NET_IFACE_OFFS_IFACENUM, r16
sts netInterfaceData2+NET_IFACE_OFFS_IFACENUM, r16
; set interface number for UART1
ldi r16, TTYONUART1_IFACENUM
sts ttyOnUart1_iface+NET_IFACE_OFFS_IFACENUM, r16
@@ -247,7 +249,7 @@ letSysHandleMsg:
ld r16, X
cpi r16, 0xff
breq letSysHandleMsg_forMe
lds r17, comOnUart0_iface+NET_IFACE_OFFS_ADDRESS
lds r17, netInterfaceData2+NET_IFACE_OFFS_ADDRESS
cp r16, r17
brne letSysHandleMsg_end
letSysHandleMsg_forMe:
@@ -305,8 +307,8 @@ addMsgToInterface:
clc
ret
addMsgToInterface_toUart0:
ldi yl, LOW(comOnUart0_iface)
ldi yh, HIGH(comOnUart0_iface)
ldi yl, LOW(netInterfaceData2)
ldi yh, HIGH(netInterfaceData2)
rjmp NET_Interface_AddOutgoingMsgNum ; try to add msg to interface
addMsgToInterface_toUart1:
ldi yl, LOW(ttyOnUart1_iface)
@@ -333,5 +335,6 @@ addMsgToInterface_toUart1:
; defines for network interface
.equ netInterfaceData = ttyOnUart1_iface
.equ netInterfaceData2 = comOnUart0_iface
;.equ netInterfaceData2 = comOnUart0_iface
.equ netInterfaceData2 = com2w_iface

View File

@@ -0,0 +1,33 @@
<?xml?>
<gwbuild>
<target type="AvrHexFile" name="t03_test" >
<includes type="avrasm" >
-I $(builddir)
-I $(srcdir)
-I $(topsrcdir)/avr
-I $(topbuilddir)/avr
</includes>
<sources type="avrasm" >
main.asm
</sources>
</target>
<subdirs>
</subdirs>
<extradist>
</extradist>
</gwbuild>

View File

@@ -0,0 +1,257 @@
; ***************************************************************************
; copyright : (C) 2024 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. *
; ***************************************************************************
; ***************************************************************************
; Source file for temperature sensor node on AtTiny 84
;
; This is for the full system (i.e. not the boot loader).
;
; All definitions and changes should go into this file.
;
;
; ***************************************************************************
;.equ clock=1000000 ; Define the clock frequency
.equ clock=8000000 ; Define the clock frequency
.nolist
.include "include/tn841def.inc" ; Define device ATtiny841
.list
.include "../defs.asm"
.include "version.asm"
;.include "defs_all.asm"
.include "devices/all/defs.asm"
.include "common/calls.asm"
.include "common/utils_wait.asm"
.include "common/utils_io.asm"
; ***************************************************************************
; defines
; ---------------------------------------------------------------------------
; generic
.equ COMONUART0_IFACENUM = 1
.equ TTYONUART1_IFACENUM = 2
; ---------------------------------------------------------------------------
; firmware settings including list of modules used
#define MAIN_WITHOUT_MSG_HANDLING ; we do message handling ourselfes
#define APP_STATS_NETDEV2
#define APP_ROUTER_NO_ADDR_MGR
#define MODULES_CLOCK
;#define MODULES_COM
;#define MODULES_COM_WITH_ADDR_PROTO
;#define MODULES_LED
#define MODULES_LED_SIMPLE
;#define MODULES_TWI_MASTER
;#define MODULES_LCD
;#define LCD_MINIMAL_FONT
;#define MODULES_SI7021
;#define MODULES_STATS
;#define MODULES_CNY70
;#define MODULES_REED
;#define MODULES_OWI_MASTER
;#define MODULES_DS18B20
;#define MODULES_MOTION
#define MODULES_NETWORK
#define MODULES_COM2W0
;#define MODULES_COMONUART0
#define MODULES_TTYONUART1
#define APPS_STATS
;#define APPS_NETWORK
#define APPS_ROUTER
.equ NET_BUFFERS_NUM = 10
.equ UART_HW_MSGNUMINBUF_SIZE = 8
.equ UART_HW_MSGNUMOUTBUF_SIZE = 8
; ---------------------------------------------------------------------------
; defines for values
.equ VALUE_ID_DS18B20_TEMP = 0x06
.equ VALUE_ID_LEDSIMPLE_TIMING = 0x88
.equ VALUE_ID_ROUTER_SETRANGE = 0x89
.equ COM_DATA0_DDR = COM_DATA_DDR
.equ COM_DATA0_INPUT = COM_DATA_INPUT
.equ COM_DATA0_OUTPUT = COM_DATA_OUTPUT
.equ COM_DATA0_PUE = COM_DATA_PUE
.equ COM_DATA0_PIN = COM_DATA_PIN
.equ COM_CLK0_DDR = COM_CLK_DDR
.equ COM_CLK0_INPUT = COM_CLK_INPUT
.equ COM_CLK0_OUTPUT = COM_CLK_OUTPUT
.equ COM_CLK0_PUE = COM_CLK_PUE
.equ COM_CLK0_PIN = COM_CLK_PIN
.equ COM_IRQ_ADDR_CLK0 = COM_IRQ_ADDR_CLK
.equ COM_IRQ_BIT_CLK0 = COM_IRQ_BIT_CLK
.equ COM_IRQ_GIFR_CLK0 = COM_IRQ_GIFR_CLK
.equ COM_IRQ_GIMSK_CLK0 = COM_IRQ_GIMSK_CLK
; ***************************************************************************
; code segment
.cseg
.org 000000
; ---------------------------------------------------------------------------
; Reset and interrupt vectors
rjmp BOOTLOADER_ADDR ; 1: RESET Reset vector use this for flashed system
reti ; 2: INT0 External Interrupt Request 0
rjmp COM2W0_ClkChangeIsr ; 3: PCINT0 Pin Change Interrupt 0
reti ; 4: PCINT1 Pin Change Interrupt 1
reti ; 5: WDT Watchdog Time-out
reti ; 6: TIM1_CAPT Timer/Counter1 Capture Event
reti ; 7: TIM1_COMPA (OC1A) Timer/Counter1 Compare Match A
reti ; 8: TIM1_COMPB (OC1B) Timer/Counter1 Compare Match B
reti ; 9: TIM1_OVF (OVF1) Timer/Counter1 Overflow
rjmp baseTimerIrqOC0A ; 10: TIM0_COMPA (OC0A) Timer/Counter0 Compare Match A
reti ; 11: TIM0_COMPB (OC0B) Timer/Counter0 Compare Match B
reti ; 12: TIM0_OVF (OVF0) Timer/Counter0 Overflow
reti ; 13: ANA_COMP0 Analog Comparator 0
reti ; 14: ADC_READY ADC Conversion Complete
reti ; 15: EE_RDY (ERDY) EEPROM Ready
reti ; 16: ANA_COMP1 Analog Comparator 1
reti ; 17: TIM2_CAPT Timer/Counter2 Capture Event
reti ; 18: TIM2_COMPA (OC2A) Timer/Counter2 Compare Match A
reti ; 19: TIM2_COMPB (OC2B) Timer/Counter2 Compare Match B
reti ; 20: TIM2_OVF (OVF2) Timer/Counter2 Overflow
reti ; 21: SPI SPI Serial Transfer Complete
reti ; 22: USART0_RXS USART0 Rx Start
; rjmp ComOnUart0_RxCharIsr ; 23: USART0_RXC USART0 Rx Complete
reti ; 23: USART0_RXC USART0 Rx Complete
reti ; 24: USART0_DRE USART0 Data Register Empty
reti ; 25: USART0_TXC USART0 Tx Complete
reti ; 26: USART1_RXS USART1 Rx Start
rjmp TtyOnUart1_RxCharIsr ; 27: USART1_RXC USART1 Rx Complete
rjmp TtyOnUart1_TxUdreIsr ; 28: USART1_DRE USART1 Data Register Empty
rjmp TtyOnUart1_TxCharIsr ; 29: USART1_TXC USART1 Tx Complete
reti ; 30: TWI Two-Wire-Interface
reti ; 31: RESERVED reserved
devInfoBlock: ; 12 bytes
devInfoManufacturer: .db 'A', 'Q', 'U', 'A'
devInfoId: .db DEVICEINFO_ID, 0
devInfoVersion: .db DEVICEINFO_VERSION, DEVICEINFO_REVISION ; version, revision
firmwareVersion: .db FIRMWARE_VARIANT_TEMP_WINDOW, FIRMWARE_VERSION_MAJOR
.db FIRMWARE_VERSION_MINOR, FIRMWARE_VERSION_PATCHLEVEL
; ---------------------------------------------------------------------------
; @routine firmwareStart @global
firmwareStart:
rjmp main
; @end
; ---------------------------------------------------------------------------
; @routine onSystemStart
onSystemStart:
ldi r16, 0xf0
sts netInterfaceData+NET_IFACE_OFFS_ADDRESS, r16
sts netInterfaceData2+NET_IFACE_OFFS_ADDRESS, r16
ret
; @end
onEvery100ms:
onEverySecond:
onEveryMinute:
onEveryHour:
onEveryDay:
ret
; ---------------------------------------------------------------------------
; @routine onEveryLoop
;
; Called on every loop (i.e. after awakening from sleep).
onEveryLoop:
ret
; @end
; ---------------------------------------------------------------------------
; @routine onMessageReceived
;
; Called on every message received
onMessageReceived:
clc
ret
; @end
; ***************************************************************************
; includes
.include "devices/all/hw_tn841.asm"
.include "devices/all/includes.asm"
.include "common/debug.asm"
; ---------------------------------------------------------------------------
; defines for network interface
.equ netInterfaceData = ttyOnUart1_iface
;.equ netInterfaceData2 = comOnUart0_iface
.equ netInterfaceData2 = com2w0_iface
; debug
push r18
push r19
rcall LedSimple_SetFastTiming
pop r19
pop r18

695
avr/modules/com2w/com2w.asm Normal file
View File

@@ -0,0 +1,695 @@
; ***************************************************************************
; 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_COM2W_H
#define AVR_MODULES_COM2W_COM2W_H
.dseg
com2w_iface: .byte COM2W_IFACE_SIZE
.cseg
; ---------------------------------------------------------------------------
; @routine COM2W_Init
;
; @clobbers
COM2W_Init:
ldi yl, LOW(com2w_iface)
ldi yh, HIGH(com2w_iface)
rcall NET_Interface_Init ; (R16, R17, X)
; setup CLK line (as input, disable internal pull-up resistor)
cbi COM_CLK_DDR, COM_CLK_PIN ; set CLK as input
.ifdef COM_CLK_PUE
inr r16, COM_CLK_PUE
cbr r16, (1<<COM_CLK_PIN) ; disable pullup on CLK
outr COM_CLK_PUE, r16
.else
cbi COM_CLK_OUTPUT, COM_CLK_PIN ; disable pullup on CLK
.endif
; setup DATA line (as input, disable internal pull-up resistor)
cbi COM_DATA_DDR, COM_DATA_PIN ; set DATA as input
.ifdef COM_DATA_PUE
inr r16, COM_DATA_PUE
cbr r16, (1<<COM_DATA_PIN) ; disable pullup on DATA
outr COM_DATA_PUE, r16
.else
cbi COM_DATA_OUTPUT, COM_DATA_PIN ; disable pullup on DATA
.endif
; setup pin-change interrupt for CLK
rcall com2wEnableClkIrq
inr r16, COM_IRQ_ADDR_CLK
sbr r16, (1<<COM_IRQ_BIT_CLK) ; enable pin change irq for ATTN line
outr COM_IRQ_ADDR_CLK, r16
inr r16, GIMSK ; enable pin change irq PCIE0 or PCIE1
sbr r16, (1<<COM_IRQ_GIMSK_CLK)
outr GIMSK, r16
ldi r16, (1<<COM_IRQ_GIFR_CLK) ; clear pending irq by writing 1 to ATTN bit
outr GIFR, r16
ret
; @end
; ---------------------------------------------------------------------------
; @routine COM2W_Every100ms @global
;
; @clobbers R16, Y
COM2W_Every100ms:
ldi yl, LOW(com2w_iface)
ldi yh, HIGH(com2w_iface)
push r15
in r15, SREG
cli
rcall NET_Interface_Periodically ; (R16)
rcall com2wSendNextPkg
out SREG, r15
pop r15
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2wReceiveNextPkg
;
; Receive packet.
;
; @param Y pointer to start of interface data
; @clobbers R16, R17, R18, R19, R20, R22, R24, R25, X
com2wReceiveNextPkg:
mov xl, yl
mov xh, yh
adiw xh:xl, COM2W_IFACE_OFFS_BUFFER
ldd r18, Y+NET_IFACE_OFFS_ADDRESS
ldi r19, COM2W_BUFFER_SIZE
rcall com2wRecvMsg ; (r16, r17, r18, r19, r20, r22, r24, r25, X)
brcc com2wReceiveNextPkg_end
mov xl, yl
mov xh, yh
adiw xh:xl, COM2W_IFACE_OFFS_BUFFER
rcall NETMSG_CheckMessageInBuffer ; (R16, R17, R18, R19, R20, X)
brcc com2wReceiveNextPkg_eCrc
; msg received, alloc buffer for it
rcall NET_Buffer_Alloc ; R16=buffer num (R16, R17, X)
brcs com2wReceiveNextPkg_gotBuffer
ldi r16, NET_IFACE_OFFS_ERR_NOBUF_LOW
rcall NET_Interface_IncCounter16 ; (R24, R25)
rjmp com2wReceiveNextPkg_end
; copy received message into allocated buffer
com2wReceiveNextPkg_gotBuffer:
mov r19, r16 ; save buffer num
rcall NET_Interface_SetIfaceNumInBuffer ; (R16, R17)
mov r16, r19 ; restore buffer num
push zl
push zh
mov zl, yl
mov zh, yh
adiw zh:zl, COM2W_IFACE_OFFS_BUFFER
adiw xh:xl, 1
ldd r18, Z+NETMSG_OFFS_MSGLEN
inc r18
inc r18
inc r18
com2wReceiveNextPkg_copyLoop:
ld r17, Z+
st X+, r17
dec r18
brne com2wReceiveNextPkg_copyLoop
pop zh
pop zl
; add to incoming msg pool
rcall NET_AddIncomingMsgNum ; (R17, R18, X)
brcc com2wReceiveNextPkg_eMissed
ldi r16, NET_IFACE_OFFS_PACKETSIN_LOW
rcall NET_Interface_IncCounter16 ; (R24, R25)
sec
rjmp com2wReceiveNextPkg_end
com2wReceiveNextPkg_eCrc:
push r16
ldi r16, NET_IFACE_OFFS_ERR_CONTENT_LOW
rcall NET_Interface_IncCounter16 ; (R24, R25)
pop r16
rjmp com2wReceiveNextPkg_relBuffer
com2wReceiveNextPkg_eMissed:
push r16
ldi r16, NET_IFACE_OFFS_ERR_MISSED_LOW
rcall NET_Interface_IncCounter16 ; (R24, R25)
pop r16
; fall-through to release buffer
com2wReceiveNextPkg_relBuffer:
rcall NET_Buffer_ReleaseByNum ; (R16, X)
clc
com2wReceiveNextPkg_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2wReceiveAndCheckMsg
;
; Receive a packet into buffer pointed to by X.
; Expects interrupts to be disabled.
;
; @param R18 COM address to listen to
; @param R19 max buffer size
; @param X buffer to receive to
; @return CFLAG set if msg received, cleared on error
; @clobbers R16 (R17, R18, R19, R20, R22, R24, R25)
com2wReceiveAndCheckMsg:
push xl
push xh
rcall com2wRecvMsg ; (r16, r17, r18, r19, r20, r22, r24, r25, X)
pop xh
pop xl
brcs com2wReceiveAndCheckMsg_recvd
; fall-through, return with CF cleared (from com2wRecvMsg)
ret
com2wReceiveAndCheckMsg_recvd:
push xl
push xh
rcall NETMSG_CheckMessageInBuffer ; (R16, R17, R18, R19, R20, X)
pop xh
pop xl
brcs com2wReceiveAndCheckMsg_msgOk
ldi r16, NET_IFACE_OFFS_ERR_CONTENT_LOW
rcall NET_Interface_IncCounter16 ; (R24, R25)
clc
ret
com2wReceiveAndCheckMsg_msgOk:
ldi r16, NET_IFACE_OFFS_PACKETSIN_LOW
rcall NET_Interface_IncCounter16 ; (R24, R25)
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2wSendNextPkg @global
;
; 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, R20, R22, R24, R25, X)
com2wSendNextPkg:
rcall NET_Interface_PeekNextOutgoingMsgNum ; (R17, R18, X)
brcc com2wSendNextPkg_end
rcall NET_Buffer_Locate ; get pointer to buffer (R17)
brcc com2wSendNextPkg_end
adiw xh:xl, 1 ; skip buffer header
rcall com2wSendMsg ; (R16, R18, R20, R22, R24, R25, X)
brcc com2wSendNextPkg_end
rcall NET_Interface_GetNextOutgoingMsgNum ; remove from stack (R17, R18, X)
rcall NET_Buffer_ReleaseByNum ; release buffer (R16, X)
sec
com2wSendNextPkg_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2wSendMsg
;
; @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)
com2wSendMsg:
ldi r20, 11 ; wait for about 55us for clock low
rcall com2wWaitForClockLowMulti5Us
brcs com2wSendMsg_busy ; CLK got low while waiting, so line is busy
push r15
in r15, SREG
cli ; atomic disable irq and set CLK low
rcall com2wDisableClkIrq ; (none)
rcall com2wClkSetLow ; 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 com2wWaitTime1 ; longer wait period (R22)
rcall com2wSendBytes ; (r16, r17, r18, r22, X)
rcall com2wClkSetHigh ; make sure bus is released
rcall com2wDataSetHigh
rcall com2wEnableClkIrq ; (none)
ldi r16, NET_IFACE_OFFS_PACKETSOUT_LOW
rcall NET_Interface_IncCounter16 ; (R24, R25)
sec
ret
com2wSendMsg_busy:
ldi r16, NET_IFACE_OFFS_ERR_BUSY_LOW
rcall NET_Interface_IncCounter16 ; (R24, R25)
clc
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2wSendBytes
;
; @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)
com2wSendBytes:
com2wSendBytes_loop:
rcall com2wClkSetLow ; (none)
rcall com2wWaitTime1 ; longer wait period (R22)
ld r16, X+
rcall com2wSendByte ; (R16, R17, R22)
dec r18
brne com2wSendBytes_loop
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2wSendByte
;
; @param R16 byte to send
; @clobbers: r16, r17 (r22)
com2wSendByte:
ldi r17, 8
com2wSendByte_loop:
rcall com2wClkSetLow
rcall com2wWaitTime1 ; longer wait period (R22)
lsr r16
brcs com2wSendByte_send1
rcall com2wDataSetLow
rjmp com2wSendByte_sent
com2wSendByte_send1:
rcall com2wDataSetHigh
com2wSendByte_sent:
rcall com2wWaitTime2 ; shorter wait period (R22)
push r15
in r15, SREG
cli ; ensure time period by disabling irqs
rcall com2wClkSetHigh
rcall com2wWaitTime1 ; longer wait period (R22)
out SREG, r15
pop r15
dec r17
brne com2wSendByte_loop
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2wRecvMsg
;
; Receive a packet into buffer pointed to by X.
; Expects interrupts to be disabled.
;
; @param R18 COM address to listen to
; @param R19 max buffer size
; @param X buffer to receive to
; @return CFLAG set if msg received, cleared on error (see R16)
; @return R16 if CFLAG cleared: 0=message not for this node, otherwise error
; @clobbers r16, r17, r18, r19, r20, r22, r24, r25, X
com2wRecvMsg:
mov r21, r18 ; address
; read destination address
rcall com2wRecvByte ; (r17, r18, r20, r22)
brcc com2wRecvMsg_eIo
; check destination address
rjmp com2wRecvMsg_forMe ; DEBUG: don't check address
cp r16, r21
breq com2wRecvMsg_forMe
cpi r16, 0xff
breq com2wRecvMsg_forMe
clr r16
rjmp com2wRecvMsg_clcRet
com2wRecvMsg_forMe:
; store in buffer
subi r19, 1
brcs com2wRecvMsg_eBadSize
st X+, r16
; read remaining msg size
rcall com2wRecvByte ; (r17, r18, r20, r22)
brcc com2wRecvMsg_eIo
; store in buffer
subi r19, 1
brcs com2wRecvMsg_eBadSize
st X+, r16
inc r16 ; account for CRC byte
sub r19, r16
brcs com2wRecvMsg_eBadSize
mov r19, r16
com2wRecvMsg_loop:
rcall com2wRecvByte ; (r17, r18, r20, r22)
brcc com2wRecvMsg_eIo
st X+, r16
dec r19
brne com2wRecvMsg_loop
sec
rjmp com2wRecvMsg_end
com2wRecvMsg_eBadSize:
ldi r16, NET_IFACE_OFFS_ERR_MSGSIZE_LOW
rjmp com2wRecvMsg_incCounterRet
com2wRecvMsg_eIo:
ldi r16, NET_IFACE_OFFS_ERR_IO_LOW
com2wRecvMsg_incCounterRet:
rcall NET_Interface_IncCounter16 ; (R24, R25)
com2wRecvMsg_clcRet:
clc
com2wRecvMsg_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2wRecvByte
;
; @return CFLAG set if byte received, cleared on error
; @return r16 byte received
; @clobbers r17, r18, r20, r22
com2wRecvByte:
ldi r17, 8
clr r16
com2wRecvByte_loop:
ldi r20, 31 ; wait up to 155us for clock low
rcall com2wWaitForClockLowMulti5Us ; (R20, R22)
brcs com2wRecvByte_waitForClkHigh
ldi r20, 31 ; wait up to 155us for clock low
rcall com2wWaitForClockLowMulti5Us ; (R20, R22)
brcc com2wRecvByte_end
com2wRecvByte_waitForClkHigh:
ldi r20, 31 ; wait up to 155us for clock high
rcall com2wWaitForClockHighMulti5Us ; (R20, R22)
brcs com2wRecvByte_readBit
ldi r20, 31 ; wait up to 155us for clock high
rcall com2wWaitForClockHighMulti5Us ; (R20, R22)
brcc com2wRecvByte_end
com2wRecvByte_readBit:
; handle received bit
inr r18, COM_DATA_INPUT
andi r18, (1<<COM_DATA_PIN)
clc
breq com2wRecvByte_clockData
sec
com2wRecvByte_clockData:
ror r16
dec r17
brne com2wRecvByte_loop
sec
com2wRecvByte_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2wEnableClkIrq
;
; @clobbers
com2wEnableClkIrq:
push r16
inr r16, COM_IRQ_ADDR_CLK
sbr r16, (1<<COM_IRQ_BIT_CLK) ; enable pin change irq for CLK line
outr COM_IRQ_ADDR_CLK, r16
pop r16
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2wDisableClkIrq
;
; @clobbers none
com2wDisableClkIrq:
push r16
inr r16, COM_IRQ_ADDR_CLK
cbr r16, (1<<COM_IRQ_BIT_CLK) ; disable pin change irq for CLK line
outr COM_IRQ_ADDR_CLK, r16
pop r16
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2wClkSetHigh
;
; @clobbers none
com2wClkSetHigh:
cbi COM_CLK_DDR, COM_CLK_PIN ; set CLK as input
.ifdef COM_CLK_PUE
; cbi COM_CLK_PUE, COM_CLK_PIN ; disable pullup on CLK
.else
cbi COM_CLK_OUTPUT, COM_CLK_PIN ; disable pullup on CLK
.endif
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2wClkSetLow
;
; @clobbers none
com2wClkSetLow:
sbi COM_CLK_DDR, COM_CLK_PIN ; set CLK as output
cbi COM_CLK_OUTPUT, COM_CLK_PIN ; set CLK low
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2wDataSetHigh
;
; @clobbers none
com2wDataSetHigh:
cbi COM_DATA_DDR, COM_DATA_PIN ; set DATA as input
.ifdef COM_DATA_PUE
; cbi COM_DATA_PUE, COM_CLK_PIN ; disable pullup on DATA
.else
cbi COM_DATA_OUTPUT, COM_DATA_PIN ; disable pullup on DATA
.endif
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2wDataSetLow
;
; @clobbers none
com2wDataSetLow:
sbi COM_DATA_DDR, COM_DATA_PIN ; set DATA as output
cbi COM_DATA_OUTPUT, COM_DATA_PIN ; set DATA low
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2wWaitForClockHighMulti5Us
;
; Wait for high CLK
;
; @param R20 multiple of 5us to wait (e.g. "2" for "10" us, max: 64)
; @return CFLAG set if okay (state reached), cleared on error
; @clobbers: r20, r22
com2wWaitForClockHighMulti5Us:
.if clock == 8000000
add r20, r20 ; *2
add r20, r20 ; *4
add r20, r20 ; *8
.endif
.elif clock == 1000000
; nothing to do
.else
.error "Unhandled clock speed"
.endif
com2wWaitForClockHighMulti5Us_loop: ; 5 cycles per loop
sbic COM_CLK_INPUT, COM_CLK_PIN ; +2 if skipped, +1 if not
rjmp com2wWaitForClockHighMulti5Us_stateReached ; +2
dec r20 ; +1
brne com2wWaitForClockHighMulti5Us_loop ; +2
clc ; +1
ret ; +4
com2wWaitForClockHighMulti5Us_stateReached:
sec ; +1
ret ; +4
; @end
; ---------------------------------------------------------------------------
; @routine com2wWaitForClockLowMulti5Us
;
; Wait for low CLK
;
; @param R20 multiple of 5us to wait (e.g. "2" for "10" us, max: 64)
; @return CFLAG set if okay (state reached), cleared on error
; @clobbers: r20, r22
com2wWaitForClockLowMulti5Us:
.if clock == 8000000
add r20, r20 ; *2
add r20, r20 ; *4
add r20, r20 ; *8
.endif
.elif clock == 1000000
; nothing to do
.else
.error "Unhandled clock speed"
.endif
com2wWaitForClockLowMulti5Us_loop: ; 5 cycles per loop
sbis COM_CLK_INPUT, COM_CLK_PIN ; +2 if skipped, +1 if not
rjmp com2wWaitForClockLowMulti5Us_stateReached ; +2
dec r20 ; +1
brne com2wWaitForClockLowMulti5Us_loop ; +2
clc ; +1
ret ; +4
com2wWaitForClockLowMulti5Us_stateReached:
sec ; +1
ret ; +4
; @end
; ---------------------------------------------------------------------------
; @routine com2wWaitTime1
;
; waits for longer period (e.g. 30ns)
;
; @clobbers R22
com2wWaitTime1:
Utils_WaitNanoSecs COM2W_WAITTIME1, 7, r22 ; wait for longer time (minus RCALL and RET)
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2wWaitTime2
;
; waits for shorter period (e.g. 10ns)
;
; @clobbers R22
com2wWaitTime2:
Utils_WaitNanoSecs COM2W_WAITTIME2, 7, r22 ; wait for shorter time (minus RCALL and RET)
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2wPcintIsr @global @isr
;
; ISR for PCINT0/1
;
; @clobbers: none
com2wPcintIsr:
push r15
in r15, SREG
sbic COM_CLK_INPUT, COM_CLK_PIN
rjmp com2wPcintIsr_end
; low, read packet
push r16
push r17
push r18
push r19
push r20
push r21
push r22
push r24
push r25
push xl
push xh
push yl
push yh
ldi yl, LOW(com2w_iface)
ldi yh, HIGH(com2w_iface)
rcall com2wReceiveNextPkg ; (R16, R17, R18, R19, R20, R21, R22, R24, R25, X)
pop yh
pop yl
pop xh
pop xl
pop r25
pop r24
pop r22
pop r21
pop r20
pop r19
pop r18
pop r17
pop r16
com2wPcintIsr_end:
out SREG, r15
pop r15
reti
; @end
#endif ; AVR_MODULES_COM2W_COM2W_H

View File

@@ -0,0 +1,643 @@
; ***************************************************************************
; 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_COM2W0_H
#define AVR_MODULES_COM2W_COM2W0_H
.dseg
com2w0_iface: .byte COM2W_IFACE_SIZE
.cseg
; ---------------------------------------------------------------------------
; @routine COM2W0_Init
;
; @clobbers
COM2W0_Init:
ldi yl, LOW(com2w0_iface)
ldi yh, HIGH(com2w0_iface)
rcall NET_Interface_Init ; (R16, R17, X)
ldi r16, COM2W_MODE_IDLE
rcall com2wSetMode ; (R17)
; setup CLK line (as input, disable internal pull-up resistor)
cbi COM_CLK0_DDR, COM_CLK0_PIN ; set CLK as input
.ifdef COM_CLK0_PUE
inr r16, COM_CLK0_PUE
cbr r16, (1<<COM_CLK0_PIN) ; disable pullup on CLK
outr COM_CLK0_PUE, r16
.else
cbi COM_CLK0_OUTPUT, COM_CLK0_PIN ; disable pullup on CLK
.endif
; setup DATA line (as input, disable internal pull-up resistor)
cbi COM_DATA0_DDR, COM_DATA0_PIN ; set DATA as input
.ifdef COM_DATA0_PUE
inr r16, COM_DATA0_PUE
cbr r16, (1<<COM_DATA0_PIN) ; disable pullup on DATA
outr COM_DATA0_PUE, r16
.else
cbi COM_DATA0_OUTPUT, COM_DATA0_PIN ; disable pullup on DATA
.endif
; setup pin-change interrupt for CLK
rcall com2w0EnableClkIrq
inr r16, COM_IRQ_ADDR_CLK0
sbr r16, (1<<COM_IRQ_BIT_CLK0) ; enable pin change irq for ATTN line
outr COM_IRQ_ADDR_CLK0, r16
inr r16, GIMSK ; enable pin change irq PCIE0 or PCIE1
sbr r16, (1<<COM_IRQ_GIMSK_CLK0)
outr GIMSK, r16
ldi r16, (1<<COM_IRQ_GIFR_CLK0) ; clear pending irq by writing 1 to ATTN bit
outr GIFR, r16
ret
; @end
; ---------------------------------------------------------------------------
; @routine COM2W0_Periodically @global
;
; @clobbers R16, Y
COM2W0_Periodically:
ldi yl, LOW(com2w0_iface)
ldi yh, HIGH(com2w0_iface)
rcall com2wPeriodically
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2w0EnableClkIrq
;
; @clobbers
com2w0EnableClkIrq:
push r16
inr r16, COM_IRQ_ADDR_CLK0
sbr r16, (1<<COM_IRQ_BIT_CLK0) ; enable pin change irq for CLK line
outr COM_IRQ_ADDR_CLK0, r16
pop r16
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2w0DisableClkIrq
;
; @clobbers none
com2w0DisableClkIrq:
push r16
inr r16, COM_IRQ_ADDR_CLK0
cbr r16, (1<<COM_IRQ_BIT_CLK0) ; disable pin change irq for CLK line
outr COM_IRQ_ADDR_CLK0, r16
pop r16
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2w0ClkSetHigh
;
; @clobbers none
com2w0ClkSetHigh:
cbi COM_CLK0_DDR, COM_CLK0_PIN ; set CLK as input
.ifdef COM_CLK0_PUE
; cbi COM_CLK0_PUE, COM_CLK0_PIN ; disable pullup on CLK
.else
cbi COM_CLK0_OUTPUT, COM_CLK0_PIN ; disable pullup on CLK
.endif
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2w0ClkSetLow
;
; @clobbers none
com2w0ClkSetLow:
sbi COM_CLK0_DDR, COM_CLK0_PIN ; set CLK as output
cbi COM_CLK0_OUTPUT, COM_CLK0_PIN ; set CLK low
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2w0DataSetHigh
;
; @clobbers none
com2w0DataSetHigh:
cbi COM_DATA0_DDR, COM_DATA0_PIN ; set DATA as input
.ifdef COM_DATA0_PUE
; cbi COM_DATA0_PUE, COM_CLK0_PIN ; disable pullup on DATA
.else
cbi COM_DATA0_OUTPUT, COM_DATA0_PIN ; disable pullup on DATA
.endif
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2w0DataSetLow
;
; @clobbers none
com2w0DataSetLow:
sbi COM_DATA0_DDR, COM_DATA0_PIN ; set DATA as output
cbi COM_DATA0_OUTPUT, COM_DATA0_PIN ; set DATA low
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2w0ReadNextBit
;
; @clobbers r16, r17, r18, r20, r22
com2w0ReadNextBit:
; ldi r20, 50 ; wait for up to 250us for clock rise
; rcall com2w0WaitForClockHighMulti5Us ; (R20, R22)
; brcc com2w0ReadNextBit_end
; clock is high now, read bit
inr r17, COM_DATA0_INPUT
; reset read timer (for leaving skipping mode)
clr r16
std Y+NET_IFACE_OFFS_READTIMER, r16
; check mode
ldd r16, Y+COM2W_IFACE_OFFS_MODE
cpi r16, COM2W_MODE_READING
brne com2w0ReadNextBit_end
; handle received bit
ldd r16, Y+COM2W_IFACE_OFFS_CURRBYTE
ldd r18, Y+COM2W_IFACE_OFFS_BITCOUNTER
andi r17, (1<<COM_DATA0_PIN)
clc
breq com2w0ReadNextBit_clockData
sec
com2w0ReadNextBit_clockData:
ror r16
std Y+COM2W_IFACE_OFFS_CURRBYTE, r16
inc r18 ; bit counter
std Y+COM2W_IFACE_OFFS_BITCOUNTER, r18
cpi r18, 8
brne com2w0ReadNextBit_end
; write byte into buffer
push xl
push xh
rcall com2wByteRecvd ; (r16, r17, r18, X)
pop xh
pop xl
; prepare for next byte
clr r16
std Y+COM2W_IFACE_OFFS_BITCOUNTER, r16
std Y+COM2W_IFACE_OFFS_CURRBYTE, r16
com2w0ReadNextBit_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2w0WaitForClockHighMulti5Us
;
; Wait for high CLK
;
; @param R20 multiple of 5us to wait (e.g. "2" for "10" us, max: 64)
; @return CFLAG set if okay (state reached), cleared on error
; @clobbers: r20, r22
com2w0WaitForClockHighMulti5Us:
.if clock == 8000000
add r20, r20 ; *2
add r20, r20 ; *4
add r20, r20 ; *8
.endif
.elif clock == 1000000
; nothing to do
.else
.error "Unhandled clock speed"
.endif
com2w0WaitForClockHighMulti5Us_loop: ; 5 cycles per loop
sbic COM_CLK0_INPUT, COM_CLK0_PIN ; +2 if skipped, +1 if not
rjmp com2w0WaitForClockHighMulti5Us_stateReached ; +2
dec r20 ; +1
brne com2w0WaitForClockHighMulti5Us_loop ; +2
clc ; +1
ret ; +4
com2w0WaitForClockHighMulti5Us_stateReached:
sec ; +1
ret ; +4
; @end
; ---------------------------------------------------------------------------
; @routine com2w0WaitForClockLowMulti5Us
;
; Wait for low CLK
;
; @param R20 multiple of 5us to wait (e.g. "2" for "10" us, max: 64)
; @return CFLAG set if okay (state reached), cleared on error
; @clobbers: r20, r22
com2w0WaitForClockLowMulti5Us:
.if clock == 8000000
add r20, r20 ; *2
add r20, r20 ; *4
add r20, r20 ; *8
.endif
.elif clock == 1000000
; nothing to do
.else
.error "Unhandled clock speed"
.endif
com2w0WaitForClockLowMulti5Us_loop: ; 5 cycles per loop
sbis COM_CLK0_INPUT, COM_CLK0_PIN ; +2 if skipped, +1 if not
rjmp com2w0WaitForClockLowMulti5Us_stateReached ; +2
dec r20 ; +1
brne com2w0WaitForClockLowMulti5Us_loop ; +2
clc ; +1
ret ; +4
com2w0WaitForClockLowMulti5Us_stateReached:
sec ; +1
ret ; +4
; @end
; ---------------------------------------------------------------------------
; @routine com2w0SendMsg
;
; @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)
com2w0SendMsg:
ldi r20, 11 ; wait for about 55us for clock low
rcall com2w0WaitForClockLowMulti5Us ; (R20, R22)
brcs com2w0SendMsg_busy ; CLK got low while waiting, so line is busy
push r15
in r15, SREG
cli ; atomic disable irq and set CLK low
rcall com2w0DisableClkIrq ; (none)
rcall com2w0ClkSetLow ; 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 com2wWaitTime1 ; longer wait period (R22)
rcall com2w0SendBytes ; (r16, r17, r18, r22, X)
rcall com2w0ClkSetHigh ; make sure bus is released
rcall com2w0DataSetHigh
rcall com2w0EnableClkIrq ; (none)
ldi r16, NET_IFACE_OFFS_PACKETSOUT_LOW
rcall NET_Interface_IncCounter16 ; (R24, R25)
sec
ret
com2w0SendMsg_busy:
ldi r16, NET_IFACE_OFFS_ERR_BUSY_LOW
rcall NET_Interface_IncCounter16 ; (R24, R25)
clc
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2w0SendBytes
;
; @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)
com2w0SendBytes:
com2w0SendBytes_loop:
rcall com2w0ClkSetLow ; (none)
rcall com2wWaitTime1 ; longer wait period (R22)
ld r16, X+
rcall com2w0SendByte ; (R16, R17, R22)
dec r18
brne com2w0SendBytes_loop
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2w0SendByte
;
; @param R16 byte to send
; @clobbers: r16, r17 (r22)
com2w0SendByte:
ldi r17, 8
com2w0SendByte_loop:
rcall com2w0ClkSetLow
rcall com2wWaitTime1 ; longer wait period (R22)
lsr r16
brcs com2w0SendByte_send1
rcall com2w0DataSetLow
rjmp com2w0SendByte_sent
com2w0SendByte_send1:
rcall com2w0DataSetHigh
com2w0SendByte_sent:
rcall com2wWaitTime2 ; shorter wait period (R22)
push r15
in r15, SREG
cli ; ensure time period by disabling irqs
rcall com2w0ClkSetHigh
rcall com2wWaitTime1 ; longer wait period (R22)
out SREG, r15
pop r15
dec r17
brne com2w0SendByte_loop
ret
; @end
; ---------------------------------------------------------------------------
; @routine COM2W0_Run @global
;
; @return CFLAG set if something done, cleared otherwise
; @clobbers all
COM2W0_Run:
ldi yl, LOW(com2w0_iface)
ldi yh, HIGH(com2w0_iface)
rjmp com2w0RunMode ; (all but Y)
; @end
; ---------------------------------------------------------------------------
; @routine com2w0RunMode
;
; @clobbers all
com2w0RunMode:
cpi r16, COM2W_MODE_NUM
brcs COM2W0_Run_jump
ldi r16, COM2W_MODE_IDLE ; unknown mode, set to idle
rcall com2wSetMode ; (R17)
sec
ret
COM2W0_Run_jump:
ldi zl, LOW(com2w0ModeJumpTable)
ldi zh, HIGH(com2w0ModeJumpTable)
add zl, r16
adc zh, r16
sub zh, r16
ijmp
com2w0ModeJumpTable:
rjmp com2w0RunIdle
rjmp com2w0RunReading
rjmp com2w0RunSkipping
rjmp com2w0RunWriting
; @end
; ---------------------------------------------------------------------------
; @routine com2w0RunIdle
;
; @param Y pointer to interface data in SRAM
; @clobbers R16, R17, R22, R24, R25, X
com2w0RunIdle:
;rjmp com2w0RunIdle_end ; DEBUG
push r15
in r15, SREG
cli
; look for outbound message
rcall NET_Interface_PeekNextOutgoingMsgNum ; r16=msgNum
brcs com2w0RunIdle_haveMsg
out SREG, r15
pop r15
clc
rjmp com2w0RunIdle_end
com2w0RunIdle_haveMsg:
mov r24, r16
ldi r16, COM2W_MODE_WRITING
rcall com2wSetMode ; (R17)
mov r16, r24
out SREG, r15
pop r15
push r16
rcall NET_Buffer_Locate ; (R17)
adiw xh:xl, 1
rcall com2w0SendMsg ; (R16, R17, R22, R24, R25, X)
push r15
in r15, SREG ; save SREG (no CLI, we want to save CFLAG only)
ldi r16, COM2W_MODE_IDLE
rcall com2wSetMode ; (R17)
out SREG, r15 ; restore SREG
pop r15
pop r16
brcc com2w0RunIdle_end
push r15
in r15, SREG
cli
rcall NET_Interface_GetNextOutgoingMsgNum ; take current msg off the queue
rcall NET_Buffer_ReleaseByNum ; (R16, X)
out SREG, r15
pop r15
sec
com2w0RunIdle_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2w0RunReading
;
; @param Y pointer to interface data in SRAM
; @clobbers none
com2w0RunReading:
; check for timeout (Y+NET_IFACE_OFFS_READTIMER)
ldd r16, Y+NET_IFACE_OFFS_READTIMER
cpi r16, COM2W_READING_MAXREADCOUNTER
brcc com2w0RunReading_goIdle
ldd r16, Y+COM2W_IFACE_OFFS_MODECOUNTER
cpi r16, COM2W_READING_MAXMODECOUNTER
brcc com2w0RunReading_goIdle
clc
rjmp com2w0RunReading_end
com2w0RunReading_goIdle:
ldi r16, NET_IFACE_OFFS_ERR_IO_LOW
rcall NET_Interface_IncCounter16 ; (R24, R25)
ldi r16, COM2W_MODE_IDLE
rcall com2wSetMode ; (r17)
sec
com2w0RunReading_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2w0RunSkipping
;
; @param Y pointer to interface data in SRAM
; @clobbers r16 (r17)
com2w0RunSkipping:
; check for timeout (Y+NET_IFACE_OFFS_READTIMER)
ldd r16, Y+NET_IFACE_OFFS_READTIMER
cpi r16, COM2W_SKIPPING_MAXREADCOUNTER
brcc com2w0RunSkipping_goIdle
ldd r16, Y+COM2W_IFACE_OFFS_MODECOUNTER
cpi r16, COM2W_SKIPPING_MAXMODECOUNTER
brcc com2w0RunSkipping_goIdle
clc
rjmp com2w0RunSkipping_end
com2w0RunSkipping_goIdle:
ldi r16, COM2W_MODE_IDLE
rcall com2wSetMode ; (r17)
sec
com2w0RunSkipping_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2w0RunWriting
;
; @param Y pointer to interface data in SRAM
; @clobbers none
com2w0RunWriting:
; TODO: check for timeout
clc
ret
; @end
; ---------------------------------------------------------------------------
; @routine COM2W0_ClkChangeIsr @global @isr
;
; @clobbers none
COM2W0_ClkChangeIsr:
push r15
in r15, SREG
push r16
inr r16, COM_CLK0_INPUT ; read clk state early
rcall COM2W0_HandleClockInterrupt
pop r16
out SREG, r15
pop r15
reti
; @end
; ---------------------------------------------------------------------------
; @routine COM2W0_HandleClockInterrupt @global
;
; @param r16 data from COM_CLKn_INPUT
; @clobbers none
COM2W0_HandleClockInterrupt:
push r16
push r17
push r18
push xl
push xh
push yl
push yh
ldi yl, LOW(com2w0_iface)
ldi yh, HIGH(com2w0_iface)
rcall com2w0ActOnClock ; (r16, r17, r18, X)
pop yh
pop yl
pop xh
pop xl
pop r18
pop r17
pop r16
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2w0ActOnClock
;
; @param r16 data from COM_CLKn_INPUT
; @clobbers r16 (r17, r18, X)
com2w0ActOnClock:
andi r16, (1<<COM_CLK0_PIN)
brne com2w0ActOnClock_clockHigh
; clock low
ldd r17, Y+COM2W_IFACE_OFFS_MODE
cpi r17, COM2W_MODE_IDLE
brne com2w0ActOnClock_end
rcall com2wStartReading ; (r16, r17, X)
rjmp com2w0ActOnClock_end
com2w0ActOnClock_clockHigh:
ldd r17, Y+COM2W_IFACE_OFFS_MODE
cpi r17, COM2W_MODE_READING
brne com2w0ActOnClock_end
push r20
push r22
rcall com2w0ReadNextBit ; (r16, r17, r18, r20, r22)
pop r22
pop r20
com2w0ActOnClock_end:
ret
; @end
#endif ; AVR_MODULES_COM2W_COM2W0_H

View File

@@ -0,0 +1,638 @@
; ***************************************************************************
; 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_COM2W1_H
#define AVR_MODULES_COM2W_COM2W1_H
.dseg
com2w1_iface: .byte COM2W_IFACE_SIZE
.cseg
; ---------------------------------------------------------------------------
; @routine COM2W1_Init
;
; @clobbers
COM2W1_Init:
ldi yl, LOW(com2w1_iface)
ldi yh, HIGH(com2w1_iface)
rcall NET_Interface_Init ; (R16, R17, X)
ldi r16, COM2W_MODE_IDLE
rcall com2wSetMode ; (R17)
; setup CLK line (as input, disable internal pull-up resistor)
cbi COM_CLK1_DDR, COM_CLK1_PIN ; set CLK as input
.ifdef COM_CLK1_PUE
inr r16, COM_CLK1_PUE
cbr r16, (1<<COM_CLK1_PIN) ; disable pullup on CLK
outr COM_CLK1_PUE, r16
.else
cbi COM_CLK1_OUTPUT, COM_CLK1_PIN ; disable pullup on CLK
.endif
; setup DATA line (as input, disable internal pull-up resistor)
cbi COM_DATA1_DDR, COM_DATA1_PIN ; set DATA as input
.ifdef COM_DATA1_PUE
inr r16, COM_DATA1_PUE
cbr r16, (1<<COM_DATA1_PIN) ; disable pullup on DATA
outr COM_DATA1_PUE, r16
.else
cbi COM_DATA1_OUTPUT, COM_DATA1_PIN ; disable pullup on DATA
.endif
; setup pin-change interrupt for CLK
rcall com2w1EnableClkIrq
inr r16, COM_IRQ_ADDR_CLK1
sbr r16, (1<<COM_IRQ_BIT_CLK1) ; enable pin change irq for ATTN line
outr COM_IRQ_ADDR_CLK1, r16
inr r16, GIMSK ; enable pin change irq PCIE0 or PCIE1
sbr r16, (1<<COM_IRQ_GIMSK_CLK1)
outr GIMSK, r16
ldi r16, (1<<COM_IRQ_GIFR_CLK1) ; clear pending irq by writing 1 to ATTN bit
outr GIFR, r16
ret
; @end
; ---------------------------------------------------------------------------
; @routine COM2W1_Periodically @global
;
; @clobbers R16, Y
COM2W1_Periodically:
ldi yl, LOW(com2w1_iface)
ldi yh, HIGH(com2w1_iface)
rcall com2wPeriodically
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2w1EnableClkIrq
;
; @clobbers
com2w1EnableClkIrq:
push r16
inr r16, COM_IRQ_ADDR_CLK1
sbr r16, (1<<COM_IRQ_BIT_CLK1) ; enable pin change irq for CLK line
outr COM_IRQ_ADDR_CLK1, r16
pop r16
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2w1DisableClkIrq
;
; @clobbers none
com2w1DisableClkIrq:
push r16
inr r16, COM_IRQ_ADDR_CLK1
cbr r16, (1<<COM_IRQ_BIT_CLK1) ; disable pin change irq for CLK line
outr COM_IRQ_ADDR_CLK1, r16
pop r16
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2w1ClkSetHigh
;
; @clobbers none
com2w1ClkSetHigh:
cbi COM_CLK1_DDR, COM_CLK1_PIN ; set CLK as input
.ifdef COM_CLK1_PUE
; cbi COM_CLK1_PUE, COM_CLK1_PIN ; disable pullup on CLK
.else
cbi COM_CLK1_OUTPUT, COM_CLK1_PIN ; disable pullup on CLK
.endif
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2w1ClkSetLow
;
; @clobbers none
com2w1ClkSetLow:
sbi COM_CLK1_DDR, COM_CLK1_PIN ; set CLK as output
cbi COM_CLK1_OUTPUT, COM_CLK1_PIN ; set CLK low
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2w1DataSetHigh
;
; @clobbers none
com2w1DataSetHigh:
cbi COM_DATA1_DDR, COM_DATA1_PIN ; set DATA as input
.ifdef COM_DATA1_PUE
; cbi COM_DATA1_PUE, COM_CLK1_PIN ; disable pullup on DATA
.else
cbi COM_DATA1_OUTPUT, COM_DATA1_PIN ; disable pullup on DATA
.endif
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2w1DataSetLow
;
; @clobbers none
com2w1DataSetLow:
sbi COM_DATA1_DDR, COM_DATA1_PIN ; set DATA as output
cbi COM_DATA1_OUTPUT, COM_DATA1_PIN ; set DATA low
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2w1ReadNextBit
;
; @clobbers r16, r17, r18, r20, r22
com2w1ReadNextBit:
ldi r20, 50 ; wait for up to 250us for clock rise
rcall com2w1WaitForClockHighMulti5Us ; (R20, R22)
brcc com2w1ReadNextBit_end
; clock is high now, read bit
inr r17, COM_DATA1_INPUT
; reset read timer (for leaving skipping mode)
clr r16
std Y+NET_IFACE_OFFS_READTIMER, r16
; check mode
ldd r16, Y+COM2W_IFACE_OFFS_MODE
cpi r16, COM2W_MODE_READING
brne com2w1ReadNextBit_end
; handle received bit
ldd r16, Y+COM2W_IFACE_OFFS_CURRBYTE
ldd r18, Y+COM2W_IFACE_OFFS_BITCOUNTER
andi r17, (1<<COM_DATA1_PIN)
clc
breq com2w1ReadNextBit_clockData
sec
com2w1ReadNextBit_clockData:
ror r16
std Y+COM2W_IFACE_OFFS_CURRBYTE, r16
inc r18 ; bit counter
std Y+COM2W_IFACE_OFFS_BITCOUNTER, r18
cpi r18, 8
brne com2w1ReadNextBit_end
; write byte into buffer
push xl
push xh
rcall com2wByteRecvd ; (r16, r17, r18, X)
pop xh
pop xl
; prepare for next byte
clr r16
std Y+COM2W_IFACE_OFFS_BITCOUNTER, r16
std Y+COM2W_IFACE_OFFS_CURRBYTE, r16
com2w1ReadNextBit_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2w1WaitForClockHighMulti5Us
;
; Wait for high CLK
;
; @param R20 multiple of 5us to wait (e.g. "2" for "10" us, max: 64)
; @return CFLAG set if okay (state reached), cleared on error
; @clobbers: r20, r22
com2w1WaitForClockHighMulti5Us:
.if clock == 8000000
add r20, r20 ; *2
add r20, r20 ; *4
add r20, r20 ; *8
.endif
.elif clock == 1000000
; nothing to do
.else
.error "Unhandled clock speed"
.endif
com2w1WaitForClockHighMulti5Us_loop: ; 5 cycles per loop
sbic COM_CLK1_INPUT, COM_CLK1_PIN ; +2 if skipped, +1 if not
rjmp com2w1WaitForClockHighMulti5Us_stateReached ; +2
dec r20 ; +1
brne com2w1WaitForClockHighMulti5Us_loop ; +2
clc ; +1
ret ; +4
com2w1WaitForClockHighMulti5Us_stateReached:
sec ; +1
ret ; +4
; @end
; ---------------------------------------------------------------------------
; @routine com2w1WaitForClockLowMulti5Us
;
; Wait for low CLK
;
; @param R20 multiple of 5us to wait (e.g. "2" for "10" us, max: 64)
; @return CFLAG set if okay (state reached), cleared on error
; @clobbers: r20, r22
com2w1WaitForClockLowMulti5Us:
.if clock == 8000000
add r20, r20 ; *2
add r20, r20 ; *4
add r20, r20 ; *8
.endif
.elif clock == 1000000
; nothing to do
.else
.error "Unhandled clock speed"
.endif
com2w1WaitForClockLowMulti5Us_loop: ; 5 cycles per loop
sbis COM_CLK1_INPUT, COM_CLK1_PIN ; +2 if skipped, +1 if not
rjmp com2w1WaitForClockLowMulti5Us_stateReached ; +2
dec r20 ; +1
brne com2w1WaitForClockLowMulti5Us_loop ; +2
clc ; +1
ret ; +4
com2w1WaitForClockLowMulti5Us_stateReached:
sec ; +1
ret ; +4
; @end
; ---------------------------------------------------------------------------
; @routine com2w1SendMsg
;
; @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)
com2w1SendMsg:
ldi r20, 11 ; wait for about 55us for clock low
rcall com2w1WaitForClockLowMulti5Us
brcs com2w1SendMsg_busy ; CLK got low while waiting, so line is busy
push r15
in r15, SREG
cli ; atomic disable irq and set CLK low
rcall com2w1DisableClkIrq ; (none)
rcall com2w1ClkSetLow ; 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 com2wWaitTime1 ; longer wait period (R22)
rcall com2w1SendBytes ; (r16, r17, r18, r22, X)
rcall com2w1ClkSetHigh ; make sure bus is released
rcall com2w1DataSetHigh
rcall com2w1EnableClkIrq ; (none)
ldi r16, NET_IFACE_OFFS_PACKETSOUT_LOW
rcall NET_Interface_IncCounter16 ; (R24, R25)
sec
ret
com2w1SendMsg_busy:
ldi r16, NET_IFACE_OFFS_ERR_BUSY_LOW
rcall NET_Interface_IncCounter16 ; (R24, R25)
clc
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2w1SendBytes
;
; @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)
com2w1SendBytes:
com2w1SendBytes_loop:
rcall com2w1ClkSetLow ; (none)
rcall com2wWaitTime1 ; longer wait period (R22)
ld r16, X+
rcall com2w1SendByte ; (R16, R17, R22)
dec r18
brne com2w1SendBytes_loop
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2w1SendByte
;
; @param R16 byte to send
; @clobbers: r16, r17 (r22)
com2w1SendByte:
ldi r17, 8
com2w1SendByte_loop:
rcall com2w1ClkSetLow
rcall com2wWaitTime1 ; longer wait period (R22)
lsr r16
brcs com2w1SendByte_send1
rcall com2w1DataSetLow
rjmp com2w1SendByte_sent
com2w1SendByte_send1:
rcall com2w1DataSetHigh
com2w1SendByte_sent:
rcall com2wWaitTime2 ; shorter wait period (R22)
push r15
in r15, SREG
cli ; ensure time period by disabling irqs
rcall com2w1ClkSetHigh
rcall com2wWaitTime1 ; longer wait period (R22)
out SREG, r15
pop r15
dec r17
brne com2w1SendByte_loop
ret
; @end
; ---------------------------------------------------------------------------
; @routine COM2W1_Run @global
;
; @return CFLAG set if something done, cleared otherwise
; @clobbers all
COM2W1_Run:
ldi yl, LOW(com2w1_iface)
ldi yh, HIGH(com2w1_iface)
rjmp com2w1RunMode ; (all but Y)
; @end
; ---------------------------------------------------------------------------
; @routine com2w1RunMode
;
; @clobbers all
com2w1RunMode:
cpi r16, COM2W_MODE_NUM
brcs COM2W1_Run_jump
ldi r16, COM2W_MODE_IDLE ; unknown mode, set to idle
rcall com2wSetMode ; (R17)
sec
ret
COM2W1_Run_jump:
ldi zl, LOW(com2w1ModeJumpTable)
ldi zh, HIGH(com2w1ModeJumpTable)
add zl, r16
adc zh, r16
sub zh, r16
ijmp
com2w1ModeJumpTable:
rjmp com2w1RunIdle
rjmp com2w1RunReading
rjmp com2w1RunSkipping
rjmp com2w1RunWriting
; @end
; ---------------------------------------------------------------------------
; @routine com2w1RunIdle
;
; @param Y pointer to interface data in SRAM
; @clobbers R16, R17, R22, R24, R25, X
com2w1RunIdle:
rjmp com2w1RunIdle_end ; DEBUG
push r15
in r15, SREG
cli
; look for outbound message
rcall NET_Interface_PeekNextOutgoingMsgNum ; r16=msgNum
brcs com2w1RunIdle_haveMsg
out SREG, r15
pop r15
clc
rjmp com2w1RunIdle_end
com2w1RunIdle_haveMsg:
mov r24, r16
ldi r16, COM2W_MODE_WRITING
rcall com2wSetMode ; (R17)
mov r16, r24
out SREG, r15
pop r15
push r16
rcall NET_Buffer_Locate ; (R17)
adiw xh:xl, 1
rcall com2w1SendMsg ; (R16, R17, R22, R24, R25, X)
push r15
inr r15, SREG ; save SREG (no CLI, we want to save CFLAG only)
ldi r16, COM2W_MODE_IDLE
rcall com2wSetMode ; (R17)
out SREG, r15 ; restore SREG
pop r15
pop r16
brcc com2w1RunIdle_end
push r15
in r15, SREG
cli
rcall NET_Interface_GetNextOutgoingMsgNum ; take current msg off the queue
rcall NET_Buffer_ReleaseByNum ; (R16, X)
out SREG, r15
pop r15
sec
com2w1RunIdle_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2w1RunReading
;
; @param Y pointer to interface data in SRAM
; @clobbers none
com2w1RunReading:
; check for timeout (Y+NET_IFACE_OFFS_READTIMER)
ldd r16, Y+NET_IFACE_OFFS_READTIMER
cpi r16, COM2W_READING_MAXREADCOUNTER
brcc com2w1RunReading_goIdle
ldd r16, Y+COM2W_IFACE_OFFS_MODECOUNTER
cpi r16, COM2W_READING_MAXMODECOUNTER
brcc com2w1RunReading_goIdle
clc
rjmp com2w1RunReading_end
com2w1RunReading_goIdle:
ldi r16, NET_IFACE_OFFS_ERR_IO_LOW
rcall NET_Interface_IncCounter16 ; (R24, R25)
ldi r16, COM2W_MODE_IDLE
rcall com2wSetMode ; (r17)
sec
com2w1RunReading_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2w1RunSkipping
;
; @param Y pointer to interface data in SRAM
; @clobbers r16 (r17)
com2w1RunSkipping:
; check for timeout (Y+NET_IFACE_OFFS_READTIMER)
ldd r16, Y+NET_IFACE_OFFS_READTIMER
cpi r16, COM2W_SKIPPING_MAXREADCOUNTER
brcc com2w1RunSkipping_goIdle
ldd r16, Y+COM2W_IFACE_OFFS_MODECOUNTER
cpi r16, COM2W_SKIPPING_MAXMODECOUNTER
brcc com2w1RunSkipping_goIdle
clc
rjmp com2w1RunSkipping_end
com2w1RunSkipping_goIdle:
ldi r16, COM2W_MODE_IDLE
rcall com2wSetMode ; (r17)
sec
com2w1RunSkipping_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2w1RunWriting
;
; @param Y pointer to interface data in SRAM
; @clobbers none
com2w1RunWriting:
; TODO: check for timeout
clc
ret
; @end
; ---------------------------------------------------------------------------
; @routine COM2W1_ClkChangeIsr @global @isr
;
; @clobbers none
COM2W1_ClkChangeIsr:
push r15
in r15, SREG
push r16
inr r16, COM_CLK1_INPUT ; read clk state early
rcall COM2W1_HandleClockInterrupt
pop r16
out SREG, r15
pop r15
reti
; @end
; ---------------------------------------------------------------------------
; @routine COM2W1_HandleClockInterrupt @global
;
; @param r16 data from COM_CLKn_INPUT
; @clobbers none
COM2W1_HandleClockInterrupt:
push r16
push r17
push r18
push xl
push xh
push yl
push yh
ldi yl, LOW(com2w1_iface)
ldi yh, HIGH(com2w1_iface)
rcall com2w1ActOnClock ; (r16, r17, r18, X)
pop yh
pop yl
pop xh
pop xl
pop r18
pop r17
pop r16
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2w1ActOnClock
;
; @param r16 data from COM_CLKn_INPUT
; @clobbers r16 (r17, r18, X)
com2w1ActOnClock:
andi r16, (1<<COM_CLK1_PIN)
brne com2w1ActOnClock_end
ldd r17, Y+COM2W_IFACE_OFFS_MODE
cpi r17, COM2W_MODE_READING
breq com2w1ActOnClock_readBit
cpi r17, COM2W_MODE_IDLE
brne com2w1ActOnClock_end
rcall com2wStartReading ; (r16, r17, X)
com2w1ActOnClock_readBit:
push r20
push r22
rcall com2w1ReadNextBit ; (r16, r17, r18, r20, r22)
pop r22
pop r20
com2w1ActOnClock_end:
ret
; @end
#endif ; AVR_MODULES_COM2W_COM2W1_H

View File

@@ -0,0 +1,244 @@
; ***************************************************************************
; 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_COMMON_H
#define AVR_MODULES_COM2W_COMMON_H
; ---------------------------------------------------------------------------
; @routine com2wPeriodically @global
;
; @clobbers R16, Y
com2wPeriodically:
push r15
in r15, SREG
cli
rcall NET_Interface_Periodically
ldd r16, Y+COM2W_IFACE_OFFS_MODECOUNTER
inc r16
breq com2wPeriodically_end
std Y+COM2W_IFACE_OFFS_MODECOUNTER, r16
com2wPeriodically_end:
out SREG, r15
pop r15
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2wSetMode
;
; Doesn't change processor status flags!
;
; @param R16 mode
; @clobbers R17
com2wSetMode:
push r15
in r15, SREG
cli
ldd r17, Y+COM2W_IFACE_OFFS_MODE
cp r16, r17
breq com2wSetMode_end
std Y+COM2W_IFACE_OFFS_MODE, r16
clr r17
std Y+COM2W_IFACE_OFFS_MODECOUNTER, r17
com2wSetMode_end:
out SREG, r15
pop r15
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2wStartReading
;
; @param Y pointer to interface data in SRAM
; @clobbers R16, R17, X
com2wStartReading:
mov xl, yl
mov xh, yh
adiw xh:xl, COM2W_IFACE_OFFS_BUFFER
std Y+COM2W_IFACE_OFFS_BUFPOS_LOW, xl
std Y+COM2W_IFACE_OFFS_BUFPOS_HIGH, xh
ldi r16, COM2W_BUFFER_SIZE
std Y+COM2W_IFACE_OFFS_BUFLEFT, r16
clr r16
std Y+COM2W_IFACE_OFFS_BUFUSED, r16
ldi r16, COM2W_MODE_READING
rcall com2wSetMode ; (R17)
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2wByteRecvd
;
; @param r16 byte received
; @param Y pointer to interface data
; @return CFLAG set if okay, cleared on error
; @clobbers r16, r17, r18, X
com2wByteRecvd:
ldd xl, Y+COM2W_IFACE_OFFS_BUFPOS_LOW
ldd xh, Y+COM2W_IFACE_OFFS_BUFPOS_HIGH
ldd r17, Y+COM2W_IFACE_OFFS_BUFLEFT
ldd r18, Y+COM2W_IFACE_OFFS_BUFUSED
tst r17
breq com2wByteRecvd_overflow
st X+, r16
std Y+COM2W_IFACE_OFFS_BUFPOS_LOW, xl
std Y+COM2W_IFACE_OFFS_BUFPOS_HIGH, xh
inc r18
std Y+COM2W_IFACE_OFFS_BUFUSED, r18
dec r17
std Y+COM2W_IFACE_OFFS_BUFLEFT, r17
breq com2wByteRecvd_msgComplete
cpi r18, 2
sec
brne com2wByteRecvd_end
; determine msg size
inc r16 ; last byte was payload length, add byte for crc
cp r17, r16 ; compare remaining length against remaining space
brcs com2wByteRecvd_eMsgSize
std Y+COM2W_IFACE_OFFS_BUFLEFT, r16
tst r16
sec
brne com2wByteRecvd_end
com2wByteRecvd_msgComplete:
push r19 ; pushing these registers is now only needed *here* for every
push r20 ; message received. Otherwise they would have been pushed
push r24 ; on every bit adding much more execution time to the
push r25 ; irq service routine
push zl
push zh
rcall com2wMsgReceived ; (R16, R17, R18, R19, R20, R24, R25, X, Z)
pop zh
pop zl
pop r25
pop r24
pop r20
pop r19
rjmp com2wByteRecvd_end
com2wByteRecvd_overflow:
ldi r16, NET_IFACE_OFFS_ERR_MISSED_LOW
rjmp com2wByteRecvd_error
com2wByteRecvd_eMsgSize:
ldi r16, NET_IFACE_OFFS_ERR_MSGSIZE_LOW
com2wByteRecvd_error:
push r24
push r25
rcall NET_Interface_IncCounter16 ; (R24, R25)
pop r25
pop r24
ldi r16, COM2W_MODE_SKIPPING ; error, enter skipping mode
rcall com2wSetMode
clc
com2wByteRecvd_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2wMsgReceived
;
; @param Y pointer to interface data in SRAM
; @return CFLAG set if okay, cleared on error
; @clobbers R16, R17, R18, X, Z (R19, R20, R24, R25)
com2wMsgReceived:
mov xl, yl
mov xh, yh
adiw xh:xl, COM2W_IFACE_OFFS_BUFFER
mov zl, xl ; Z=buffer in IFACE
mov zh, xh
rcall NETMSG_CheckMessageInBuffer ; (R16, R17, R18, R19, R20, X)
brcc com2wMsgReceived_econtent
; msg valid, alloc buffer
rcall NET_Buffer_Alloc ; X=buffer, R16=bufnum (R16, R17, X)
brcc com2wMsgReceived_enobuf
mov r18, r16 ; buffer num
rcall NET_Interface_SetIfaceNumInBuffer ; (R16, R17)
adiw xh:xl, 1 ; skip buffer header
ldd r17, Y+COM2W_IFACE_OFFS_BUFUSED ; always is at least 2 here
com2wMsgReceived_copyLoop:
ld r16, Z+
st X+, r16
dec r17
brne com2wMsgReceived_copyLoop
mov r16, r18 ; buffer num
rcall NET_AddIncomingMsgNum ; (R17, R18, X)
brcc com2wMsgReceived_enoadd
ldi r16, NET_IFACE_OFFS_PACKETSIN_LOW
rcall NET_Interface_IncCounter16 ; (R24, R25)
sec
rjmp com2wMsgReceived_setIdleAndEnd
com2wMsgReceived_enoadd:
rcall NET_Buffer_ReleaseByNum
rjmp com2wMsgReceived_enobuf
com2wMsgReceived_enobuf:
ldi r16, NET_IFACE_OFFS_ERR_NOBUF_LOW
rjmp com2wMsgReceived_err
com2wMsgReceived_econtent:
ldi r16, NET_IFACE_OFFS_ERR_CONTENT_LOW
com2wMsgReceived_err:
rcall NET_Interface_IncCounter16 ; (R24, R25)
clc
com2wMsgReceived_setIdleAndEnd:
ldi r16, COM2W_MODE_IDLE
rcall com2wSetMode ; (R17, doesn't change CFLAG!)
com2wMsgReceived_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2wWaitTime1
;
; waits for longer period (e.g. 30ns)
;
; @clobbers R22
com2wWaitTime1:
Utils_WaitNanoSecs COM2W_WAITTIME1, 7, r22 ; wait for longer time (minus RCALL and RET)
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2wWaitTime2
;
; waits for shorter period (e.g. 10ns)
;
; @clobbers R22
com2wWaitTime2:
Utils_WaitNanoSecs COM2W_WAITTIME2, 7, r22 ; wait for shorter time (minus RCALL and RET)
ret
; @end
#endif ; AVR_MODULES_COM2W_COMMON_H

View File

@@ -0,0 +1,74 @@
; ***************************************************************************
; 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_DEFS_H
#define AVR_MODULES_COM2W_DEFS_H
.equ COM2W_WAITTIME1 = 30000
.equ COM2W_WAITTIME2 = 10000
.equ COM2W_SKIPPING_MAXREADCOUNTER = 1
.equ COM2W_SKIPPING_MAXMODECOUNTER = 20 ; stay max 2s in skipping mode
.equ COM2W_READING_MAXREADCOUNTER = 1
.equ COM2W_READING_MAXMODECOUNTER = 20 ; stay max 2s in reading mode
;
; .equ COM2W_DATA0_DDR = DDRA
; .equ COM2W_DATA0_INPUT = PINA
; .equ COM2W_DATA0_OUTPUT = PORTA
; .equ COM2W_DATA0_PUE = PUEA
; .equ COM2W_DATA0_PIN = PORTA2
;
; .equ COM2W_CLK0_DDR = DDRA
; .equ COM2W_CLK0_INPUT = PINA
; .equ COM2W_CLK0_OUTPUT = PORTA
; .equ COM2W_CLK0_PUE = PUEA
; .equ COM2W_CLK0_PIN = PORTA0
; .equ COM2W_IRQ_ADDR_CLK0 = PCMSK0
; .equ COM2W_IRQ_BIT_CLK0 = PCINT0 ; bit 0 in PCMSK0
; .equ COM2W_IRQ_GIFR_CLK0 = PCIF0
; .equ COM2W_IRQ_GIMSK_CLK0 = PCIE0
.equ COM2W_BUFFER_SIZE = NET_BUFFERS_SIZE-1
.equ COM2W_MODE_IDLE = 0
.equ COM2W_MODE_READING = 1
.equ COM2W_MODE_SKIPPING = 2
.equ COM2W_MODE_WRITING = 3
.equ COM2W_MODE_NUM = 4
.equ COM2W_IFACE_OFFS_BEGIN = NET_IFACE_SIZE
.equ COM2W_IFACE_OFFS_CURRBYTE = COM2W_IFACE_OFFS_BEGIN
.equ COM2W_IFACE_OFFS_BITCOUNTER = COM2W_IFACE_OFFS_BEGIN+1
.equ COM2W_IFACE_OFFS_MODE = COM2W_IFACE_OFFS_BEGIN+2
.equ COM2W_IFACE_OFFS_MODECOUNTER = COM2W_IFACE_OFFS_BEGIN+3
.equ COM2W_IFACE_OFFS_BUFPOS_LOW = COM2W_IFACE_OFFS_BEGIN+4
.equ COM2W_IFACE_OFFS_BUFPOS_HIGH = COM2W_IFACE_OFFS_BEGIN+5
.equ COM2W_IFACE_OFFS_BUFUSED = COM2W_IFACE_OFFS_BEGIN+6
.equ COM2W_IFACE_OFFS_BUFLEFT = COM2W_IFACE_OFFS_BEGIN+7
.equ COM2W_IFACE_OFFS_BUFFER = COM2W_IFACE_OFFS_BEGIN+8
.equ COM2W_IFACE_SIZE = COM2W_IFACE_OFFS_BUFFER+COM2W_BUFFER_SIZE
#endif ; AVR_MODULES_COM2W_DEFS_H

View File

@@ -306,10 +306,10 @@ Offset Length Meaning
2 1 command code
3 1 source address
---------------------------------------------------------
4 2 msg id/ref msg id
6 n data bytes
4 4 ROM address
8 n data bytes
---------------------------------------------------------
6+n 1 CRC8 byte
8+n 1 CRC8 byte

View File

@@ -9,6 +9,7 @@
flash4p.asm
flashxp.asm
flashprocess.asm
io_stub.asm
io.asm
io_attn.asm
io_bitbang.asm

View File

@@ -0,0 +1,462 @@
; ***************************************************************************
; 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_FLASH_IO_COM2W_H
#define AVR_MODULES_FLASH_IO_COM2W_H
.equ COM2W_WAITTIME1 = 30000
.equ COM2W_WAITTIME2 = 10000
; ***************************************************************************
; code
.cseg
; ---------------------------------------------------------------------------
; @routine ioRawInit
;
; Init raw message subsystem.
;
ioRawInit:
; setup CLK line (as input, disable internal pull-up resistor)
cbi COM_CLK_DDR, COM_CLK_PIN ; set CLK as input
.ifdef COM_CLK_PUE
inr r16, COM_CLK_PUE
cbr r16, (1<<COM_CLK_PIN) ; disable pullup on CLK
outr COM_CLK_PUE, r16
.else
cbi COM_CLK_OUTPUT, COM_CLK_PIN ; disable pullup on CLK
.endif
; setup DATA line (as input, disable internal pull-up resistor)
cbi COM_DATA_DDR, COM_DATA_PIN ; set DATA as input
.ifdef COM_DATA_PUE
inr r16, COM_DATA_PUE
cbr r16, (1<<COM_DATA_PIN) ; disable pullup on DATA
outr COM_DATA_PUE, r16
.else
cbi COM_DATA_OUTPUT, COM_DATA_PIN ; disable pullup on DATA
.endif
ret
; @end
; ---------------------------------------------------------------------------
; @routine ioRawSendMsg
;
; Send a message
;
ioRawSendMsg:
ioRawSendMsg_loop:
ldi xl, LOW(flashSendBuffer)
ldi xh, HIGH(flashSendBuffer)
ldi r19, FLASH_RECVBUFFER_MAXLEN
rcall com2wSendMsg
brcc ioRawSendMsg_loop
ret
; @end
; ---------------------------------------------------------------------------
; @routine ioRawWaitForValidMsg
;
; Wait for valid incoming msg
;
; @return CFLAG set if okay (packet received), cleared on error
ioRawWaitForValidMsg:
; wait for CLK low
ldi r19, 20 ; wait for up to 10s
ioRawWaitForValidMsg_waitLowLoop1:
.ifdef LED_PIN
sbi LED_PIN, LED_PINNUM ; toggle
.endif
ldi r18, 5
ioRawWaitForValidMsg_waitLowLoop2:
ldi r20, 20 ; wait for about 100us for clock low
rcall com2wWaitForClockLowMulti5Us ; R20, R22
brcs ioRawWaitForValidMsg_recvMsg
dec r18
brne ioRawWaitForValidMsg_waitLowLoop2
dec r19
brne ioRawWaitForValidMsg_waitLowLoop1
clc ; no msg received
rjmp ioRawWaitForValidMsg_end
ioRawWaitForValidMsg_recvMsg:
; receive message
ldi xl, LOW(flashRecvBuffer)
ldi xh, HIGH(flashRecvBuffer)
ldi r18, NET_MAINTENANCE_ADDR
ldi r19, FLASH_RECVBUFFER_MAXLEN
rcall com2wRecvMsg
brcc ioRawWaitForValidMsg_end
; validate CRC
ldi xl, LOW(flashRecvBuffer)
ldi xh, HIGH(flashRecvBuffer)
rcall NETMSG_CheckMessageInBuffer ; (R16, R17, R18, R19, R20, X)
ioRawWaitForValidMsg_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2wSendMsg
;
; @param X pointer to bytes to send
; @return CFLAG set if message sent, cleared otherwise
; @clobbers R18, R20 (R16, R17, R20, R22, X)
com2wSendMsg:
ldi r20, 11 ; wait for about 55us for clock low
rcall com2wWaitForClockLowMulti5Us
brcs com2wSendMsg_busy ; CLK got low while waiting, so line is busy
rcall com2wClkSetLow ; reserve bus (none)
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 com2wWaitTime1 ; longer wait period (R22)
rcall com2wSendBytes ; (r16, r17, r18, r22, X)
rcall com2wClkSetHigh ; make sure bus is released
rcall com2wDataSetHigh
sec
ret
com2wSendMsg_busy:
clc
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2wSendBytes
;
; @param R18 number of bytes to send
; @param X pointer to bytes to send
; @clobbers: r16, r18, X (r17, r22)
com2wSendBytes:
com2wSendBytes_loop:
rcall com2wClkSetLow ; (none)
rcall com2wWaitTime1 ; longer wait period (R22)
ld r16, X+
rcall com2wSendByte ; (R16, R17, R22)
dec r18
brne com2wSendBytes_loop
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2wSendByte
;
; @param R16 byte to send
; @clobbers: r16, r17 (r22)
com2wSendByte:
ldi r17, 8
com2wSendByte_loop:
rcall com2wClkSetLow
rcall com2wWaitTime1 ; longer wait period (R22)
lsr r16
brcs com2wSendByte_send1
rcall com2wDataSetLow
rjmp com2wSendByte_sent
com2wSendByte_send1:
rcall com2wDataSetHigh
com2wSendByte_sent:
rcall com2wWaitTime2 ; shorter wait period (R22)
rcall com2wClkSetHigh
rcall com2wWaitTime1 ; longer wait period (R22)
dec r17
brne com2wSendByte_loop
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2wRecvMsg
;
; Receive a packet into buffer pointed to by X.
; Expects interrupts to be disabled.
;
; @param R18 COM address to listen to
; @param R19 max buffer size
; @param X buffer to receive to
; @return CFLAG set if msg received, cleared on error (see R16)
; @return R16 if CFLAG cleared: 0=message not for this node, otherwise error
; @clobbers r16, r17, r18, r19, r20, r22, r24, r25, X
com2wRecvMsg:
mov r21, r18 ; address
; read destination address
rcall com2wRecvByte ; (r17, r18, r20, r22)
brcc com2wRecvMsg_eIo
; store in buffer
subi r19, 1
brcs com2wRecvMsg_eBadSize
st X+, r16
; read remaining msg size
rcall com2wRecvByte ; (r17, r18, r20, r22)
brcc com2wRecvMsg_eIo
; store in buffer
subi r19, 1
brcs com2wRecvMsg_eBadSize
st X+, r16
inc r16 ; account for CRC byte
sub r19, r16
brcs com2wRecvMsg_eBadSize
mov r19, r16
com2wRecvMsg_loop:
rcall com2wRecvByte ; (r17, r18, r20, r22)
brcc com2wRecvMsg_eIo
st X+, r16
dec r19
brne com2wRecvMsg_loop
sec
rjmp com2wRecvMsg_end
com2wRecvMsg_eBadSize:
com2wRecvMsg_eIo:
com2wRecvMsg_clcRet:
clc
com2wRecvMsg_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2wRecvByte
;
; @return CFLAG set if byte received, cleared on error
; @return r16 byte received
; @clobbers r17, r18, r20, r22
com2wRecvByte:
ldi r17, 8
clr r16
com2wRecvByte_loop:
ldi r20, 31 ; wait up to 155us for clock low
rcall com2wWaitForClockLowMulti5Us ; (R20, R22)
brcs com2wRecvByte_waitForClkHigh
ldi r20, 31 ; wait up to 155us for clock low
rcall com2wWaitForClockLowMulti5Us ; (R20, R22)
brcc com2wRecvByte_end
com2wRecvByte_waitForClkHigh:
ldi r20, 31 ; wait up to 155us for clock high
rcall com2wWaitForClockHighMulti5Us ; (R20, R22)
brcs com2wRecvByte_readBit
ldi r20, 31 ; wait up to 155us for clock high
rcall com2wWaitForClockHighMulti5Us ; (R20, R22)
brcc com2wRecvByte_end
com2wRecvByte_readBit:
; handle received bit
inr r18, COM_DATA_INPUT
andi r18, (1<<COM_DATA_PIN)
clc
breq com2wRecvByte_clockData
sec
com2wRecvByte_clockData:
ror r16
dec r17
brne com2wRecvByte_loop
sec
com2wRecvByte_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2wClkSetHigh
;
; @clobbers none
com2wClkSetHigh:
cbi COM_CLK_DDR, COM_CLK_PIN ; set CLK as input
.ifdef COM_CLK_PUE
; cbi COM_CLK_PUE, COM_CLK_PIN ; disable pullup on CLK
.else
cbi COM_CLK_OUTPUT, COM_CLK_PIN ; disable pullup on CLK
.endif
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2wClkSetLow
;
; @clobbers none
com2wClkSetLow:
sbi COM_CLK_DDR, COM_CLK_PIN ; set CLK as output
cbi COM_CLK_OUTPUT, COM_CLK_PIN ; set CLK low
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2wDataSetHigh
;
; @clobbers none
com2wDataSetHigh:
cbi COM_DATA_DDR, COM_DATA_PIN ; set DATA as input
.ifdef COM_DATA_PUE
; cbi COM_DATA_PUE, COM_CLK_PIN ; disable pullup on DATA
.else
cbi COM_DATA_OUTPUT, COM_DATA_PIN ; disable pullup on DATA
.endif
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2wDataSetLow
;
; @clobbers none
com2wDataSetLow:
sbi COM_DATA_DDR, COM_DATA_PIN ; set DATA as output
cbi COM_DATA_OUTPUT, COM_DATA_PIN ; set DATA low
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2wWaitForClockHighMulti5Us
;
; Wait for high CLK
;
; @param R20 multiple of 5us to wait (e.g. "2" for "10" us, max: 64)
; @return CFLAG set if okay (state reached), cleared on error
; @clobbers: r20, r22
com2wWaitForClockHighMulti5Us:
.if clock == 8000000
add r20, r20 ; *2
add r20, r20 ; *4
add r20, r20 ; *8
.endif
.elif clock == 1000000
; nothing to do
.else
.error "Unhandled clock speed"
.endif
com2wWaitForClockHighMulti5Us_loop: ; 5 cycles per loop
sbic COM_CLK_INPUT, COM_CLK_PIN ; +2 if skipped, +1 if not
rjmp com2wWaitForClockHighMulti5Us_stateReached ; +2
dec r20 ; +1
brne com2wWaitForClockHighMulti5Us_loop ; +2
clc ; +1
ret ; +4
com2wWaitForClockHighMulti5Us_stateReached:
sec ; +1
ret ; +4
; @end
; ---------------------------------------------------------------------------
; @routine com2wWaitForClockLowMulti5Us
;
; Wait for low CLK
;
; @param R20 multiple of 5us to wait (e.g. "2" for "10" us, max: 64)
; @return CFLAG set if okay (state reached), cleared on error
; @clobbers: r20, r22
com2wWaitForClockLowMulti5Us:
.if clock == 8000000
add r20, r20 ; *2
add r20, r20 ; *4
add r20, r20 ; *8
.endif
.elif clock == 1000000
; nothing to do
.else
.error "Unhandled clock speed"
.endif
com2wWaitForClockLowMulti5Us_loop: ; 5 cycles per loop
sbis COM_CLK_INPUT, COM_CLK_PIN ; +2 if skipped, +1 if not
rjmp com2wWaitForClockLowMulti5Us_stateReached ; +2
dec r20 ; +1
brne com2wWaitForClockLowMulti5Us_loop ; +2
clc ; +1
ret ; +4
com2wWaitForClockLowMulti5Us_stateReached:
sec ; +1
ret ; +4
; @end
; ---------------------------------------------------------------------------
; @routine com2wWaitTime1
;
; waits for longer period (e.g. 30ns)
;
; @clobbers R22
com2wWaitTime1:
Utils_WaitNanoSecs COM2W_WAITTIME1, 7, r22 ; wait for longer time (minus RCALL and RET)
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2wWaitTime2
;
; waits for shorter period (e.g. 10ns)
;
; @clobbers R22
com2wWaitTime2:
Utils_WaitNanoSecs COM2W_WAITTIME2, 7, r22 ; wait for shorter time (minus RCALL and RET)
ret
; @end
#endif ; AVR_MODULES_FLASH_IO_COM2W_H

View File

@@ -0,0 +1,60 @@
; ***************************************************************************
; 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. *
; ***************************************************************************
; ***************************************************************************
; code
.cseg
; ---------------------------------------------------------------------------
; @routine ioRawInit
;
; Init raw message subsystem.
;
ioRawInit:
ret
; @end
; ---------------------------------------------------------------------------
; @routine ioRawSendMsg
;
; Send a message
;
ioRawSendMsg:
ret
; @end
; ---------------------------------------------------------------------------
; @routine ioRawWaitForValidMsg
;
; Wait for valid incoming msg
;
; @return CFLAG set if okay (packet received), cleared on error
ioRawWaitForValidMsg:
ret
; @end

View File

@@ -124,6 +124,8 @@ NET_Buffer_ReleaseByNum_end:
NET_Buffer_Locate:
cpi r16, NET_BUFFERS_NUM
brcc NET_Buffer_Locate_end ; out of range
.if NET_BUFFERS_SIZE == 32
mov xh, r16 ; * 256
clr xl
lsr xh ; *128
@@ -132,10 +134,31 @@ NET_Buffer_Locate:
ror xl
lsr xh ; *32
ror xl
.elif NET_BUFFERS_SIZE == 28
clr r17
mov xl, r16 ; * 256
clr xh
lsl xl ; * 2
rol xh
add xl, r16 ; * 3
adc xh, r17
lsl xl ; * 6
rol xh
add xl, r16 ; * 7
adc xh, r17
lsl xl ; * 14
rol xh
lsl xl ; * 28
rol xh
.else
.error "Unhandled buffer size"
.endif
ldi r17, LOW(netBuffers)
add xl, r17
ldi r17, HIGH(netBuffers)
adc xh, r17
sec
NET_Buffer_Locate_end:
ret

View File

@@ -9,9 +9,12 @@
; defs
.equ NET_MSGNUMINBUF_SIZE = 4 ; max buffer nums in ringbuffer (global incoming)
.equ NET_IFACE_OUTMSGBUF_SIZE = 4 ; max buffer nums in ringbuffer (per interface outbound)
.equ NET_BUFFERS_SIZE = 28 ; CAVE: need to adapt routine NET_Buffer_Locate when changing this value!!
.equ NET_MSGNUMINBUF_SIZE = 8 ; max buffer nums in ringbuffer (global incoming)
.equ NET_IFACE_OUTMSGBUF_SIZE = 8 ; max buffer nums in ringbuffer (per interface outbound)
.equ NET_IFACE_BUFFER_INUSE_BIT = 7

View File

@@ -13,6 +13,9 @@
device-w.asm
memstats-w.asm
pong-w.asm
range-d.asm
range-r.asm
range-w.asm
reboot-d.asm
reboot-r.asm
recvstats-w.asm

View File

@@ -26,6 +26,7 @@
.equ NETMSG_CMD_CLAIM_ADDRESS = 62
.equ NETMSG_CMD_DENY_ADDRESS = 63
.equ NETMSG_CMD_ADDRESS_RANGE = 64
.equ NETMSG_CMD_REENUM = 65
.equ NETMSG_CMD_FLASH_START = 70
.equ NETMSG_CMD_FLASH_END = 71

View File

@@ -0,0 +1,18 @@
; ***************************************************************************
; 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. *
; ***************************************************************************
.equ NETMSG_RANGE_OFFS_UID = 4
.equ NETMSG_RANGE_OFFS_FROM = 8
.equ NETMSG_RANGE_OFFS_TO = 9

View File

@@ -0,0 +1,38 @@
; ***************************************************************************
; 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. *
; ***************************************************************************
; ***************************************************************************
; code
.cseg
; ---------------------------------------------------------------------------
; @routine NETMSG_RangeRead @global
; Read a RANGE message.
;
; @param X buffer to read from
; @return R18 command
; @return R20 range begin
; @return R21 range end
; @clobbers none
NETMSG_Range_Read:
adiw xh:xl, NETMSG_OFFS_CMD
ld r18, X ; command
adiw xh:xl, NETMSG_RANGE_OFFS_FROM-NETMSG_OFFS_CMD ; skip src addr and uid
ld r20, X+ ; range from
ld r21, X ; range to
sbiw xh:xl, NETMSG_RANGE_OFFS_TO ; back to msg begin
ret
; @end

View File

@@ -0,0 +1,44 @@
; ***************************************************************************
; 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. *
; ***************************************************************************
; ---------------------------------------------------------------------------
; @routine NETMSG_Range_Write
;
; @param Y pointer to device to write msg for
; @param X pointer to buffer to write to
; @param R18 command
; @param R20 range begin
; @param R21 range end
; @clobbers R16, R18 (R17, R19, R20, R21, Z)
NETMSG_Range_Write:
ldi r16, 0xff
st X+, r16 ; dest address
ldi r16, 8 ; msg code+src address+6 payload bytes
st X+, r16 ; msg len
st X+, r18 ; msg code
ldd r16, Y+NET_IFACE_OFFS_ADDRESS
st X+, r16 ; src address
push r20
push r21
rcall NETMSG_Common_AddUidToBuffer ; (R16, R18, R19, R20, R21)
pop r21
pop r20
st X+, r20 ; range begin
st X+, r21 ; range end
sbiw xh:xl, 10 ; go back to beginning of message (1 byte dst addr, 1 byte length, 8 bytes payload)
rcall NETMSG_CalcAndAddChecksumByte ; (R16, R17, R18, R19, R20, X)
sbiw xh:xl, 11 ; go back to beginning of message (1 byte dst addr, 1 byte length, 8 bytes payload, 1 byte crc)
ret
; @end

View File

@@ -33,15 +33,16 @@ ComOnUart0_Init:
ldi yl, LOW(comOnUart0_iface)
ldi yh, HIGH(comOnUart0_iface)
rcall NET_Interface_Init ; (R16, R17, X)
ldi r16, 0xff
std Y+UART_HW2_IFACE_OFFS_WRITEBUFNUM, r16
ldi r16, UART_HW2_MODE_IDLE
std Y+UART_HW2_IFACE_OFFS_MODE, r16
clr r16
std Y+NET_IFACE_OFFS_IFACENUM, r16
rcall comOnUart0SetAttnInput
sbi COM_IRQ_ADDR_ATTN0, COM_IRQ_BIT_ATTN0 ; enable pin change irq for ATTN line
inr r16, COM_IRQ_ADDR_ATTN0
sbr r16, (1<<COM_IRQ_BIT_ATTN0) ; enable pin change irq for ATTN line
outr COM_IRQ_ADDR_ATTN0, r16
inr r16, GIMSK ; enable pin change irq PCIE0 or PCIE1
sbr r16, (1<<COM_IRQ_GIMSK_ATTN0)
outr GIMSK, r16
@@ -131,7 +132,7 @@ comOnUart0StartReading:
adiw xh:xl, UART_HW2_IFACE_OFFS_BUFFER
std Y+UART_HW2_IFACE_OFFS_BUFPOS_LOW, xl
std Y+UART_HW2_IFACE_OFFS_BUFPOS_HIGH, xh
ldi r16, UART_HW2_BUFFER_SIZE-1
ldi r16, UART_HW2_BUFFER_SIZE
std Y+UART_HW2_IFACE_OFFS_BUFLEFT, r16
clr r16
std Y+UART_HW2_IFACE_OFFS_BUFUSED, r16
@@ -143,87 +144,35 @@ comOnUart0StartReading:
; ---------------------------------------------------------------------------
; @routine comOnUart0StartWriting
;
; @param Y pointer to interface data in SRAM
; @param R16 buffer number
; @return CFLAG set if writing started, cleared otherwise
; @clobbers R16, R17, X, Z (R22, R24, R25)
comOnUart0StartWriting:
push r15
inr r15, SREG
cli
rcall comOnUart0StartWriting_noIrq
brcc comOnUart0StartWriting_clc
outr SREG, r15
pop r15
sec
ret
comOnUart0StartWriting_clc:
outr SREG, r15
pop r15
clc
ret
comOnUart0StartWriting_noIrq:
rcall comOnUart0AcquireAttn ; (R22)
brcc comOnUart0StartWriting_ebusy
; copy buffer
rcall NET_Buffer_Locate ; (R17)
std Y+UART_HW2_IFACE_OFFS_WRITEBUFNUM, r16
adiw xh:xl, NETMSG_OFFS_MSGLEN+1
ld r17, X
sbiw xh:xl, NETMSG_OFFS_MSGLEN+1
subi r17, -3 ; add dest addr, msglen, crc
; TODO: check size!
std Y+UART_HW2_IFACE_OFFS_BUFUSED, r17
std Y+UART_HW2_IFACE_OFFS_BUFLEFT, r17
; copy into IFACE buffer
mov zl, yl
mov zh, yh
adiw zh:zl, UART_HW2_IFACE_OFFS_BUFFER ; dest
std Y+UART_HW2_IFACE_OFFS_BUFPOS_LOW, zl
std Y+UART_HW2_IFACE_OFFS_BUFPOS_HIGH, zh
adiw xh:xl, 1 ; src (skip buffer header)
comOnUart0StartWriting_loop:
ld r16, X+
st Z+, r16
dec r17
brne comOnUart0StartWriting_loop
ldi r16, UART_HW2_MODE_WRITING
rcall comOnUart0SetMode ; (R17)
rcall comOnUart0StartTx ; should be the last call here (R16)
sec
rjmp comOnUart0StartWriting_end
comOnUart0StartWriting_ebusy:
ldi r16, NET_IFACE_OFFS_ERR_BUSY_LOW
rcall NET_Interface_IncCounter16 ; (R24, R25)
clc
comOnUart0StartWriting_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine ComOnUart0_Run @global
;
; @return CFLAG set if something done, cleared otherwise
; @clobbers all
ComOnUart0_Run:
ldi yl, LOW(comOnUart0_iface)
ldi yh, HIGH(comOnUart0_iface)
ldd r16, Y+UART_HW2_IFACE_OFFS_MODE
clr r18
ComOnUart0_Run_loop:
push r16 ; current state
rcall comOnUart0RunMode ; (all but Y)
pop r17 ; previous state (pop from r16 into r17)
push r18
push r16 ; current state
rcall comOnUart0RunMode ; (all but Y)
pop r17 ; previous state (pop from r16 into r17)
pop r18
; read new state
ldd r16, Y+UART_HW2_IFACE_OFFS_MODE
cp r16, r17
brne ComOnUart0_Run_loop ; state changed, run again
breq ComOnUart0_Run_loopEnd
ldi r18, 1
rjmp ComOnUart0_Run_loop ; state changed, run again
ComOnUart0_Run_loopEnd:
tst r18
clc
breq ComOnUart0_Run_end
sec
ComOnUart0_Run_end:
ret
; @end
@@ -251,10 +200,7 @@ comOnUart0ModeJumpTable:
rjmp comOnUart0RunIdle
rjmp comOnUart0RunReading
rjmp comOnUart0RunSkipping
rjmp comOnUart0RunMsgReceived
rjmp comOnUart0RunWriting
rjmp comOnUart0RunWaitBufferEmpty
rjmp comOnUart0RunMsgSent
; @end
@@ -263,15 +209,48 @@ comOnUart0ModeJumpTable:
; @routine comOnUart0RunIdle
;
; @param Y pointer to interface data in SRAM
; @clobbers R16, R17, R24, R25, X, Z
; @clobbers R16, R17, R22, R24, R25, X
comOnUart0RunIdle:
; look for outbound message
rcall NET_Interface_PeekNextOutgoingMsgNum ; r16=msgNum
brcc comOnUart0RunIdle_end ; no outmsg in queue
rcall comOnUart0StartWriting ; (R16, R17, R22, R24, R25, X, Z)
push r15
inr r15, SREG
cli
; look for outbound message
rcall NET_Interface_PeekNextOutgoingMsgNum ; r16=msgNum
brcs comOnUart0RunIdle_haveMsg
out SREG, r15
pop r15
rjmp comOnUart0RunIdle_end
comOnUart0RunIdle_haveMsg:
mov r24, r16
ldi r16, UART_HW2_MODE_WRITING
rcall comOnUart0SetMode ; (R17)
mov r16, r24
out SREG, r15
pop r15
push r16
rcall NET_Buffer_Locate ; (R17)
adiw xh:xl, 1
rcall comOnUart0SendMsg ; (R16, R17, R22, R24, R25, X)
push r15
inr r15, SREG ; save SREG (no CLI, we want to save CFLAG only)
ldi r16, UART_HW2_MODE_IDLE
rcall comOnUart0SetMode ; (R17)
out SREG, r15 ; restore SREG
pop r15
pop r16
brcc comOnUart0RunIdle_end
rcall NET_Interface_GetNextOutgoingMsgNum ; take current msg off the queue
push r15
inr r15, SREG
cli
rcall NET_Interface_GetNextOutgoingMsgNum ; take current msg off the queue
rcall NET_Buffer_ReleaseByNum ; (R16, X)
out SREG, r15
pop r15
sec
comOnUart0RunIdle_end:
ret
; @end
@@ -308,12 +287,12 @@ comOnUart0RunSkipping_end:
; ---------------------------------------------------------------------------
; @routine comOnUart0RunMsgReceived
; @routine comOnUart0HandleMsgReceived
;
; @param Y pointer to interface data in SRAM
; @clobbers R16, R17, R18, X, Z (R19, R20, R24, R25)
comOnUart0RunMsgReceived:
comOnUart0HandleMsgReceived:
mov xl, yl
mov xh, yh
adiw xh:xl, UART_HW2_IFACE_OFFS_BUFFER
@@ -371,42 +350,6 @@ comOnUart0RunWriting:
; ---------------------------------------------------------------------------
; @routine comOnUart0RunWaitBufferEmpty
;
; @clobbers none
comOnUart0RunWaitBufferEmpty:
; TODO: check for timeout etc.
ret
; @end
; ---------------------------------------------------------------------------
; @routine comOnUart0RunWriting
;
; @param Y pointer to interface data in SRAM
; @clobbers R16 (R17, R22, R24, R25, X)
comOnUart0RunMsgSent:
ldd r16, Y+UART_HW2_IFACE_OFFS_WRITEBUFNUM
rcall NET_Buffer_ReleaseByNum ; (R16, X)
ldi r16, 0xff
std Y+UART_HW2_IFACE_OFFS_WRITEBUFNUM, r16
ldi r16, NET_IFACE_OFFS_PACKETSOUT_LOW
rcall NET_Interface_IncCounter16 ; (R24, R25)
ldi r16, UART_HW2_MODE_IDLE
rcall comOnUart0SetMode ; (R17)
rcall comOnUart0SetAttnInput ; release ATTN (none)
rcall Utils_WaitFor10MicroSecs ; make sure ATTN is at least high for a short period (R22)
ret
; @end
; ---------------------------------------------------------------------------
; @routine comOnUart0AcquireAttn
;
@@ -467,10 +410,11 @@ comOnUart0StopRx:
comOnUart0StartTx:
inr r16, UCSR0A
cbr r16, (1<<TXC0) ; clear TXCn interrupt
cbr r16, (1<<TXC0) ; clear TXCn interrupt
outr UCSR0A, r16
inr r16, UCSR0B
sbr r16, (1<<UDRIE0) | (1<<TXCIE0) | (1<<TXEN0) ; enable TX UDRE and TXC0 interrupt, enable transceive
cbr r16, (1<<UDRIE0) | (1<<TXCIE0) ; disable TX UDRE and TXC0 interrupt, enable transceive
sbr r16, (1<<TXEN0) ; enable TX UDRE and TXC0 interrupt, enable transceive
outr UCSR0B, r16
ret
; @end
@@ -484,7 +428,7 @@ comOnUart0StartTx:
comOnUart0StopTx:
inr r16, UCSR0B
cbr r16, (1<<UDRIE0) | (1<<TXCIE0) | (1<<TXEN0) ; disable TX UDRE and TXC0 interrupt, enable transceive
cbr r16, (1<<UDRIE0) | (1<<TXCIE0) | (1<<TXEN0) ; disable TX UDRE and TXC0 interrupt, disable transceive
outr UCSR0B, r16
ret
; @end
@@ -506,6 +450,13 @@ comOnUart0SetAttnInput:
.else
cbi COM_ATTN0_OUTPUT, COM_ATTN0_PIN ; disable pullup on ATTN
.endif
push r16
inr r16, COM_IRQ_ADDR_ATTN0
sbr r16, (1<<COM_IRQ_BIT_ATTN0) ; enable pin change irq for ATTN line
outr COM_IRQ_ADDR_ATTN0, r16
pop r16
ret
; @end
@@ -519,8 +470,13 @@ comOnUart0SetAttnInput:
; @clobbers none
comOnUart0SetAttnLow:
sbi COM_ATTN0_DDR, COM_ATTN0_PIN ; set ATTN as output
cbi COM_ATTN0_OUTPUT, COM_ATTN0_PIN ; set ATTN low
push r16
inr r16, COM_IRQ_ADDR_ATTN0
cbr r16, (1<<COM_IRQ_BIT_ATTN0) ; disable pin change irq for ATTN line
outr COM_IRQ_ADDR_ATTN0, r16
pop r16
sbi COM_ATTN0_DDR, COM_ATTN0_PIN ; set ATTN as output
cbi COM_ATTN0_OUTPUT, COM_ATTN0_PIN ; set ATTN low
ret
; @end
@@ -552,21 +508,29 @@ ComOnUart0_RxCharIsr:
push r16
push r17
push r18
push r24
push r25
push xl
push xh
push yl
push yh
ldi yl, LOW(comOnUart0_iface)
ldi yh, HIGH(comOnUart0_iface)
rcall comOnUart0RxCharIsr ; (R16, R17, R18, R24, R25, X)
pop yh
pop yl
pop xh
pop xl
pop r25
pop r24
push r19
push r20
push r24
push r25
push xl
push xh
push yl
push yh
push zl
push zh
ldi yl, LOW(comOnUart0_iface)
ldi yh, HIGH(comOnUart0_iface)
rcall comOnUart0RxCharIsr ; (R16, R17, R18, R19, R20, R24, R25, X, Z)
pop zh
pop zl
pop yh
pop yl
pop xh
pop xl
pop r25
pop r24
pop r20
pop r19
pop r18
pop r17
pop r16
@@ -577,62 +541,6 @@ ComOnUart0_RxCharIsr:
; ---------------------------------------------------------------------------
; @routine ComOnUart0_TxUdreIsr @global @isr
;
; @clobbers none
ComOnUart0_TxUdreIsr:
push r15
in r15, SREG
push r16
push r17
push xl
push xh
push yl
push yh
ldi yl, LOW(comOnUart0_iface)
ldi yh, HIGH(comOnUart0_iface)
rcall comOnUart0TxUdreIsr ; (R16, R17, X)
pop yh
pop yl
pop xh
pop xl
pop r17
pop r16
out SREG, r15
pop r15
reti
; @end
; ---------------------------------------------------------------------------
; @routine ComOnUart0_TxCharIsr @global @isr
;
; @clobbers none
ComOnUart0_TxCharIsr:
push r15
in r15, SREG
push r16
push r17
push yl
push yh
ldi yl, LOW(comOnUart0_iface)
ldi yh, HIGH(comOnUart0_iface)
rcall comOnUart0TxCharIsr ; (R16, R17)
pop yh
pop yl
pop r17
pop r16
out SREG, r15
pop r15
reti
; @end
; ---------------------------------------------------------------------------
; @routine ComOnUart0AttnChangeIsr @global @isr
;
@@ -707,7 +615,7 @@ comOnUart0ActOnAttn_end:
; @routine comOnUart0RxCharIsr @global
;
; @param Y pointer to interface data in SRAM
; @clobbers R16, R17, R18, R24, R25, X
; @clobbers R16, R17, R18, R19, R20, R24, R25, X, Z
comOnUart0RxCharIsr:
; check for errors
@@ -742,15 +650,18 @@ comOnUart0RxCharIsr:
brne comOnUart0RxCharIsr_end
; determine msg size
inc r16 ; last byte was payload length, add byte for crc
cp r16, r17 ; compare remaining length against remaining space
brcc comOnUart0RxCharIsr_emsgsize ; msg too long
; cp r16, r17 ; compare remaining length against remaining space
; brcc comOnUart0RxCharIsr_emsgsize ; msg too long
cp r17, r16 ; compare remaining length against remaining space
brcs comOnUart0RxCharIsr_emsgsize ; msg too long
std Y+UART_HW2_IFACE_OFFS_BUFLEFT, r16 ; set new number of bytes left
tst r16
brne comOnUart0RxCharIsr_end ; jmp if still bytes left to receive
comOnUart0RxCharIsr_complete:
rcall comOnUart0StopRx
ldi r16, UART_HW2_MODE_MSGRECEIVED
rcall comOnUart0SetMode ; (R17)
rcall comOnUart0HandleMsgReceived ; (R16, R17, R18, R19, R20, R24, R25, X, Z)
rjmp comOnUart0RxCharIsr_end
comOnUart0RxCharIsr_hwerr:
ldi r16, NET_IFACE_OFFS_ERR_IO_LOW
@@ -772,76 +683,56 @@ comOnUart0RxCharIsr_end:
; ---------------------------------------------------------------------------
; @routine comOnUart0TxUdreIsr @global
; @routine comOnUart0SendMsg
;
; Handler for UDRE1 interrupt called when TX data register is empty.
;
; @param Y pointer to interface data in SRAM (see @ref UART_HW_IFACE_OFFS_MODE)
; @clobbers R16, R17, X
; @param Y pointer to interface data in SRAM
; @param X pointer to buffer to send
; @return CFLAG set if writing started, cleared otherwise
; @clobbers R16, R17, X (R22, R24, R25)
comOnUart0TxUdreIsr:
inr r16, UCSR0A
sbrs r16, UDRE0
rjmp comOnUart0TxUdreIsr_disable_irq ; not ready
; check bytes left
ldd r17, Y+UART_HW2_IFACE_OFFS_BUFLEFT
tst r17
breq comOnUart0TxUdreIsr_finished
; read byte
ldd xl, Y+UART_HW2_IFACE_OFFS_BUFPOS_LOW
ldd xh, Y+UART_HW2_IFACE_OFFS_BUFPOS_HIGH
ld r16, X+
std Y+UART_HW2_IFACE_OFFS_BUFPOS_LOW, xl
std Y+UART_HW2_IFACE_OFFS_BUFPOS_HIGH, xh
; send byte
outr UDR0, r16 ; send byte
; decreased counter
dec r17
std Y+UART_HW2_IFACE_OFFS_BUFLEFT, r17
brne comOnUart0TxUdreIsr_end ; still bytes left to send, jump
comOnUart0TxUdreIsr_finished:
ldi r16, UART_HW2_MODE_WAITBUFFEREMPTY
rcall comOnUart0SetMode ; (R17)
comOnUart0TxUdreIsr_disable_irq:
; disable further DRE interrupts
inr r16, UCSR0B
cbr r16, (1<<UDRIE0) ; disable TX data register empty interrupt
outr UCSR0B, r16
comOnUart0TxUdreIsr_end:
comOnUart0SendMsg:
rcall comOnUart0AcquireAttn ; (R22)
brcc comOnUart0SendMsg_ebusy
adiw xh:xl, NETMSG_OFFS_MSGLEN
ld r17, X
sbiw xh:xl, NETMSG_OFFS_MSGLEN
subi r17, -3 ; add dest addr, msglen, crc
rcall comOnUart0StartTx ; (R16)
; TODO: check size!
; r17=number of bytes to write, X=buffer
comOnUart0SendMsg_loop:
; wait until transceiver ready
inr r16, UCSR0A
sbrs r16, UDRE0
rjmp comOnUart0SendMsg_loop
; clear TXC flag by sending a 1
sbr r16, (1<<TXC0)
outr UCSR0A, r16
; write byte to uart data register
ld r16, X+
outr UDR0, r16
dec r17
brne comOnUart0SendMsg_loop
; wait until all data send (i.e. send buffer empty and all bits shifted out)
comOnUart0SendMsg_loopComplete:
inr r16, UCSR0A
sbrs r16, TXC0
rjmp comOnUart0SendMsg_loopComplete
rcall comOnUart0StopTx ; (R16)
ldi r16, NET_IFACE_OFFS_PACKETSOUT_LOW
rcall NET_Interface_IncCounter16 ; (R24, R25)
rcall comOnUart0SetAttnInput ; release ATTN (none)
rcall Utils_WaitFor10MicroSecs ; make sure ATTN is at least high for a short period (R22)
sec
rjmp comOnUart0SendMsg_end
comOnUart0SendMsg_ebusy:
ldi r16, NET_IFACE_OFFS_ERR_BUSY_LOW
rcall NET_Interface_IncCounter16 ; (R24, R25)
clc
comOnUart0SendMsg_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine comOnUart0TxCharIsr @global
;
; Handler for TXC0 interrupt called when the last byte has been completely sent and
; the data register is empty.
;
; @param Y pointer to interface data in SRAM (see @ref UART_HW_IFACE_OFFS_MODE)
; @clobbers R16, R17
comOnUart0TxCharIsr:
; disable further TXC interrupts
inr r16, UCSR0B
cbr r16, (1<<TXCIE0) ; disable TXC1 interrupt
outr UCSR0B, r16
rcall comOnUart0StopTx ; (R16)
ldi r16, UART_HW2_MODE_MSGSENT
rcall comOnUart0SetMode ; (R17)
ret
; @end
#endif ; AVR_MODULES_UART_HW2_COMONUART0_H

View File

@@ -33,21 +33,12 @@ ComOnUart1_Init:
ldi yl, LOW(comOnUart1_iface)
ldi yh, HIGH(comOnUart1_iface)
rcall NET_Interface_Init ; (R16, R17, X)
ldi r16, 0xff
std Y+UART_HW2_IFACE_OFFS_WRITEBUFNUM, r16
ldi r16, UART_HW2_MODE_IDLE
std Y+UART_HW2_IFACE_OFFS_MODE, r16
clr r16
std Y+NET_IFACE_OFFS_IFACENUM, r16
rcall comOnUart1SetAttnInput
.ifdef COM_ATTN1_PUE
inr r16, COM_ATTN1_PUE
cbr r16, (1<<COM_ATTN1_PIN)
outr COM_ATTN1_PUE, r16
.endif
inr r16, COM_IRQ_ADDR_ATTN1
sbr r16, (1<<COM_IRQ_BIT_ATTN1) ; enable pin change irq for ATTN line
outr COM_IRQ_ADDR_ATTN1, r16
@@ -141,7 +132,7 @@ comOnUart1StartReading:
adiw xh:xl, UART_HW2_IFACE_OFFS_BUFFER
std Y+UART_HW2_IFACE_OFFS_BUFPOS_LOW, xl
std Y+UART_HW2_IFACE_OFFS_BUFPOS_HIGH, xh
ldi r16, UART_HW2_BUFFER_SIZE-1
ldi r16, UART_HW2_BUFFER_SIZE
std Y+UART_HW2_IFACE_OFFS_BUFLEFT, r16
clr r16
std Y+UART_HW2_IFACE_OFFS_BUFUSED, r16
@@ -153,95 +144,35 @@ comOnUart1StartReading:
; ---------------------------------------------------------------------------
; @routine comOnUart1StartWriting
;
; @param Y pointer to interface data in SRAM
; @param R16 buffer number
; @return CFLAG set if writing started, cleared otherwise
; @clobbers R16, R17, X, Z (R22, R24, R25)
comOnUart1StartWriting:
push r15
inr r15, SREG
cli
rcall comOnUart1StartWriting_noIrq
brcc comOnUart1StartWriting_clc
outr SREG, r15
pop r15
sec
ret
comOnUart1StartWriting_clc:
outr SREG, r15
pop r15
clc
ret
comOnUart1StartWriting_noIrq:
rcall comOnUart1AcquireAttn ; (R22)
brcc comOnUart1StartWriting_ebusy
; copy buffer
rcall NET_Buffer_Locate ; (R17)
std Y+UART_HW2_IFACE_OFFS_WRITEBUFNUM, r16
adiw xh:xl, NETMSG_OFFS_MSGLEN+1
ld r17, X
sbiw xh:xl, NETMSG_OFFS_MSGLEN+1
subi r17, -3 ; add dest addr, msglen, crc
; TODO: check size!
std Y+UART_HW2_IFACE_OFFS_BUFUSED, r17
std Y+UART_HW2_IFACE_OFFS_BUFLEFT, r17
; copy into IFACE buffer
mov zl, yl
mov zh, yh
adiw zh:zl, UART_HW2_IFACE_OFFS_BUFFER ; dest
std Y+UART_HW2_IFACE_OFFS_BUFPOS_LOW, zl
std Y+UART_HW2_IFACE_OFFS_BUFPOS_HIGH, zh
adiw xh:xl, 1 ; src (skip buffer header)
comOnUart1StartWriting_loop:
ld r16, X+
st Z+, r16
dec r17
brne comOnUart1StartWriting_loop
ldi r16, UART_HW2_MODE_WRITING
rcall comOnUart1SetMode ; (R17)
rcall comOnUart1StartTx ; should be the last call here (R16)
sec
rjmp comOnUart1StartWriting_end
comOnUart1StartWriting_ebusy:
ldi r16, NET_IFACE_OFFS_ERR_BUSY_LOW
rcall NET_Interface_IncCounter16 ; (R24, R25)
clc
comOnUart1StartWriting_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine ComOnUart1_Run @global
;
; @return CFLAG set if something done, cleared otherwise
; @clobbers all
ComOnUart1_Run:
push r15
inr r15, SREG
cli
rcall ComOnUart1_Run_noirq
outr SREG, r15
pop r15
ret
ComOnUart1_Run_noirq:
ldi yl, LOW(comOnUart1_iface)
ldi yh, HIGH(comOnUart1_iface)
ldd r16, Y+UART_HW2_IFACE_OFFS_MODE
clr r18
ComOnUart1_Run_loop:
push r16 ; current state
rcall comOnUart1RunMode ; (all but Y)
pop r17 ; previous state (pop from r16 into r17)
push r18
push r16 ; current state
rcall comOnUart1RunMode ; (all but Y)
pop r17 ; previous state (pop from r16 into r17)
pop r18
; read new state
ldd r16, Y+UART_HW2_IFACE_OFFS_MODE
cp r16, r17
brne ComOnUart1_Run_loop ; state changed, run again
breq ComOnUart1_Run_loopEnd
ldi r18, 1
rjmp ComOnUart1_Run_loop ; state changed, run again
ComOnUart1_Run_loopEnd:
tst r18
clc
breq ComOnUart1_Run_end
sec
ComOnUart1_Run_end:
ret
; @end
@@ -269,10 +200,7 @@ comOnUart1ModeJumpTable:
rjmp comOnUart1RunIdle
rjmp comOnUart1RunReading
rjmp comOnUart1RunSkipping
rjmp comOnUart1RunMsgReceived
rjmp comOnUart1RunWriting
rjmp comOnUart1RunWaitBufferEmpty
rjmp comOnUart1RunMsgSent
; @end
@@ -281,15 +209,48 @@ comOnUart1ModeJumpTable:
; @routine comOnUart1RunIdle
;
; @param Y pointer to interface data in SRAM
; @clobbers R16, R17, R24, R25, X, Z
; @clobbers R16, R17, R22, R24, R25, X
comOnUart1RunIdle:
; look for outbound message
rcall NET_Interface_PeekNextOutgoingMsgNum ; r16=msgNum
brcc comOnUart1RunIdle_end ; no outmsg in queue
rcall comOnUart1StartWriting ; (R16, R17, R22, R24, R25, X, Z)
push r15
in r15, SREG
cli
; look for outbound message
rcall NET_Interface_PeekNextOutgoingMsgNum ; r16=msgNum
brcs comOnUart1RunIdle_haveMsg
out SREG, r15
pop r15
rjmp comOnUart1RunIdle_end
comOnUart1RunIdle_haveMsg:
mov r24, r16
ldi r16, UART_HW2_MODE_WRITING
rcall comOnUart1SetMode ; (R17)
mov r16, r24
out SREG, r15
pop r15
push r16
rcall NET_Buffer_Locate ; (R17)
adiw xh:xl, 1
rcall comOnUart1SendMsg ; (R16, R17, R22, R24, R25, X)
push r15
inr r15, SREG ; save SREG (no CLI, we want to save CFLAG only)
ldi r16, UART_HW2_MODE_IDLE
rcall comOnUart1SetMode ; (R17)
out SREG, r15 ; restore SREG
pop r15
pop r16
brcc comOnUart1RunIdle_end
rcall NET_Interface_GetNextOutgoingMsgNum ; take current msg off the queue
push r15
in r15, SREG
cli
rcall NET_Interface_GetNextOutgoingMsgNum ; take current msg off the queue
rcall NET_Buffer_ReleaseByNum ; (R16, X)
out SREG, r15
pop r15
sec
comOnUart1RunIdle_end:
ret
; @end
@@ -326,12 +287,12 @@ comOnUart1RunSkipping_end:
; ---------------------------------------------------------------------------
; @routine comOnUart1RunMsgReceived
; @routine comOnUart1HandleMsgReceived
;
; @param Y pointer to interface data in SRAM
; @clobbers R16, R17, R18, X, Z (R19, R20, R24, R25)
comOnUart1RunMsgReceived:
comOnUart1HandleMsgReceived:
mov xl, yl
mov xh, yh
adiw xh:xl, UART_HW2_IFACE_OFFS_BUFFER
@@ -389,42 +350,6 @@ comOnUart1RunWriting:
; ---------------------------------------------------------------------------
; @routine comOnUart1RunWaitBufferEmpty
;
; @clobbers none
comOnUart1RunWaitBufferEmpty:
; TODO: check for timeout etc.
ret
; @end
; ---------------------------------------------------------------------------
; @routine comOnUart1RunWriting
;
; @param Y pointer to interface data in SRAM
; @clobbers R16 (R17, R22, R24, R25, X)
comOnUart1RunMsgSent:
ldd r16, Y+UART_HW2_IFACE_OFFS_WRITEBUFNUM
rcall NET_Buffer_ReleaseByNum ; (R16, X)
ldi r16, 0xff
std Y+UART_HW2_IFACE_OFFS_WRITEBUFNUM, r16
ldi r16, NET_IFACE_OFFS_PACKETSOUT_LOW
rcall NET_Interface_IncCounter16 ; (R24, R25)
ldi r16, UART_HW2_MODE_IDLE
rcall comOnUart1SetMode ; (R17)
rcall comOnUart1SetAttnInput ; release ATTN (none)
rcall Utils_WaitFor10MicroSecs ; make sure ATTN is at least high for a short period (R22)
ret
; @end
; ---------------------------------------------------------------------------
; @routine comOnUart1AcquireAttn
;
@@ -485,10 +410,11 @@ comOnUart1StopRx:
comOnUart1StartTx:
inr r16, UCSR1A
cbr r16, (1<<TXC1) ; clear TXCn interrupt
cbr r16, (1<<TXC1) ; clear TXCn interrupt
outr UCSR1A, r16
inr r16, UCSR1B
sbr r16, (1<<UDRIE1) | (1<<TXCIE1) | (1<<TXEN1) ; enable TX UDRE and TXC0 interrupt, enable transceive
cbr r16, (1<<UDRIE1) | (1<<TXCIE1) ; disable TX UDRE and TXC0 interrupt, enable transceive
sbr r16, (1<<TXEN1) ; enable TX UDRE and TXC0 interrupt, enable transceive
outr UCSR1B, r16
ret
; @end
@@ -502,7 +428,7 @@ comOnUart1StartTx:
comOnUart1StopTx:
inr r16, UCSR1B
cbr r16, (1<<UDRIE1) | (1<<TXCIE1) | (1<<TXEN1) ; disable TX UDRE and TXC0 interrupt, enable transceive
cbr r16, (1<<UDRIE1) | (1<<TXCIE1) | (1<<TXEN1) ; disable TX UDRE and TXC0 interrupt, disable transceive
outr UCSR1B, r16
ret
; @end
@@ -520,10 +446,17 @@ comOnUart1StopTx:
comOnUart1SetAttnInput:
cbi COM_ATTN1_DDR, COM_ATTN1_PIN ; set ATTN as input
.ifdef COM_ATTN1_PUE
; cbi COM_ATTN1_PUE, COM_ATTN_PIN ; disable pullup on ATTN
; cbi COM_ATTN1_PUE, COM_ATTN_PIN ; disable pullup on ATTN
.else
cbi COM_ATTN1_OUTPUT, COM_ATTN1_PIN ; disable pullup on ATTN
.endif
push r16
inr r16, COM_IRQ_ADDR_ATTN1
sbr r16, (1<<COM_IRQ_BIT_ATTN1) ; enable pin change irq for ATTN line
outr COM_IRQ_ADDR_ATTN1, r16
pop r16
ret
; @end
@@ -537,8 +470,13 @@ comOnUart1SetAttnInput:
; @clobbers none
comOnUart1SetAttnLow:
sbi COM_ATTN1_DDR, COM_ATTN1_PIN ; set ATTN as output
cbi COM_ATTN1_OUTPUT, COM_ATTN1_PIN ; set ATTN low
push r16
inr r16, COM_IRQ_ADDR_ATTN1
cbr r16, (1<<COM_IRQ_BIT_ATTN1) ; disable pin change irq for ATTN line
outr COM_IRQ_ADDR_ATTN1, r16
pop r16
sbi COM_ATTN1_DDR, COM_ATTN1_PIN ; set ATTN as output
cbi COM_ATTN1_OUTPUT, COM_ATTN1_PIN ; set ATTN low
ret
; @end
@@ -570,21 +508,29 @@ ComOnUart1_RxCharIsr:
push r16
push r17
push r18
push r24
push r25
push xl
push xh
push yl
push yh
ldi yl, LOW(comOnUart1_iface)
ldi yh, HIGH(comOnUart1_iface)
rcall comOnUart1RxCharIsr ; (R16, R17, R18, R24, R25, X)
pop yh
pop yl
pop xh
pop xl
pop r25
pop r24
push r19
push r20
push r24
push r25
push xl
push xh
push yl
push yh
push zl
push zh
ldi yl, LOW(comOnUart1_iface)
ldi yh, HIGH(comOnUart1_iface)
rcall comOnUart1RxCharIsr ; (R16, R17, R18, R19, R20, R24, R25, X, Z)
pop zh
pop zl
pop yh
pop yl
pop xh
pop xl
pop r25
pop r24
pop r20
pop r19
pop r18
pop r17
pop r16
@@ -595,62 +541,6 @@ ComOnUart1_RxCharIsr:
; ---------------------------------------------------------------------------
; @routine ComOnUart1_TxUdreIsr @global @isr
;
; @clobbers none
ComOnUart1_TxUdreIsr:
push r15
in r15, SREG
push r16
push r17
push xl
push xh
push yl
push yh
ldi yl, LOW(comOnUart1_iface)
ldi yh, HIGH(comOnUart1_iface)
rcall comOnUart1TxUdreIsr ; (R16, R17, X)
pop yh
pop yl
pop xh
pop xl
pop r17
pop r16
out SREG, r15
pop r15
reti
; @end
; ---------------------------------------------------------------------------
; @routine ComOnUart1_TxCharIsr @global @isr
;
; @clobbers none
ComOnUart1_TxCharIsr:
push r15
in r15, SREG
push r16
push r17
push yl
push yh
ldi yl, LOW(comOnUart1_iface)
ldi yh, HIGH(comOnUart1_iface)
rcall comOnUart1TxCharIsr ; (R16, R17)
pop yh
pop yl
pop r17
pop r16
out SREG, r15
pop r15
reti
; @end
; ---------------------------------------------------------------------------
; @routine ComOnUart1AttnChangeIsr @global @isr
;
@@ -701,10 +591,10 @@ ComOnUart1_HandleAttnChange:
; @clobbers R16 (R17, X)
comOnUart1ActOnAttn:
ldd r16, Y+UART_HW2_IFACE_OFFS_MODE
rcall comOnUart1IsAttnLow ; (none)
brcc comOnUart1ActOnAttn_attnHigh
; ATTN low
ldd r16, Y+UART_HW2_IFACE_OFFS_MODE
cpi r16, UART_HW2_MODE_IDLE
brne comOnUart1ActOnAttn_end ; not idle
rcall comOnUart1StartReading ; (R16, R17, X)
@@ -725,7 +615,7 @@ comOnUart1ActOnAttn_end:
; @routine comOnUart1RxCharIsr @global
;
; @param Y pointer to interface data in SRAM
; @clobbers R16, R17, R18, R24, R25, X
; @clobbers R16, R17, R18, R19, R20, R24, R25, X, Z
comOnUart1RxCharIsr:
; check for errors
@@ -760,15 +650,17 @@ comOnUart1RxCharIsr:
brne comOnUart1RxCharIsr_end
; determine msg size
inc r16 ; last byte was payload length, add byte for crc
cp r16, r17 ; compare remaining length against remaining space
brcc comOnUart1RxCharIsr_emsgsize ; msg too long
; cp r16, r17 ; compare remaining length against remaining space
; brcc comOnUart1RxCharIsr_emsgsize ; msg too long
cp r17, r16 ; compare remaining length against remaining space
brcs comOnUart1RxCharIsr_emsgsize ; msg too long
std Y+UART_HW2_IFACE_OFFS_BUFLEFT, r16 ; set new number of bytes left
tst r16
brne comOnUart1RxCharIsr_end ; jmp if still bytes left to receive
comOnUart1RxCharIsr_complete:
rcall comOnUart1StopRx
ldi r16, UART_HW2_MODE_MSGRECEIVED
rcall comOnUart1SetMode ; (R17)
rcall comOnUart1HandleMsgReceived ; (R16, R17, R18, R19, R20, R24, R25, X, Z)
rjmp comOnUart1RxCharIsr_end
comOnUart1RxCharIsr_hwerr:
ldi r16, NET_IFACE_OFFS_ERR_IO_LOW
@@ -790,76 +682,56 @@ comOnUart1RxCharIsr_end:
; ---------------------------------------------------------------------------
; @routine comOnUart1TxUdreIsr @global
; @routine comOnUart1SendMsg
;
; Handler for UDRE1 interrupt called when TX data register is empty.
;
; @param Y pointer to interface data in SRAM (see @ref UART_HW_IFACE_OFFS_MODE)
; @clobbers R16, R17, X
; @param Y pointer to interface data in SRAM
; @param X pointer to buffer to send
; @return CFLAG set if writing started, cleared otherwise
; @clobbers R16, R17, X (R22, R24, R25)
comOnUart1TxUdreIsr:
inr r16, UCSR1A
sbrs r16, UDRE1
rjmp comOnUart1TxUdreIsr_disable_irq ; not ready
; check bytes left
ldd r17, Y+UART_HW2_IFACE_OFFS_BUFLEFT
tst r17
breq comOnUart1TxUdreIsr_finished
; read byte
ldd xl, Y+UART_HW2_IFACE_OFFS_BUFPOS_LOW
ldd xh, Y+UART_HW2_IFACE_OFFS_BUFPOS_HIGH
ld r16, X+
std Y+UART_HW2_IFACE_OFFS_BUFPOS_LOW, xl
std Y+UART_HW2_IFACE_OFFS_BUFPOS_HIGH, xh
; send byte
outr UDR1, r16 ; send byte
; decreased counter
dec r17
std Y+UART_HW2_IFACE_OFFS_BUFLEFT, r17
brne comOnUart1TxUdreIsr_end ; still bytes left to send, jump
comOnUart1TxUdreIsr_finished:
ldi r16, UART_HW2_MODE_WAITBUFFEREMPTY
rcall comOnUart1SetMode ; (R17)
comOnUart1TxUdreIsr_disable_irq:
; disable further DRE interrupts
inr r16, UCSR1B
cbr r16, (1<<UDRIE1) ; disable TX data register empty interrupt
outr UCSR1B, r16
comOnUart1TxUdreIsr_end:
comOnUart1SendMsg:
rcall comOnUart1AcquireAttn ; (R22)
brcc comOnUart1SendMsg_ebusy
adiw xh:xl, NETMSG_OFFS_MSGLEN
ld r17, X
sbiw xh:xl, NETMSG_OFFS_MSGLEN
subi r17, -3 ; add dest addr, msglen, crc
rcall comOnUart1StartTx ; (R16)
; TODO: check size!
; r17=number of bytes to write, X=buffer
comOnUart1SendMsg_loop:
; wait until transceiver ready
inr r16, UCSR1A
sbrs r16, UDRE1
rjmp comOnUart1SendMsg_loop
; clear TXC flag by sending a 1
sbr r16, (1<<TXC1)
outr UCSR1A, r16
; write byte to uart data register
ld r16, X+
outr UDR1, r16
dec r17
brne comOnUart1SendMsg_loop
; wait until all data send (i.e. send buffer empty and all bits shifted out)
comOnUart1SendMsg_loopComplete:
inr r16, UCSR1A
sbrs r16, TXC1
rjmp comOnUart1SendMsg_loopComplete
rcall comOnUart1StopTx ; (R16)
ldi r16, NET_IFACE_OFFS_PACKETSOUT_LOW
rcall NET_Interface_IncCounter16 ; (R24, R25)
rcall comOnUart1SetAttnInput ; release ATTN (none)
rcall Utils_WaitFor10MicroSecs ; make sure ATTN is at least high for a short period (R22)
sec
rjmp comOnUart1SendMsg_end
comOnUart1SendMsg_ebusy:
ldi r16, NET_IFACE_OFFS_ERR_BUSY_LOW
rcall NET_Interface_IncCounter16 ; (R24, R25)
clc
comOnUart1SendMsg_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine comOnUart1TxCharIsr @global
;
; Handler for TXC0 interrupt called when the last byte has been completely sent and
; the data register is empty.
;
; @param Y pointer to interface data in SRAM (see @ref UART_HW_IFACE_OFFS_MODE)
; @clobbers R16, R17
comOnUart1TxCharIsr:
; disable further TXC interrupts
inr r16, UCSR1B
cbr r16, (1<<TXCIE1) ; disable TXC1 interrupt
outr UCSR1B, r16
rcall comOnUart1StopTx ; (R16)
ldi r16, UART_HW2_MODE_MSGSENT
rcall comOnUart1SetMode ; (R17)
ret
; @end
#endif ; AVR_MODULES_UART_HW2_COMONUART1_H

View File

@@ -11,29 +11,26 @@
#define AVR_MODULES_UART_HW2_DEFS_H
.equ UART_HW2_BUFFER_SIZE = NET_BUFFERS_SIZE
;.equ UART_HW2_BUFFER_SIZE = NET_BUFFERS_SIZE
.equ UART_HW2_BUFFER_SIZE = NET_BUFFERS_SIZE-1
.equ UART_HW2_MODE_IDLE = 0
.equ UART_HW2_MODE_READING = 1
.equ UART_HW2_MODE_SKIPPING = 2
.equ UART_HW2_MODE_MSGRECEIVED = 3
.equ UART_HW2_MODE_WRITING = 4
.equ UART_HW2_MODE_WAITBUFFEREMPTY = 5
.equ UART_HW2_MODE_MSGSENT = 6
.equ UART_HW2_MODE_NUM = 7
.equ UART_HW2_MODE_WRITING = 3
.equ UART_HW2_MODE_NUM = 4
.equ UART_HW2_IFACE_OFFS_BEGIN = NET_IFACE_SIZE
.equ UART_HW2_IFACE_OFFS_MODE = UART_HW2_IFACE_OFFS_BEGIN
.equ UART_HW2_IFACE_OFFS_MODECOUNTER = UART_HW2_IFACE_OFFS_BEGIN+1
.equ UART_HW2_IFACE_OFFS_WRITEBUFNUM = UART_HW2_IFACE_OFFS_BEGIN+2
.equ UART_HW2_IFACE_OFFS_BUFPOS_LOW = UART_HW2_IFACE_OFFS_BEGIN+3
.equ UART_HW2_IFACE_OFFS_BUFPOS_HIGH = UART_HW2_IFACE_OFFS_BEGIN+4
.equ UART_HW2_IFACE_OFFS_BUFUSED = UART_HW2_IFACE_OFFS_BEGIN+5
.equ UART_HW2_IFACE_OFFS_BUFLEFT = UART_HW2_IFACE_OFFS_BEGIN+6
.equ UART_HW2_IFACE_OFFS_BUFFER = UART_HW2_IFACE_OFFS_BEGIN+7
.equ UART_HW2_IFACE_OFFS_BUFPOS_LOW = UART_HW2_IFACE_OFFS_BEGIN+2
.equ UART_HW2_IFACE_OFFS_BUFPOS_HIGH = UART_HW2_IFACE_OFFS_BEGIN+3
.equ UART_HW2_IFACE_OFFS_BUFUSED = UART_HW2_IFACE_OFFS_BEGIN+4
.equ UART_HW2_IFACE_OFFS_BUFLEFT = UART_HW2_IFACE_OFFS_BEGIN+5
.equ UART_HW2_IFACE_OFFS_BUFFER = UART_HW2_IFACE_OFFS_BEGIN+6
.equ UART_HW2_IFACE_SIZE = UART_HW2_IFACE_OFFS_BUFFER+UART_HW2_BUFFER_SIZE

View File

@@ -0,0 +1,58 @@
; ***************************************************************************
; 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_UART_HW2_SYNC_H
#define AVR_MODULES_UART_HW2_SYNC_H
.dseg
.cseg
; sync length is 1000 us, so this should return:
; - 125 for 1 MHz
; - 1000 for 8 MHz
syncRecv:
syncRecv_waitForHigh:
sbis COM_DATA0_INPUT, COM_DATA0_PIN
rjmp syncRecv_waitForHigh
clr r24
clr r25
syncRecv_waitForLow:
sbic COM_DATA0_INPUT, COM_DATA0_PIN
rjmp syncRecv_waitForLow
syncRecv_countLow: ; total: +8 per loop
sbic COM_DATA0_INPUT, COM_DATA0_PIN ; +1 if noskip, +2 if skip
rjmp syncRecv_countDone ; +2, total: +2 every loop, +3 in last loop
adiw r25:r24, 1 ; +1
breq syncRecv_countError ; +1 if not 0, +2 if 0
nop ; +1
nop ; +1
rjmp syncRecv_countLow ; +2
syncRecv_countError:
clr r24
clr r25
syncRecv_countDone:
ret
; @end
#endif

View File

@@ -11,5 +11,5 @@
.equ FIRMWARE_VERSION_MAJOR = 1
.equ FIRMWARE_VERSION_MINOR = 0
.equ FIRMWARE_VERSION_PATCHLEVEL = 10
.equ FIRMWARE_VERSION_PATCHLEVEL = 14

View File

@@ -5,10 +5,10 @@
<deviceversion>16</deviceversion>
<values>
<value name="SI7021_TEMP" id="0x01" type="sensor" dataType="rational" modality="temperature" units="C" denom="100" />
<value name="SI7021_HUM" id="0x02" type="sensor" dataType="rational" modality="humidity" units="%" denom="1" />
<value name="MOTION" id="0x07" type="sensor" dataType="rational" modality="motion" denom="1" />
<value name="DOOR" id="0x08" type="sensor" dataType="rational" modality="door" denom="1" />
<value name="SI7021_TEMP" id="0x01" type="sensor" dataType="rational" modality="temperature" units="C" denom="100" />
<value name="SI7021_HUM" id="0x02" type="sensor" dataType="rational" modality="humidity" units="%" denom="1" />
<value name="MOTION" id="0x07" type="sensor" dataType="rational" modality="motion" denom="1" />
<value name="DOOR" id="0x08" type="sensor" dataType="rational" modality="door" denom="1" />
<value name="stats_packets_in" id="0xe0" type="sensor" dataType="uint16" denom="1" />
<value name="stats_packets_out" id="0xe1" type="sensor" dataType="uint16" denom="1" />
@@ -17,8 +17,10 @@
<value name="stats_nobuf_errors" id="0xe4" type="sensor" dataType="uint16" denom="1" />
<value name="stats_collision_errors" id="0xe5" type="sensor" dataType="uint16" denom="1" />
<value name="stats_busy_errors" id="0xe6" type="sensor" dataType="uint16" denom="1" />
<value name="stats_msgsize_errors" id="0xe7" type="sensor" dataType="uint16" denom="1" />
<value name="stats_missed_errors" id="0xe8" type="sensor" dataType="uint16" denom="1" />
<value name="LEDTIMING" id="0x88" type="actor" dataType="uint16" />
<value name="LEDTIMING" id="0x88" type="actor" dataType="uint16" />
</values>

View File

@@ -5,9 +5,9 @@
<deviceversion>17</deviceversion>
<values>
<value name="SI7021_TEMP" id="0x01" type="sensor" dataType="rational" modality="temperature" units="C" denom="100" />
<value name="SI7021_HUM" id="0x02" type="sensor" dataType="rational" modality="humidity" units="%" denom="1" />
<value name="MOTION" id="0x07" type="sensor" dataType="rational" modality="motion" denom="1" />
<value name="SI7021_TEMP" id="0x01" type="sensor" dataType="rational" modality="temperature" units="C" denom="100" />
<value name="SI7021_HUM" id="0x02" type="sensor" dataType="rational" modality="humidity" units="%" denom="1" />
<value name="MOTION" id="0x07" type="sensor" dataType="rational" modality="motion" denom="1" />
<value name="stats_packets_in" id="0xe0" type="sensor" dataType="uint16" denom="1" />
<value name="stats_packets_out" id="0xe1" type="sensor" dataType="uint16" denom="1" />
@@ -16,8 +16,10 @@
<value name="stats_nobuf_errors" id="0xe4" type="sensor" dataType="uint16" denom="1" />
<value name="stats_collision_errors" id="0xe5" type="sensor" dataType="uint16" denom="1" />
<value name="stats_busy_errors" id="0xe6" type="sensor" dataType="uint16" denom="1" />
<value name="stats_msgsize_errors" id="0xe7" type="sensor" dataType="uint16" denom="1" />
<value name="stats_missed_errors" id="0xe8" type="sensor" dataType="uint16" denom="1" />
<value name="LEDTIMING" id="0x88" type="actor" dataType="uint16" />
<value name="LEDTIMING" id="0x88" type="actor" dataType="uint16" />
</values>

View File

@@ -5,10 +5,10 @@
<deviceversion>18</deviceversion>
<values>
<value name="SI7021_TEMP" id="0x01" type="sensor" dataType="rational" modality="temperature" units="C" denom="100" />
<value name="SI7021_HUM" id="0x02" type="sensor" dataType="rational" modality="humidity" units="%" denom="1" />
<value name="CCS811_CO2" id="0x07" type="sensor" dataType="rational" modality="co2" units="ppm" denom="1" />
<value name="CCS811_TVOC" id="0x08" type="sensor" dataType="rational" modality="tvoc" units="ppb" denom="1" />
<value name="SI7021_TEMP" id="0x01" type="sensor" dataType="rational" modality="temperature" units="C" denom="100" />
<value name="SI7021_HUM" id="0x02" type="sensor" dataType="rational" modality="humidity" units="%" denom="1" />
<value name="CCS811_CO2" id="0x07" type="sensor" dataType="rational" modality="co2" units="ppm" denom="1" />
<value name="CCS811_TVOC" id="0x08" type="sensor" dataType="rational" modality="tvoc" units="ppb" denom="1" />
<value name="stats_packets_in" id="0xe0" type="sensor" dataType="uint16" denom="1" />
<value name="stats_packets_out" id="0xe1" type="sensor" dataType="uint16" denom="1" />
@@ -17,8 +17,10 @@
<value name="stats_nobuf_errors" id="0xe4" type="sensor" dataType="uint16" denom="1" />
<value name="stats_collision_errors" id="0xe5" type="sensor" dataType="uint16" denom="1" />
<value name="stats_busy_errors" id="0xe6" type="sensor" dataType="uint16" denom="1" />
<value name="stats_msgsize_errors" id="0xe7" type="sensor" dataType="uint16" denom="1" />
<value name="stats_missed_errors" id="0xe8" type="sensor" dataType="uint16" denom="1" />
<value name="LEDTIMING" id="0x88" type="actor" dataType="uint16" />
<value name="LEDTIMING" id="0x88" type="actor" dataType="uint16" />
</values>
</device>

View File

@@ -5,10 +5,10 @@
<deviceversion>19</deviceversion>
<values>
<value name="SI7021_TEMP" id="0x01" type="sensor" dataType="rational" modality="temperature" units="C" denom="100" />
<value name="SI7021_HUM" id="0x02" type="sensor" dataType="rational" modality="humidity" units="%" denom="1" />
<value name="CCS811_CO2" id="0x07" type="sensor" dataType="rational" modality="co2" units="ppm" denom="1" />
<value name="CCS811_TVOC" id="0x08" type="sensor" dataType="rational" modality="tvoc" units="ppb" denom="1" />
<value name="SI7021_TEMP" id="0x01" type="sensor" dataType="rational" modality="temperature" units="C" denom="100" />
<value name="SI7021_HUM" id="0x02" type="sensor" dataType="rational" modality="humidity" units="%" denom="1" />
<value name="CCS811_CO2" id="0x07" type="sensor" dataType="rational" modality="co2" units="ppm" denom="1" />
<value name="CCS811_TVOC" id="0x08" type="sensor" dataType="rational" modality="tvoc" units="ppb" denom="1" />
<value name="stats_packets_in" id="0xe0" type="sensor" dataType="uint16" denom="1" />
<value name="stats_packets_out" id="0xe1" type="sensor" dataType="uint16" denom="1" />
@@ -17,8 +17,10 @@
<value name="stats_nobuf_errors" id="0xe4" type="sensor" dataType="uint16" denom="1" />
<value name="stats_collision_errors" id="0xe5" type="sensor" dataType="uint16" denom="1" />
<value name="stats_busy_errors" id="0xe6" type="sensor" dataType="uint16" denom="1" />
<value name="stats_msgsize_errors" id="0xe7" type="sensor" dataType="uint16" denom="1" />
<value name="stats_missed_errors" id="0xe8" type="sensor" dataType="uint16" denom="1" />
<value name="LEDTIMING" id="0x88" type="actor" dataType="uint16" />
<value name="LEDTIMING" id="0x88" type="actor" dataType="uint16" />
</values>

View File

@@ -5,11 +5,11 @@
<deviceversion>20</deviceversion>
<values>
<value name="SI7021_TEMP" id="0x01" type="sensor" dataType="rational" modality="temperature" units="C" denom="100" />
<value name="SI7021_HUM" id="0x02" type="sensor" dataType="rational" modality="humidity" units="%" denom="1" />
<value name="MOTION" id="0x07" type="sensor" dataType="rational" modality="motion" denom="1" />
<value name="CCS811_CO2" id="0x08" type="sensor" dataType="rational" modality="co2" units="ppm" denom="1" />
<value name="CCS811_TVOC" id="0x09" type="sensor" dataType="rational" modality="tvoc" units="ppb" denom="1" />
<value name="SI7021_TEMP" id="0x01" type="sensor" dataType="rational" modality="temperature" units="C" denom="100" />
<value name="SI7021_HUM" id="0x02" type="sensor" dataType="rational" modality="humidity" units="%" denom="1" />
<value name="MOTION" id="0x07" type="sensor" dataType="rational" modality="motion" denom="1" />
<value name="CCS811_CO2" id="0x08" type="sensor" dataType="rational" modality="co2" units="ppm" denom="1" />
<value name="CCS811_TVOC" id="0x09" type="sensor" dataType="rational" modality="tvoc" units="ppb" denom="1" />
<value name="stats_packets_in" id="0xe0" type="sensor" dataType="uint16" denom="1" />
<value name="stats_packets_out" id="0xe1" type="sensor" dataType="uint16" denom="1" />
@@ -18,8 +18,10 @@
<value name="stats_nobuf_errors" id="0xe4" type="sensor" dataType="uint16" denom="1" />
<value name="stats_collision_errors" id="0xe5" type="sensor" dataType="uint16" denom="1" />
<value name="stats_busy_errors" id="0xe6" type="sensor" dataType="uint16" denom="1" />
<value name="stats_msgsize_errors" id="0xe7" type="sensor" dataType="uint16" denom="1" />
<value name="stats_missed_errors" id="0xe8" type="sensor" dataType="uint16" denom="1" />
<value name="LEDTIMING" id="0x88" type="actor" dataType="uint16" />
<value name="LEDTIMING" id="0x88" type="actor" dataType="uint16" />
</values>
</device>

View File

@@ -5,15 +5,15 @@
<deviceversion>22</deviceversion>
<values>
<value name="DS18B20_TEMP" id="0x06" type="sensor" dataType="rational" modality="temperature" units="C" denom="16" />
<value name="DS18B20_TEMP" id="0x06" type="sensor" dataType="rational" modality="temperature" units="C" denom="16" />
<value name="NUMLEDS" id="0x82" type="actor" dataType="int" />
<value name="RGBWVALUE" id="0x83" type="actor" dataType="dword" />
<value name="NUMLEDS" id="0x82" type="actor" dataType="int" />
<value name="RGBWVALUE" id="0x83" type="actor" dataType="dword" />
<value name="MALRGBWVALUE" id="0x84" type="actor" dataType="dword" />
<value name="MALONTIME" id="0x85" type="actor" dataType="uint16" />
<value name="MALSOURCE1" id="0x86" type="actor" dataType="uint16" />
<value name="MALSOURCE2" id="0x87" type="actor" dataType="uint16" />
<value name="MALRGBWVALUE" id="0x84" type="actor" dataType="dword" />
<value name="MALONTIME" id="0x85" type="actor" dataType="uint16" />
<value name="MALSOURCE1" id="0x86" type="actor" dataType="uint16" />
<value name="MALSOURCE2" id="0x87" type="actor" dataType="uint16" />
<value name="stats_packets_in" id="0xe0" type="sensor" dataType="uint16" denom="1" />
<value name="stats_packets_out" id="0xe1" type="sensor" dataType="uint16" denom="1" />
@@ -22,8 +22,10 @@
<value name="stats_nobuf_errors" id="0xe4" type="sensor" dataType="uint16" denom="1" />
<value name="stats_collision_errors" id="0xe5" type="sensor" dataType="uint16" denom="1" />
<value name="stats_busy_errors" id="0xe6" type="sensor" dataType="uint16" denom="1" />
<value name="stats_msgsize_errors" id="0xe7" type="sensor" dataType="uint16" denom="1" />
<value name="stats_missed_errors" id="0xe8" type="sensor" dataType="uint16" denom="1" />
<value name="LEDTIMING" id="0x88" type="actor" dataType="uint16" />
<value name="LEDTIMING" id="0x88" type="actor" dataType="uint16" />
</values>
</device>