started reorganizing code into subfolders.

This commit is contained in:
Martin Preuss
2023-04-22 00:04:10 +02:00
parent 97016b21b9
commit 5e12b8ad4e
40 changed files with 38 additions and 60 deletions

View File

@@ -0,0 +1,142 @@
; ***************************************************************************
; copyright : (C) 2023 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. *
; ***************************************************************************
; ***************************************************************************
; data
.dseg
cproDataBegin:
cproMode: .byte 1
cproDataEnd:
; ***************************************************************************
; code
.cseg
CPRO_BEGIN:
CPRO_Init:
; preset SRAM data area
ldi xh, HIGH(cproDataBegin)
ldi xl, LOW(cproDataBegin)
clr r16
ldi r17, (cproDataEnd-cproDataBegin)
rcall Utils_FillSram
#ifdef MODULES_COM_WITH_ADDR_PROTO
rcall CPRO_Address_Init
#endif
sec
ret
; ---------------------------------------------------------------------------
; CPRO_OnPacketReceived:
;
; Try to handle the given packet.
;
; IN:
; - X : pointer to received buffer
; OUT:
; - CFLAG: set if handled, cleared otherwise
; USED: depending on called routines
CPRO_OnPacketReceived:
adiw xh:xl, COM2_MSG_OFFS_CMD
ld r16, x
sbiw xh:xl, COM2_MSG_OFFS_CMD
cpi r16, CPRO_CMD_PING
brne CPRO_OnPacketReceived_l1
rjmp cproHandlePing
CPRO_OnPacketReceived_l1:
#ifndef BASE_SYSTEM
cpi r16, CPRO_CMD_REBOOT_REQUEST
brne CPRO_OnPacketReceived_l2
rjmp cproHandleReboot
#endif
CPRO_OnPacketReceived_l2:
#ifdef MODULES_COM_WITH_ADDR_PROTO
rjmp CPRO_Address_OnPacketReceived
#else
clc
ret
#endif
cproHandlePing:
adiw xh:xl, COM2_MSG_OFFS_SRCADDR
ld r16, x
tst r16 ; dont handle src address 0
breq cproHandlePing_notHandled
inc r16
breq cproHandlePing_notHandled ; dont handle src address 255
dec r16
ldi xl, LOW(com2SendBuffer)
ldi xh, HIGH(com2SendBuffer)
rcall CPRO_WritePong
rjmp COM2_SendPacket ; use carry flag from this routine
cproHandlePing_notHandled:
clc
ret
; ---------------------------------------------------------------------------
; Compare the UID from a message against out own UID.
;
;IN:
; - X: pointer to UID in a message to compare against out own uid
; OUT:
; - CFLAG set if matches, cleared otherwise
; REGS: r16, r18, r19, r20, r21, X
cproCheckUidInMsg:
push xl
push xh
rcall Utils_ReadUid
pop xh
pop xl
ld r16, X+
cp r16, r18
brne cproCheckUidInMsg_notMe
ld r16, X+
cp r16, r19
brne cproCheckUidInMsg_notMe
ld r16, X+
cp r16, r20
brne cproCheckUidInMsg_notMe
ld r16, X+
cp r16, r21
brne cproCheckUidInMsg_notMe
sec
ret
cproCheckUidInMsg_notMe:
clc
ret
CPRO_END:
.equ MODULE_SIZE_CPRO = CPRO_END-CPRO_BEGIN

View File

@@ -0,0 +1,434 @@
; ***************************************************************************
; copyright : (C) 2023 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. *
; ***************************************************************************
; ***************************************************************************
; This sub-module contains code for cooperative address management.
; Because the network of nodes doen't have a central control unit the nodes
; need to assign addresses to themselves with help from the community of existing
; nodes.
;
; Protocol A: Full Address Assignment Protocol
; --------------------------------------------
; This protocol is used when a node has no currently or previously assigned address.
; In this case we need to find a free address which no other node uses.
;
; 1) a node needs an address. It sends the packet "NEED_ADDRESS"
; 2) every node which already has an address sees this message and answers with
; a "HAVE_ADDRESS" packet. The nodes must not answer all at once to avoid
; congestions. Instead, the time it takes for a node to respond depends on
; its own address (e.g. a node with address 10 will wait for 10+3s before answering)
; 3) the initial node collects all "HAVE_ADDRESS" packets and puts the addresses
; received this way into a bitfield in which for every address received a bit is
; set
; 4) after about 130s all nodes in the address range 1-127 should have answered.
; So after this time the initial node looks at the bitfield of received addresses
; and selects the first unused address (corresponding bit cleared in bitfield).
; For this address the initial node sends a "CLAIM_ADDRESS" packet, three times
; with about 30s between the packets.
; 5) if the to-be-claimed address is already in use by another node, that node will
; send a "DENY_ADDRESS" packet. This is the second line of defense against address
; collisions and should very rarely occur.
; 6) after no node denied the to-be-claimed address the initial node finally takes the
; address and sends a "HAVE_ADDRESS" packet.
; 7) this concludes the address assignemt protocol
;
; Protocol B: Shortened Address Assignment Protocol
; -------------------------------------------------
; This protocol is used upon boot when a node previously got an address assigned to it.
; In this case the address is probably not used by an other node so we can shorten the
; procedure.
;
; 1) a node sends the packet CLAIM_ADDRESS with the previously assigned address
; 2) is any other node objects to this node using that address (e.g. because the other
; node now uses that address) that node will send a DENY_ADDRESS packet.
; 3) if no DENY_ADDRESS has been received within 10s the address can be used.
; 4) Otherwise the node changes into protocol A (see above).
#ifdef MODULES_COM_WITH_ADDR_PROTO
; ***************************************************************************
; defs
; ***************************************************************************
; data
.dseg
cproAddressDataBegin:
cproAddrRangeBegin: .byte 1
cproAddrRangeEnd: .byte 1
cproUsedAddresses: .byte 16 ; one bit per address known to b in use
cproAddressDataEnd:
cproAddresModeTimer: .byte 2 ; timer must not be zeroed, this is done by the timer module!!
; ***************************************************************************
; code
.cseg
CPRO_Address_Init:
ldi xh, HIGH(cproAddressDataBegin)
ldi xl, LOW(cproAddressDataBegin)
clr r16
ldi r17, (cproAddressDataEnd-cproAddressDataBegin)
rcall Utils_FillSram
; setup timer for address setup (after 10s)
ldi r16, CPRO_MODE_NOADDRESS
sts cproMode, r16
ldi r18, 10
ldi r19, 0
rcall cproAddressSetTimer
ret
CPRO_StartReclaimAddrProcedure:
ldi xl, LOW(EEPROM_OFFS_COMADDR)
ldi xh, HIGH(EEPROM_OFFS_COMADDR)
in r15, SREG
push r15
cli
rcall Utils_ReadEepromIncr ; (R16)
tst r16
breq CPRO_StartReclaimAddrProcedure_l1
cpi r16, 0xff
breq CPRO_StartReclaimAddrProcedure_l1
sts cproAddrRangeBegin, r16 ; currently claimed address
ldi r16, CPRO_MODE_SEND_RECLAIM_ADDR
sts cproMode, r16
rcall cproAddressSetTimer1s ; use singleshot timer, send after 1s
pop r15
out SREG, r15
sec
ret
CPRO_StartReclaimAddrProcedure_l1:
rcall CPRO_StartGetAddrProcedure
pop r15
out SREG, r15
ret
CPRO_StartGetAddrProcedure:
; reset bitfield of used addresses
ldi xh, HIGH(cproUsedAddresses)
ldi xl, LOW(cproUsedAddresses)
clr r16
ldi r17, 16
rcall Utils_FillSram
; preset range
ldi r16, 1
sts cproAddrRangeBegin, r16
ldi r16, 126
sts cproAddrRangeEnd, r16
; setup singleshot timer to later send "NEED_ADDRESS" packet
ldi r16, CPRO_MODE_SEND_NEED_ADDR
sts cproMode, r16
rcall cproAddressSetTimer1s
sec
ret
; REGS: r18, r19
;
cproAddressSetTimer1s:
ldi r18, 1
ldi r19, 0
rjmp cproAddressSetTimer
; IN:
; - r18: timer value (low)
; - r19: timer value (high)
; REGS: none
cproAddressSetTimer:
push r15
in r15, SREG
cli
sts cproAddresModeTimer, r18
sts cproAddresModeTimer+1, r19
out SREG, r15
pop r15
ret
cproGetFirstFreeAddr:
rjmp cproGetFreeAddr
cproGetNextFreeAddr:
lds r16, cproAddrRangeBegin
inc r16
sts cproAddrRangeBegin, r16
rjmp cproGetFreeAddr
cproGetFreeAddr:
lds r16, cproAddrRangeBegin
lds r17, cproAddrRangeEnd
cp r16, r17
brge cproGetFreeAddr_error
rcall cproFindFreeAddr
brcc cproGetFreeAddr_error
sec
ret
cproGetFreeAddr_error:
clc
ret
cproHandleAddrRange: ; not handled for now
; TODO
clc
ret
; ---------------------------------------------------------------------------
; cproFindFreeAddr
;
; find a free address in the bitfield cproUsedAddresses
;
; IN:
; - nothing
; OUT:
; - CFLAG: set if handled, cleared otherwise
; - R16: free address (if CFLAG set)
; USED: R16, R17, R18, R19, R20, R21 X, (R1, R2, Z)
cproFindFreeAddr:
ldi xl, LOW(cproUsedAddresses)
ldi xh, HIGH(cproUsedAddresses)
lds r16, cproAddrRangeBegin
dec r16
rcall cproGetPosAndMaskInBitField ; r1=bit pos, r2=mask (r1, r2, r17, Z)
clr r17
add xl, r1
adc xh, r17 ; X: pointer to byte
mov r17, r2 ; mask
lds r18, cproAddrRangeBegin
dec r18
lds r19, cproAddrRangeEnd
inc r19 ; to make comparision easier
ldi r20, 8
cproFindFreeAddr_byteLoop:
ld r16, X+
cpi r16, 0xff
breq cproFindFreeAddr_nextByte ; byte full, skip
cproFindFreeAddr_bitLoop:
mov r21, r16
and r21, r17
brne cproFindFreeAddr_nextBit
; found a clear bit, return
inc r18
sts cproAddrRangeBegin, r18
mov r16, r18
sec
ret
cproFindFreeAddr_nextBit:
inc r18 ; next address
lsl r17 ; shift mask to the left
brcc cproFindFreeAddr_bitLoop
dec r18 ; take back inc
cproFindFreeAddr_nextByte:
add r18, r20
andi r18, 0xf8 ; clear lower 3 bits
cp r18, r19 ; compare to end address+1
brcc cproFindFreeAddr_allFull
ldi r17, 0x01 ; mask
rjmp cproFindFreeAddr_byteLoop
cproFindFreeAddr_allFull:
clc
ret
; ---------------------------------------------------------------------------
; cproSetBitInBitfield
;
; IN:
; - R16 : bit number to set (0-127)
; OUT:
; - nothing
; USED: R16, R17, X (r1, r2, Z)
cproSetBitInBitfield:
; set bit corresponding to given address in bitfield of used addresses
rcall cproGetPosAndMaskInBitField ; get offset into R1, mask into R2 (r1, r2, r17, Z)
ldi xl, LOW(cproUsedAddresses)
ldi xh, HIGH(cproUsedAddresses)
clr r17
add xl, r1
adc xh, r17
ld r16, X
or r16, r2
st X, r16
ret
; ---------------------------------------------------------------------------
; Get offset and mask for a given bit in a bitfield
; IN:
; - R16: bit to request position for
; OUT:
; - R1: offset into the bitfield to the byte containing the given bit
; - R2: mask for given id (apply to r1)
; USED REGISTERS: r1, r2, r17, Z
cproGetPosAndMaskInBitField:
mov r1, r16 ; divide by 8 to get the offset to the byte containing the given module id
lsr r1
lsr r1
lsr r1 ; r1=offset of the byte holding the given bit
mov r2, r16 ; get bit mask for bit position in table byte
ldi r17, 7 ; keep lower 3 bits
and r2, r17
ldi zh, HIGH(cproModuleBitNumToMaskMap*2)
ldi zl, LOW(cproModuleBitNumToMaskMap*2)
add zl, r2
brcc cproGetPosAndMaskInBitField_noOverflow
inc zh
cproGetPosAndMaskInBitField_noOverflow:
lpm r2, z ; r2=mask for bit in byte from bitfield
ret
cproModuleBitNumToMaskMap:
.db 1, 2, 4, 8, 16, 32, 64, 128
; ---------------------------------------------------------------------------
; Send a NEEDADDRESS packet.
;
; IN:
; - nothing
; OUT:
; - CFLAG: set if okay, clear otherwise
; MODIFIED REGS: R18 (R3, R4, R15, R16, R17, R20, R21, X, Y (R18, R19)
CPRO_SendNeedAddress:
ldi r18, CPRO_CMD_NEED_ADDRESS
rjmp cproSendAddressPacket
; ---------------------------------------------------------------------------
; Send a HAVE_ADDRESS packet.
;
; IN:
; - nothing
; - R19: address to send
; OUT:
; - CFLAG: set if okay, clear otherwise
; MODIFIED REGS: R18 (R3, R4, R15, R16, R17, R18, R19, R20, R21, X, Y)
CPRO_SendHaveAddress:
ldi r18, CPRO_CMD_HAVE_ADDRESS
rjmp cproSendAddressPacket
; ---------------------------------------------------------------------------
; Send a CLAIM_ADDRESS packet.
;
; IN:
; - R19: claimed address
; OUT:
; - CFLAG: set if okay, clear otherwise
; MODIFIED REGS: R18 (R3, R4, R15, R16, R17, R18, R19, R20, R21, X, Y)
CPRO_SendClaimAddress:
ldi r18, CPRO_CMD_CLAIM_ADDRESS
rjmp cproSendAddressPacket
; ---------------------------------------------------------------------------
; Send a DENY_ADDRESS packet.
;
; IN:
; - nothing
; OUT:
; - CFLAG: set if okay, clear otherwise
; MODIFIED REGS: R18, R19 (R3, R4, R15, R16, R17, R20, R21, X, Y)
CPRO_SendDenyAddress:
ldi r18, CPRO_CMD_DENY_ADDRESS
lds r19, com2Address
rjmp cproSendAddressPacket
; ---------------------------------------------------------------------------
; cproSendAddressPacket
; Send a NEED/HAVE/CLAIM ADDRESS packet.
;
; IN:
; - R18: command (either CPRO_CMD_NEED_ADDRESS, CPRO_CMD_HAVE_ADDRESS or CPRO_CMD_CLAIM_ADDRESS)
; - R19: address to send (claim, have)
; OUT:
; - CFLAG: set if okay, clear otherwise
; MODIFIED REGS: R16, R17, R20, R21, X, Y (R3, R4, R15, R16, R17, R18, R19, R21, X)
cproSendAddressPacket:
ldi xl, LOW(com2SendBuffer)
ldi xh, HIGH(com2SendBuffer)
mov r6, r19
ldi r16, 0xff
ldi r17, COM2_PAYLOAD_FLAGS_UID | (1<<COM2_PAYLOAD_FLAGS_SHIFT_NUM)
rcall COM2_BeginMsgWithVariablePayload ; (R3, R4, R16, R17, R18, R19, R20, R21, X)
st X+, r6 ; address
ldi xl, LOW(com2SendBuffer)
ldi xh, HIGH(com2SendBuffer)
rcall com2CalcAndAddChecksumByte ; (R16, R17, R18, R19, X)
rjmp COM2_SendPacket
.include "modules/comproto/comproto_addr1.asm"
.include "modules/comproto/comproto_addr2.asm"
#endif ; MODULES_COM_WITH_ADDR_PROTO

View File

@@ -0,0 +1,166 @@
; ***************************************************************************
; copyright : (C) 2023 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. *
; ***************************************************************************
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; This file contains timer handlers for the address protocol
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
; ***************************************************************************
; code
.cseg
CPRO_Address_OnTimer:
lds r16, cproMode
ldi r17, CPRO_MODE_NEXT_FREE
ldi zl, LOW(cproAddressOnTimerTable)
ldi zh, HIGH(cproAddressOnTimerTable)
rjmp Utils_TableJump
cproAddressOnTimerTable:
.dw CPRO_StartReclaimAddrProcedure ; CPRO_MODE_NOADDRESS
.dw 0 ; CPRO_MODE_NORMAL
.dw cproHandle1sNeedAddr ; CPRO_MODE_SEND_NEED_ADDR
.dw cproHandle1sGetAddrStarted ; CPRO_MODE_GETADDRSTARTED
.dw cproHandle1sSendClaimAddr1 ; CPRO_MODE_SEND_CLAIM_ADDR1
.dw cproHandle1sClaimingAddr12 ; CPRO_MODE_CLAIMING_ADDR1
.dw cproHandle1sClaimingAddr12 ; CPRO_MODE_CLAIMING_ADDR2
.dw cproHandle1sClaimingAddr3 ; CPRO_MODE_CLAIMING_ADDR3
.dw cproHandle1sSendingHaveAddress ; CPRO_MODE_SENDING_HAVE_ADDR
.dw cproHandle1sSendReclaimAddr ; CPRO_MODE_SEND_RECLAIM_ADDR
.dw cproHandle1sReclaimingAddr ; CPRO_MODE_RECLAIMING_ADDR
.dw cproHandle1sSendDenyAddr ; CPRO_MODE_SEND_DENY_ADDR
cproHandle1sSendingHaveAddress:
lds r19, com2Address
rcall CPRO_SendHaveAddress
brcs cproHandle1sSendingHaveAddress_okay
rcall cproAddressSetTimer1s ; could not send, restart timer 1s and retry later
ret
cproHandle1sSendingHaveAddress_okay:
ldi r16, CPRO_MODE_NORMAL
sts cproMode, r16
ret
cproHandle1sNeedAddr:
rcall CPRO_SendNeedAddress
brcs cproHandle1sNeedAddr_okay
rjmp cproAddressSetTimer1s ; could not send, restart timer 1s and retry later
cproHandle1sNeedAddr_okay:
ldi r16, CPRO_MODE_GETADDRSTARTED ; wait for incoming messages
sts cproMode, r16
ldi r18, CPRO_WAITTIME_GETADDR ; set timeout
clr r19
rjmp cproAddressSetTimer
cproHandle1sSendDenyAddr:
rcall CPRO_SendDenyAddress
brcs cproHandle1sSendDenyAddr_okay
rjmp cproAddressSetTimer1s ; could not send, restart timer 1s and retry later
cproHandle1sSendDenyAddr_okay:
ldi r16, CPRO_MODE_NORMAL ; DENY_ADDR sent, back to normal
sts cproMode, r16
ret
cproHandle1sSendReclaimAddr:
lds r19, cproAddrRangeBegin
rcall CPRO_SendClaimAddress
brcs cproHandle1sSendReclaimAddr_okay
rjmp cproAddressSetTimer1s ; could not send, restart timer 1s and retry later
cproHandle1sSendReclaimAddr_okay:
ldi r16, CPRO_MODE_RECLAIMING_ADDR
sts cproMode, r16
ldi r18, CPRO_WAITTIME_RECLAIMADDR
clr r19
rjmp cproAddressSetTimer ; prepare time for next stage
cproHandle1sGetAddrStarted:
rcall cproGetFirstFreeAddr
brcs cproHandle1sGetAddrStarted_gotAddr
; no free address, abort TODO: send an error message to bus ("bus full")
ldi r16, CPRO_MODE_NOADDRESS
sts cproMode, r16
ret
cproHandle1sGetAddrStarted_gotAddr:
ldi r16, CPRO_MODE_SEND_CLAIM_ADDR1
sts cproMode, r16
rjmp cproAddressSetTimer1s ; start
cproHandle1sSendClaimAddr1:
lds r19, cproAddrRangeBegin
rcall CPRO_SendClaimAddress
brcs cproHandle1sClaimSend_okay
rjmp cproAddressSetTimer1s ; could not send, restart timer 1s and retry later
cproHandle1sClaimSend_okay: ; goto nex stage
ldi r16, CPRO_MODE_CLAIMING_ADDR1
sts cproMode, r16
ldi r18, CPRO_WAITTIME_CLAIMADDR
clr r19
rjmp cproAddressSetTimer ; prepare timer for next stage
cproHandle1sClaimingAddr12:
lds r19, cproAddrRangeBegin ; currently claimed address
rcall CPRO_SendClaimAddress
brcs cproHandle1sClaimingAddr12_okay
rjmp cproAddressSetTimer1s ; could not send, restart timer 1s and retry later
cproHandle1sClaimingAddr12_okay:
lds r16, cproMode
inc r16
sts cproMode, r16
ldi r18, CPRO_WAITTIME_CLAIMADDR
clr r19
rjmp cproAddressSetTimer ; prepare time for next stage
cproHandle1sClaimingAddr3:
cproHandle1sReclaimingAddr:
; claimed given address 3rd time or addr reclaimed, set address and enter "normal" mode
lds r19, cproAddrRangeBegin ; currently claimed address
sts com2Address, r19
rcall CPRO_SendHaveAddress
brcs cproHandle1sClaimingAddr3_okay
rjmp cproAddressSetTimer1s ; could not send, restart timer 1s and retry later
cproHandle1sClaimingAddr3_okay:
in r15, SREG
push r15
cli
lds r16, com2Address ; currently sent address is in cproAddrRangeBegin
ldi xl, LOW(EEPROM_OFFS_COMADDR) ; write address into eeprom
ldi xh, HIGH(EEPROM_OFFS_COMADDR)
rcall Utils_WriteEepromIncr ; write address to EEPROM
pop r15
out SREG, r15
ldi r16, CPRO_MODE_NORMAL ; set mode to "normal"
sts cproMode, r16
ret

View File

@@ -0,0 +1,168 @@
; ***************************************************************************
; copyright : (C) 2023 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. *
; ***************************************************************************
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; This file contains packet receiption handlers for the address protocol
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; ***************************************************************************
; code
.cseg
; ---------------------------------------------------------------------------
; CPRO_Address_OnPacketReceived:
;
; Try to handle the given packet.
;
; IN:
; - X : pointer to received buffer
; OUT:
; - CFLAG: set if handled, cleared otherwise
; USED: depending on called routines
CPRO_Address_OnPacketReceived:
adiw xh:xl, COM2_MSG_OFFS_CMD
ld r16, x
sbiw xh:xl, COM2_MSG_OFFS_CMD
ldi r17, (cproPacketTypeTransTableEnd-cproPacketTypeTransTableBegin) & 0xff
ldi zl, LOW(cproPacketTypeTransTableBegin)
ldi zh, HIGH(cproPacketTypeTransTableBegin)
rcall Utils_FindBytePositionInTable
brcc CPRO_Address_OnPacketReceived_nc
ldi r17, (cproPacketTypeTransTableEnd-cproPacketTypeTransTableBegin) & 0xff
ldi zl, LOW(cproPacketTypeHandleTable)
ldi zh, HIGH(cproPacketTypeHandleTable)
rcall Utils_TableJump
sec
ret
CPRO_Address_OnPacketReceived_nc:
clc
ret
cproPacketTypeTransTableBegin:
.db CPRO_CMD_PING, CPRO_CMD_NEED_ADDRESS, CPRO_CMD_HAVE_ADDRESS, CPRO_CMD_ADDRESS_RANGE, CPRO_CMD_DENY_ADDRESS, CPRO_CMD_CLAIM_ADDRESS
cproPacketTypeTransTableEnd:
; position within table must be in same order as in table above!
cproPacketTypeHandleTable:
.dw cproHandlePing, cproHandleNeedAddr, cproHandleHaveAddr, cproHandleAddrRange, cproHandleDenyAddr, cproHandleClaimAddr
cproHandleNeedAddr:
lds r17, cproMode
cpi r17, CPRO_MODE_NORMAL
brne cproHandleNeedAddr_done
; enter CPRO_MODE_SENDING_HAVE_ADDR mode
lds r16, com2Address
tst r16
breq cproHandleNeedAddr_done ; we have no address, don't handle
ldi r24, CPRO_MODE_SENDING_HAVE_ADDR ; start singleshot timer for sending HAVE_ADDRESS
sts cproMode, r24
lds r24, com2Address
clr r25
adiw r25:r24, 3
rjmp cproAddressSetTimer
cproHandleNeedAddr_done:
sec
ret
cproHandleHaveAddr:
lds r17, cproMode
cpi r17, CPRO_MODE_GETADDRSTARTED
brne cproHandleHaveAddr_done
; validate address
adiw xh:xl, CPRO_PACKET_HAVEADDR_OFFS_ADDRESS
ld r16, x
sbiw xh:xl, CPRO_PACKET_HAVEADDR_OFFS_ADDRESS
tst r16
breq cproHandleHaveAddr_done ; invalid address, ignore
cpi r16, 127
brcc cproHandleHaveAddr_done ; invalid address, ignore
; set bit corresponding to given address in bitfield of used addresses
dec r16
rcall cproSetBitInBitfield
cproHandleHaveAddr_done:
sec
ret
cproHandleClaimAddr:
adiw xh:xl, CPRO_PACKET_CLAIMADDR_OFFS_ADDRESS
ld r16, x
tst r16
breq cproHandleClaimAddr_done
cpi r16, 0xff
breq cproHandleClaimAddr_done
lds r17, com2Address
tst r17
breq cproHandleClaimAddr_done
cp r16, r17
brne cproHandleClaimAddr_done
ldi r16, CPRO_MODE_SEND_DENY_ADDR
sts cproMode, r16
rcall cproAddressSetTimer1s
cproHandleClaimAddr_done:
sec
ret
cproHandleDenyAddr:
; check mode
lds r17, cproMode
cpi r17, CPRO_MODE_CLAIMING_ADDR1
brcs cproHandleDenyAddr_notInClaimAddr13Mode
cpi r17, CPRO_MODE_CLAIMING_ADDR3+1
brcc cproHandleDenyAddr_notInClaimAddr13Mode
; we are in one of the three CLAIM_ADDRESS modes and received a DENY_ADDR, check address
adiw xh:xl, CPRO_PACKET_DENYADDR_OFFS_ADDRESS
ld r16, x
sbiw xh:xl, CPRO_PACKET_DENYADDR_OFFS_ADDRESS
lds r17, cproAddrRangeBegin
cp r16, r17
brne cproHandleDenyAddr_done ; not our currently claimed address, ignore
; someone denied us our claimed address, try next
rcall cproGetNextFreeAddr
brcs cproHandleDenyAddr_gotFreeAddr
; no free address, abort TODO: send an error message to bus ("bus full")
ldi r16, CPRO_MODE_NOADDRESS
sts cproMode, r16
ret
cproHandleDenyAddr_gotFreeAddr: ; claim next address
ldi r16, CPRO_MODE_SEND_CLAIM_ADDR1
sts cproMode, r16
rcall cproAddressSetTimer1s ; start timer
rjmp cproHandleDenyAddr_done
cproHandleDenyAddr_notInClaimAddr13Mode: ; reclaim mode?
lds r17, cproMode
cpi r17, CPRO_MODE_RECLAIMING_ADDR
brne cproHandleDenyAddr_done
; reclaiming went wrong, go through full address assignment protocol
rcall CPRO_StartGetAddrProcedure
cproHandleDenyAddr_done:
sec
ret

View File

@@ -0,0 +1,67 @@
; ***************************************************************************
; copyright : (C) 2023 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
; ---------------------------------------------------------------------------
; Enqueue a DEBUG packet.
;
; IN:
; - R16: destination address
; - R1: debug value 1
; - R2: debug value 2
; OUT:
; - CFLAG: set if okay, clear otherwise
; MODIFIED REGS: R16, R17, R20, X (R15, Y)
CPRO_EnqueueDebug:
push r16
rcall COM_AllocBufferAndGetXY ; (r16, r17, r21)
pop r16
brcc CPRO_EnqueueDebug_error
clr r17 ; r17: XOR byte
; write header (dest address, msg length)
st X+, r16 ; destination address
eor r17, r16
ldi r16, 4 ; 2 bytes payload
st X+, r16
eor r17, r16
; write payload
ldi r16, CPRO_CMD_DEBUG
st X+, r16
eor r17, r16
lds r16, comAddress
st X+, r16
eor r17, r16
mov r16, r1 ; debug 1
st X+, r16
eor r17, r16
mov r16, r2 ; debug 2
st X+, r16
eor r17, r16
; store XOR byte
st X+, r17
; mark buffer as enqueued with PRIO "info" (limited amount of retries)
ldi r20, COM_BUFFER_PRIO_INFO
rcall COM_EnqueuePacket ; (R15, R16)
brcc CPRO_EnqueueDebug_error
sec
ret
CPRO_EnqueueDebug_error:
clc
ret

View File

@@ -0,0 +1,74 @@
; ***************************************************************************
; copyright : (C) 2023 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
.equ CPRO_CMD_PING = 10
.equ CPRO_CMD_PONG = 11
.equ CPRO_CMD_COMSENDSTATS = 20
.equ CPRO_CMD_COMRECVSTATS = 21
.equ CPRO_CMD_TWIBUSMEMBER = 30
.equ CPRO_CMD_DEBUG = 40
.equ CPRO_CMD_VALUE = 51 ; was 50 when sending timestamp instead of uid
.equ CPRO_CMD_NEED_ADDRESS = 60
.equ CPRO_CMD_HAVE_ADDRESS = 61
.equ CPRO_CMD_CLAIM_ADDRESS = 62
.equ CPRO_CMD_DENY_ADDRESS = 63
.equ CPRO_CMD_ADDRESS_RANGE = 64
.equ CPRO_CMD_FLASH_START = 70
.equ CPRO_CMD_FLASH_END = 71
.equ CPRO_CMD_FLASH_READY = 72
.equ CPRO_CMD_FLASH_DATA = 73
.equ CPRO_CMD_FLASH_RSP = 74
.equ CPRO_CMD_DEVICE = 80
.equ CPRO_CMD_MEMSTATS = 81
.equ CPRO_CMD_SYSSTATS = 82
.equ CPRO_CMD_REBOOT_REQUEST = 90
.equ CPRO_CMD_REBOOT_RESPONSE = 91
.equ CPRO_PACKET_HAVEADDR_OFFS_ADDRESS = COM2_MSG_OFFS_PAYLOAD+4
.equ CPRO_PACKET_CLAIMADDR_OFFS_ADDRESS = COM2_MSG_OFFS_PAYLOAD+4
.equ CPRO_PACKET_DENYADDR_OFFS_ADDRESS = COM2_MSG_OFFS_PAYLOAD+4
.equ CPRO_PACKET_REBOOTREQ_OFFS_UID = COM2_MSG_OFFS_PAYLOAD+0
.equ CPRO_WAITTIME_INITIAL = 10
.equ CPRO_WAITTIME_GETADDR = 130
.equ CPRO_WAITTIME_CLAIMADDR = 17
.equ CPRO_WAITTIME_RECLAIMADDR = 10
; current mode of operation
.equ CPRO_MODE_NOADDRESS = 0x00 ; no address, yet
.equ CPRO_MODE_NORMAL = 0x01 ; normal operation
.equ CPRO_MODE_SEND_NEED_ADDR = 0x02 ; wait to send need address
.equ CPRO_MODE_GETADDRSTARTED = 0x03 ; waiting for HAVE_ADDRESS and ADDRESS_RANGE packets to arrive
.equ CPRO_MODE_SEND_CLAIM_ADDR1 = 0x04 ; send CLAIM_ADDRESS as part of reclaiming procedure
.equ CPRO_MODE_CLAIMING_ADDR1 = 0x05 ; CLAIM_ADDRESS sent, waiting for HAVE_ADDRESS packet to reject the claim
.equ CPRO_MODE_CLAIMING_ADDR2 = 0x06 ; CLAIM_ADDRESS sent, 2nd try
.equ CPRO_MODE_CLAIMING_ADDR3 = 0x07 ; CLAIM_ADDRESS sent, 3rd try
.equ CPRO_MODE_SENDING_HAVE_ADDR = 0x08 ; waiting for our turn to send HAVE_ADDRESS packet
.equ CPRO_MODE_SEND_RECLAIM_ADDR = 0x09 ; send CLAIM_ADDRESS as part of reclaiming procedure
.equ CPRO_MODE_RECLAIMING_ADDR = 0x0a ; CLAIM_ADDRESS with the previously used address sent after bootup
.equ CPRO_MODE_SEND_DENY_ADDR = 0x0b ; someone claimed our address, send a DENY_ADDR message
.equ CPRO_MODE_NEXT_FREE = 0x0c ; next free mode

View File

@@ -0,0 +1,53 @@
; ***************************************************************************
; copyright : (C) 2023 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
; ---------------------------------------------------------------------------
; Enqueue a DEVICE packet.
;
; IN:
; - R16: destination address
; - X : buffer to write to
; OUT:
; - nothing
; REGS: R3, R4, R16, R17, R18, X (R19, R20, R21)
CPRO_WriteDevice:
ldi r17, COM2_PAYLOAD_FLAGS_UID | (6<<COM2_PAYLOAD_FLAGS_SHIFT_NUM)
ldi r18, CPRO_CMD_DEVICE
push xh
push xl
rcall COM2_BeginMsgWithVariablePayload ; (R3, R4, R16, R17, R18, R19, R20, R21, X)
lds r17, firmwareType
st X+, r17 ; 6: firmware type low
lds r17, firmwareType+1
st X+, r17 ; 7: firmware type high
lds r17, firmwareVersion
st X+, r17 ; 8: version low
lds r17, firmwareVersion+1
st X+, r17 ; 9: version high
lds r17, firmwareModules
st X+, r17 ; 10: modules mask low
lds r17, firmwareModules+1
st X+, r17 ; 11: modules mask low
pop xl
pop xh
rcall com2CalcAndAddChecksumByte ; (R16, R17, R18, R19, X)
ret

View File

@@ -0,0 +1,57 @@
; ***************************************************************************
; copyright : (C) 2023 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
; ---------------------------------------------------------------------------
; Enqueue a MEMSTATS packet.
;
; IN:
; - R16: destination address
; OUT:
; - nothing
; REGS: R3, R4, R16, R17, R18, X (R19, R20, R21)
CPRO_WriteMemStats:
ldi r17, COM2_PAYLOAD_FLAGS_UID | COM2_PAYLOAD_FLAGS_SECONDS | (6<<COM2_PAYLOAD_FLAGS_SHIFT_NUM)
ldi r18, CPRO_CMD_MEMSTATS
push xh
push xl
rcall COM2_BeginMsgWithVariablePayload ; (R3, R4, R16, R17, R18, R19, R20, R21, X)
; payload
ldi r20, LOW(RAMEND)
ldi r21, HIGH(RAMEND)
in r17, SPL
sub r20, r17
st X+, r20 ; stack used
in r17, SPH
sbc r21, r17
st X+, r21
lds r17, com2RecvBuffersUsed
st X+, r17 ; used buffers
lds r17, com2MaxBuffersUsed
st X+, r17 ; max used buffers
lds r17, com2StatsNoBufferError
st X+, r17 ; recvNoBuffer
lds r17, com2StatsNoBufferError+1
st X+, r17
pop xl
pop xh
rcall com2CalcAndAddChecksumByte ; (R16, R17, R18, R19, X)
ret

View File

@@ -0,0 +1,33 @@
; ***************************************************************************
; copyright : (C) 2023 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
; ---------------------------------------------------------------------------
; Write a PING packet.
;
; IN:
; - R16: destination address
; - X : buffer to write to
; OUT:
; - nothing
; REGS: R3, R4, R16, R17, R18, X (R19, R20, R21)
CPRO_WritePing:
ldi r18, CPRO_CMD_PING
rjmp COM2_WriteMsgWithCmdAndSrcAddr

View File

@@ -0,0 +1,33 @@
; ***************************************************************************
; copyright : (C) 2023 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
; ---------------------------------------------------------------------------
; Write a PONG packet.
;
; IN:
; - R16: destination address
; - X : buffer to write to
; OUT:
; - nothing
; REGS: R3, R4, R16, R17, R18, X (R19, R20, R21)
CPRO_WritePong:
ldi r18, CPRO_CMD_PONG
rjmp COM2_WriteMsgWithCmdAndSrcAddr

View File

@@ -0,0 +1,71 @@
; ***************************************************************************
; copyright : (C) 2023 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
; ---------------------------------------------------------------------------
; Handle reboot request
;
; IN:
; - X : buffer containing the received packet
; OUT:
; - nothing
; REGS:
cproHandleReboot:
adiw xh:xl, CPRO_PACKET_REBOOTREQ_OFFS_UID
rcall cproCheckUidInMsg
brcc cproHandleReboot_notHandled
sbiw xh:xl, CPRO_PACKET_REBOOTREQ_OFFS_UID+4
adiw xh:xl, COM2_MSG_OFFS_SRCADDR
ld r16, x
cpi r16, 0xff
breq cproHandleReboot_notHandled ; dont handle src address 255
cproHandleReboot_loop1:
push r16
ldi xl, LOW(com2SendBuffer)
ldi xh, HIGH(com2SendBuffer)
rcall CPRO_WriteRebootResponse
rcall COM2_SendPacket
pop r16
brcc cproHandleReboot_loop1
; directly call bootloader
cli
rjmp AQHOME_BOOTLOADER_ADDR
cproHandleReboot_notHandled:
clc
ret
; ---------------------------------------------------------------------------
; Write a Reboot Response packet.
;
; IN:
; - R16: destination address
; - X : buffer to write to
; OUT:
; - nothing
; REGS: R3, R4, R16, R17, R18, X (R19, R20, R21)
CPRO_WriteRebootResponse:
ldi r18, CPRO_CMD_REBOOT_RESPONSE
rjmp COM2_WriteMsgWithCmdAndSrcAddr ; R3, R4, R15, R16, R17, R18, R19, R20, R21, X

View File

@@ -0,0 +1,66 @@
; ***************************************************************************
; copyright : (C) 2023 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
; ---------------------------------------------------------------------------
; Write a COM reception stats packet.
;
; IN:
; - R16: destination address
; - X : buffer to write to
; OUT:
; - nothing
; REGS: R3, R4, R16, R17, R18, X (R19, R20, R21)
CPRO_WriteComRecvStats:
ldi r17, COM2_PAYLOAD_FLAGS_UID | (12<<COM2_PAYLOAD_FLAGS_SHIFT_NUM) ; seconds + 12 bytes payload
ldi r18, CPRO_CMD_COMRECVSTATS
push xh
push xl
rcall COM2_BeginMsgWithVariablePayload ; (R3, R4, R16, R17, R18, R19, R20, R21, X)
lds r16, com2StatsPacketsIn ; packets in
st X+, r16
lds r16, com2StatsPacketsIn+1
st X+, r16
lds r16, com2StatsContentError ; CRC errors
st X+, r16
lds r16, com2StatsContentError+1
st X+, r16
lds r16, com2StatsIoError ; IO errors
st X+, r16
lds r16, com2StatsIoError+1
st X+, r16
lds r16, com2StatsNoBufferError ; no buffer
st X+, r16
lds r16, com2StatsNoBufferError+1
st X+, r16
lds r16, com2StatsHandled
st X+, r16
lds r16, com2StatsHandled+1
st X+, r16
lds r16, com2StatsMissed
st X+, r16
lds r16, com2StatsMissed+1
st X+, r16
pop xl
pop xh
rcall com2CalcAndAddChecksumByte ; (R16, R17, R18, R19, X)
ret

View File

@@ -0,0 +1,53 @@
; ***************************************************************************
; copyright : (C) 2023 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
; ---------------------------------------------------------------------------
; Write a ComSendStats packet.
;
; IN:
; - R16: destination address
; - X : buffer to write to
; OUT:
; - nothing
; REGS: R3, R4, R16, R17, R18, X (R19, R20, R21)
CPRO_WriteComSendStats:
ldi r17, COM2_PAYLOAD_FLAGS_UID | (6<<COM2_PAYLOAD_FLAGS_SHIFT_NUM) ; UID + 6 bytes payload
ldi r18, CPRO_CMD_COMSENDSTATS
push xh
push xl
rcall COM2_BeginMsgWithVariablePayload ; (R3, R4, R16, R17, R18, R19, R20, R21, X)
lds r16, com2StatsPacketsOut ; packets out
st X+, r16
lds r16, com2StatsPacketsOut+1
st X+, r16
lds r16, com2StatsCollisions ; collisions
st X+, r16
lds r16, com2StatsCollisions+1
st X+, r16
lds r16, com2StatsBusyError ; busy
st X+, r16
lds r16, com2StatsBusyError+1
st X+, r16
pop xl
pop xh
rcall com2CalcAndAddChecksumByte ; (R16, R17, R18, R19, X)
ret

View File

@@ -0,0 +1,50 @@
; ***************************************************************************
; copyright : (C) 2023 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
; ---------------------------------------------------------------------------
; Write a SYSSTATS packet.
;
; IN:
; - R16: destination address
; - X : buffer to write to
; OUT:
; - nothing
; REGS: R3, R4, R16, R17, R18, X (R19, R20, R21)
CPRO_WriteSysStats:
ldi r17, COM2_PAYLOAD_FLAGS_UID | COM2_PAYLOAD_FLAGS_SECONDS | (4<<COM2_PAYLOAD_FLAGS_SHIFT_NUM)
ldi r18, CPRO_CMD_SYSSTATS
push xh
push xl
rcall COM2_BeginMsgWithVariablePayload ; (R3, R4, R16, R17, R18, R19, R20, R21, X)
; payload
lds r17, com2Interrupts
st X+, r17 ; com interrupts
lds r17, com2Interrupts+1
st X+, r17
lds r17, timerInterrupts
st X+, r17 ; timer interrupts
lds r17, timerInterrupts+1
st X+, r17
pop xl
pop xh
rcall com2CalcAndAddChecksumByte ; (R16, R17, R18, R19, X)
ret

View File

@@ -0,0 +1,67 @@
; ***************************************************************************
; copyright : (C) 2023 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
; ---------------------------------------------------------------------------
; Enqueue a TWI Bus Member packet.
;
; IN:
; - R16: destination address
; - R1 : Address of the bus member
; - R2 : availability (0=not available, 1=available)
; OUT:
; - CFLAG: set if okay, clear otherwise
; MODIFIED REGS: R16, R17, R20, X (R15, Y)
CPRO_EnqueueTwiBusMember:
push r16
rcall COM_AllocBufferAndGetXY ; (r16, r17, r21)
pop r16
brcc CPRO_EnqueueTwiBusMember_error
clr r17 ; r17: XOR byte
; write header (dest address, msg length)
st X+, r16 ; destination address
eor r17, r16
ldi r16, 4 ; 4 bytes payload
st X+, r16
eor r17, r16
; write payload
ldi r16, CPRO_CMD_TWIBUSMEMBER ; send command
st X+, r16
eor r17, r16
lds r16, comAddress ; send source address
st X+, r16
eor r17, r16
mov r16, r1 ; send i2c bus member address
st X+, r16
eor r17, r16
mov r16, r2 ; send i2c bus member availability
st X+, r16
eor r17, r16
; store XOR byte
st X+, r17
; mark buffer as enqueued with PRIO "info" (limited amount of retries)
ldi r20, COM_BUFFER_PRIO_INFO
rcall COM_EnqueuePacket ; (R15, R16)
brcc CPRO_EnqueueTwiBusMember_error
sec
ret
CPRO_EnqueueTwiBusMember_error:
clc
ret

View File

@@ -0,0 +1,58 @@
; ***************************************************************************
; copyright : (C) 2023 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
; ---------------------------------------------------------------------------
; Write a VALUE packet.
;
; IN:
; - R16: destination address
; - R17: value id
; - R19:R18: value
; - R21:R20: denom (e.g. 100, meaning value must be divided by 100)
; - R22: value type
; - X : buffer to write to
; OUT:
; - CFLAG: set if okay, clear otherwise
; MODIFIED REGS: R6, R7, R8, R9, R10, R11, R12, R16, R17, X, Y (R3, R4, R15, R16, R17, R18, R19, R20, R21)
CPRO_WriteValue:
mov r7, r17
mov r8, r18
mov r9, r19
mov r10, r20
mov r11, r21
mov r12, r22
ldi r17, COM2_PAYLOAD_FLAGS_UID | (6<<COM2_PAYLOAD_FLAGS_SHIFT_NUM)
ldi r18, CPRO_CMD_VALUE
push xh
push xl
rcall COM2_BeginMsgWithVariablePayload ; R3, R4, R16, R17, R18, R19, R20, R21, X
st X+, r7 ; 6: value id
st X+, r12 ; 7: value type
st X+, r8 ; 8: low value
st X+, r9 ; 9: high value
st X+, r10 ; 10: low denom
st X+, r11 ; 11: high denom
pop xl
pop xh
rcall com2CalcAndAddChecksumByte ; (R16, R17, R18, R19, X)
ret