; *************************************************************************** ; 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_NEED_ADDRESS brcs CPRO_Address_OnPacketReceived_nc ; smaller than 60 cpi r16, (CPRO_CMD_ADDRESS_RANGE+1) brcc CPRO_Address_OnPacketReceived_nc CPRO_Address_OnPacketReceived_debug2: ldi r17, (cproPacketTypeTransTableEnd-cproPacketTypeTransTableBegin)*2 ldi zl, LOW(cproPacketTypeTransTableBegin) ldi zh, HIGH(cproPacketTypeTransTableBegin) rcall Utils_FindBytePositionInTable brcc CPRO_Address_OnPacketReceived_nc ldi r17, (cproPacketTypeTransTableEnd-cproPacketTypeTransTableBegin)*2 ldi zl, LOW(cproPacketTypeHandleTable) ldi zh, HIGH(cproPacketTypeHandleTable) rcall Utils_TableJump sec ret CPRO_Address_OnPacketReceived_nc: clc ret cproPacketTypeTransTableBegin: .db CPRO_CMD_NEED_ADDRESS, CPRO_CMD_HAVE_ADDRESS, CPRO_CMD_ADDRESS_RANGE, CPRO_CMD_DENY_ADDRESS, CPRO_CMD_CLAIM_ADDRESS, CPRO_CMD_PING cproPacketTypeTransTableEnd: ; position within table must be in same order as in table above! cproPacketTypeHandleTable: .dw cproHandleNeedAddr, cproHandleHaveAddr, cproHandleAddrRange, cproHandleDenyAddr, cproHandleClaimAddr, cproHandlePing 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 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_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