Files
aqhomecontrol/avr/modules/comproto/addr2.asm
2024-09-27 00:33:11 +02:00

193 lines
5.3 KiB
NASM

; ***************************************************************************
; 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
cpi r16, CPRO_CMD_DENY_ADDRESS
breq CPRO_Address_OnPacketReceived_denyAddr
cpi r16, CPRO_CMD_CLAIM_ADDRESS
breq CPRO_Address_OnPacketReceived_claimAddr
rjmp CPRO_Address_OnPacketReceived_nc
cpi r16, CPRO_CMD_NEED_ADDRESS
brcs CPRO_Address_OnPacketReceived_nc ; smaller than 60
cpi r16, (CPRO_CMD_ADDRESS_RANGE+1)
brcc CPRO_Address_OnPacketReceived_nc
subi r16, CPRO_CMD_NEED_ADDRESS
ldi r17, (cproPacketTypeHandleTableEnd-cproPacketTypeHandleTableBegin)
ldi zl, LOW(cproPacketTypeHandleTableBegin)
ldi zh, HIGH(cproPacketTypeHandleTableBegin)
rcall Utils_TableJump
sec
ret
CPRO_Address_OnPacketReceived_denyAddr:
rjmp cproHandleDenyAddr
CPRO_Address_OnPacketReceived_claimAddr:
rjmp cproHandleClaimAddr
CPRO_Address_OnPacketReceived_nc:
clc
ret
; fixed position from CPRO_CMD_NEED_ADDRESS to CPRO_CMD_ADDRESS_RANGE!!
cproPacketTypeHandleTableBegin:
.dw cproHandleNeedAddr, cproHandleHaveAddr, cproHandleClaimAddr, cproHandleDenyAddr, cproHandleAddrRange
cproPacketTypeHandleTableEnd:
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
lsl r24 ; *2
rol r25
lsl r24 ; *4
rol r25
lsl r24 ; *8
rol r25
adiw r25:r24, 30 ; add 3 secs
mov r18, r24
mov r19, r25
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
sbiw xh:xl, CPRO_PACKET_CLAIMADDR_OFFS_ADDRESS
tst r16 ; dont handle claim addr 0
breq cproHandleClaimAddr_done
cpi r16, 0xff ; dont handle claim addr 0
breq cproHandleClaimAddr_done
lds r17, com2Address
tst r17
breq cproHandleClaimAddr_done ; we have no address, yet
cp r16, r17
brne cproHandleClaimAddr_done ; not our address
ldi r16, CPRO_MODE_SEND_DENY_ADDR1
sts cproMode, r16
rcall cproAddressSetTimer1s
cproHandleClaimAddr_done:
sec
ret
cproHandleDenyAddr:
; debug
; cbi LED_SIMPLE_PORT, LED_SIMPLE_PINNUM ; on
; 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